]> git.neil.brown.name Git - history.git/commitdiff
[Bluetooth] Dynamic allocation of HCI device
authorMarcel Holtmann <marcel@holtmann.org>
Thu, 26 Feb 2004 03:07:39 +0000 (04:07 +0100)
committerMarcel Holtmann <marcel@holtmann.org>
Thu, 26 Feb 2004 03:07:39 +0000 (04:07 +0100)
For correct integration into the driver model the allocation of the HCI
device must be dynamic.

17 files changed:
drivers/bluetooth/bfusb.c
drivers/bluetooth/bluecard_cs.c
drivers/bluetooth/bt3c_cs.c
drivers/bluetooth/btuart_cs.c
drivers/bluetooth/dtl1_cs.c
drivers/bluetooth/hci_bcsp.c
drivers/bluetooth/hci_h4.c
drivers/bluetooth/hci_ldisc.c
drivers/bluetooth/hci_uart.h
drivers/bluetooth/hci_usb.c
drivers/bluetooth/hci_usb.h
drivers/bluetooth/hci_vhci.c
drivers/bluetooth/hci_vhci.h
include/net/bluetooth/hci_core.h
net/bluetooth/hci_core.c
net/bluetooth/hci_sysfs.c
net/bluetooth/syms.c

index 7becc5b351a7c6af17896bdb7ee32aa26b349a2a..ac2bdf2120e34e5babe8505435123d7837cfd01c 100644 (file)
@@ -70,7 +70,7 @@ MODULE_DEVICE_TABLE(usb, bfusb_table);
 #define BFUSB_MAX_BULK_RX      2
 
 struct bfusb {
-       struct hci_dev          hdev;
+       struct hci_dev          *hdev;
 
        unsigned long           state;
 
@@ -155,7 +155,7 @@ static int bfusb_send_bulk(struct bfusb *bfusb, struct sk_buff *skb)
        err = usb_submit_urb(urb, GFP_ATOMIC);
        if (err) {
                BT_ERR("%s bulk tx submit failed urb %p err %d", 
-                                       bfusb->hdev.name, urb, err);
+                                       bfusb->hdev->name, urb, err);
                skb_unlink(skb);
                usb_free_urb(urb);
        } else
@@ -200,13 +200,13 @@ static void bfusb_tx_complete(struct urb *urb, struct pt_regs *regs)
 
        atomic_dec(&bfusb->pending_tx);
 
-       if (!test_bit(HCI_RUNNING, &bfusb->hdev.flags))
+       if (!test_bit(HCI_RUNNING, &bfusb->hdev->flags))
                return;
 
        if (!urb->status)
-               bfusb->hdev.stat.byte_tx += skb->len;
+               bfusb->hdev->stat.byte_tx += skb->len;
        else
-               bfusb->hdev.stat.err_tx++;
+               bfusb->hdev->stat.err_tx++;
 
        read_lock(&bfusb->lock);
 
@@ -250,7 +250,7 @@ static int bfusb_rx_submit(struct bfusb *bfusb, struct urb *urb)
        err = usb_submit_urb(urb, GFP_ATOMIC);
        if (err) {
                BT_ERR("%s bulk rx submit failed urb %p err %d",
-                                       bfusb->hdev.name, urb, err);
+                                       bfusb->hdev->name, urb, err);
                skb_unlink(skb);
                kfree_skb(skb);
                usb_free_urb(urb);
