From 278be27fc401119c985235ee549dc229d85e6bf5 Mon Sep 17 00:00:00 2001 From: Kulikov Vasiliy Date: Mon, 5 Jul 2010 12:01:22 +0400 Subject: Bluetooth: Silence warning in btmrvl SDIO driver MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Clone checking of ret to simplify the code. This patch silences a compiler warning: drivers/bluetooth/btmrvl_sdio.c: In function ‘btmrvl_sdio_verify_fw_download’: drivers/bluetooth/btmrvl_sdio.c:80: warning: ‘fws1’ may be used uninitialized in this function drivers/bluetooth/btmrvl_sdio.c:80: note: ‘fws1’ was declared here Signed-off-by: Kulikov Vasiliy Reviewed-by: Dan Carpenter Signed-off-by: Marcel Holtmann --- drivers/bluetooth/btmrvl_sdio.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/bluetooth') diff --git a/drivers/bluetooth/btmrvl_sdio.c b/drivers/bluetooth/btmrvl_sdio.c index df0773ebd9e4..47f0f917dec9 100644 --- a/drivers/bluetooth/btmrvl_sdio.c +++ b/drivers/bluetooth/btmrvl_sdio.c @@ -83,10 +83,10 @@ static int btmrvl_sdio_read_fw_status(struct btmrvl_sdio_card *card, u16 *dat) *dat = 0; fws0 = sdio_readb(card->func, CARD_FW_STATUS0_REG, &ret); + if (ret) + return -EIO; - if (!ret) - fws1 = sdio_readb(card->func, CARD_FW_STATUS1_REG, &ret); - + fws1 = sdio_readb(card->func, CARD_FW_STATUS1_REG, &ret); if (ret) return -EIO; -- cgit v1.2.3-70-g09d2 From 7452d24cfb91e84f9be61beda5ad68d2a56d0938 Mon Sep 17 00:00:00 2001 From: "Justin P. Mattock" Date: Mon, 14 Jun 2010 18:26:40 -0700 Subject: Bluetooth: Fix warning: variable 'tty' set but not used The patch below fixes a warning message when using gcc 4.6.0. CC [M] drivers/bluetooth/hci_ldisc.o drivers/bluetooth/hci_ldisc.c: In function 'hci_uart_send_frame': drivers/bluetooth/hci_ldisc.c:213:21: warning: variable 'tty' set but not used Signed-off-by: Justin P. Mattock Reviewed-By: Gustavo F. Padovan Signed-off-by: Marcel Holtmann --- drivers/bluetooth/hci_ldisc.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers/bluetooth') diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c index 76a1abb8f214..e8beffe80b31 100644 --- a/drivers/bluetooth/hci_ldisc.c +++ b/drivers/bluetooth/hci_ldisc.c @@ -210,7 +210,6 @@ static int hci_uart_close(struct hci_dev *hdev) static int hci_uart_send_frame(struct sk_buff *skb) { struct hci_dev* hdev = (struct hci_dev *) skb->dev; - struct tty_struct *tty; struct hci_uart *hu; if (!hdev) { @@ -222,7 +221,6 @@ static int hci_uart_send_frame(struct sk_buff *skb) return -EBUSY; hu = (struct hci_uart *) hdev->driver_data; - tty = hu->tty; BT_DBG("%s: type %d len %d", hdev->name, bt_cb(skb)->pkt_type, skb->len); -- cgit v1.2.3-70-g09d2 From d1d10d783089cc26a14be92fc12fccda9aa6593a Mon Sep 17 00:00:00 2001 From: Amitkumar Karwar Date: Thu, 27 May 2010 16:38:37 -0700 Subject: Bluetooth: Process interrupt in main thread of btmrvl driver as well When driver is sending a command or data and the firmware is also sending a sleep event, sometimes it is observed that driver will continue to send the command/data to firmware right after processing sleep event. Once sleep event is processed driver is not supposed to send anything because firmware is in sleep state after that. Previously interrupt processing was done in SDIO interrupt callback handler. Now it is done in btmrvl driver main thread to solve the cross-sending properly. Signed-off-by: Amitkumar Karwar Signed-off-by: Bing Zhao Signed-off-by: Marcel Holtmann --- drivers/bluetooth/btmrvl_drv.h | 1 + drivers/bluetooth/btmrvl_main.c | 5 ++- drivers/bluetooth/btmrvl_sdio.c | 97 +++++++++++++++++++++-------------------- 3 files changed, 55 insertions(+), 48 deletions(-) (limited to 'drivers/bluetooth') diff --git a/drivers/bluetooth/btmrvl_drv.h b/drivers/bluetooth/btmrvl_drv.h index bed0ba630235..872cb6cfcd0d 100644 --- a/drivers/bluetooth/btmrvl_drv.h +++ b/drivers/bluetooth/btmrvl_drv.h @@ -76,6 +76,7 @@ struct btmrvl_private { int (*hw_host_to_card) (struct btmrvl_private *priv, u8 *payload, u16 nb); int (*hw_wakeup_firmware) (struct btmrvl_private *priv); + int (*hw_process_int_status) (struct btmrvl_private *priv); spinlock_t driver_lock; /* spinlock used by driver */ #ifdef CONFIG_DEBUG_FS void *debugfs_data; diff --git a/drivers/bluetooth/btmrvl_main.c b/drivers/bluetooth/btmrvl_main.c index ee37ef0caee2..0d32ec82e9bf 100644 --- a/drivers/bluetooth/btmrvl_main.c +++ b/drivers/bluetooth/btmrvl_main.c @@ -502,14 +502,17 @@ static int btmrvl_service_main_thread(void *data) spin_lock_irqsave(&priv->driver_lock, flags); if (adapter->int_count) { adapter->int_count = 0; + spin_unlock_irqrestore(&priv->driver_lock, flags); + priv->hw_process_int_status(priv); } else if (adapter->ps_state == PS_SLEEP && !skb_queue_empty(&adapter->tx_queue)) { spin_unlock_irqrestore(&priv->driver_lock, flags); adapter->wakeup_tries++; priv->hw_wakeup_firmware(priv); continue; + } else { + spin_unlock_irqrestore(&priv->driver_lock, flags); } - spin_unlock_irqrestore(&priv->driver_lock, flags); if (adapter->ps_state == PS_SLEEP) continue; diff --git a/drivers/bluetooth/btmrvl_sdio.c b/drivers/bluetooth/btmrvl_sdio.c index 47f0f917dec9..182e55345d6a 100644 --- a/drivers/bluetooth/btmrvl_sdio.c +++ b/drivers/bluetooth/btmrvl_sdio.c @@ -47,6 +47,7 @@ * module_exit function is called. */ static u8 user_rmmod; +static u8 sdio_ireg; static const struct btmrvl_sdio_device btmrvl_sdio_sd6888 = { .helper = "sd8688_helper.bin", @@ -555,78 +556,79 @@ exit: return ret; } -static int btmrvl_sdio_get_int_status(struct btmrvl_private *priv, u8 * ireg) +static int btmrvl_sdio_process_int_status(struct btmrvl_private *priv) { - int ret; - u8 sdio_ireg = 0; + ulong flags; + u8 ireg; struct btmrvl_sdio_card *card = priv->btmrvl_dev.card; - *ireg = 0; - - sdio_ireg = sdio_readb(card->func, HOST_INTSTATUS_REG, &ret); - if (ret) { - BT_ERR("sdio_readb: read int status register failed"); - ret = -EIO; - goto done; - } - - if (sdio_ireg != 0) { - /* - * DN_LD_HOST_INT_STATUS and/or UP_LD_HOST_INT_STATUS - * Clear the interrupt status register and re-enable the - * interrupt. - */ - BT_DBG("sdio_ireg = 0x%x", sdio_ireg); - - sdio_writeb(card->func, ~(sdio_ireg) & (DN_LD_HOST_INT_STATUS | - UP_LD_HOST_INT_STATUS), - HOST_INTSTATUS_REG, &ret); - if (ret) { - BT_ERR("sdio_writeb: clear int status register " - "failed"); - ret = -EIO; - goto done; - } - } + spin_lock_irqsave(&priv->driver_lock, flags); + ireg = sdio_ireg; + sdio_ireg = 0; + spin_unlock_irqrestore(&priv->driver_lock, flags); - if (sdio_ireg & DN_LD_HOST_INT_STATUS) { + sdio_claim_host(card->func); + if (ireg & DN_LD_HOST_INT_STATUS) { if (priv->btmrvl_dev.tx_dnld_rdy) BT_DBG("tx_done already received: " - " int_status=0x%x", sdio_ireg); + " int_status=0x%x", ireg); else priv->btmrvl_dev.tx_dnld_rdy = true; } - if (sdio_ireg & UP_LD_HOST_INT_STATUS) + if (ireg & UP_LD_HOST_INT_STATUS) btmrvl_sdio_card_to_host(priv); - *ireg = sdio_ireg; - - ret = 0; + sdio_release_host(card->func); -done: - return ret; + return 0; } static void btmrvl_sdio_interrupt(struct sdio_func *func) { struct btmrvl_private *priv; - struct hci_dev *hcidev; struct btmrvl_sdio_card *card; + ulong flags; u8 ireg = 0; + int ret; card = sdio_get_drvdata(func); - if (card && card->priv) { - priv = card->priv; - hcidev = priv->btmrvl_dev.hcidev; + if (!card || !card->priv) { + BT_ERR("sbi_interrupt(%p) card or priv is " + "NULL, card=%p\n", func, card); + return; + } - if (btmrvl_sdio_get_int_status(priv, &ireg)) - BT_ERR("reading HOST_INT_STATUS_REG failed"); - else - BT_DBG("HOST_INT_STATUS_REG %#x", ireg); + priv = card->priv; - btmrvl_interrupt(priv); + ireg = sdio_readb(card->func, HOST_INTSTATUS_REG, &ret); + if (ret) { + BT_ERR("sdio_readb: read int status register failed"); + return; } + + if (ireg != 0) { + /* + * DN_LD_HOST_INT_STATUS and/or UP_LD_HOST_INT_STATUS + * Clear the interrupt status register and re-enable the + * interrupt. + */ + BT_DBG("ireg = 0x%x", ireg); + + sdio_writeb(card->func, ~(ireg) & (DN_LD_HOST_INT_STATUS | + UP_LD_HOST_INT_STATUS), + HOST_INTSTATUS_REG, &ret); + if (ret) { + BT_ERR("sdio_writeb: clear int status register failed"); + return; + } + } + + spin_lock_irqsave(&priv->driver_lock, flags); + sdio_ireg |= ireg; + spin_unlock_irqrestore(&priv->driver_lock, flags); + + btmrvl_interrupt(priv); } static int btmrvl_sdio_register_dev(struct btmrvl_sdio_card *card) @@ -930,6 +932,7 @@ static int btmrvl_sdio_probe(struct sdio_func *func, /* Initialize the interface specific function pointers */ priv->hw_host_to_card = btmrvl_sdio_host_to_card; priv->hw_wakeup_firmware = btmrvl_sdio_wakeup_fw; + priv->hw_process_int_status = btmrvl_sdio_process_int_status; if (btmrvl_register_hdev(priv)) { BT_ERR("Register hdev failed!"); -- cgit v1.2.3-70-g09d2 From 5ee283c063a236b19e4582c675a2d8d615d5809c Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Sat, 15 May 2010 23:19:15 +0200 Subject: Bluetooth: Use kmemdup for drivers Use kmemdup when some other buffer is immediately copied into the allocated region. A simplified version of the semantic patch that makes this change is as follows: (http://coccinelle.lip6.fr/) // @@ expression from,to,size,flag; statement S; @@ - to = \(kmalloc\|kzalloc\)(size,flag); + to = kmemdup(from,size,flag); if (to==NULL || ...) S - memcpy(to, from, size); // Signed-off-by: Julia Lawall Acked-by: Gustavo F. Padovan Signed-off-by: Marcel Holtmann --- drivers/bluetooth/bcm203x.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers/bluetooth') diff --git a/drivers/bluetooth/bcm203x.c b/drivers/bluetooth/bcm203x.c index b0c84c19f442..8b1b643a519b 100644 --- a/drivers/bluetooth/bcm203x.c +++ b/drivers/bluetooth/bcm203x.c @@ -224,7 +224,7 @@ static int bcm203x_probe(struct usb_interface *intf, const struct usb_device_id BT_DBG("firmware data %p size %zu", firmware->data, firmware->size); - data->fw_data = kmalloc(firmware->size, GFP_KERNEL); + data->fw_data = kmemdup(firmware->data, firmware->size, GFP_KERNEL); if (!data->fw_data) { BT_ERR("Can't allocate memory for firmware image"); release_firmware(firmware); @@ -234,7 +234,6 @@ static int bcm203x_probe(struct usb_interface *intf, const struct usb_device_id return -ENOMEM; } - memcpy(data->fw_data, firmware->data, firmware->size); data->fw_size = firmware->size; data->fw_sent = 0; -- cgit v1.2.3-70-g09d2 From f8df39f1810b02f877c1ba1eed8e0710019e3b48 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Thu, 13 May 2010 22:02:03 +0200 Subject: Bluetooth: Use kzalloc for drivers Use kzalloc rather than the combination of kmalloc and memset. The semantic patch that makes this change is as follows: (http://coccinelle.lip6.fr/) // @@ expression x,size,flags; statement S; @@ -x = kmalloc(size,flags); +x = kzalloc(size,flags); if (x == NULL) S -memset(x, 0, size); // Signed-off-by: Julia Lawall Acked-by: Gustavo F. Padovan Signed-off-by: Marcel Holtmann --- drivers/bluetooth/btmrvl_sdio.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) (limited to 'drivers/bluetooth') diff --git a/drivers/bluetooth/btmrvl_sdio.c b/drivers/bluetooth/btmrvl_sdio.c index 182e55345d6a..dcc2a6ec23f0 100644 --- a/drivers/bluetooth/btmrvl_sdio.c +++ b/drivers/bluetooth/btmrvl_sdio.c @@ -217,7 +217,7 @@ static int btmrvl_sdio_download_helper(struct btmrvl_sdio_card *card) tmphlprbufsz = ALIGN_SZ(BTM_UPLD_SIZE, BTSDIO_DMA_ALIGN); - tmphlprbuf = kmalloc(tmphlprbufsz, GFP_KERNEL); + tmphlprbuf = kzalloc(tmphlprbufsz, GFP_KERNEL); if (!tmphlprbuf) { BT_ERR("Unable to allocate buffer for helper." " Terminating download"); @@ -225,8 +225,6 @@ static int btmrvl_sdio_download_helper(struct btmrvl_sdio_card *card) goto done; } - memset(tmphlprbuf, 0, tmphlprbufsz); - helperbuf = (u8 *) ALIGN_ADDR(tmphlprbuf, BTSDIO_DMA_ALIGN); /* Perform helper data transfer */ @@ -319,7 +317,7 @@ static int btmrvl_sdio_download_fw_w_helper(struct btmrvl_sdio_card *card) BT_DBG("Downloading FW image (%d bytes)", firmwarelen); tmpfwbufsz = ALIGN_SZ(BTM_UPLD_SIZE, BTSDIO_DMA_ALIGN); - tmpfwbuf = kmalloc(tmpfwbufsz, GFP_KERNEL); + tmpfwbuf = kzalloc(tmpfwbufsz, GFP_KERNEL); if (!tmpfwbuf) { BT_ERR("Unable to allocate buffer for firmware." " Terminating download"); @@ -327,8 +325,6 @@ static int btmrvl_sdio_download_fw_w_helper(struct btmrvl_sdio_card *card) goto done; } - memset(tmpfwbuf, 0, tmpfwbufsz); - /* Ensure aligned firmware buffer */ fwbuf = (u8 *) ALIGN_ADDR(tmpfwbuf, BTSDIO_DMA_ALIGN); -- cgit v1.2.3-70-g09d2 From 63c7d09cd52fe23ad2baee26bcc10a590944cfa4 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Mon, 12 Jul 2010 11:37:04 -0300 Subject: Bluetooth: Add HCIUARTSETFLAGS and HCIUARTGETFLAGS ioctls This patch introduces two new ioctls: HCIUARTSETFLAGS and HCIUARTGETFLAGS. The only flag available for now is HCI_UART_RAW_DEVICE which allows to initialize a UART device into RAW mode from userspace. This is particularly useful for experimenting with Bluetooth controllers that don't yet have proper support in BlueZ. Signed-off-by: Johan Hedberg Signed-off-by: Marcel Holtmann --- drivers/bluetooth/hci_ldisc.c | 12 ++++++++++++ drivers/bluetooth/hci_uart.h | 7 ++++++- fs/compat_ioctl.c | 2 ++ 3 files changed, 20 insertions(+), 1 deletion(-) (limited to 'drivers/bluetooth') diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c index e8beffe80b31..a57dbfccb3fb 100644 --- a/drivers/bluetooth/hci_ldisc.c +++ b/drivers/bluetooth/hci_ldisc.c @@ -395,6 +395,9 @@ static int hci_uart_register_dev(struct hci_uart *hu) if (!reset) set_bit(HCI_QUIRK_NO_RESET, &hdev->quirks); + if (test_bit(HCI_UART_RAW_DEVICE, &hu->hdev_flags)) + set_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks); + if (hci_register_dev(hdev) < 0) { BT_ERR("Can't register HCI device"); hci_free_dev(hdev); @@ -475,6 +478,15 @@ static int hci_uart_tty_ioctl(struct tty_struct *tty, struct file * file, return hu->hdev->id; return -EUNATCH; + case HCIUARTSETFLAGS: + if (test_bit(HCI_UART_PROTO_SET, &hu->flags)) + return -EBUSY; + hu->hdev_flags = arg; + break; + + case HCIUARTGETFLAGS: + return hu->hdev_flags; + default: err = n_tty_ioctl_helper(tty, file, cmd, arg); break; diff --git a/drivers/bluetooth/hci_uart.h b/drivers/bluetooth/hci_uart.h index 50113db06b9f..9694d9d60905 100644 --- a/drivers/bluetooth/hci_uart.h +++ b/drivers/bluetooth/hci_uart.h @@ -31,6 +31,8 @@ #define HCIUARTSETPROTO _IOW('U', 200, int) #define HCIUARTGETPROTO _IOR('U', 201, int) #define HCIUARTGETDEVICE _IOR('U', 202, int) +#define HCIUARTSETFLAGS _IOW('U', 203, int) +#define HCIUARTGETFLAGS _IOR('U', 204, int) /* UART protocols */ #define HCI_UART_MAX_PROTO 5 @@ -41,6 +43,8 @@ #define HCI_UART_H4DS 3 #define HCI_UART_LL 4 +#define HCI_UART_RAW_DEVICE 0 + struct hci_uart; struct hci_uart_proto { @@ -57,6 +61,7 @@ struct hci_uart { struct tty_struct *tty; struct hci_dev *hdev; unsigned long flags; + unsigned long hdev_flags; struct hci_uart_proto *proto; void *priv; @@ -66,7 +71,7 @@ struct hci_uart { spinlock_t rx_lock; }; -/* HCI_UART flag bits */ +/* HCI_UART proto flag bits */ #define HCI_UART_PROTO_SET 0 /* TX states */ diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c index 547452de5ca2..8ea5e3374507 100644 --- a/fs/compat_ioctl.c +++ b/fs/compat_ioctl.c @@ -604,6 +604,8 @@ static int ioc_settimeout(unsigned int fd, unsigned int cmd, #define HCIUARTSETPROTO _IOW('U', 200, int) #define HCIUARTGETPROTO _IOR('U', 201, int) #define HCIUARTGETDEVICE _IOR('U', 202, int) +#define HCIUARTSETFLAGS _IOW('U', 203, int) +#define HCIUARTGETFLAGS _IOR('U', 204, int) #define BNEPCONNADD _IOW('B', 200, int) #define BNEPCONNDEL _IOW('B', 201, int) -- cgit v1.2.3-70-g09d2 From be60b94030339b89c2bcff18c76882f0a4c01ce6 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Mon, 12 Jul 2010 13:49:57 -0700 Subject: Bluetooth: Remove unnecessary casts of private_data in drivers Signed-off-by: Joe Perches Signed-off-by: Marcel Holtmann --- drivers/bluetooth/btmrvl_debugfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/bluetooth') diff --git a/drivers/bluetooth/btmrvl_debugfs.c b/drivers/bluetooth/btmrvl_debugfs.c index b50b41d97a7f..54739b08c308 100644 --- a/drivers/bluetooth/btmrvl_debugfs.c +++ b/drivers/bluetooth/btmrvl_debugfs.c @@ -216,7 +216,7 @@ static const struct file_operations btmrvl_gpiogap_fops = { static ssize_t btmrvl_hscmd_write(struct file *file, const char __user *ubuf, size_t count, loff_t *ppos) { - struct btmrvl_private *priv = (struct btmrvl_private *) file->private_data; + struct btmrvl_private *priv = file->private_data; char buf[16]; long result, ret; -- cgit v1.2.3-70-g09d2 From 0a79f67445de50ca0a8dc1d34f3cc406d89c28b2 Mon Sep 17 00:00:00 2001 From: Cyril Lacoux Date: Wed, 14 Jul 2010 10:29:27 +0400 Subject: Bluetooth: Added support for controller shipped with iMac i5 Device class is ff(vend.) instead of e0(wlcon). Output from command `usb-devices`: T: Bus=01 Lev=03 Prnt=03 Port=00 Cnt=01 Dev#= 6 Spd=12 MxCh= 0 D: Ver= 2.00 Cls=ff(vend.) Sub=01 Prot=01 MxPS=64 #Cfgs= 1 P: Vendor=05ac ProdID=8215 Rev=01.82 S: Manufacturer=Apple Inc. S: Product=Bluetooth USB Host Controller S: SerialNumber=7C6D62936607 C: #Ifs= 4 Cfg#= 1 Atr=e0 MxPwr=0mA I: If#= 0 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=01 Prot=01 Driver=btusb I: If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb I: If#= 2 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=(none) I: If#= 3 Alt= 0 #EPs= 0 Cls=fe(app. ) Sub=01 Prot=00 Driver=(none) Signed-off-by: Cyril Lacoux Signed-off-by: Marcel Holtmann --- drivers/bluetooth/btusb.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers/bluetooth') diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index 5d9cc53bd643..6fcb97124be8 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -59,6 +59,9 @@ static struct usb_device_id btusb_table[] = { /* Generic Bluetooth USB device */ { USB_DEVICE_INFO(0xe0, 0x01, 0x01) }, + /* Apple iMac11,1 */ + { USB_DEVICE(0x05ac, 0x8215) }, + /* AVM BlueFRITZ! USB v2.0 */ { USB_DEVICE(0x057c, 0x3800) }, -- cgit v1.2.3-70-g09d2 From 08b8b6c454092ae19cea82787b86ee9596ae1951 Mon Sep 17 00:00:00 2001 From: "Gustavo F. Padovan" Date: Fri, 16 Jul 2010 17:20:33 -0300 Subject: Bluetooth: Move bit-field variable in USB driver to data->flags did_iso_resume keeps only a bit-field value, so moving that to a proper flags place. Signed-off-by: Gustavo F. Padovan Signed-off-by: Marcel Holtmann --- drivers/bluetooth/btusb.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'drivers/bluetooth') diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index 6fcb97124be8..d22ce3cc611e 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -149,6 +149,7 @@ static struct usb_device_id blacklist_table[] = { #define BTUSB_BULK_RUNNING 1 #define BTUSB_ISOC_RUNNING 2 #define BTUSB_SUSPENDING 3 +#define BTUSB_DID_ISO_RESUME 4 struct btusb_data { struct hci_dev *hdev; @@ -182,7 +183,6 @@ struct btusb_data { unsigned int sco_num; int isoc_altsetting; int suspend_count; - int did_iso_resume:1; }; static int inc_tx(struct btusb_data *data) @@ -810,7 +810,7 @@ static void btusb_work(struct work_struct *work) int err; if (hdev->conn_hash.sco_num > 0) { - if (!data->did_iso_resume) { + if (!test_bit(BTUSB_DID_ISO_RESUME, &data->flags)) { err = usb_autopm_get_interface(data->isoc); if (err < 0) { clear_bit(BTUSB_ISOC_RUNNING, &data->flags); @@ -818,7 +818,7 @@ static void btusb_work(struct work_struct *work) return; } - data->did_iso_resume = 1; + set_bit(BTUSB_DID_ISO_RESUME, &data->flags); } if (data->isoc_altsetting != 2) { clear_bit(BTUSB_ISOC_RUNNING, &data->flags); @@ -839,10 +839,8 @@ static void btusb_work(struct work_struct *work) usb_kill_anchored_urbs(&data->isoc_anchor); __set_isoc_interface(hdev, 0); - if (data->did_iso_resume) { - data->did_iso_resume = 0; + if (test_and_clear_bit(BTUSB_DID_ISO_RESUME, &data->flags)) usb_autopm_put_interface(data->isoc); - } } } -- cgit v1.2.3-70-g09d2 From 81ca405aee7e4a1a432c3887bc83ae798fd2cccd Mon Sep 17 00:00:00 2001 From: "Gustavo F. Padovan" Date: Mon, 19 Jul 2010 13:54:05 -0300 Subject: Bluetooth: Use __packed annotation for drivers Use the __packed annotation instead of the __attribute__((packed)). Signed-off-by: Gustavo F. Padovan Signed-off-by: Marcel Holtmann --- drivers/bluetooth/bpa10x.c | 2 +- drivers/bluetooth/btmrvl_drv.h | 4 ++-- drivers/bluetooth/dtl1_cs.c | 2 +- drivers/bluetooth/hci_ll.c | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers/bluetooth') diff --git a/drivers/bluetooth/bpa10x.c b/drivers/bluetooth/bpa10x.c index d945cd12433a..751b338d904a 100644 --- a/drivers/bluetooth/bpa10x.c +++ b/drivers/bluetooth/bpa10x.c @@ -62,7 +62,7 @@ struct hci_vendor_hdr { __u8 type; __le16 snum; __le16 dlen; -} __attribute__ ((packed)); +} __packed; static int bpa10x_recv(struct hci_dev *hdev, int queue, void *buf, int count) { diff --git a/drivers/bluetooth/btmrvl_drv.h b/drivers/bluetooth/btmrvl_drv.h index 872cb6cfcd0d..90bda50dc446 100644 --- a/drivers/bluetooth/btmrvl_drv.h +++ b/drivers/bluetooth/btmrvl_drv.h @@ -119,13 +119,13 @@ struct btmrvl_cmd { __le16 ocf_ogf; u8 length; u8 data[4]; -} __attribute__ ((packed)); +} __packed; struct btmrvl_event { u8 ec; /* event counter */ u8 length; u8 data[4]; -} __attribute__ ((packed)); +} __packed; /* Prototype of global function */ diff --git a/drivers/bluetooth/dtl1_cs.c b/drivers/bluetooth/dtl1_cs.c index ef044d55cb25..cbe9e44a42e9 100644 --- a/drivers/bluetooth/dtl1_cs.c +++ b/drivers/bluetooth/dtl1_cs.c @@ -104,7 +104,7 @@ typedef struct { u8 type; u8 zero; u16 len; -} __attribute__ ((packed)) nsh_t; /* Nokia Specific Header */ +} __packed nsh_t; /* Nokia Specific Header */ #define NSHL 4 /* Nokia Specific Header Length */ diff --git a/drivers/bluetooth/hci_ll.c b/drivers/bluetooth/hci_ll.c index fb8445c7365e..5744aba8272e 100644 --- a/drivers/bluetooth/hci_ll.c +++ b/drivers/bluetooth/hci_ll.c @@ -74,7 +74,7 @@ enum hcill_states_e { struct hcill_cmd { u8 cmd; -} __attribute__((packed)); +} __packed; struct ll_struct { unsigned long rx_state; -- cgit v1.2.3-70-g09d2 From b3190df628617c7a4f188a9465aeabe1f5761933 Mon Sep 17 00:00:00 2001 From: Suraj Sumangala Date: Mon, 19 Jul 2010 12:34:07 +0530 Subject: Bluetooth: Support for Atheros AR300x serial chip Implements Atheros AR300x serial HCI protocol. This protocol extends H4 serial protocol to implement enhanced power management features supported by Atheros AR300x serial Bluetooth chipsets. Signed-off-by: Suraj Sumangala Signed-off-by: Marcel Holtmann --- drivers/bluetooth/Kconfig | 12 +++ drivers/bluetooth/Makefile | 1 + drivers/bluetooth/hci_ath.c | 235 ++++++++++++++++++++++++++++++++++++++++++ drivers/bluetooth/hci_ldisc.c | 6 ++ drivers/bluetooth/hci_uart.h | 8 +- 5 files changed, 261 insertions(+), 1 deletion(-) create mode 100755 drivers/bluetooth/hci_ath.c (limited to 'drivers/bluetooth') diff --git a/drivers/bluetooth/Kconfig b/drivers/bluetooth/Kconfig index 058fbccf2f52..02deef424926 100644 --- a/drivers/bluetooth/Kconfig +++ b/drivers/bluetooth/Kconfig @@ -58,6 +58,18 @@ config BT_HCIUART_BCSP Say Y here to compile support for HCI BCSP protocol. +config BT_HCIUART_ATH3K + bool "Atheros AR300x serial support" + depends on BT_HCIUART + help + HCIATH3K (HCI Atheros AR300x) is a serial protocol for + communication between host and Atheros AR300x Bluetooth devices. + This protocol enables AR300x chips to be enabled with + power management support. + Enable this if you have Atheros AR300x serial Bluetooth device. + + Say Y here to compile support for HCI UART ATH3K protocol. + config BT_HCIUART_LL bool "HCILL protocol support" depends on BT_HCIUART diff --git a/drivers/bluetooth/Makefile b/drivers/bluetooth/Makefile index 7e5aed598121..71bdf13287c4 100644 --- a/drivers/bluetooth/Makefile +++ b/drivers/bluetooth/Makefile @@ -26,4 +26,5 @@ hci_uart-y := hci_ldisc.o hci_uart-$(CONFIG_BT_HCIUART_H4) += hci_h4.o hci_uart-$(CONFIG_BT_HCIUART_BCSP) += hci_bcsp.o hci_uart-$(CONFIG_BT_HCIUART_LL) += hci_ll.o +hci_uart-$(CONFIG_BT_HCIUART_ATH3K) += hci_ath.o hci_uart-objs := $(hci_uart-y) diff --git a/drivers/bluetooth/hci_ath.c b/drivers/bluetooth/hci_ath.c new file mode 100755 index 000000000000..5ab258bccccb --- /dev/null +++ b/drivers/bluetooth/hci_ath.c @@ -0,0 +1,235 @@ +/* + * Atheros Communication Bluetooth HCIATH3K UART protocol + * + * HCIATH3K (HCI Atheros AR300x Protocol) is a Atheros Communication's + * power management protocol extension to H4 to support AR300x Bluetooth Chip. + * + * Copyright (c) 2009-2010 Atheros Communications Inc. + * + * Acknowledgements: + * This file is based on hci_h4.c, which was written + * by Maxim Krasnyansky and Marcel Holtmann. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "hci_uart.h" + +struct ath_struct { + struct hci_uart *hu; + unsigned int cur_sleep; + + struct sk_buff_head txq; + struct work_struct ctxtsw; +}; + +static int ath_wakeup_ar3k(struct tty_struct *tty) +{ + struct termios settings; + int status = tty->driver->ops->tiocmget(tty, NULL); + + if (status & TIOCM_CTS) + return status; + + /* Disable Automatic RTSCTS */ + n_tty_ioctl_helper(tty, NULL, TCGETS, (unsigned long)&settings); + settings.c_cflag &= ~CRTSCTS; + n_tty_ioctl_helper(tty, NULL, TCSETS, (unsigned long)&settings); + + /* Clear RTS first */ + status = tty->driver->ops->tiocmget(tty, NULL); + tty->driver->ops->tiocmset(tty, NULL, 0x00, TIOCM_RTS); + mdelay(20); + + /* Set RTS, wake up board */ + status = tty->driver->ops->tiocmget(tty, NULL); + tty->driver->ops->tiocmset(tty, NULL, TIOCM_RTS, 0x00); + mdelay(20); + + status = tty->driver->ops->tiocmget(tty, NULL); + + n_tty_ioctl_helper(tty, NULL, TCGETS, (unsigned long)&settings); + settings.c_cflag |= CRTSCTS; + n_tty_ioctl_helper(tty, NULL, TCSETS, (unsigned long)&settings); + + return status; +} + +static void ath_hci_uart_work(struct work_struct *work) +{ + int status; + struct ath_struct *ath; + struct hci_uart *hu; + struct tty_struct *tty; + + ath = container_of(work, struct ath_struct, ctxtsw); + + hu = ath->hu; + tty = hu->tty; + + /* verify and wake up controller */ + if (ath->cur_sleep) { + status = ath_wakeup_ar3k(tty); + if (!(status & TIOCM_CTS)) + return; + } + + /* Ready to send Data */ + clear_bit(HCI_UART_SENDING, &hu->tx_state); + hci_uart_tx_wakeup(hu); +} + +/* Initialize protocol */ +static int ath_open(struct hci_uart *hu) +{ + struct ath_struct *ath; + + BT_DBG("hu %p", hu); + + ath = kzalloc(sizeof(*ath), GFP_ATOMIC); + if (!ath) + return -ENOMEM; + + skb_queue_head_init(&ath->txq); + + hu->priv = ath; + ath->hu = hu; + + INIT_WORK(&ath->ctxtsw, ath_hci_uart_work); + + return 0; +} + +/* Flush protocol data */ +static int ath_flush(struct hci_uart *hu) +{ + struct ath_struct *ath = hu->priv; + + BT_DBG("hu %p", hu); + + skb_queue_purge(&ath->txq); + + return 0; +} + +/* Close protocol */ +static int ath_close(struct hci_uart *hu) +{ + struct ath_struct *ath = hu->priv; + + BT_DBG("hu %p", hu); + + skb_queue_purge(&ath->txq); + + cancel_work_sync(&ath->ctxtsw); + + hu->priv = NULL; + kfree(ath); + + return 0; +} + +#define HCI_OP_ATH_SLEEP 0xFC04 + +/* Enqueue frame for transmittion */ +static int ath_enqueue(struct hci_uart *hu, struct sk_buff *skb) +{ + struct ath_struct *ath = hu->priv; + + if (bt_cb(skb)->pkt_type == HCI_SCODATA_PKT) { + kfree(skb); + return 0; + } + + /* + * Update power management enable flag with parameters of + * HCI sleep enable vendor specific HCI command. + */ + if (bt_cb(skb)->pkt_type == HCI_COMMAND_PKT) { + struct hci_command_hdr *hdr = (void *)skb->data; + + if (__le16_to_cpu(hdr->opcode) == HCI_OP_ATH_SLEEP) + ath->cur_sleep = skb->data[HCI_COMMAND_HDR_SIZE]; + } + + BT_DBG("hu %p skb %p", hu, skb); + + /* Prepend skb with frame type */ + memcpy(skb_push(skb, 1), &bt_cb(skb)->pkt_type, 1); + + skb_queue_tail(&ath->txq, skb); + set_bit(HCI_UART_SENDING, &hu->tx_state); + + schedule_work(&ath->ctxtsw); + + return 0; +} + +static struct sk_buff *ath_dequeue(struct hci_uart *hu) +{ + struct ath_struct *ath = hu->priv; + + return skb_dequeue(&ath->txq); +} + +/* Recv data */ +static int ath_recv(struct hci_uart *hu, void *data, int count) +{ + if (hci_recv_stream_fragment(hu->hdev, data, count) < 0) + BT_ERR("Frame Reassembly Failed"); + + return count; +} + +static struct hci_uart_proto athp = { + .id = HCI_UART_ATH3K, + .open = ath_open, + .close = ath_close, + .recv = ath_recv, + .enqueue = ath_enqueue, + .dequeue = ath_dequeue, + .flush = ath_flush, +}; + +int ath_init(void) +{ + int err = hci_uart_register_proto(&athp); + + if (!err) + BT_INFO("HCIATH3K protocol initialized"); + else + BT_ERR("HCIATH3K protocol registration failed"); + + return err; +} + +int ath_deinit(void) +{ + return hci_uart_unregister_proto(&athp); +} diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c index a57dbfccb3fb..998833d93c13 100644 --- a/drivers/bluetooth/hci_ldisc.c +++ b/drivers/bluetooth/hci_ldisc.c @@ -552,6 +552,9 @@ static int __init hci_uart_init(void) #ifdef CONFIG_BT_HCIUART_LL ll_init(); #endif +#ifdef CONFIG_BT_HCIUART_ATH3K + ath_init(); +#endif return 0; } @@ -569,6 +572,9 @@ static void __exit hci_uart_exit(void) #ifdef CONFIG_BT_HCIUART_LL ll_deinit(); #endif +#ifdef CONFIG_BT_HCIUART_ATH3K + ath_deinit(); +#endif /* Release tty registration of line discipline */ if ((err = tty_unregister_ldisc(N_HCI))) diff --git a/drivers/bluetooth/hci_uart.h b/drivers/bluetooth/hci_uart.h index 9694d9d60905..99fb35239d1f 100644 --- a/drivers/bluetooth/hci_uart.h +++ b/drivers/bluetooth/hci_uart.h @@ -35,13 +35,14 @@ #define HCIUARTGETFLAGS _IOR('U', 204, int) /* UART protocols */ -#define HCI_UART_MAX_PROTO 5 +#define HCI_UART_MAX_PROTO 6 #define HCI_UART_H4 0 #define HCI_UART_BCSP 1 #define HCI_UART_3WIRE 2 #define HCI_UART_H4DS 3 #define HCI_UART_LL 4 +#define HCI_UART_ATH3K 5 #define HCI_UART_RAW_DEVICE 0 @@ -96,3 +97,8 @@ int bcsp_deinit(void); int ll_init(void); int ll_deinit(void); #endif + +#ifdef CONFIG_BT_HCIUART_ATH3K +int ath_init(void); +int ath_deinit(void); +#endif -- cgit v1.2.3-70-g09d2 From 0bbdf6cba0fb730ae2f2cfd5ead3d1e2e5498ddc Mon Sep 17 00:00:00 2001 From: "Gustavo F. Padovan" Date: Sat, 24 Jul 2010 01:06:05 -0300 Subject: Bluetooth: Fix permission of hci_ath.c .c file shall not have the 'x' permission. Signed-off-by: Gustavo F. Padovan Signed-off-by: Marcel Holtmann --- drivers/bluetooth/hci_ath.c | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 drivers/bluetooth/hci_ath.c (limited to 'drivers/bluetooth') diff --git a/drivers/bluetooth/hci_ath.c b/drivers/bluetooth/hci_ath.c old mode 100755 new mode 100644 -- cgit v1.2.3-70-g09d2 From e9da101f6d0c9a8fda9f78a80365ba2a9f75603f Mon Sep 17 00:00:00 2001 From: "Gustavo F. Padovan" Date: Sat, 24 Jul 2010 01:46:57 -0300 Subject: Bluetooth: Use hci_recv_stream_fragment() in UART driver Use the new hci_recv_stream_fragment() to reassembly incoming UART streams. Signed-off-by: Gustavo F. Padovan Tested-by: Ville Tervo Signed-off-by: Marcel Holtmann --- drivers/bluetooth/hci_h4.c | 103 +-------------------------------------------- 1 file changed, 2 insertions(+), 101 deletions(-) (limited to 'drivers/bluetooth') diff --git a/drivers/bluetooth/hci_h4.c b/drivers/bluetooth/hci_h4.c index 3f038f5308a4..b2cf50e3cafb 100644 --- a/drivers/bluetooth/hci_h4.c +++ b/drivers/bluetooth/hci_h4.c @@ -151,107 +151,8 @@ static inline int h4_check_data_len(struct h4_struct *h4, int len) /* Recv data */ static int h4_recv(struct hci_uart *hu, void *data, int count) { - struct h4_struct *h4 = hu->priv; - register char *ptr; - struct hci_event_hdr *eh; - struct hci_acl_hdr *ah; - struct hci_sco_hdr *sh; - register int len, type, dlen; - - BT_DBG("hu %p count %d rx_state %ld rx_count %ld", - hu, count, h4->rx_state, h4->rx_count); - - ptr = data; - while (count) { - if (h4->rx_count) { - len = min_t(unsigned int, h4->rx_count, count); - memcpy(skb_put(h4->rx_skb, len), ptr, len); - h4->rx_count -= len; count -= len; ptr += len; - - if (h4->rx_count) - continue; - - switch (h4->rx_state) { - case H4_W4_DATA: - BT_DBG("Complete data"); - - hci_recv_frame(h4->rx_skb); - - h4->rx_state = H4_W4_PACKET_TYPE; - h4->rx_skb = NULL; - continue; - - case H4_W4_EVENT_HDR: - eh = hci_event_hdr(h4->rx_skb); - - BT_DBG("Event header: evt 0x%2.2x plen %d", eh->evt, eh->plen); - - h4_check_data_len(h4, eh->plen); - continue; - - case H4_W4_ACL_HDR: - ah = hci_acl_hdr(h4->rx_skb); - dlen = __le16_to_cpu(ah->dlen); - - BT_DBG("ACL header: dlen %d", dlen); - - h4_check_data_len(h4, dlen); - continue; - - case H4_W4_SCO_HDR: - sh = hci_sco_hdr(h4->rx_skb); - - BT_DBG("SCO header: dlen %d", sh->dlen); - - h4_check_data_len(h4, sh->dlen); - continue; - } - } - - /* H4_W4_PACKET_TYPE */ - switch (*ptr) { - case HCI_EVENT_PKT: - BT_DBG("Event packet"); - h4->rx_state = H4_W4_EVENT_HDR; - h4->rx_count = HCI_EVENT_HDR_SIZE; - type = HCI_EVENT_PKT; - break; - - case HCI_ACLDATA_PKT: - BT_DBG("ACL packet"); - h4->rx_state = H4_W4_ACL_HDR; - h4->rx_count = HCI_ACL_HDR_SIZE; - type = HCI_ACLDATA_PKT; - break; - - case HCI_SCODATA_PKT: - BT_DBG("SCO packet"); - h4->rx_state = H4_W4_SCO_HDR; - h4->rx_count = HCI_SCO_HDR_SIZE; - type = HCI_SCODATA_PKT; - break; - - default: - BT_ERR("Unknown HCI packet type %2.2x", (__u8)*ptr); - hu->hdev->stat.err_rx++; - ptr++; count--; - continue; - }; - - ptr++; count--; - - /* Allocate packet */ - h4->rx_skb = bt_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_ATOMIC); - if (!h4->rx_skb) { - BT_ERR("Can't allocate mem for new packet"); - h4->rx_state = H4_W4_PACKET_TYPE; - h4->rx_count = 0; - return -ENOMEM; - } - - h4->rx_skb->dev = (void *) hu->hdev; - bt_cb(h4->rx_skb)->pkt_type = type; - } + if (hci_recv_stream_fragment(hu->hdev, data, count) < 0) + BT_ERR("Frame Reassembly Failed"); return count; } -- cgit v1.2.3-70-g09d2 From f2b94bb9e0b8bd048331a6e9d616e918f4bcbd97 Mon Sep 17 00:00:00 2001 From: "Gustavo F. Padovan" Date: Sat, 24 Jul 2010 02:04:44 -0300 Subject: Bluetooth: Add __init and __exit marks to UART drivers Those marks are useful to save space in the binary and in the memory. Signed-off-by: Gustavo F. Padovan Signed-off-by: Marcel Holtmann --- drivers/bluetooth/hci_ath.c | 4 ++-- drivers/bluetooth/hci_bcsp.c | 4 ++-- drivers/bluetooth/hci_h4.c | 4 ++-- drivers/bluetooth/hci_ll.c | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) (limited to 'drivers/bluetooth') diff --git a/drivers/bluetooth/hci_ath.c b/drivers/bluetooth/hci_ath.c index 5ab258bccccb..b941dd5dc981 100644 --- a/drivers/bluetooth/hci_ath.c +++ b/drivers/bluetooth/hci_ath.c @@ -217,7 +217,7 @@ static struct hci_uart_proto athp = { .flush = ath_flush, }; -int ath_init(void) +int __init ath_init(void) { int err = hci_uart_register_proto(&athp); @@ -229,7 +229,7 @@ int ath_init(void) return err; } -int ath_deinit(void) +int __exit ath_deinit(void) { return hci_uart_unregister_proto(&athp); } diff --git a/drivers/bluetooth/hci_bcsp.c b/drivers/bluetooth/hci_bcsp.c index 42d69d4de05c..9c5b2dc38e29 100644 --- a/drivers/bluetooth/hci_bcsp.c +++ b/drivers/bluetooth/hci_bcsp.c @@ -739,7 +739,7 @@ static struct hci_uart_proto bcsp = { .flush = bcsp_flush }; -int bcsp_init(void) +int __init bcsp_init(void) { int err = hci_uart_register_proto(&bcsp); @@ -751,7 +751,7 @@ int bcsp_init(void) return err; } -int bcsp_deinit(void) +int __exit bcsp_deinit(void) { return hci_uart_unregister_proto(&bcsp); } diff --git a/drivers/bluetooth/hci_h4.c b/drivers/bluetooth/hci_h4.c index b2cf50e3cafb..7b8ad93e2c36 100644 --- a/drivers/bluetooth/hci_h4.c +++ b/drivers/bluetooth/hci_h4.c @@ -173,7 +173,7 @@ static struct hci_uart_proto h4p = { .flush = h4_flush, }; -int h4_init(void) +int __init h4_init(void) { int err = hci_uart_register_proto(&h4p); @@ -185,7 +185,7 @@ int h4_init(void) return err; } -int h4_deinit(void) +int __exit h4_deinit(void) { return hci_uart_unregister_proto(&h4p); } diff --git a/drivers/bluetooth/hci_ll.c b/drivers/bluetooth/hci_ll.c index 5744aba8272e..38595e782d02 100644 --- a/drivers/bluetooth/hci_ll.c +++ b/drivers/bluetooth/hci_ll.c @@ -517,7 +517,7 @@ static struct hci_uart_proto llp = { .flush = ll_flush, }; -int ll_init(void) +int __init ll_init(void) { int err = hci_uart_register_proto(&llp); @@ -529,7 +529,7 @@ int ll_init(void) return err; } -int ll_deinit(void) +int __exit ll_deinit(void) { return hci_uart_unregister_proto(&llp); } -- cgit v1.2.3-70-g09d2 From 4ebaa4edf8799cab19d5a0642dc95f04fd284e06 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Fri, 23 Jul 2010 12:11:04 +0200 Subject: Bluetooth: Fix kfree() => kfree_skb() in hci_ath.c sk_buffs have to be freed with kfree_skb() instead of kfree(). Signed-off-by: Dan Carpenter Acked-by: Gustavo F. Padovan Signed-off-by: Marcel Holtmann --- drivers/bluetooth/hci_ath.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/bluetooth') diff --git a/drivers/bluetooth/hci_ath.c b/drivers/bluetooth/hci_ath.c index b941dd5dc981..6a160c17ea94 100644 --- a/drivers/bluetooth/hci_ath.c +++ b/drivers/bluetooth/hci_ath.c @@ -163,7 +163,7 @@ static int ath_enqueue(struct hci_uart *hu, struct sk_buff *skb) struct ath_struct *ath = hu->priv; if (bt_cb(skb)->pkt_type == HCI_SCODATA_PKT) { - kfree(skb); + kfree_skb(skb); return 0; } -- cgit v1.2.3-70-g09d2