Commit d30e2d06 authored by Marcel Holtmann's avatar Marcel Holtmann

[Bluetooth] Dynamic allocation of HCI device

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