@@ -264,7 +264,7 @@ static inline int bfusb_recv_block(struct bfusb *bfusb, int hdr, unsigned char *
        BT_DBG("bfusb %p hdr 0x%02x data %p len %d", bfusb, hdr, data, len);
 
        if (hdr & 0x10) {
-               BT_ERR("%s error in block", bfusb->hdev.name);
+               BT_ERR("%s error in block", bfusb->hdev->name);
                if (bfusb->reassembly)
                        kfree_skb(bfusb->reassembly);
                bfusb->reassembly = NULL;
@@ -277,13 +277,13 @@ static inline int bfusb_recv_block(struct bfusb *bfusb, int hdr, unsigned char *
                int pkt_len = 0;
 
                if (bfusb->reassembly) {
-                       BT_ERR("%s unexpected start block", bfusb->hdev.name);
+                       BT_ERR("%s unexpected start block", bfusb->hdev->name);
                        kfree_skb(bfusb->reassembly);
                        bfusb->reassembly = NULL;
                }
 
                if (len < 1) {
-                       BT_ERR("%s no packet type found", bfusb->hdev.name);
+                       BT_ERR("%s no packet type found", bfusb->hdev->name);
                        return -EPROTO;
                }
 
@@ -295,7 +295,7 @@ static inline int bfusb_recv_block(struct bfusb *bfusb, int hdr, unsigned char *
                                struct hci_event_hdr *hdr = (struct hci_event_hdr *) data;
                                pkt_len = HCI_EVENT_HDR_SIZE + hdr->plen;
                        } else {
-                               BT_ERR("%s event block is too short", bfusb->hdev.name);
+                               BT_ERR("%s event block is too short", bfusb->hdev->name);
                                return -EILSEQ;
                        }
                        break;
@@ -305,7 +305,7 @@ static inline int bfusb_recv_block(struct bfusb *bfusb, int hdr, unsigned char *
                                struct hci_acl_hdr *hdr = (struct hci_acl_hdr *) data;
                                pkt_len = HCI_ACL_HDR_SIZE + __le16_to_cpu(hdr->dlen);
                        } else {
-                               BT_ERR("%s data block is too short", bfusb->hdev.name);
+                               BT_ERR("%s data block is too short", bfusb->hdev->name);
                                return -EILSEQ;
                        }
                        break;
@@ -315,7 +315,7 @@ static inline int bfusb_recv_block(struct bfusb *bfusb, int hdr, unsigned char *
                                struct hci_sco_hdr *hdr = (struct hci_sco_hdr *) data;
                                pkt_len = HCI_SCO_HDR_SIZE + hdr->dlen;
                        } else {
-                               BT_ERR("%s audio block is too short", bfusb->hdev.name);
+                               BT_ERR("%s audio block is too short", bfusb->hdev->name);
                                return -EILSEQ;
                        }
                        break;
@@ -323,17 +323,17 @@ static inline int bfusb_recv_block(struct bfusb *bfusb, int hdr, unsigned char *
 
                skb = bt_skb_alloc(pkt_len, GFP_ATOMIC);
                if (!skb) {
-                       BT_ERR("%s no memory for the packet", bfusb->hdev.name);
+                       BT_ERR("%s no memory for the packet", bfusb->hdev->name);
                        return -ENOMEM;
                }
 
-               skb->dev = (void *) &bfusb->hdev;
+               skb->dev = (void *) bfusb->hdev;
                skb->pkt_type = pkt_type;
 
                bfusb->reassembly = skb;
        } else {
                if (!bfusb->reassembly) {
-                       BT_ERR("%s unexpected continuation block", bfusb->hdev.name);
+                       BT_ERR("%s unexpected continuation block", bfusb->hdev->name);
                        return -EIO;
                }
        }
@@ -359,7 +359,7 @@ static void bfusb_rx_complete(struct urb *urb, struct pt_regs *regs)
 
        BT_DBG("bfusb %p urb %p skb %p len %d", bfusb, urb, skb, skb->len);
 
-       if (!test_bit(HCI_RUNNING, &bfusb->hdev.flags))
+       if (!test_bit(HCI_RUNNING, &bfusb->hdev->flags))
                return;
 
        read_lock(&bfusb->lock);
@@ -367,7 +367,7 @@ static void bfusb_rx_complete(struct urb *urb, struct pt_regs *regs)
        if (urb->status || !count)
                goto resubmit;
 
-       bfusb->hdev.stat.byte_rx += count;
+       bfusb->hdev->stat.byte_rx += count;
 
        skb_put(skb, count);
 
@@ -386,7 +386,7 @@ static void bfusb_rx_complete(struct urb *urb, struct pt_regs *regs)
 
                if (count < len) {
                        BT_ERR("%s block extends over URB buffer ranges",
-                                       bfusb->hdev.name);
+                                       bfusb->hdev->name);
                }
 
                if ((hdr & 0xe1) == 0xc1)
@@ -411,7 +411,7 @@ resubmit:
        err = usb_submit_urb(urb, GFP_ATOMIC);
        if (err) {
                BT_ERR("%s bulk resubmit failed urb %p err %d",
-                                       bfusb->hdev.name, urb, err);
+                                       bfusb->hdev->name, urb, err);
        }
 
        read_unlock(&bfusb->lock);
@@ -698,7 +698,13 @@ static int bfusb_probe(struct usb_interface *intf, const struct usb_device_id *i
        release_firmware(firmware);
 
        /* Initialize and register HCI device */
-       hdev = &bfusb->hdev;
+       hdev = hci_alloc_dev();
+       if (!hdev) {
+               BT_ERR("Can't allocate HCI device");
+               goto error;
+       }
+
+       bfusb->hdev = hdev;
 
        hdev->type = HCI_USB;
        hdev->driver_data = bfusb;
@@ -715,6 +721,7 @@ static int bfusb_probe(struct usb_interface *intf, const struct usb_device_id *i
 
        if (hci_register_dev(hdev) < 0) {
                BT_ERR("Can't register HCI device");
+               hci_free_dev(hdev);
                goto error;
        }
 
@@ -735,7 +742,7 @@ done:
 static void bfusb_disconnect(struct usb_interface *intf)
 {
        struct bfusb *bfusb = usb_get_intfdata(intf);
-       struct hci_dev *hdev = &bfusb->hdev;
+       struct hci_dev *hdev = bfusb->hdev;
 
        BT_DBG("intf %p", intf);
 
@@ -748,6 +755,8 @@ static void bfusb_disconnect(struct usb_interface *intf)
 
        if (hci_unregister_dev(hdev) < 0)
                BT_ERR("Can't unregister HCI device %s", hdev->name);
+
+       hci_free_dev(hdev);
 }
 
 static struct usb_driver bfusb_driver = {
index fb2424336e68c6457bb471dc61d39fa0febf8166..a108413ce698744470acb56c40da89bf23fd07dd 100644 (file)
@@ -72,7 +72,7 @@ typedef struct bluecard_info_t {
        dev_link_t link;
        dev_node_t node;
 
-       struct hci_dev hdev;
+       struct hci_dev *hdev;
 
        spinlock_t lock;                /* For serializing operations */
        struct timer_list timer;        /* For LED control */
@@ -333,7 +333,7 @@ static void bluecard_write_wakeup(bluecard_info_t *info)
                        skb_queue_head(&(info->txq), skb);
                }
 
-               info->hdev.stat.byte_tx += len;
+               info->hdev->stat.byte_tx += len;
 
                /* Change buffer */
                change_bit(XMIT_BUFFER_NUMBER, &(info->tx_state));
@@ -404,7 +404,7 @@ static void bluecard_receive(bluecard_info_t *info, unsigned int offset)
 
                if (info->rx_state == RECV_WAIT_PACKET_TYPE) {
 
-                       info->rx_skb->dev = (void *)&(info->hdev);
+                       info->rx_skb->dev = (void *) info->hdev;
                        info->rx_skb->pkt_type = buf[i];
 
                        switch (info->rx_skb->pkt_type) {
@@ -440,7 +440,7 @@ static void bluecard_receive(bluecard_info_t *info, unsigned int offset)
                        default:
                                /* unknown packet */
                                printk(KERN_WARNING "bluecard_cs: Unknown HCI packet with type 0x%02x received.\n", info->rx_skb->pkt_type);
-                               info->hdev.stat.err_rx++;
+                               info->hdev->stat.err_rx++;
 
                                kfree_skb(info->rx_skb);
                                info->rx_skb = NULL;
@@ -495,7 +495,7 @@ static void bluecard_receive(bluecard_info_t *info, unsigned int offset)
 
        }
 
-       info->hdev.stat.byte_rx += len;
+       info->hdev->stat.byte_rx += len;
 }
 
 
@@ -778,8 +778,13 @@ int bluecard_open(bluecard_info_t *info)
 
 
        /* Initialize and register HCI device */
+       hdev = hci_alloc_dev();
+       if (!hdev) {
+               printk(KERN_WARNING "bluecard_cs: Can't allocate HCI device.\n");
+               return -ENOMEM;
+       }
 
-       hdev = &(info->hdev);
+       info->hdev = hdev;
 
        hdev->type = HCI_PCCARD;
        hdev->driver_data = info;
@@ -794,7 +799,8 @@ int bluecard_open(bluecard_info_t *info)
        hdev->owner = THIS_MODULE;
        
        if (hci_register_dev(hdev) < 0) {
-               printk(KERN_WARNING "bluecard_cs: Can't register HCI device %s.\n", hdev->name);
+               printk(KERN_WARNING "bluecard_cs: Can't register HCI device.\n");
+               hci_free_dev(hdev);
                return -ENODEV;
        }
 
@@ -805,7 +811,7 @@ int bluecard_open(bluecard_info_t *info)
 int bluecard_close(bluecard_info_t *info)
 {
        unsigned int iobase = info->link.io.BasePort1;
-       struct hci_dev *hdev = &(info->hdev);
+       struct hci_dev *hdev = info->hdev;
 
        bluecard_hci_close(hdev);
 
@@ -821,6 +827,8 @@ int bluecard_close(bluecard_info_t *info)
        if (hci_unregister_dev(hdev) < 0)
                printk(KERN_WARNING "bluecard_cs: Can't unregister HCI device %s.\n", hdev->name);
 
+       hci_free_dev(hdev);
+
        return 0;
 }
 
@@ -988,7 +996,7 @@ void bluecard_config(dev_link_t *link)
        if (bluecard_open(info) != 0)
                goto failed;
 
-       strcpy(info->node.dev_name, info->hdev.name);
+       strcpy(info->node.dev_name, info->hdev->name);
        link->dev = &info->node;
        link->state &= ~DEV_CONFIG_PENDING;
 
index dcfee26a9766e1def933536fe4c151c8fe3701f5..73afb11803d2802510d94432bcff93e2a98f1852 100644 (file)
@@ -79,7 +79,7 @@ typedef struct bt3c_info_t {
        dev_link_t link;
        dev_node_t node;
 
-       struct hci_dev hdev;
+       struct hci_dev *hdev;
 
        spinlock_t lock;                /* For serializing operations */
 
@@ -227,7 +227,7 @@ static void bt3c_write_wakeup(bt3c_info_t *info, int from)
 
                kfree_skb(skb);
 
-               info->hdev.stat.byte_tx += len;
+               info->hdev->stat.byte_tx += len;
 
        } while (0);
 
@@ -253,7 +253,7 @@ static void bt3c_receive(bt3c_info_t *info)
        bt3c_address(iobase, 0x7480);
        while (size < avail) {
                size++;
-               info->hdev.stat.byte_rx++;
+               info->hdev->stat.byte_rx++;
 
                /* Allocate packet */
                if (info->rx_skb == NULL) {
@@ -268,7 +268,7 @@ static void bt3c_receive(bt3c_info_t *info)
 
                if (info->rx_state == RECV_WAIT_PACKET_TYPE) {
 
-                       info->rx_skb->dev = (void *)&(info->hdev);
+                       info->rx_skb->dev = (void *) info->hdev;
                        info->rx_skb->pkt_type = inb(iobase + DATA_L);
                        inb(iobase + DATA_H);
                        //printk("bt3c: PACKET_TYPE=%02x\n", info->rx_skb->pkt_type);
@@ -293,8 +293,8 @@ static void bt3c_receive(bt3c_info_t *info)
                        default:
                                /* Unknown packet */
                                printk(KERN_WARNING "bt3c_cs: Unknown HCI packet with type 0x%02x received.\n", info->rx_skb->pkt_type);
-                               info->hdev.stat.err_rx++;
-                               clear_bit(HCI_RUNNING, &(info->hdev.flags));
+                               info->hdev->stat.err_rx++;
+                               clear_bit(HCI_RUNNING, &(info->hdev->flags));
 
                                kfree_skb(info->rx_skb);
                                info->rx_skb = NULL;
@@ -534,8 +534,13 @@ int bt3c_open(bt3c_info_t *info)
 
 
        /* Initialize and register HCI device */
+       hdev = hci_alloc_dev();
+       if (!hdev) {
+               printk(KERN_WARNING "bt3c_cs: Can't allocate HCI device.\n");
+               return -ENOMEM;
+       }
 
-       hdev = &(info->hdev);
+       info->hdev = hdev;
 
        hdev->type = HCI_PCCARD;
        hdev->driver_data = info;
@@ -550,7 +555,8 @@ int bt3c_open(bt3c_info_t *info)
        hdev->owner = THIS_MODULE;
        
        if (hci_register_dev(hdev) < 0) {
-               printk(KERN_WARNING "bt3c_cs: Can't register HCI device %s.\n", hdev->name);
+               printk(KERN_WARNING "bt3c_cs: Can't register HCI device.\n");
+               hci_free_dev(hdev);
                return -ENODEV;
        }
 
@@ -560,13 +566,15 @@ int bt3c_open(bt3c_info_t *info)
 
 int bt3c_close(bt3c_info_t *info)
 {
-       struct hci_dev *hdev = &(info->hdev);
+       struct hci_dev *hdev = info->hdev;
 
        bt3c_hci_close(hdev);
 
        if (hci_unregister_dev(hdev) < 0)
                printk(KERN_WARNING "bt3c_cs: Can't unregister HCI device %s.\n", hdev->name);
 
+       hci_free_dev(hdev);
+
        return 0;
 }
 
@@ -781,7 +789,7 @@ found_port:
        if (bt3c_open(info) != 0)
                goto failed;
 
-       strcpy(info->node.dev_name, info->hdev.name);
+       strcpy(info->node.dev_name, info->hdev->name);
        link->dev = &info->node;
        link->state &= ~DEV_CONFIG_PENDING;
 
index 9c5fcdbe70bed0ec3e8c0bb27a4b802294e32605..4c56bfdec6d9dfcd555965f7a5b37f4f0fb6912c 100644 (file)
@@ -77,7 +77,7 @@ typedef struct btuart_info_t {
        dev_link_t link;
        dev_node_t node;
 
-       struct hci_dev hdev;
+       struct hci_dev *hdev;
 
        spinlock_t lock;        /* For serializing operations */
 
@@ -181,7 +181,7 @@ static void btuart_write_wakeup(btuart_info_t *info)
                        skb_queue_head(&(info->txq), skb);
                }
 
-               info->hdev.stat.byte_tx += len;
+               info->hdev->stat.byte_tx += len;
 
        } while (test_bit(XMIT_WAKEUP, &(info->tx_state)));
 
@@ -202,7 +202,7 @@ static void btuart_receive(btuart_info_t *info)
        iobase = info->link.io.BasePort1;
 
        do {
-               info->hdev.stat.byte_rx++;
+               info->hdev->stat.byte_rx++;
 
                /* Allocate packet */
                if (info->rx_skb == NULL) {
@@ -216,7 +216,7 @@ static void btuart_receive(btuart_info_t *info)
 
                if (info->rx_state == RECV_WAIT_PACKET_TYPE) {
 
-                       info->rx_skb->dev = (void *)&(info->hdev);
+                       info->rx_skb->dev = (void *) info->hdev;
                        info->rx_skb->pkt_type = inb(iobase + UART_RX);
 
                        switch (info->rx_skb->pkt_type) {
@@ -239,8 +239,8 @@ static void btuart_receive(btuart_info_t *info)
                        default:
                                /* Unknown packet */
                                printk(KERN_WARNING "btuart_cs: Unknown HCI packet with type 0x%02x received.\n", info->rx_skb->pkt_type);
-                               info->hdev.stat.err_rx++;
-                               clear_bit(HCI_RUNNING, &(info->hdev.flags));
+                               info->hdev->stat.err_rx++;
+                               clear_bit(HCI_RUNNING, &(info->hdev->flags));
 
                                kfree_skb(info->rx_skb);
                                info->rx_skb = NULL;
@@ -529,8 +529,13 @@ int btuart_open(btuart_info_t *info)
 
 
        /* Initialize and register HCI device */
+       hdev = hci_alloc_dev();
+       if (!hdev) {
+               printk(KERN_WARNING "btuart_cs: Can't allocate HCI device.\n");
+               return -ENOMEM;
+       }
 
-       hdev = &(info->hdev);
+       info->hdev = hdev;
 
        hdev->type = HCI_PCCARD;
        hdev->driver_data = info;
@@ -545,7 +550,8 @@ int btuart_open(btuart_info_t *info)
        hdev->owner = THIS_MODULE;
        
        if (hci_register_dev(hdev) < 0) {
-               printk(KERN_WARNING "btuart_cs: Can't register HCI device %s.\n", hdev->name);
+               printk(KERN_WARNING "btuart_cs: Can't register HCI device.\n");
+               hci_free_dev(hdev);
                return -ENODEV;
        }
 
@@ -557,7 +563,7 @@ int btuart_close(btuart_info_t *info)
 {
        unsigned long flags;
        unsigned int iobase = info->link.io.BasePort1;
-       struct hci_dev *hdev = &(info->hdev);
+       struct hci_dev *hdev = info->hdev;
 
        btuart_hci_close(hdev);
 
@@ -574,6 +580,8 @@ int btuart_close(btuart_info_t *info)
        if (hci_unregister_dev(hdev) < 0)
                printk(KERN_WARNING "btuart_cs: Can't unregister HCI device %s.\n", hdev->name);
 
+       hci_free_dev(hdev);
+
        return 0;
 }
 
@@ -789,7 +797,7 @@ found_port:
        if (btuart_open(info) != 0)
                goto failed;
 
-       strcpy(info->node.dev_name, info->hdev.name);
+       strcpy(info->node.dev_name, info->hdev->name);
        link->dev = &info->node;
        link->state &= ~DEV_CONFIG_PENDING;
 
index 322879ad0635794817cc682910301bbadebc1314..4cf803ba022fa739586434c3f21ea7ece32d80c2 100644 (file)
@@ -77,7 +77,7 @@ typedef struct dtl1_info_t {
        dev_link_t link;
        dev_node_t node;
 
-       struct hci_dev hdev;
+       struct hci_dev *hdev;
 
        spinlock_t lock;                /* For serializing operations */
 
@@ -188,7 +188,7 @@ static void dtl1_write_wakeup(dtl1_info_t *info)
                        skb_queue_head(&(info->txq), skb);
                }
 
-               info->hdev.stat.byte_tx += len;
+               info->hdev->stat.byte_tx += len;
 
        } while (test_bit(XMIT_WAKEUP, &(info->tx_state)));
 
@@ -233,7 +233,7 @@ static void dtl1_receive(dtl1_info_t *info)
        iobase = info->link.io.BasePort1;
 
        do {
-               info->hdev.stat.byte_rx++;
+               info->hdev->stat.byte_rx++;
 
                /* Allocate packet */
                if (info->rx_skb == NULL)
@@ -277,7 +277,7 @@ static void dtl1_receive(dtl1_info_t *info)
                                case 0x83:
                                case 0x84:
                                        /* send frame to the HCI layer */
-                                       info->rx_skb->dev = (void *)&(info->hdev);
+                                       info->rx_skb->dev = (void *) info->hdev;
                                        info->rx_skb->pkt_type &= 0x0f;
                                        hci_recv_frame(info->rx_skb);
                                        break;
@@ -508,8 +508,13 @@ int dtl1_open(dtl1_info_t *info)
 
 
        /* Initialize and register HCI device */
+       hdev = hci_alloc_dev();
+       if (!hdev) {
+               printk(KERN_WARNING "dtl1_cs: Can't allocate HCI device.\n");
+               return -ENOMEM;
+       }
 
-       hdev = &(info->hdev);
+       info->hdev = hdev;
 
        hdev->type = HCI_PCCARD;
        hdev->driver_data = info;
@@ -522,9 +527,10 @@ int dtl1_open(dtl1_info_t *info)
        hdev->ioctl = dtl1_hci_ioctl;
 
        hdev->owner = THIS_MODULE;
-       
+
        if (hci_register_dev(hdev) < 0) {
-               printk(KERN_WARNING "dtl1_cs: Can't register HCI device %s.\n", hdev->name);
+               printk(KERN_WARNING "dtl1_cs: Can't register HCI device.\n");
+               hci_free_dev(hdev);
                return -ENODEV;
        }
 
@@ -536,7 +542,7 @@ int dtl1_close(dtl1_info_t *info)
 {
        unsigned long flags;
        unsigned int iobase = info->link.io.BasePort1;
-       struct hci_dev *hdev = &(info->hdev);
+       struct hci_dev *hdev = info->hdev;
 
        dtl1_hci_close(hdev);
 
@@ -553,6 +559,8 @@ int dtl1_close(dtl1_info_t *info)
        if (hci_unregister_dev(hdev) < 0)
                printk(KERN_WARNING "dtl1_cs: Can't unregister HCI device %s.\n", hdev->name);
 
+       hci_free_dev(hdev);
+
        return 0;
 }
 
@@ -741,7 +749,7 @@ void dtl1_config(dev_link_t *link)
        if (dtl1_open(info) != 0)
                goto failed;
 
-       strcpy(info->node.dev_name, info->hdev.name);
+       strcpy(info->node.dev_name, info->hdev->name);
        link->dev = &info->node;
        link->state &= ~DEV_CONFIG_PENDING;
 
index d5582fd30527f1d5b6bf2fd5e4e40827bafb84e9..f5d2742a9f88deddffc8a2fed75b4119a4d504ae 100644 (file)
@@ -617,7 +617,7 @@ static int bcsp_recv(struct hci_uart *hu, void *data, int count)
                                        bcsp->rx_count = 0;
                                        return 0;
                                }
-                               bcsp->rx_skb->dev = (void *) &hu->hdev;
+                               bcsp->rx_skb->dev = (void *) hu->hdev;
                                break;
                        }
                        break;
index 25c9725717b749fa2acd36dacb5abfbcec15451a..ade94a57bb11292e15ad3e45f1c7ac3badedb9fc 100644 (file)
@@ -229,7 +229,7 @@ static int h4_recv(struct hci_uart *hu, void *data, int count)
 
                default:
                        BT_ERR("Unknown HCI packet type %2.2x", (__u8)*ptr);
-                       hu->hdev.stat.err_rx++;
+                       hu->hdev->stat.err_rx++;
                        ptr++; count--;
                        continue;
                };
@@ -243,7 +243,7 @@ static int h4_recv(struct hci_uart *hu, void *data, int count)
                        h4->rx_count = 0;
                        return 0;
                }
-               h4->rx_skb->dev = (void *) &hu->hdev;
+               h4->rx_skb->dev = (void *) hu->hdev;
                h4->rx_skb->pkt_type = type;
        }
        return count;
index 9cb38f1c6db51d6cbd85620fc70ecec73f19d0d4..caf25e9a55015830a5d297a18dd0899205f97c7c 100644 (file)
@@ -96,7 +96,7 @@ static struct hci_uart_proto *hci_uart_get_proto(unsigned int id)
 
 static inline void hci_uart_tx_complete(struct hci_uart *hu, int pkt_type)
 {
-       struct hci_dev *hdev = &hu->hdev;
+       struct hci_dev *hdev = hu->hdev;
        
        /* Update HCI stat counters */
        switch (pkt_type) {
@@ -127,7 +127,7 @@ 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 hci_dev *hdev = hu->hdev;
        struct sk_buff *skb;
        
        if (test_and_set_bit(HCI_UART_SENDING, &hu->tx_state)) {
@@ -306,12 +306,13 @@ static void hci_uart_tty_close(struct tty_struct *tty)
        tty->disc_data = NULL;
 
        if (hu) {
-               struct hci_dev *hdev = &hu->hdev;
+               struct hci_dev *hdev = hu->hdev;
                hci_uart_close(hdev);
 
                if (test_and_clear_bit(HCI_UART_PROTO_SET, &hu->flags)) {
                        hu->proto->close(hu);
                        hci_unregister_dev(hdev);
+                       hci_free_dev(hdev);
                }
        }
 }
@@ -380,7 +381,7 @@ static void hci_uart_tty_receive(struct tty_struct *tty, const __u8 *data, char
        
        spin_lock(&hu->rx_lock);
        hu->proto->recv(hu, (void *) data, count);
-       hu->hdev.stat.byte_rx += count;
+       hu->hdev->stat.byte_rx += count;
        spin_unlock(&hu->rx_lock);
 
        if (test_and_clear_bit(TTY_THROTTLED,&tty->flags) && tty->driver->unthrottle)
@@ -394,7 +395,13 @@ static int hci_uart_register_dev(struct hci_uart *hu)
        BT_DBG("");
 
        /* Initialize and register HCI device */
-       hdev = &hu->hdev;
+       hdev = hci_alloc_dev();
+       if (!hdev) {
+               BT_ERR("Can't allocate HCI device");
+               return -ENOMEM;
+       }
+
+       hu->hdev = hdev;
 
        hdev->type = HCI_UART;
        hdev->driver_data = hu;
@@ -408,7 +415,8 @@ static int hci_uart_register_dev(struct hci_uart *hu)
        hdev->owner = THIS_MODULE;
        
        if (hci_register_dev(hdev) < 0) {
-               BT_ERR("Can't register HCI device %s", hdev->name);
+               BT_ERR("Can't register HCI device");
+               hci_free_dev(hdev);
                return -ENODEV;
        }
 
index 4b6cac7a4a60791c5e5f79c7d167c1b9e3e9d04a..f0271bb4c2150e347040c1a2d0326c32c3f49bc5 100644 (file)
@@ -56,7 +56,7 @@ struct hci_uart_proto {
 
 struct hci_uart {
        struct tty_struct  *tty;
-       struct hci_dev     hdev;
+       struct hci_dev     *hdev;
        unsigned long      flags;
 
        struct hci_uart_proto *proto;
index c1f5178692fb1e34c90acdd3799ac747f6e22e81..8787ca4ee653e4df9eec821b5ff426f747871f41 100644 (file)
@@ -165,7 +165,7 @@ static int hci_usb_intr_rx_submit(struct hci_usb *husb)
        int err, pipe, interval, size;
        void *buf;
 
-       BT_DBG("%s", husb->hdev.name);
+       BT_DBG("%s", husb->hdev->name);
 
         size = husb->intr_in_ep->desc.wMaxPacketSize;
 
@@ -189,7 +189,7 @@ static int hci_usb_intr_rx_submit(struct hci_usb *husb)
        err = usb_submit_urb(urb, GFP_ATOMIC);
        if (err) {
                BT_ERR("%s intr rx submit failed urb %p err %d",
-                               husb->hdev.name, urb, err);
+                               husb->hdev->name, urb, err);
                _urb_unlink(_urb);
                _urb_free(_urb);
                kfree(buf);
@@ -221,12 +221,12 @@ static int hci_usb_bulk_rx_submit(struct hci_usb *husb)
         usb_fill_bulk_urb(urb, husb->udev, pipe, buf, size, hci_usb_rx_complete, husb);
         urb->transfer_flags = 0;
 
-       BT_DBG("%s urb %p", husb->hdev.name, urb);
+       BT_DBG("%s urb %p", husb->hdev->name, urb);
 
        err = usb_submit_urb(urb, GFP_ATOMIC);
        if (err) {
                BT_ERR("%s bulk rx submit failed urb %p err %d",
-                               husb->hdev.name, urb, err);
+                               husb->hdev->name, urb, err);
                _urb_unlink(_urb);
                _urb_free(_urb);
                kfree(buf);
@@ -270,12 +270,12 @@ static int hci_usb_isoc_rx_submit(struct hci_usb *husb)
 
        __fill_isoc_desc(urb, size, mtu);
 
-       BT_DBG("%s urb %p", husb->hdev.name, urb);
+       BT_DBG("%s urb %p", husb->hdev->name, urb);
 
        err = usb_submit_urb(urb, GFP_ATOMIC);
        if (err) {
                BT_ERR("%s isoc rx submit failed urb %p err %d",
-                               husb->hdev.name, urb, err);
+                               husb->hdev->name, urb, err);
                _urb_unlink(_urb);
                _urb_free(_urb);
                kfree(buf);
@@ -333,7 +333,7 @@ static void hci_usb_unlink_urbs(struct hci_usb *husb)
 {
        int i;
 
-       BT_DBG("%s", husb->hdev.name);
+       BT_DBG("%s", husb->hdev->name);
 
        for (i=0; i < 4; i++) {
                struct _urb *_urb;
@@ -343,7 +343,7 @@ static void hci_usb_unlink_urbs(struct hci_usb *husb)
                while ((_urb = _urb_dequeue(&husb->pending_q[i]))) {
                        urb = &_urb->urb;
                        BT_DBG("%s unlinking _urb %p type %d urb %p", 
-                                       husb->hdev.name, _urb, _urb->type, urb);
+                                       husb->hdev->name, _urb, _urb->type, urb);
                        usb_unlink_urb(urb);
                        _urb_queue_tail(__completed_q(husb, _urb->type), _urb);
                }
@@ -352,7 +352,7 @@ static void hci_usb_unlink_urbs(struct hci_usb *husb)
                while ((_urb = _urb_dequeue(&husb->completed_q[i]))) {
                        urb = &_urb->urb;
                        BT_DBG("%s freeing _urb %p type %d urb %p",
-                                       husb->hdev.name, _urb, _urb->type, urb);
+                                       husb->hdev->name, _urb, _urb->type, urb);
                        if (urb->setup_packet)
                                kfree(urb->setup_packet);
                        if (urb->transfer_buffer)
@@ -393,13 +393,13 @@ static int __tx_submit(struct hci_usb *husb, struct _urb *_urb)
        struct urb *urb = &_urb->urb;
        int err;
 
-       BT_DBG("%s urb %p type %d", husb->hdev.name, urb, _urb->type);
+       BT_DBG("%s urb %p type %d", husb->hdev->name, urb, _urb->type);
        
        _urb_queue_tail(__pending_q(husb, _urb->type), _urb);
        err = usb_submit_urb(urb, GFP_ATOMIC);
        if (err) {
                BT_ERR("%s tx submit failed urb %p type %d err %d",
-                               husb->hdev.name, urb, _urb->type, err);
+                               husb->hdev->name, urb, _urb->type, err);
                _urb_unlink(_urb);
                _urb_queue_tail(__completed_q(husb, _urb->type), _urb);
        } else
@@ -438,7 +438,7 @@ static inline int hci_usb_send_ctrl(struct hci_usb *husb, struct sk_buff *skb)
        usb_fill_control_urb(urb, husb->udev, usb_sndctrlpipe(husb->udev, 0),
                (void *) dr, skb->data, skb->len, hci_usb_tx_complete, husb);
 
-       BT_DBG("%s skb %p len %d", husb->hdev.name, skb, skb->len);
+       BT_DBG("%s skb %p len %d", husb->hdev->name, skb, skb->len);
        
        _urb->priv = skb;
        return __tx_submit(husb, _urb);
@@ -463,7 +463,7 @@ static inline int hci_usb_send_bulk(struct hci_usb *husb, struct sk_buff *skb)
                        hci_usb_tx_complete, husb);
        urb->transfer_flags = URB_ZERO_PACKET;
 
-       BT_DBG("%s skb %p len %d", husb->hdev.name, skb, skb->len);
+       BT_DBG("%s skb %p len %d", husb->hdev->name, skb, skb->len);
 
        _urb->priv = skb;
        return __tx_submit(husb, _urb);
@@ -482,7 +482,7 @@ static inline int hci_usb_send_isoc(struct hci_usb *husb, struct sk_buff *skb)
                _urb->type = skb->pkt_type;
        }
 
-       BT_DBG("%s skb %p len %d", husb->hdev.name, skb, skb->len);
+       BT_DBG("%s skb %p len %d", husb->hdev->name, skb, skb->len);
 
        urb = &_urb->urb;
        
@@ -507,7 +507,7 @@ static void hci_usb_tx_process(struct hci_usb *husb)
        struct sk_buff_head *q;
        struct sk_buff *skb;
 
-       BT_DBG("%s", husb->hdev.name);
+       BT_DBG("%s", husb->hdev->name);
 
        do {
                clear_bit(HCI_USB_TX_WAKEUP, &husb->state);
@@ -601,9 +601,9 @@ static int hci_usb_send_frame(struct sk_buff *skb)
 
 static inline int __recv_frame(struct hci_usb *husb, int type, void *data, int count)
 {
-       BT_DBG("%s type %d data %p count %d", husb->hdev.name, type, data, count);
+       BT_DBG("%s type %d data %p count %d", husb->hdev->name, type, data, count);
 
-       husb->hdev.stat.byte_rx += count;
+       husb->hdev->stat.byte_rx += count;
 
        while (count) {
                struct sk_buff *skb = __reassembly(husb, type);
@@ -643,10 +643,10 @@ static inline int __recv_frame(struct hci_usb *husb, int type, void *data, int c
                                
                        skb = bt_skb_alloc(len, GFP_ATOMIC);
                        if (!skb) {
-                               BT_ERR("%s no memory for the packet", husb->hdev.name);
+                               BT_ERR("%s no memory for the packet", husb->hdev->name);
                                return -ENOMEM;
                        }
-                       skb->dev = (void *) &husb->hdev;
+                       skb->dev = (void *) husb->hdev;
                        skb->pkt_type = type;
        
                        __reassembly(husb, type) = skb;
@@ -679,7 +679,7 @@ static void hci_usb_rx_complete(struct urb *urb, struct pt_regs *regs)
 {
        struct _urb *_urb = container_of(urb, struct _urb, urb);
        struct hci_usb *husb = (void *) urb->context;
-       struct hci_dev *hdev = &husb->hdev;
+       struct hci_dev *hdev = husb->hdev;
        int    err, count = urb->actual_length;
 
        BT_DBG("%s urb %p type %d status %d count %d flags %x", hdev->name, urb,
@@ -714,7 +714,7 @@ static void hci_usb_rx_complete(struct urb *urb, struct pt_regs *regs)
                err = __recv_frame(husb, _urb->type, urb->transfer_buffer, count);
                if (err < 0) { 
                        BT_ERR("%s corrupted packet: type %d count %d",
-                                       husb->hdev.name, _urb->type, count);
+                                       husb->hdev->name, _urb->type, count);
                        hdev->stat.err_rx++;
                }
        }
@@ -732,7 +732,7 @@ static void hci_usb_tx_complete(struct urb *urb, struct pt_regs *regs)
 {
        struct _urb *_urb = container_of(urb, struct _urb, urb);
        struct hci_usb *husb = (void *) urb->context;
-       struct hci_dev *hdev = &husb->hdev;
+       struct hci_dev *hdev = husb->hdev;
 
        BT_DBG("%s urb %p status %d flags %x", hdev->name, urb,
                        urb->status, urb->transfer_flags);
@@ -904,9 +904,15 @@ int hci_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
        }
 
        /* Initialize and register HCI device */
-       hdev = &husb->hdev;
+       hdev = hci_alloc_dev();
+       if (!hdev) {
+               BT_ERR("Can't allocate HCI device");
+               goto probe_error;
+       }
 
-       hdev->type  = HCI_USB;
+       husb->hdev = hdev;
+
+       hdev->type = HCI_USB;
        hdev->driver_data = husb;
        SET_HCIDEV_DEV(hdev, &intf->dev);
 
@@ -920,6 +926,7 @@ int hci_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
 
        if (hci_register_dev(hdev) < 0) {
                BT_ERR("Can't register HCI device");
+               hci_free_dev(hdev);
                goto probe_error;
        }
 
@@ -936,7 +943,7 @@ done:
 static void hci_usb_disconnect(struct usb_interface *intf)
 {
        struct hci_usb *husb = usb_get_intfdata(intf);
-       struct hci_dev *hdev = &husb->hdev;
+       struct hci_dev *hdev = husb->hdev;
 
        if (!husb)
                return;
@@ -951,6 +958,8 @@ static void hci_usb_disconnect(struct usb_interface *intf)
 
        if (hci_unregister_dev(hdev) < 0)
                BT_ERR("Can't unregister HCI device %s", hdev->name);
+
+       hci_free_dev(hdev);
 }
 
 static struct usb_driver hci_usb_driver = {
index e2ba50da30210dc1d178685cd933e62cfd3a46d9..09381b215bf17094e2574c6474c970e41dae40d0 100644 (file)
@@ -112,7 +112,7 @@ struct _urb *_urb_dequeue(struct _urb_queue *q);
 #endif
 
 struct hci_usb {
-       struct hci_dev          hdev;
+       struct hci_dev          *hdev;
 
        unsigned long           state;
        
index 60b4d6e6c3f9306e34f622617c28a0d8ee7fbe79..871f3832961014330f8fb226bdb74445a3fa69a7 100644 (file)
@@ -142,7 +142,7 @@ static inline ssize_t hci_vhci_get_user(struct hci_vhci_struct *hci_vhci, const
                return -EFAULT;
        }
 
-       skb->dev = (void *) &hci_vhci->hdev;
+       skb->dev = (void *) hci_vhci->hdev;
        skb->pkt_type = *((__u8 *) skb->data);
        skb_pull(skb, 1);
 
@@ -175,18 +175,18 @@ static inline ssize_t hci_vhci_put_user(struct hci_vhci_struct *hci_vhci,
                return -EFAULT;
        total += len;
 
-       hci_vhci->hdev.stat.byte_tx += len;
+       hci_vhci->hdev->stat.byte_tx += len;
        switch (skb->pkt_type) {
                case HCI_COMMAND_PKT:
-                       hci_vhci->hdev.stat.cmd_tx++;
+                       hci_vhci->hdev->stat.cmd_tx++;
                        break;
 
                case HCI_ACLDATA_PKT:
-                       hci_vhci->hdev.stat.acl_tx++;
+                       hci_vhci->hdev->stat.acl_tx++;
                        break;
 
                case HCI_SCODATA_PKT:
-                       hci_vhci->hdev.stat.cmd_tx++;
+                       hci_vhci->hdev->stat.cmd_tx++;
                        break;
        };
 
@@ -275,7 +275,13 @@ static int hci_vhci_chr_open(struct inode *inode, struct file * file)
        init_waitqueue_head(&hci_vhci->read_wait);
 
        /* Initialize and register HCI device */
-       hdev = &hci_vhci->hdev;
+       hdev = hci_alloc_dev();
+       if (!hdev) {
+               kfree(hci_vhci);
+               return -ENOMEM;
+       }
+
+       hci_vhci->hdev = hdev;
 
        hdev->type = HCI_VHCI;
        hdev->driver_data = hci_vhci;
@@ -290,6 +296,7 @@ static int hci_vhci_chr_open(struct inode *inode, struct file * file)
        
        if (hci_register_dev(hdev) < 0) {
                kfree(hci_vhci);
+               hci_free_dev(hdev);
                return -EBUSY;
        }
 
@@ -301,10 +308,12 @@ static int hci_vhci_chr_close(struct inode *inode, struct file *file)
 {
        struct hci_vhci_struct *hci_vhci = (struct hci_vhci_struct *) file->private_data;
 
-       if (hci_unregister_dev(&hci_vhci->hdev) < 0) {
-               BT_ERR("Can't unregister HCI device %s", hci_vhci->hdev.name);
+       if (hci_unregister_dev(hci_vhci->hdev) < 0) {
+               BT_ERR("Can't unregister HCI device %s", hci_vhci->hdev->name);
        }
 
+       hci_free_dev(hci_vhci->hdev);
+
        file->private_data = NULL;
        return 0;
 }
index f680471aef4d4551a912acd98af2c5b6b6815211..53b11f9ef76dddfc59e73cc917e97ced422404a2 100644 (file)
@@ -32,7 +32,7 @@
 #ifdef __KERNEL__
 
 struct hci_vhci_struct {
-       struct hci_dev       hdev;
+       struct hci_dev       *hdev;
        __u32                flags;
        wait_queue_head_t    read_wait;
        struct sk_buff_head  readq;
index 3abfa75738646fbedd526201e9f0b86740a6df19..4ce3430b34edbc278c74476b52ed0e7fe6e68689 100644 (file)
@@ -348,6 +348,9 @@ static inline struct hci_dev *hci_dev_hold(struct hci_dev *d)
 
 struct hci_dev *hci_dev_get(int index);
 struct hci_dev *hci_get_route(bdaddr_t *src, bdaddr_t *dst);
+
+struct hci_dev *hci_alloc_dev(void);
+void hci_free_dev(struct hci_dev *hdev);
 int hci_register_dev(struct hci_dev *hdev);
 int hci_unregister_dev(struct hci_dev *hdev);
 int hci_suspend_dev(struct hci_dev *hdev);
index 7be1b6724d3aad5eb6098cdc5c0b2deaaf2dfb50..77e7e9b7fcc97a36e4b598f41055f18ee7ed5334 100644 (file)
@@ -762,6 +762,27 @@ int hci_get_dev_info(unsigned long arg)
 
 /* ---- Interface to HCI drivers ---- */
 
+/* Alloc HCI device */
+struct hci_dev *hci_alloc_dev(void)
+{
+       struct hci_dev *hdev;
+
+       hdev = kmalloc(sizeof(struct hci_dev), GFP_KERNEL);
+       if (!hdev)
+               return NULL;
+
+       memset(hdev, 0, sizeof(struct hci_dev));
+
+       return hdev;
+}
+
+/* Free HCI device */
+void hci_free_dev(struct hci_dev *hdev)
+{
+       /* will free via class release */
+       class_device_put(&hdev->class_dev);
+}
+
 /* Register HCI device */
 int hci_register_dev(struct hci_dev *hdev)
 {
index 3ef724ef484668dda0c6acb59bcbcd685c0c997c..37d8798cffc520ab6fefdb952a176216d46d490f 100644 (file)
@@ -96,6 +96,9 @@ static int bt_hotplug(struct class_device *cdev, char **envp, int num_envp, char
 
 static void bt_release(struct class_device *cdev)
 {
+       struct hci_dev *hdev = class_get_devdata(cdev);
+
+       kfree(hdev);
 }
 
 static struct class bt_class = {
index 587e7bdee32e98aa357c661ced3f33dfa8bfbc44..20d81017f122d50b349478863af652e414eff789 100644 (file)
@@ -42,6 +42,8 @@
 #include <net/bluetooth/hci_core.h>
 
 /* HCI Core */
+EXPORT_SYMBOL(hci_alloc_dev);
+EXPORT_SYMBOL(hci_free_dev);
 EXPORT_SYMBOL(hci_register_dev);
 EXPORT_SYMBOL(hci_unregister_dev);
 EXPORT_SYMBOL(hci_suspend_dev);