X-Git-Url: https://git.openpandora.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=drivers%2Fbluetooth%2Fhci_ldisc.c;h=08bbc48c43f6823b7067517c6f3a5cab7c53f16e;hb=af37d866c8aa1b8b61650629a53c6fab2a17e867;hp=b3f01996318f04c0f432a38112226dbbeba0efcf;hpb=86dd7909c2c4ae3f219a9233bf0f095b05632ecf;p=pandora-kernel.git diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c index b3f01996318f..08bbc48c43f6 100644 --- a/drivers/bluetooth/hci_ldisc.c +++ b/drivers/bluetooth/hci_ldisc.c @@ -120,10 +120,6 @@ static inline struct sk_buff *hci_uart_dequeue(struct hci_uart *hu) int hci_uart_tx_wakeup(struct hci_uart *hu) { - struct tty_struct *tty = hu->tty; - struct hci_dev *hdev = hu->hdev; - struct sk_buff *skb; - if (test_and_set_bit(HCI_UART_SENDING, &hu->tx_state)) { set_bit(HCI_UART_TX_WAKEUP, &hu->tx_state); return 0; @@ -131,6 +127,22 @@ int hci_uart_tx_wakeup(struct hci_uart *hu) BT_DBG(""); + schedule_work(&hu->write_work); + + return 0; +} + +static void hci_uart_write_work(struct work_struct *work) +{ + struct hci_uart *hu = container_of(work, struct hci_uart, write_work); + struct tty_struct *tty = hu->tty; + struct hci_dev *hdev = hu->hdev; + struct sk_buff *skb; + + /* REVISIT: should we cope with bad skbs or ->write() returning + * and error value ? + */ + restart: clear_bit(HCI_UART_TX_WAKEUP, &hu->tx_state); @@ -155,7 +167,6 @@ restart: goto restart; clear_bit(HCI_UART_SENDING, &hu->tx_state); - return 0; } /* ------- Interface to HCI layer ------ */ @@ -237,7 +248,6 @@ static void hci_uart_destruct(struct hci_dev *hdev) return; BT_DBG("%s", hdev->name); - kfree(hdev->driver_data); } /* ------ LDISC part ------ */ @@ -275,6 +285,8 @@ static int hci_uart_tty_open(struct tty_struct *tty) hu->tty = tty; tty->receive_room = 65536; + INIT_WORK(&hu->write_work, hci_uart_write_work); + spin_lock_init(&hu->rx_lock); /* Flush any pending characters in the driver and line discipline. */ @@ -309,13 +321,16 @@ static void hci_uart_tty_close(struct tty_struct *tty) if (hdev) hci_uart_close(hdev); + cancel_work_sync(&hu->write_work); + if (test_and_clear_bit(HCI_UART_PROTO_SET, &hu->flags)) { - hu->proto->close(hu); if (hdev) { hci_unregister_dev(hdev); hci_free_dev(hdev); } + hu->proto->close(hu); } + kfree(hu); } } @@ -355,29 +370,24 @@ static void hci_uart_tty_wakeup(struct tty_struct *tty) * flags pointer to flags for data * count count of received data in bytes * - * Return Value: Number of bytes received + * Return Value: None */ -static unsigned int hci_uart_tty_receive(struct tty_struct *tty, - const u8 *data, char *flags, int count) +static void hci_uart_tty_receive(struct tty_struct *tty, const u8 *data, char *flags, int count) { struct hci_uart *hu = (void *)tty->disc_data; - int received; if (!hu || tty != hu->tty) - return -ENODEV; + return; if (!test_bit(HCI_UART_PROTO_SET, &hu->flags)) - return -EINVAL; + return; spin_lock(&hu->rx_lock); - received = hu->proto->recv(hu, (void *) data, count); - if (received > 0) - hu->hdev->stat.byte_rx += received; + hu->proto->recv(hu, (void *) data, count); + hu->hdev->stat.byte_rx += count; spin_unlock(&hu->rx_lock); tty_unthrottle(tty); - - return received; } static int hci_uart_register_dev(struct hci_uart *hu)