Commit 4475a0a9 authored by John W. Linville's avatar John W. Linville

Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/padovan/bluetooth

parents 16a9d06c 687beaa0
...@@ -63,6 +63,7 @@ static struct usb_device_id ath3k_table[] = { ...@@ -63,6 +63,7 @@ static struct usb_device_id ath3k_table[] = {
/* Atheros AR3011 with sflash firmware*/ /* Atheros AR3011 with sflash firmware*/
{ USB_DEVICE(0x0CF3, 0x3002) }, { USB_DEVICE(0x0CF3, 0x3002) },
{ USB_DEVICE(0x13d3, 0x3304) }, { USB_DEVICE(0x13d3, 0x3304) },
{ USB_DEVICE(0x0930, 0x0215) },
/* Atheros AR9285 Malbec with sflash firmware */ /* Atheros AR9285 Malbec with sflash firmware */
{ USB_DEVICE(0x03F0, 0x311D) }, { USB_DEVICE(0x03F0, 0x311D) },
......
...@@ -106,6 +106,7 @@ static struct usb_device_id blacklist_table[] = { ...@@ -106,6 +106,7 @@ static struct usb_device_id blacklist_table[] = {
/* Atheros 3011 with sflash firmware */ /* Atheros 3011 with sflash firmware */
{ USB_DEVICE(0x0cf3, 0x3002), .driver_info = BTUSB_IGNORE }, { USB_DEVICE(0x0cf3, 0x3002), .driver_info = BTUSB_IGNORE },
{ USB_DEVICE(0x13d3, 0x3304), .driver_info = BTUSB_IGNORE }, { USB_DEVICE(0x13d3, 0x3304), .driver_info = BTUSB_IGNORE },
{ USB_DEVICE(0x0930, 0x0215), .driver_info = BTUSB_IGNORE },
/* Atheros AR9285 Malbec with sflash firmware */ /* Atheros AR9285 Malbec with sflash firmware */
{ USB_DEVICE(0x03f0, 0x311d), .driver_info = BTUSB_IGNORE }, { USB_DEVICE(0x03f0, 0x311d), .driver_info = BTUSB_IGNORE },
...@@ -256,7 +257,9 @@ static void btusb_intr_complete(struct urb *urb) ...@@ -256,7 +257,9 @@ static void btusb_intr_complete(struct urb *urb)
err = usb_submit_urb(urb, GFP_ATOMIC); err = usb_submit_urb(urb, GFP_ATOMIC);
if (err < 0) { if (err < 0) {
if (err != -EPERM) /* -EPERM: urb is being killed;
* -ENODEV: device got disconnected */
if (err != -EPERM && err != -ENODEV)
BT_ERR("%s urb %p failed to resubmit (%d)", BT_ERR("%s urb %p failed to resubmit (%d)",
hdev->name, urb, -err); hdev->name, urb, -err);
usb_unanchor_urb(urb); usb_unanchor_urb(urb);
...@@ -341,7 +344,9 @@ static void btusb_bulk_complete(struct urb *urb) ...@@ -341,7 +344,9 @@ static void btusb_bulk_complete(struct urb *urb)
err = usb_submit_urb(urb, GFP_ATOMIC); err = usb_submit_urb(urb, GFP_ATOMIC);
if (err < 0) { if (err < 0) {
if (err != -EPERM) /* -EPERM: urb is being killed;
* -ENODEV: device got disconnected */
if (err != -EPERM && err != -ENODEV)
BT_ERR("%s urb %p failed to resubmit (%d)", BT_ERR("%s urb %p failed to resubmit (%d)",
hdev->name, urb, -err); hdev->name, urb, -err);
usb_unanchor_urb(urb); usb_unanchor_urb(urb);
...@@ -431,7 +436,9 @@ static void btusb_isoc_complete(struct urb *urb) ...@@ -431,7 +436,9 @@ static void btusb_isoc_complete(struct urb *urb)
err = usb_submit_urb(urb, GFP_ATOMIC); err = usb_submit_urb(urb, GFP_ATOMIC);
if (err < 0) { if (err < 0) {
if (err != -EPERM) /* -EPERM: urb is being killed;
* -ENODEV: device got disconnected */
if (err != -EPERM && err != -ENODEV)
BT_ERR("%s urb %p failed to resubmit (%d)", BT_ERR("%s urb %p failed to resubmit (%d)",
hdev->name, urb, -err); hdev->name, urb, -err);
usb_unanchor_urb(urb); usb_unanchor_urb(urb);
......
...@@ -494,9 +494,8 @@ int bt_sock_wait_state(struct sock *sk, int state, unsigned long timeo) ...@@ -494,9 +494,8 @@ int bt_sock_wait_state(struct sock *sk, int state, unsigned long timeo)
BT_DBG("sk %p", sk); BT_DBG("sk %p", sk);
add_wait_queue(sk_sleep(sk), &wait); add_wait_queue(sk_sleep(sk), &wait);
set_current_state(TASK_INTERRUPTIBLE);
while (sk->sk_state != state) { while (sk->sk_state != state) {
set_current_state(TASK_INTERRUPTIBLE);
if (!timeo) { if (!timeo) {
err = -EINPROGRESS; err = -EINPROGRESS;
break; break;
...@@ -510,12 +509,13 @@ int bt_sock_wait_state(struct sock *sk, int state, unsigned long timeo) ...@@ -510,12 +509,13 @@ int bt_sock_wait_state(struct sock *sk, int state, unsigned long timeo)
release_sock(sk); release_sock(sk);
timeo = schedule_timeout(timeo); timeo = schedule_timeout(timeo);
lock_sock(sk); lock_sock(sk);
set_current_state(TASK_INTERRUPTIBLE);
err = sock_error(sk); err = sock_error(sk);
if (err) if (err)
break; break;
} }
set_current_state(TASK_RUNNING); __set_current_state(TASK_RUNNING);
remove_wait_queue(sk_sleep(sk), &wait); remove_wait_queue(sk_sleep(sk), &wait);
return err; return err;
} }
......
...@@ -155,6 +155,7 @@ struct bnep_session { ...@@ -155,6 +155,7 @@ struct bnep_session {
unsigned int role; unsigned int role;
unsigned long state; unsigned long state;
unsigned long flags; unsigned long flags;
atomic_t terminate;
struct task_struct *task; struct task_struct *task;
struct ethhdr eh; struct ethhdr eh;
......
...@@ -484,9 +484,11 @@ static int bnep_session(void *arg) ...@@ -484,9 +484,11 @@ static int bnep_session(void *arg)
init_waitqueue_entry(&wait, current); init_waitqueue_entry(&wait, current);
add_wait_queue(sk_sleep(sk), &wait); add_wait_queue(sk_sleep(sk), &wait);
while (!kthread_should_stop()) { while (1) {
set_current_state(TASK_INTERRUPTIBLE); set_current_state(TASK_INTERRUPTIBLE);
if (atomic_read(&s->terminate))
break;
/* RX */ /* RX */
while ((skb = skb_dequeue(&sk->sk_receive_queue))) { while ((skb = skb_dequeue(&sk->sk_receive_queue))) {
skb_orphan(skb); skb_orphan(skb);
...@@ -504,7 +506,7 @@ static int bnep_session(void *arg) ...@@ -504,7 +506,7 @@ static int bnep_session(void *arg)
schedule(); schedule();
} }
set_current_state(TASK_RUNNING); __set_current_state(TASK_RUNNING);
remove_wait_queue(sk_sleep(sk), &wait); remove_wait_queue(sk_sleep(sk), &wait);
/* Cleanup session */ /* Cleanup session */
...@@ -640,9 +642,10 @@ int bnep_del_connection(struct bnep_conndel_req *req) ...@@ -640,9 +642,10 @@ int bnep_del_connection(struct bnep_conndel_req *req)
down_read(&bnep_session_sem); down_read(&bnep_session_sem);
s = __bnep_get_session(req->dst); s = __bnep_get_session(req->dst);
if (s) if (s) {
kthread_stop(s->task); atomic_inc(&s->terminate);
else wake_up_process(s->task);
} else
err = -ENOENT; err = -ENOENT;
up_read(&bnep_session_sem); up_read(&bnep_session_sem);
......
...@@ -386,7 +386,8 @@ static void cmtp_reset_ctr(struct capi_ctr *ctrl) ...@@ -386,7 +386,8 @@ static void cmtp_reset_ctr(struct capi_ctr *ctrl)
capi_ctr_down(ctrl); capi_ctr_down(ctrl);
kthread_stop(session->task); atomic_inc(&session->terminate);
wake_up_process(session->task);
} }
static void cmtp_register_appl(struct capi_ctr *ctrl, __u16 appl, capi_register_params *rp) static void cmtp_register_appl(struct capi_ctr *ctrl, __u16 appl, capi_register_params *rp)
......
...@@ -81,6 +81,7 @@ struct cmtp_session { ...@@ -81,6 +81,7 @@ struct cmtp_session {
char name[BTNAMSIZ]; char name[BTNAMSIZ];
atomic_t terminate;
struct task_struct *task; struct task_struct *task;
wait_queue_head_t wait; wait_queue_head_t wait;
......
...@@ -292,9 +292,11 @@ static int cmtp_session(void *arg) ...@@ -292,9 +292,11 @@ static int cmtp_session(void *arg)
init_waitqueue_entry(&wait, current); init_waitqueue_entry(&wait, current);
add_wait_queue(sk_sleep(sk), &wait); add_wait_queue(sk_sleep(sk), &wait);
while (!kthread_should_stop()) { while (1) {
set_current_state(TASK_INTERRUPTIBLE); set_current_state(TASK_INTERRUPTIBLE);
if (atomic_read(&session->terminate))
break;
if (sk->sk_state != BT_CONNECTED) if (sk->sk_state != BT_CONNECTED)
break; break;
...@@ -307,7 +309,7 @@ static int cmtp_session(void *arg) ...@@ -307,7 +309,7 @@ static int cmtp_session(void *arg)
schedule(); schedule();
} }
set_current_state(TASK_RUNNING); __set_current_state(TASK_RUNNING);
remove_wait_queue(sk_sleep(sk), &wait); remove_wait_queue(sk_sleep(sk), &wait);
down_write(&cmtp_session_sem); down_write(&cmtp_session_sem);
...@@ -380,16 +382,17 @@ int cmtp_add_connection(struct cmtp_connadd_req *req, struct socket *sock) ...@@ -380,16 +382,17 @@ int cmtp_add_connection(struct cmtp_connadd_req *req, struct socket *sock)
if (!(session->flags & (1 << CMTP_LOOPBACK))) { if (!(session->flags & (1 << CMTP_LOOPBACK))) {
err = cmtp_attach_device(session); err = cmtp_attach_device(session);
if (err < 0) if (err < 0) {
goto detach; atomic_inc(&session->terminate);
wake_up_process(session->task);
up_write(&cmtp_session_sem);
return err;
}
} }
up_write(&cmtp_session_sem); up_write(&cmtp_session_sem);
return 0; return 0;
detach:
cmtp_detach_device(session);
unlink: unlink:
__cmtp_unlink_session(session); __cmtp_unlink_session(session);
...@@ -414,7 +417,8 @@ int cmtp_del_connection(struct cmtp_conndel_req *req) ...@@ -414,7 +417,8 @@ int cmtp_del_connection(struct cmtp_conndel_req *req)
skb_queue_purge(&session->transmit); skb_queue_purge(&session->transmit);
/* Stop session thread */ /* Stop session thread */
kthread_stop(session->task); atomic_inc(&session->terminate);
wake_up_process(session->task);
} else } else
err = -ENOENT; err = -ENOENT;
......
...@@ -1209,7 +1209,6 @@ static void hci_cmd_timer(unsigned long arg) ...@@ -1209,7 +1209,6 @@ static void hci_cmd_timer(unsigned long arg)
BT_ERR("%s command tx timeout", hdev->name); BT_ERR("%s command tx timeout", hdev->name);
atomic_set(&hdev->cmd_cnt, 1); atomic_set(&hdev->cmd_cnt, 1);
clear_bit(HCI_RESET, &hdev->flags);
tasklet_schedule(&hdev->cmd_task); tasklet_schedule(&hdev->cmd_task);
} }
...@@ -1327,7 +1326,7 @@ int hci_blacklist_add(struct hci_dev *hdev, bdaddr_t *bdaddr) ...@@ -1327,7 +1326,7 @@ int hci_blacklist_add(struct hci_dev *hdev, bdaddr_t *bdaddr)
entry = kzalloc(sizeof(struct bdaddr_list), GFP_KERNEL); entry = kzalloc(sizeof(struct bdaddr_list), GFP_KERNEL);
if (!entry) { if (!entry) {
return -ENOMEM; err = -ENOMEM;
goto err; goto err;
} }
...@@ -2408,7 +2407,10 @@ static void hci_cmd_task(unsigned long arg) ...@@ -2408,7 +2407,10 @@ static void hci_cmd_task(unsigned long arg)
if (hdev->sent_cmd) { if (hdev->sent_cmd) {
atomic_dec(&hdev->cmd_cnt); atomic_dec(&hdev->cmd_cnt);
hci_send_frame(skb); hci_send_frame(skb);
mod_timer(&hdev->cmd_timer, if (test_bit(HCI_RESET, &hdev->flags))
del_timer(&hdev->cmd_timer);
else
mod_timer(&hdev->cmd_timer,
jiffies + msecs_to_jiffies(HCI_CMD_TIMEOUT)); jiffies + msecs_to_jiffies(HCI_CMD_TIMEOUT));
} else { } else {
skb_queue_head(&hdev->cmd_q, skb); skb_queue_head(&hdev->cmd_q, skb);
......
...@@ -764,6 +764,7 @@ static int hidp_session(void *arg) ...@@ -764,6 +764,7 @@ static int hidp_session(void *arg)
up_write(&hidp_session_sem); up_write(&hidp_session_sem);
kfree(session->rd_data);
kfree(session); kfree(session);
return 0; return 0;
} }
...@@ -841,7 +842,8 @@ static int hidp_setup_input(struct hidp_session *session, ...@@ -841,7 +842,8 @@ static int hidp_setup_input(struct hidp_session *session,
err = input_register_device(input); err = input_register_device(input);
if (err < 0) { if (err < 0) {
hci_conn_put_device(session->conn); input_free_device(input);
session->input = NULL;
return err; return err;
} }
...@@ -1044,8 +1046,12 @@ int hidp_add_connection(struct hidp_connadd_req *req, struct socket *ctrl_sock, ...@@ -1044,8 +1046,12 @@ int hidp_add_connection(struct hidp_connadd_req *req, struct socket *ctrl_sock,
} }
err = hid_add_device(session->hid); err = hid_add_device(session->hid);
if (err < 0) if (err < 0) {
goto err_add_device; atomic_inc(&session->terminate);
wake_up_process(session->task);
up_write(&hidp_session_sem);
return err;
}
if (session->input) { if (session->input) {
hidp_send_ctrl_message(session, hidp_send_ctrl_message(session,
...@@ -1059,12 +1065,6 @@ int hidp_add_connection(struct hidp_connadd_req *req, struct socket *ctrl_sock, ...@@ -1059,12 +1065,6 @@ int hidp_add_connection(struct hidp_connadd_req *req, struct socket *ctrl_sock,
up_write(&hidp_session_sem); up_write(&hidp_session_sem);
return 0; return 0;
err_add_device:
hid_destroy_device(session->hid);
session->hid = NULL;
atomic_inc(&session->terminate);
wake_up_process(session->task);
unlink: unlink:
hidp_del_timer(session); hidp_del_timer(session);
...@@ -1090,7 +1090,6 @@ int hidp_add_connection(struct hidp_connadd_req *req, struct socket *ctrl_sock, ...@@ -1090,7 +1090,6 @@ int hidp_add_connection(struct hidp_connadd_req *req, struct socket *ctrl_sock,
failed: failed:
up_write(&hidp_session_sem); up_write(&hidp_session_sem);
input_free_device(session->input);
kfree(session); kfree(session);
return err; return err;
} }
......
...@@ -1159,9 +1159,8 @@ int __l2cap_wait_ack(struct sock *sk) ...@@ -1159,9 +1159,8 @@ int __l2cap_wait_ack(struct sock *sk)
int timeo = HZ/5; int timeo = HZ/5;
add_wait_queue(sk_sleep(sk), &wait); add_wait_queue(sk_sleep(sk), &wait);
while ((chan->unacked_frames > 0 && chan->conn)) { set_current_state(TASK_INTERRUPTIBLE);
set_current_state(TASK_INTERRUPTIBLE); while (chan->unacked_frames > 0 && chan->conn) {
if (!timeo) if (!timeo)
timeo = HZ/5; timeo = HZ/5;
...@@ -1173,6 +1172,7 @@ int __l2cap_wait_ack(struct sock *sk) ...@@ -1173,6 +1172,7 @@ int __l2cap_wait_ack(struct sock *sk)
release_sock(sk); release_sock(sk);
timeo = schedule_timeout(timeo); timeo = schedule_timeout(timeo);
lock_sock(sk); lock_sock(sk);
set_current_state(TASK_INTERRUPTIBLE);
err = sock_error(sk); err = sock_error(sk);
if (err) if (err)
......
...@@ -235,30 +235,26 @@ static int l2cap_sock_accept(struct socket *sock, struct socket *newsock, int fl ...@@ -235,30 +235,26 @@ static int l2cap_sock_accept(struct socket *sock, struct socket *newsock, int fl
lock_sock_nested(sk, SINGLE_DEPTH_NESTING); lock_sock_nested(sk, SINGLE_DEPTH_NESTING);
if (sk->sk_state != BT_LISTEN) {
err = -EBADFD;
goto done;
}
timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK); timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK);
BT_DBG("sk %p timeo %ld", sk, timeo); BT_DBG("sk %p timeo %ld", sk, timeo);
/* Wait for an incoming connection. (wake-one). */ /* Wait for an incoming connection. (wake-one). */
add_wait_queue_exclusive(sk_sleep(sk), &wait); add_wait_queue_exclusive(sk_sleep(sk), &wait);
while (!(nsk = bt_accept_dequeue(sk, newsock))) { while (1) {
set_current_state(TASK_INTERRUPTIBLE); set_current_state(TASK_INTERRUPTIBLE);
if (!timeo) {
err = -EAGAIN; if (sk->sk_state != BT_LISTEN) {
err = -EBADFD;
break; break;
} }
release_sock(sk); nsk = bt_accept_dequeue(sk, newsock);
timeo = schedule_timeout(timeo); if (nsk)
lock_sock_nested(sk, SINGLE_DEPTH_NESTING); break;
if (sk->sk_state != BT_LISTEN) { if (!timeo) {
err = -EBADFD; err = -EAGAIN;
break; break;
} }
...@@ -266,8 +262,12 @@ static int l2cap_sock_accept(struct socket *sock, struct socket *newsock, int fl ...@@ -266,8 +262,12 @@ static int l2cap_sock_accept(struct socket *sock, struct socket *newsock, int fl
err = sock_intr_errno(timeo); err = sock_intr_errno(timeo);
break; break;
} }
release_sock(sk);
timeo = schedule_timeout(timeo);
lock_sock_nested(sk, SINGLE_DEPTH_NESTING);
} }
set_current_state(TASK_RUNNING); __set_current_state(TASK_RUNNING);
remove_wait_queue(sk_sleep(sk), &wait); remove_wait_queue(sk_sleep(sk), &wait);
if (err) if (err)
...@@ -993,7 +993,7 @@ static struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock, int p ...@@ -993,7 +993,7 @@ static struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock, int p
INIT_LIST_HEAD(&bt_sk(sk)->accept_q); INIT_LIST_HEAD(&bt_sk(sk)->accept_q);
sk->sk_destruct = l2cap_sock_destruct; sk->sk_destruct = l2cap_sock_destruct;
sk->sk_sndtimeo = msecs_to_jiffies(L2CAP_CONN_TIMEOUT); sk->sk_sndtimeo = L2CAP_CONN_TIMEOUT;
sock_reset_flag(sk, SOCK_ZAPPED); sock_reset_flag(sk, SOCK_ZAPPED);
......
...@@ -62,7 +62,6 @@ static DEFINE_MUTEX(rfcomm_mutex); ...@@ -62,7 +62,6 @@ static DEFINE_MUTEX(rfcomm_mutex);
#define rfcomm_lock() mutex_lock(&rfcomm_mutex) #define rfcomm_lock() mutex_lock(&rfcomm_mutex)
#define rfcomm_unlock() mutex_unlock(&rfcomm_mutex) #define rfcomm_unlock() mutex_unlock(&rfcomm_mutex)
static unsigned long rfcomm_event;
static LIST_HEAD(session_list); static LIST_HEAD(session_list);
...@@ -120,7 +119,6 @@ static inline void rfcomm_schedule(void) ...@@ -120,7 +119,6 @@ static inline void rfcomm_schedule(void)
{ {
if (!rfcomm_thread) if (!rfcomm_thread)
return; return;
set_bit(RFCOMM_SCHED_WAKEUP, &rfcomm_event);
wake_up_process(rfcomm_thread); wake_up_process(rfcomm_thread);
} }
...@@ -2038,19 +2036,18 @@ static int rfcomm_run(void *unused) ...@@ -2038,19 +2036,18 @@ static int rfcomm_run(void *unused)
rfcomm_add_listener(BDADDR_ANY); rfcomm_add_listener(BDADDR_ANY);
while (!kthread_should_stop()) { while (1) {
set_current_state(TASK_INTERRUPTIBLE); set_current_state(TASK_INTERRUPTIBLE);
if (!test_bit(RFCOMM_SCHED_WAKEUP, &rfcomm_event)) {
/* No pending events. Let's sleep. if (kthread_should_stop())
* Incoming connections and data will wake us up. */ break;
schedule();
}
set_current_state(TASK_RUNNING);
/* Process stuff */ /* Process stuff */
clear_bit(RFCOMM_SCHED_WAKEUP, &rfcomm_event);
rfcomm_process_sessions(); rfcomm_process_sessions();
schedule();
} }
__set_current_state(TASK_RUNNING);
rfcomm_kill_listener(); rfcomm_kill_listener();
......
...@@ -485,11 +485,6 @@ static int rfcomm_sock_accept(struct socket *sock, struct socket *newsock, int f ...@@ -485,11 +485,6 @@ static int rfcomm_sock_accept(struct socket *sock, struct socket *newsock, int f
lock_sock(sk); lock_sock(sk);
if (sk->sk_state != BT_LISTEN) {
err = -EBADFD;
goto done;
}
if (sk->sk_type != SOCK_STREAM) { if (sk->sk_type != SOCK_STREAM) {
err = -EINVAL; err = -EINVAL;
goto done; goto done;
...@@ -501,19 +496,20 @@ static int rfcomm_sock_accept(struct socket *sock, struct socket *newsock, int f ...@@ -501,19 +496,20 @@ static int rfcomm_sock_accept(struct socket *sock, struct socket *newsock, int f
/* Wait for an incoming connection. (wake-one). */ /* Wait for an incoming connection. (wake-one). */
add_wait_queue_exclusive(sk_sleep(sk), &wait); add_wait_queue_exclusive(sk_sleep(sk), &wait);
while (!(nsk = bt_accept_dequeue(sk, newsock))) { while (1) {
set_current_state(TASK_INTERRUPTIBLE); set_current_state(TASK_INTERRUPTIBLE);
if (!timeo) {
err = -EAGAIN; if (sk->sk_state != BT_LISTEN) {
err = -EBADFD;
break; break;
} }
release_sock(sk); nsk = bt_accept_dequeue(sk, newsock);
timeo = schedule_timeout(timeo); if (nsk)
lock_sock(sk); break;
if (sk->sk_state != BT_LISTEN) { if (!timeo) {
err = -EBADFD; err = -EAGAIN;
break; break;
} }
...@@ -521,8 +517,12 @@ static int rfcomm_sock_accept(struct socket *sock, struct socket *newsock, int f ...@@ -521,8 +517,12 @@ static int rfcomm_sock_accept(struct socket *sock, struct socket *newsock, int f
err = sock_intr_errno(timeo); err = sock_intr_errno(timeo);
break; break;
} }
release_sock(sk);
timeo = schedule_timeout(timeo);
lock_sock(sk);
} }
set_current_state(TASK_RUNNING); __set_current_state(TASK_RUNNING);
remove_wait_queue(sk_sleep(sk), &wait); remove_wait_queue(sk_sleep(sk), &wait);
if (err) if (err)
......
...@@ -564,30 +564,26 @@ static int sco_sock_accept(struct socket *sock, struct socket *newsock, int flag ...@@ -564,30 +564,26 @@ static int sco_sock_accept(struct socket *sock, struct socket *newsock, int flag
lock_sock(sk); lock_sock(sk);
if (sk->sk_state != BT_LISTEN) {
err = -EBADFD;
goto done;
}
timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK); timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK);
BT_DBG("sk %p timeo %ld", sk, timeo); BT_DBG("sk %p timeo %ld", sk, timeo);
/* Wait for an incoming connection. (wake-one). */ /* Wait for an incoming connection. (wake-one). */
add_wait_queue_exclusive(sk_sleep(sk), &wait); add_wait_queue_exclusive(sk_sleep(sk), &wait);
while (!(ch = bt_accept_dequeue(sk, newsock))) { while (1) {
set_current_state(TASK_INTERRUPTIBLE); set_current_state(TASK_INTERRUPTIBLE);
if (!timeo) {
err = -EAGAIN; if (sk->sk_state != BT_LISTEN) {
err = -EBADFD;
break; break;
} }
release_sock(sk); ch = bt_accept_dequeue(sk, newsock);
timeo = schedule_timeout(timeo); if (ch)
lock_sock(sk); break;
if (sk->sk_state != BT_LISTEN) { if (!timeo) {
err = -EBADFD; err = -EAGAIN;
break; break;
} }
...@@ -595,8 +591,12 @@ static int sco_sock_accept(struct socket *sock, struct socket *newsock, int flag ...@@ -595,8 +591,12 @@ static int sco_sock_accept(struct socket *sock, struct socket *newsock, int flag
err = sock_intr_errno(timeo); err = sock_intr_errno(timeo);
break; break;
} }
release_sock(sk);
timeo = schedule_timeout(timeo);
lock_sock(sk);
} }
set_current_state(TASK_RUNNING); __set_current_state(TASK_RUNNING);
remove_wait_queue(sk_sleep(sk), &wait); remove_wait_queue(sk_sleep(sk), &wait);
if (err) if (err)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment