#define VERSION "1.1"
+static int ignore = 0;
+
static struct usb_driver bfusb_driver;
static struct usb_device_id bfusb_table[] = {
#define BFUSB_MAX_BLOCK_SIZE 256
-#define BFUSB_BLOCK_TIMEOUT (HZ * 3)
+#define BFUSB_BLOCK_TIMEOUT 3000
#define BFUSB_TX_PROCESS 1
#define BFUSB_TX_WAKEUP 2
static void bfusb_tx_complete(struct urb *urb, struct pt_regs *regs);
static void bfusb_rx_complete(struct urb *urb, struct pt_regs *regs);
-static inline void bfusb_wait_for_urb(struct urb *urb)
-{
- while (atomic_read(&urb->count) > 1) {
- current->state = TASK_UNINTERRUPTIBLE;
- schedule_timeout((5 * HZ + 999) / 1000);
- }
-}
-
static struct urb *bfusb_get_completed(struct bfusb *bfusb)
{
struct sk_buff *skb;
while ((skb = skb_dequeue(&bfusb->pending_q))) {
urb = ((struct bfusb_scb *) skb->cb)->urb;
- usb_unlink_urb(urb);
- bfusb_wait_for_urb(urb);
+ usb_kill_urb(urb);
skb_queue_tail(&bfusb->completed_q, skb);
}
if (err) {
BT_ERR("%s bulk tx submit failed urb %p err %d",
bfusb->hdev->name, urb, err);
- skb_unlink(skb);
+ skb_unlink(skb, &bfusb->pending_q);
usb_free_urb(urb);
} else
atomic_inc(&bfusb->pending_tx);
read_lock(&bfusb->lock);
- skb_unlink(skb);
+ skb_unlink(skb, &bfusb->pending_q);
skb_queue_tail(&bfusb->completed_q, skb);
bfusb_tx_wakeup(bfusb);
if (err) {
BT_ERR("%s bulk rx submit failed urb %p err %d",
bfusb->hdev->name, urb, err);
- skb_unlink(skb);
+ skb_unlink(skb, &bfusb->pending_q);
kfree_skb(skb);
usb_free_urb(urb);
}
}
skb->dev = (void *) bfusb->hdev;
- skb->pkt_type = pkt_type;
+ bt_cb(skb)->pkt_type = pkt_type;
bfusb->reassembly = skb;
} else {
buf += len;
}
- skb_unlink(skb);
+ skb_unlink(skb, &bfusb->pending_q);
kfree_skb(skb);
bfusb_rx_submit(bfusb, urb);
unsigned char buf[3];
int sent = 0, size, count;
- BT_DBG("hdev %p skb %p type %d len %d", hdev, skb, skb->pkt_type, skb->len);
+ BT_DBG("hdev %p skb %p type %d len %d", hdev, skb, bt_cb(skb)->pkt_type, skb->len);
if (!hdev) {
BT_ERR("Frame for unknown HCI device (hdev=NULL)");
bfusb = (struct bfusb *) hdev->driver_data;
- switch (skb->pkt_type) {
+ switch (bt_cb(skb)->pkt_type) {
case HCI_COMMAND_PKT:
hdev->stat.cmd_tx++;
break;
};
/* Prepend skb with frame type */
- memcpy(skb_push(skb, 1), &(skb->pkt_type), 1);
+ memcpy(skb_push(skb, 1), &bt_cb(skb)->pkt_type, 1);
count = skb->len;
pipe = usb_sndctrlpipe(bfusb->udev, 0);
if (usb_control_msg(bfusb->udev, pipe, USB_REQ_SET_CONFIGURATION,
- 0, 1, 0, NULL, 0, HZ * USB_CTRL_SET_TIMEOUT) < 0) {
+ 0, 1, 0, NULL, 0, USB_CTRL_SET_TIMEOUT) < 0) {
BT_ERR("Can't change to loading configuration");
return -EBUSY;
}
+ bfusb->udev->toggle[0] = bfusb->udev->toggle[1] = 0;
+
buf = kmalloc(BFUSB_MAX_BLOCK_SIZE + 3, GFP_ATOMIC);
if (!buf) {
BT_ERR("Can't allocate memory chunk for firmware");
pipe = usb_sndctrlpipe(bfusb->udev, 0);
if ((err = usb_control_msg(bfusb->udev, pipe, USB_REQ_SET_CONFIGURATION,
- 0, 2, 0, NULL, 0, HZ * USB_CTRL_SET_TIMEOUT)) < 0) {
+ 0, 2, 0, NULL, 0, USB_CTRL_SET_TIMEOUT)) < 0) {
BT_ERR("Can't change to running configuration");
goto error;
}
+ bfusb->udev->toggle[0] = bfusb->udev->toggle[1] = 0;
+
BT_INFO("BlueFRITZ! USB device ready");
kfree(buf);
pipe = usb_sndctrlpipe(bfusb->udev, 0);
usb_control_msg(bfusb->udev, pipe, USB_REQ_SET_CONFIGURATION,
- 0, 0, 0, NULL, 0, HZ * USB_CTRL_SET_TIMEOUT);
+ 0, 0, 0, NULL, 0, USB_CTRL_SET_TIMEOUT);
return err;
}
BT_DBG("intf %p id %p", intf, id);
+ if (ignore)
+ return -ENODEV;
+
/* Check number of endpoints */
- if (intf->altsetting[0].desc.bNumEndpoints < 2)
+ if (intf->cur_altsetting->desc.bNumEndpoints < 2)
return -EIO;
- bulk_out_ep = &intf->altsetting[0].endpoint[0];
- bulk_in_ep = &intf->altsetting[0].endpoint[1];
+ bulk_out_ep = &intf->cur_altsetting->endpoint[0];
+ bulk_in_ep = &intf->cur_altsetting->endpoint[1];
if (!bulk_out_ep || !bulk_in_ep) {
BT_ERR("Bulk endpoints not found");
}
/* Initialize control structure and load firmware */
- if (!(bfusb = kmalloc(sizeof(struct bfusb), GFP_KERNEL))) {
+ if (!(bfusb = kzalloc(sizeof(struct bfusb), GFP_KERNEL))) {
BT_ERR("Can't allocate memory for control structure");
goto done;
}
- memset(bfusb, 0, sizeof(struct bfusb));
-
bfusb->udev = udev;
bfusb->bulk_in_ep = bulk_in_ep->desc.bEndpointAddress;
bfusb->bulk_out_ep = bulk_out_ep->desc.bEndpointAddress;
- bfusb->bulk_pkt_size = bulk_out_ep->desc.wMaxPacketSize;
+ bfusb->bulk_pkt_size = le16_to_cpu(bulk_out_ep->desc.wMaxPacketSize);
- bfusb->lock = RW_LOCK_UNLOCKED;
+ rwlock_init(&bfusb->lock);
bfusb->reassembly = NULL;
}
static struct usb_driver bfusb_driver = {
- .owner = THIS_MODULE,
.name = "bfusb",
.probe = bfusb_probe,
.disconnect = bfusb_disconnect,
module_init(bfusb_init);
module_exit(bfusb_exit);
+module_param(ignore, bool, 0644);
+MODULE_PARM_DESC(ignore, "Ignore devices from the matching table");
+
MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
MODULE_DESCRIPTION("BlueFRITZ! USB driver ver " VERSION);
MODULE_VERSION(VERSION);