diff options
Diffstat (limited to 'net/bluetooth/rfcomm/tty.c')
-rw-r--r-- | net/bluetooth/rfcomm/tty.c | 262 |
1 files changed, 144 insertions, 118 deletions
diff --git a/net/bluetooth/rfcomm/tty.c b/net/bluetooth/rfcomm/tty.c index f9c0980abeea..403ec09f480a 100644 --- a/net/bluetooth/rfcomm/tty.c +++ b/net/bluetooth/rfcomm/tty.c | |||
@@ -40,6 +40,7 @@ | |||
40 | #define RFCOMM_TTY_MAJOR 216 /* device node major id of the usb/bluetooth.c driver */ | 40 | #define RFCOMM_TTY_MAJOR 216 /* device node major id of the usb/bluetooth.c driver */ |
41 | #define RFCOMM_TTY_MINOR 0 | 41 | #define RFCOMM_TTY_MINOR 0 |
42 | 42 | ||
43 | static DEFINE_MUTEX(rfcomm_ioctl_mutex); | ||
43 | static struct tty_driver *rfcomm_tty_driver; | 44 | static struct tty_driver *rfcomm_tty_driver; |
44 | 45 | ||
45 | struct rfcomm_dev { | 46 | struct rfcomm_dev { |
@@ -51,6 +52,8 @@ struct rfcomm_dev { | |||
51 | unsigned long flags; | 52 | unsigned long flags; |
52 | int err; | 53 | int err; |
53 | 54 | ||
55 | unsigned long status; /* don't export to userspace */ | ||
56 | |||
54 | bdaddr_t src; | 57 | bdaddr_t src; |
55 | bdaddr_t dst; | 58 | bdaddr_t dst; |
56 | u8 channel; | 59 | u8 channel; |
@@ -58,7 +61,6 @@ struct rfcomm_dev { | |||
58 | uint modem_status; | 61 | uint modem_status; |
59 | 62 | ||
60 | struct rfcomm_dlc *dlc; | 63 | struct rfcomm_dlc *dlc; |
61 | wait_queue_head_t conn_wait; | ||
62 | 64 | ||
63 | struct device *tty_dev; | 65 | struct device *tty_dev; |
64 | 66 | ||
@@ -83,10 +85,6 @@ static void rfcomm_dev_destruct(struct tty_port *port) | |||
83 | 85 | ||
84 | BT_DBG("dev %p dlc %p", dev, dlc); | 86 | BT_DBG("dev %p dlc %p", dev, dlc); |
85 | 87 | ||
86 | spin_lock(&rfcomm_dev_lock); | ||
87 | list_del(&dev->list); | ||
88 | spin_unlock(&rfcomm_dev_lock); | ||
89 | |||
90 | rfcomm_dlc_lock(dlc); | 88 | rfcomm_dlc_lock(dlc); |
91 | /* Detach DLC if it's owned by this dev */ | 89 | /* Detach DLC if it's owned by this dev */ |
92 | if (dlc->owner == dev) | 90 | if (dlc->owner == dev) |
@@ -95,7 +93,12 @@ static void rfcomm_dev_destruct(struct tty_port *port) | |||
95 | 93 | ||
96 | rfcomm_dlc_put(dlc); | 94 | rfcomm_dlc_put(dlc); |
97 | 95 | ||
98 | tty_unregister_device(rfcomm_tty_driver, dev->id); | 96 | if (dev->tty_dev) |
97 | tty_unregister_device(rfcomm_tty_driver, dev->id); | ||
98 | |||
99 | spin_lock(&rfcomm_dev_lock); | ||
100 | list_del(&dev->list); | ||
101 | spin_unlock(&rfcomm_dev_lock); | ||
99 | 102 | ||
100 | kfree(dev); | 103 | kfree(dev); |
101 | 104 | ||
@@ -104,60 +107,24 @@ static void rfcomm_dev_destruct(struct tty_port *port) | |||
104 | module_put(THIS_MODULE); | 107 | module_put(THIS_MODULE); |
105 | } | 108 | } |
106 | 109 | ||
107 | static struct device *rfcomm_get_device(struct rfcomm_dev *dev) | ||
108 | { | ||
109 | struct hci_dev *hdev; | ||
110 | struct hci_conn *conn; | ||
111 | |||
112 | hdev = hci_get_route(&dev->dst, &dev->src); | ||
113 | if (!hdev) | ||
114 | return NULL; | ||
115 | |||
116 | conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &dev->dst); | ||
117 | |||
118 | hci_dev_put(hdev); | ||
119 | |||
120 | return conn ? &conn->dev : NULL; | ||
121 | } | ||
122 | |||
123 | /* device-specific initialization: open the dlc */ | 110 | /* device-specific initialization: open the dlc */ |
124 | static int rfcomm_dev_activate(struct tty_port *port, struct tty_struct *tty) | 111 | static int rfcomm_dev_activate(struct tty_port *port, struct tty_struct *tty) |
125 | { | 112 | { |
126 | struct rfcomm_dev *dev = container_of(port, struct rfcomm_dev, port); | 113 | struct rfcomm_dev *dev = container_of(port, struct rfcomm_dev, port); |
127 | DEFINE_WAIT(wait); | ||
128 | int err; | 114 | int err; |
129 | 115 | ||
130 | err = rfcomm_dlc_open(dev->dlc, &dev->src, &dev->dst, dev->channel); | 116 | err = rfcomm_dlc_open(dev->dlc, &dev->src, &dev->dst, dev->channel); |
131 | if (err) | 117 | if (err) |
132 | return err; | 118 | set_bit(TTY_IO_ERROR, &tty->flags); |
133 | 119 | return err; | |
134 | while (1) { | 120 | } |
135 | prepare_to_wait(&dev->conn_wait, &wait, TASK_INTERRUPTIBLE); | ||
136 | |||
137 | if (dev->dlc->state == BT_CLOSED) { | ||
138 | err = -dev->err; | ||
139 | break; | ||
140 | } | ||
141 | |||
142 | if (dev->dlc->state == BT_CONNECTED) | ||
143 | break; | ||
144 | |||
145 | if (signal_pending(current)) { | ||
146 | err = -ERESTARTSYS; | ||
147 | break; | ||
148 | } | ||
149 | |||
150 | tty_unlock(tty); | ||
151 | schedule(); | ||
152 | tty_lock(tty); | ||
153 | } | ||
154 | finish_wait(&dev->conn_wait, &wait); | ||
155 | 121 | ||
156 | if (!err) | 122 | /* we block the open until the dlc->state becomes BT_CONNECTED */ |
157 | device_move(dev->tty_dev, rfcomm_get_device(dev), | 123 | static int rfcomm_dev_carrier_raised(struct tty_port *port) |
158 | DPM_ORDER_DEV_AFTER_PARENT); | 124 | { |
125 | struct rfcomm_dev *dev = container_of(port, struct rfcomm_dev, port); | ||
159 | 126 | ||
160 | return err; | 127 | return (dev->dlc->state == BT_CONNECTED); |
161 | } | 128 | } |
162 | 129 | ||
163 | /* device-specific cleanup: close the dlc */ | 130 | /* device-specific cleanup: close the dlc */ |
@@ -176,9 +143,10 @@ static const struct tty_port_operations rfcomm_port_ops = { | |||
176 | .destruct = rfcomm_dev_destruct, | 143 | .destruct = rfcomm_dev_destruct, |
177 | .activate = rfcomm_dev_activate, | 144 | .activate = rfcomm_dev_activate, |
178 | .shutdown = rfcomm_dev_shutdown, | 145 | .shutdown = rfcomm_dev_shutdown, |
146 | .carrier_raised = rfcomm_dev_carrier_raised, | ||
179 | }; | 147 | }; |
180 | 148 | ||
181 | static struct rfcomm_dev *__rfcomm_dev_get(int id) | 149 | static struct rfcomm_dev *__rfcomm_dev_lookup(int id) |
182 | { | 150 | { |
183 | struct rfcomm_dev *dev; | 151 | struct rfcomm_dev *dev; |
184 | 152 | ||
@@ -195,20 +163,41 @@ static struct rfcomm_dev *rfcomm_dev_get(int id) | |||
195 | 163 | ||
196 | spin_lock(&rfcomm_dev_lock); | 164 | spin_lock(&rfcomm_dev_lock); |
197 | 165 | ||
198 | dev = __rfcomm_dev_get(id); | 166 | dev = __rfcomm_dev_lookup(id); |
199 | 167 | ||
200 | if (dev) { | 168 | if (dev && !tty_port_get(&dev->port)) |
201 | if (test_bit(RFCOMM_TTY_RELEASED, &dev->flags)) | 169 | dev = NULL; |
202 | dev = NULL; | ||
203 | else | ||
204 | tty_port_get(&dev->port); | ||
205 | } | ||
206 | 170 | ||
207 | spin_unlock(&rfcomm_dev_lock); | 171 | spin_unlock(&rfcomm_dev_lock); |
208 | 172 | ||
209 | return dev; | 173 | return dev; |
210 | } | 174 | } |
211 | 175 | ||
176 | static void rfcomm_reparent_device(struct rfcomm_dev *dev) | ||
177 | { | ||
178 | struct hci_dev *hdev; | ||
179 | struct hci_conn *conn; | ||
180 | |||
181 | hdev = hci_get_route(&dev->dst, &dev->src); | ||
182 | if (!hdev) | ||
183 | return; | ||
184 | |||
185 | /* The lookup results are unsafe to access without the | ||
186 | * hci device lock (FIXME: why is this not documented?) | ||
187 | */ | ||
188 | hci_dev_lock(hdev); | ||
189 | conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &dev->dst); | ||
190 | |||
191 | /* Just because the acl link is in the hash table is no | ||
192 | * guarantee the sysfs device has been added ... | ||
193 | */ | ||
194 | if (conn && device_is_registered(&conn->dev)) | ||
195 | device_move(dev->tty_dev, &conn->dev, DPM_ORDER_DEV_AFTER_PARENT); | ||
196 | |||
197 | hci_dev_unlock(hdev); | ||
198 | hci_dev_put(hdev); | ||
199 | } | ||
200 | |||
212 | static ssize_t show_address(struct device *tty_dev, struct device_attribute *attr, char *buf) | 201 | static ssize_t show_address(struct device *tty_dev, struct device_attribute *attr, char *buf) |
213 | { | 202 | { |
214 | struct rfcomm_dev *dev = dev_get_drvdata(tty_dev); | 203 | struct rfcomm_dev *dev = dev_get_drvdata(tty_dev); |
@@ -224,17 +213,16 @@ static ssize_t show_channel(struct device *tty_dev, struct device_attribute *att | |||
224 | static DEVICE_ATTR(address, S_IRUGO, show_address, NULL); | 213 | static DEVICE_ATTR(address, S_IRUGO, show_address, NULL); |
225 | static DEVICE_ATTR(channel, S_IRUGO, show_channel, NULL); | 214 | static DEVICE_ATTR(channel, S_IRUGO, show_channel, NULL); |
226 | 215 | ||
227 | static int rfcomm_dev_add(struct rfcomm_dev_req *req, struct rfcomm_dlc *dlc) | 216 | static struct rfcomm_dev *__rfcomm_dev_add(struct rfcomm_dev_req *req, |
217 | struct rfcomm_dlc *dlc) | ||
228 | { | 218 | { |
229 | struct rfcomm_dev *dev, *entry; | 219 | struct rfcomm_dev *dev, *entry; |
230 | struct list_head *head = &rfcomm_dev_list; | 220 | struct list_head *head = &rfcomm_dev_list; |
231 | int err = 0; | 221 | int err = 0; |
232 | 222 | ||
233 | BT_DBG("id %d channel %d", req->dev_id, req->channel); | ||
234 | |||
235 | dev = kzalloc(sizeof(struct rfcomm_dev), GFP_KERNEL); | 223 | dev = kzalloc(sizeof(struct rfcomm_dev), GFP_KERNEL); |
236 | if (!dev) | 224 | if (!dev) |
237 | return -ENOMEM; | 225 | return ERR_PTR(-ENOMEM); |
238 | 226 | ||
239 | spin_lock(&rfcomm_dev_lock); | 227 | spin_lock(&rfcomm_dev_lock); |
240 | 228 | ||
@@ -282,7 +270,6 @@ static int rfcomm_dev_add(struct rfcomm_dev_req *req, struct rfcomm_dlc *dlc) | |||
282 | 270 | ||
283 | tty_port_init(&dev->port); | 271 | tty_port_init(&dev->port); |
284 | dev->port.ops = &rfcomm_port_ops; | 272 | dev->port.ops = &rfcomm_port_ops; |
285 | init_waitqueue_head(&dev->conn_wait); | ||
286 | 273 | ||
287 | skb_queue_head_init(&dev->pending); | 274 | skb_queue_head_init(&dev->pending); |
288 | 275 | ||
@@ -318,22 +305,37 @@ static int rfcomm_dev_add(struct rfcomm_dev_req *req, struct rfcomm_dlc *dlc) | |||
318 | holds reference to this module. */ | 305 | holds reference to this module. */ |
319 | __module_get(THIS_MODULE); | 306 | __module_get(THIS_MODULE); |
320 | 307 | ||
308 | spin_unlock(&rfcomm_dev_lock); | ||
309 | return dev; | ||
310 | |||
321 | out: | 311 | out: |
322 | spin_unlock(&rfcomm_dev_lock); | 312 | spin_unlock(&rfcomm_dev_lock); |
313 | kfree(dev); | ||
314 | return ERR_PTR(err); | ||
315 | } | ||
316 | |||
317 | static int rfcomm_dev_add(struct rfcomm_dev_req *req, struct rfcomm_dlc *dlc) | ||
318 | { | ||
319 | struct rfcomm_dev *dev; | ||
320 | struct device *tty; | ||
321 | |||
322 | BT_DBG("id %d channel %d", req->dev_id, req->channel); | ||
323 | 323 | ||
324 | if (err < 0) | 324 | dev = __rfcomm_dev_add(req, dlc); |
325 | goto free; | 325 | if (IS_ERR(dev)) { |
326 | rfcomm_dlc_put(dlc); | ||
327 | return PTR_ERR(dev); | ||
328 | } | ||
326 | 329 | ||
327 | dev->tty_dev = tty_port_register_device(&dev->port, rfcomm_tty_driver, | 330 | tty = tty_port_register_device(&dev->port, rfcomm_tty_driver, |
328 | dev->id, NULL); | 331 | dev->id, NULL); |
329 | if (IS_ERR(dev->tty_dev)) { | 332 | if (IS_ERR(tty)) { |
330 | err = PTR_ERR(dev->tty_dev); | 333 | tty_port_put(&dev->port); |
331 | spin_lock(&rfcomm_dev_lock); | 334 | return PTR_ERR(tty); |
332 | list_del(&dev->list); | ||
333 | spin_unlock(&rfcomm_dev_lock); | ||
334 | goto free; | ||
335 | } | 335 | } |
336 | 336 | ||
337 | dev->tty_dev = tty; | ||
338 | rfcomm_reparent_device(dev); | ||
337 | dev_set_drvdata(dev->tty_dev, dev); | 339 | dev_set_drvdata(dev->tty_dev, dev); |
338 | 340 | ||
339 | if (device_create_file(dev->tty_dev, &dev_attr_address) < 0) | 341 | if (device_create_file(dev->tty_dev, &dev_attr_address) < 0) |
@@ -343,24 +345,23 @@ out: | |||
343 | BT_ERR("Failed to create channel attribute"); | 345 | BT_ERR("Failed to create channel attribute"); |
344 | 346 | ||
345 | return dev->id; | 347 | return dev->id; |
346 | |||
347 | free: | ||
348 | kfree(dev); | ||
349 | return err; | ||
350 | } | 348 | } |
351 | 349 | ||
352 | /* ---- Send buffer ---- */ | 350 | /* ---- Send buffer ---- */ |
353 | static inline unsigned int rfcomm_room(struct rfcomm_dlc *dlc) | 351 | static inline unsigned int rfcomm_room(struct rfcomm_dev *dev) |
354 | { | 352 | { |
355 | /* We can't let it be zero, because we don't get a callback | 353 | struct rfcomm_dlc *dlc = dev->dlc; |
356 | when tx_credits becomes nonzero, hence we'd never wake up */ | 354 | |
357 | return dlc->mtu * (dlc->tx_credits?:1); | 355 | /* Limit the outstanding number of packets not yet sent to 40 */ |
356 | int pending = 40 - atomic_read(&dev->wmem_alloc); | ||
357 | |||
358 | return max(0, pending) * dlc->mtu; | ||
358 | } | 359 | } |
359 | 360 | ||
360 | static void rfcomm_wfree(struct sk_buff *skb) | 361 | static void rfcomm_wfree(struct sk_buff *skb) |
361 | { | 362 | { |
362 | struct rfcomm_dev *dev = (void *) skb->sk; | 363 | struct rfcomm_dev *dev = (void *) skb->sk; |
363 | atomic_sub(skb->truesize, &dev->wmem_alloc); | 364 | atomic_dec(&dev->wmem_alloc); |
364 | if (test_bit(RFCOMM_TTY_ATTACHED, &dev->flags)) | 365 | if (test_bit(RFCOMM_TTY_ATTACHED, &dev->flags)) |
365 | tty_port_tty_wakeup(&dev->port); | 366 | tty_port_tty_wakeup(&dev->port); |
366 | tty_port_put(&dev->port); | 367 | tty_port_put(&dev->port); |
@@ -369,28 +370,24 @@ static void rfcomm_wfree(struct sk_buff *skb) | |||
369 | static void rfcomm_set_owner_w(struct sk_buff *skb, struct rfcomm_dev *dev) | 370 | static void rfcomm_set_owner_w(struct sk_buff *skb, struct rfcomm_dev *dev) |
370 | { | 371 | { |
371 | tty_port_get(&dev->port); | 372 | tty_port_get(&dev->port); |
372 | atomic_add(skb->truesize, &dev->wmem_alloc); | 373 | atomic_inc(&dev->wmem_alloc); |
373 | skb->sk = (void *) dev; | 374 | skb->sk = (void *) dev; |
374 | skb->destructor = rfcomm_wfree; | 375 | skb->destructor = rfcomm_wfree; |
375 | } | 376 | } |
376 | 377 | ||
377 | static struct sk_buff *rfcomm_wmalloc(struct rfcomm_dev *dev, unsigned long size, gfp_t priority) | 378 | static struct sk_buff *rfcomm_wmalloc(struct rfcomm_dev *dev, unsigned long size, gfp_t priority) |
378 | { | 379 | { |
379 | if (atomic_read(&dev->wmem_alloc) < rfcomm_room(dev->dlc)) { | 380 | struct sk_buff *skb = alloc_skb(size, priority); |
380 | struct sk_buff *skb = alloc_skb(size, priority); | 381 | if (skb) |
381 | if (skb) { | 382 | rfcomm_set_owner_w(skb, dev); |
382 | rfcomm_set_owner_w(skb, dev); | 383 | return skb; |
383 | return skb; | ||
384 | } | ||
385 | } | ||
386 | return NULL; | ||
387 | } | 384 | } |
388 | 385 | ||
389 | /* ---- Device IOCTLs ---- */ | 386 | /* ---- Device IOCTLs ---- */ |
390 | 387 | ||
391 | #define NOCAP_FLAGS ((1 << RFCOMM_REUSE_DLC) | (1 << RFCOMM_RELEASE_ONHUP)) | 388 | #define NOCAP_FLAGS ((1 << RFCOMM_REUSE_DLC) | (1 << RFCOMM_RELEASE_ONHUP)) |
392 | 389 | ||
393 | static int rfcomm_create_dev(struct sock *sk, void __user *arg) | 390 | static int __rfcomm_create_dev(struct sock *sk, void __user *arg) |
394 | { | 391 | { |
395 | struct rfcomm_dev_req req; | 392 | struct rfcomm_dev_req req; |
396 | struct rfcomm_dlc *dlc; | 393 | struct rfcomm_dlc *dlc; |
@@ -412,16 +409,22 @@ static int rfcomm_create_dev(struct sock *sk, void __user *arg) | |||
412 | dlc = rfcomm_pi(sk)->dlc; | 409 | dlc = rfcomm_pi(sk)->dlc; |
413 | rfcomm_dlc_hold(dlc); | 410 | rfcomm_dlc_hold(dlc); |
414 | } else { | 411 | } else { |
412 | /* Validate the channel is unused */ | ||
413 | dlc = rfcomm_dlc_exists(&req.src, &req.dst, req.channel); | ||
414 | if (IS_ERR(dlc)) | ||
415 | return PTR_ERR(dlc); | ||
416 | else if (dlc) { | ||
417 | rfcomm_dlc_put(dlc); | ||
418 | return -EBUSY; | ||
419 | } | ||
415 | dlc = rfcomm_dlc_alloc(GFP_KERNEL); | 420 | dlc = rfcomm_dlc_alloc(GFP_KERNEL); |
416 | if (!dlc) | 421 | if (!dlc) |
417 | return -ENOMEM; | 422 | return -ENOMEM; |
418 | } | 423 | } |
419 | 424 | ||
420 | id = rfcomm_dev_add(&req, dlc); | 425 | id = rfcomm_dev_add(&req, dlc); |
421 | if (id < 0) { | 426 | if (id < 0) |
422 | rfcomm_dlc_put(dlc); | ||
423 | return id; | 427 | return id; |
424 | } | ||
425 | 428 | ||
426 | if (req.flags & (1 << RFCOMM_REUSE_DLC)) { | 429 | if (req.flags & (1 << RFCOMM_REUSE_DLC)) { |
427 | /* DLC is now used by device. | 430 | /* DLC is now used by device. |
@@ -432,7 +435,7 @@ static int rfcomm_create_dev(struct sock *sk, void __user *arg) | |||
432 | return id; | 435 | return id; |
433 | } | 436 | } |
434 | 437 | ||
435 | static int rfcomm_release_dev(void __user *arg) | 438 | static int __rfcomm_release_dev(void __user *arg) |
436 | { | 439 | { |
437 | struct rfcomm_dev_req req; | 440 | struct rfcomm_dev_req req; |
438 | struct rfcomm_dev *dev; | 441 | struct rfcomm_dev *dev; |
@@ -452,6 +455,12 @@ static int rfcomm_release_dev(void __user *arg) | |||
452 | return -EPERM; | 455 | return -EPERM; |
453 | } | 456 | } |
454 | 457 | ||
458 | /* only release once */ | ||
459 | if (test_and_set_bit(RFCOMM_DEV_RELEASED, &dev->status)) { | ||
460 | tty_port_put(&dev->port); | ||
461 | return -EALREADY; | ||
462 | } | ||
463 | |||
455 | if (req.flags & (1 << RFCOMM_HANGUP_NOW)) | 464 | if (req.flags & (1 << RFCOMM_HANGUP_NOW)) |
456 | rfcomm_dlc_close(dev->dlc, 0); | 465 | rfcomm_dlc_close(dev->dlc, 0); |
457 | 466 | ||
@@ -462,14 +471,35 @@ static int rfcomm_release_dev(void __user *arg) | |||
462 | tty_kref_put(tty); | 471 | tty_kref_put(tty); |
463 | } | 472 | } |
464 | 473 | ||
465 | if (!test_bit(RFCOMM_RELEASE_ONHUP, &dev->flags) && | 474 | if (!test_bit(RFCOMM_TTY_OWNED, &dev->status)) |
466 | !test_and_set_bit(RFCOMM_TTY_RELEASED, &dev->flags)) | ||
467 | tty_port_put(&dev->port); | 475 | tty_port_put(&dev->port); |
468 | 476 | ||
469 | tty_port_put(&dev->port); | 477 | tty_port_put(&dev->port); |
470 | return 0; | 478 | return 0; |
471 | } | 479 | } |
472 | 480 | ||
481 | static int rfcomm_create_dev(struct sock *sk, void __user *arg) | ||
482 | { | ||
483 | int ret; | ||
484 | |||
485 | mutex_lock(&rfcomm_ioctl_mutex); | ||
486 | ret = __rfcomm_create_dev(sk, arg); | ||
487 | mutex_unlock(&rfcomm_ioctl_mutex); | ||
488 | |||
489 | return ret; | ||
490 | } | ||
491 | |||
492 | static int rfcomm_release_dev(void __user *arg) | ||
493 | { | ||
494 | int ret; | ||
495 | |||
496 | mutex_lock(&rfcomm_ioctl_mutex); | ||
497 | ret = __rfcomm_release_dev(arg); | ||
498 | mutex_unlock(&rfcomm_ioctl_mutex); | ||
499 | |||
500 | return ret; | ||
501 | } | ||
502 | |||
473 | static int rfcomm_get_dev_list(void __user *arg) | 503 | static int rfcomm_get_dev_list(void __user *arg) |
474 | { | 504 | { |
475 | struct rfcomm_dev *dev; | 505 | struct rfcomm_dev *dev; |
@@ -497,7 +527,7 @@ static int rfcomm_get_dev_list(void __user *arg) | |||
497 | spin_lock(&rfcomm_dev_lock); | 527 | spin_lock(&rfcomm_dev_lock); |
498 | 528 | ||
499 | list_for_each_entry(dev, &rfcomm_dev_list, list) { | 529 | list_for_each_entry(dev, &rfcomm_dev_list, list) { |
500 | if (test_bit(RFCOMM_TTY_RELEASED, &dev->flags)) | 530 | if (!tty_port_get(&dev->port)) |
501 | continue; | 531 | continue; |
502 | (di + n)->id = dev->id; | 532 | (di + n)->id = dev->id; |
503 | (di + n)->flags = dev->flags; | 533 | (di + n)->flags = dev->flags; |
@@ -505,6 +535,7 @@ static int rfcomm_get_dev_list(void __user *arg) | |||
505 | (di + n)->channel = dev->channel; | 535 | (di + n)->channel = dev->channel; |
506 | bacpy(&(di + n)->src, &dev->src); | 536 | bacpy(&(di + n)->src, &dev->src); |
507 | bacpy(&(di + n)->dst, &dev->dst); | 537 | bacpy(&(di + n)->dst, &dev->dst); |
538 | tty_port_put(&dev->port); | ||
508 | if (++n >= dev_num) | 539 | if (++n >= dev_num) |
509 | break; | 540 | break; |
510 | } | 541 | } |
@@ -601,9 +632,11 @@ static void rfcomm_dev_state_change(struct rfcomm_dlc *dlc, int err) | |||
601 | BT_DBG("dlc %p dev %p err %d", dlc, dev, err); | 632 | BT_DBG("dlc %p dev %p err %d", dlc, dev, err); |
602 | 633 | ||
603 | dev->err = err; | 634 | dev->err = err; |
604 | wake_up_interruptible(&dev->conn_wait); | 635 | if (dlc->state == BT_CONNECTED) { |
636 | rfcomm_reparent_device(dev); | ||
605 | 637 | ||
606 | if (dlc->state == BT_CLOSED) | 638 | wake_up_interruptible(&dev->port.open_wait); |
639 | } else if (dlc->state == BT_CLOSED) | ||
607 | tty_port_tty_hangup(&dev->port, false); | 640 | tty_port_tty_hangup(&dev->port, false); |
608 | } | 641 | } |
609 | 642 | ||
@@ -703,8 +736,10 @@ static int rfcomm_tty_install(struct tty_driver *driver, struct tty_struct *tty) | |||
703 | * when the last process closes the tty. The behaviour is expected by | 736 | * when the last process closes the tty. The behaviour is expected by |
704 | * userspace. | 737 | * userspace. |
705 | */ | 738 | */ |
706 | if (test_bit(RFCOMM_RELEASE_ONHUP, &dev->flags)) | 739 | if (test_bit(RFCOMM_RELEASE_ONHUP, &dev->flags)) { |
740 | set_bit(RFCOMM_TTY_OWNED, &dev->status); | ||
707 | tty_port_put(&dev->port); | 741 | tty_port_put(&dev->port); |
742 | } | ||
708 | 743 | ||
709 | return 0; | 744 | return 0; |
710 | } | 745 | } |
@@ -750,7 +785,7 @@ static int rfcomm_tty_write(struct tty_struct *tty, const unsigned char *buf, in | |||
750 | struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data; | 785 | struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data; |
751 | struct rfcomm_dlc *dlc = dev->dlc; | 786 | struct rfcomm_dlc *dlc = dev->dlc; |
752 | struct sk_buff *skb; | 787 | struct sk_buff *skb; |
753 | int err = 0, sent = 0, size; | 788 | int sent = 0, size; |
754 | 789 | ||
755 | BT_DBG("tty %p count %d", tty, count); | 790 | BT_DBG("tty %p count %d", tty, count); |
756 | 791 | ||
@@ -758,7 +793,6 @@ static int rfcomm_tty_write(struct tty_struct *tty, const unsigned char *buf, in | |||
758 | size = min_t(uint, count, dlc->mtu); | 793 | size = min_t(uint, count, dlc->mtu); |
759 | 794 | ||
760 | skb = rfcomm_wmalloc(dev, size + RFCOMM_SKB_RESERVE, GFP_ATOMIC); | 795 | skb = rfcomm_wmalloc(dev, size + RFCOMM_SKB_RESERVE, GFP_ATOMIC); |
761 | |||
762 | if (!skb) | 796 | if (!skb) |
763 | break; | 797 | break; |
764 | 798 | ||
@@ -766,32 +800,24 @@ static int rfcomm_tty_write(struct tty_struct *tty, const unsigned char *buf, in | |||
766 | 800 | ||
767 | memcpy(skb_put(skb, size), buf + sent, size); | 801 | memcpy(skb_put(skb, size), buf + sent, size); |
768 | 802 | ||
769 | err = rfcomm_dlc_send(dlc, skb); | 803 | rfcomm_dlc_send_noerror(dlc, skb); |
770 | if (err < 0) { | ||
771 | kfree_skb(skb); | ||
772 | break; | ||
773 | } | ||
774 | 804 | ||
775 | sent += size; | 805 | sent += size; |
776 | count -= size; | 806 | count -= size; |
777 | } | 807 | } |
778 | 808 | ||
779 | return sent ? sent : err; | 809 | return sent; |
780 | } | 810 | } |
781 | 811 | ||
782 | static int rfcomm_tty_write_room(struct tty_struct *tty) | 812 | static int rfcomm_tty_write_room(struct tty_struct *tty) |
783 | { | 813 | { |
784 | struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data; | 814 | struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data; |
785 | int room; | 815 | int room = 0; |
786 | 816 | ||
787 | BT_DBG("tty %p", tty); | 817 | if (dev && dev->dlc) |
788 | 818 | room = rfcomm_room(dev); | |
789 | if (!dev || !dev->dlc) | ||
790 | return 0; | ||
791 | 819 | ||
792 | room = rfcomm_room(dev->dlc) - atomic_read(&dev->wmem_alloc); | 820 | BT_DBG("tty %p room %d", tty, room); |
793 | if (room < 0) | ||
794 | room = 0; | ||
795 | 821 | ||
796 | return room; | 822 | return room; |
797 | } | 823 | } |
@@ -1125,7 +1151,7 @@ int __init rfcomm_init_ttys(void) | |||
1125 | rfcomm_tty_driver->subtype = SERIAL_TYPE_NORMAL; | 1151 | rfcomm_tty_driver->subtype = SERIAL_TYPE_NORMAL; |
1126 | rfcomm_tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; | 1152 | rfcomm_tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; |
1127 | rfcomm_tty_driver->init_termios = tty_std_termios; | 1153 | rfcomm_tty_driver->init_termios = tty_std_termios; |
1128 | rfcomm_tty_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL; | 1154 | rfcomm_tty_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL; |
1129 | rfcomm_tty_driver->init_termios.c_lflag &= ~ICANON; | 1155 | rfcomm_tty_driver->init_termios.c_lflag &= ~ICANON; |
1130 | tty_set_operations(rfcomm_tty_driver, &rfcomm_ops); | 1156 | tty_set_operations(rfcomm_tty_driver, &rfcomm_ops); |
1131 | 1157 | ||