CTC++ Coverage Report - Execution Profile    #313/1532

Files Summary | Functions Summary | Execution Profile | Index | No Index
First | Previous | Next | Last


File: drivers/bluetooth/bcm203x.c
Instrumentation mode: function-decision-multicondition
TER: 0 % ( 0/ 66)

Start/ End/    
True False - Line Source

  1 /*
  2  *
  3  *  Broadcom Blutonium firmware driver
  4  *
  5  *  Copyright (C) 2003  Maxim Krasnyansky <maxk@qualcomm.com>
  6  *  Copyright (C) 2003  Marcel Holtmann <marcel@holtmann.org>
  7  *
  8  *
  9  *  This program is free software; you can redistribute it and/or modify
  10  *  it under the terms of the GNU General Public License as published by
  11  *  the Free Software Foundation; either version 2 of the License, or
  12  *  (at your option) any later version.
  13  *
  14  *  This program is distributed in the hope that it will be useful,
  15  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  16  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17  *  GNU General Public License for more details.
  18  *
  19  *  You should have received a copy of the GNU General Public License
  20  *  along with this program; if not, write to the Free Software
  21  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  22  *
  23  */
  24 
  25 #include <linux/config.h>
  26 #include <linux/module.h>
  27 
  28 #include <linux/kernel.h>
  29 #include <linux/init.h>
  30 #include <linux/slab.h>
  31 #include <linux/types.h>
  32 #include <linux/errno.h>
  33 #include <linux/timer.h>
  34 
  35 #include <linux/device.h>
  36 #include <linux/firmware.h>
  37 
  38 #include <linux/usb.h>
  39 
  40 #include <net/bluetooth/bluetooth.h>
  41 
  42 #ifndef CONFIG_BT_HCIBCM203X_DEBUG
  43 #undef  BT_DBG
  44 #define BT_DBG(D...)
  45 #endif
  46 
  47 #define VERSION "1.0"
  48 
  49 static int ignore = 0;
  50 
  51 static struct usb_device_id bcm203x_table[] = {
  52    /* Broadcom Blutonium (BCM2033) */
  53    { USB_DEVICE(0x0a5c, 0x2033) },
  54 
  55    { }   /* Terminating entry */
  56 };
  57 
  58 MODULE_DEVICE_TABLE(usb, bcm203x_table);
  59 
  60 #define BCM203X_ERROR      0
  61 #define BCM203X_RESET      1
  62 #define BCM203X_LOAD_MINIDRV   2
  63 #define BCM203X_SELECT_MEMORY   3
  64 #define BCM203X_CHECK_MEMORY   4
  65 #define BCM203X_LOAD_FIRMWARE   5
  66 #define BCM203X_CHECK_FIRMWARE   6
  67 
  68 #define BCM203X_IN_EP      0x81
  69 #define BCM203X_OUT_EP      0x02
  70 
  71 struct bcm203x_data {
  72    struct usb_device   *udev;
  73 
  74    unsigned long      state;
  75 
  76    struct timer_list   timer;
  77 
  78    struct urb      *urb;
  79    unsigned char      *buffer;
  80 
  81    unsigned char      *fw_data;
  82    unsigned int      fw_size;
  83    unsigned int      fw_sent;
  84 };
  85 
 
- 86 static void bcm203x_complete(struct urb *urb, struct pt_regs *regs)
  87 {
  88    struct bcm203x_data *data = urb->context;
  89    struct usb_device *udev = urb->dev;
  90    int len;
  91 
  92    BT_DBG("udev %p urb %p", udev, urb);
  93 
- 94    if (urb->status) {
  95       BT_ERR("URB failed with status %d", urb->status);
  96       data->state = BCM203X_ERROR;
 - 97       return;
  98    }
  99 
    100    switch (data->state) {
 - 101    case BCM203X_LOAD_MINIDRV:
  102       memcpy(data->buffer, "#", 1);
  103 
  104       usb_fill_bulk_urb(urb, udev, usb_sndbulkpipe(udev, BCM203X_OUT_EP),
  105             data->buffer, 1, bcm203x_complete, data);
  106 
  107       data->state = BCM203X_SELECT_MEMORY;
  108 
  109       mod_timer(&data->timer, jiffies + (HZ / 10));
 - 110       break;
  111 
 - 112    case BCM203X_SELECT_MEMORY:
  113       usb_fill_int_urb(urb, udev, usb_rcvintpipe(udev, BCM203X_IN_EP),
  114             data->buffer, 32, bcm203x_complete, data, 1);
  115 
  116       data->state = BCM203X_CHECK_MEMORY;
  117 
- 118       if (usb_submit_urb(data->urb, GFP_ATOMIC) < 0)
  119          BT_ERR("Can't submit URB");
 - 120       break;
  121 
 - 122    case BCM203X_CHECK_MEMORY:
- 123       if (data->buffer[0] != '#') {
  124          BT_ERR("Memory select failed");
  125          data->state = BCM203X_ERROR;
 - 126          break;
  127       }
  128 
  129       data->state = BCM203X_LOAD_FIRMWARE;
  130 
 - 131    case BCM203X_LOAD_FIRMWARE:
- 132       if (data->fw_sent == data->fw_size) {
  133          usb_fill_int_urb(urb, udev, usb_rcvintpipe(udev, BCM203X_IN_EP),
  134             data->buffer, 32, bcm203x_complete, data, 1);
  135 
  136          data->state = BCM203X_CHECK_FIRMWARE;
    137       } else {
  138          len = min_t(uint, data->fw_size - data->fw_sent, 4096);
  139 
  140          usb_fill_bulk_urb(urb, udev, usb_sndbulkpipe(udev, BCM203X_OUT_EP),
  141             data->fw_data + data->fw_sent, len, bcm203x_complete, data);
  142 
  143          data->fw_sent += len;
  144       }
  145 
- 146       if (usb_submit_urb(data->urb, GFP_ATOMIC) < 0)
  147          BT_ERR("Can't submit URB");
 - 148       break;
  149 
 - 150    case BCM203X_CHECK_FIRMWARE:
- 151       if (data->buffer[0] != '.') {
  152          BT_ERR("Firmware loading failed");
  153          data->state = BCM203X_ERROR;
 - 154          break;
  155       }
  156 
  157       data->state = BCM203X_RESET;
 - 158       break;
  159    }
  160 }
  161 
 
- 162 static void bcm203x_timer(unsigned long user_data)
  163 {
  164    struct bcm203x_data *data = (struct bcm203x_data *) user_data;
  165 
- 166    if (usb_submit_urb(data->urb, GFP_ATOMIC) < 0)
  167       BT_ERR("Can't submit URB");
  168 }
  169 
 
- 170 static int bcm203x_probe(struct usb_interface *intf, const struct usb_device_id *id)
  171 {
  172    const struct firmware *firmware;
  173    struct usb_device *udev = interface_to_usbdev(intf);
  174    struct bcm203x_data *data;
  175    int size;
  176 
  177    BT_DBG("intf %p id %p", intf, id);
  178 
- 179    if (ignore || (intf->cur_altsetting->desc.bInterfaceNumber != 0))
 - 179   T || (_)
 - 179   F || (T)
 - 179   F || (F)
 - 180       return -ENODEV;
  181 
  182    data = kzalloc(sizeof(*data), GFP_KERNEL);
- 183    if (!data) {
  184       BT_ERR("Can't allocate memory for data structure");
 - 185       return -ENOMEM;
  186    }
  187 
  188    data->udev  = udev;
  189    data->state = BCM203X_LOAD_MINIDRV;
  190 
  191    data->urb = usb_alloc_urb(0, GFP_KERNEL);
- 192    if (!data->urb) {
  193       BT_ERR("Can't allocate URB");
  194       kfree(data);
 - 195       return -ENOMEM;
  196    }
  197 
- 198    if (request_firmware(&firmware, "BCM2033-MD.hex", &udev->dev) < 0) {
  199       BT_ERR("Mini driver request failed");
  200       usb_free_urb(data->urb);
  201       kfree(data);
 - 202       return -EIO;
  203    }
  204 
  205    BT_DBG("minidrv data %p size %d", firmware->data, firmware->size);
  206 
  207    size = max_t(uint, firmware->size, 4096);
  208 
  209    data->buffer = kmalloc(size, GFP_KERNEL);
- 210    if (!data->buffer) {
  211       BT_ERR("Can't allocate memory for mini driver");
  212       release_firmware(firmware);
  213       usb_free_urb(data->urb);
  214       kfree(data);
 - 215       return -ENOMEM;
  216    }
  217 
  218    memcpy(data->buffer, firmware->data, firmware->size);
  219 
  220    usb_fill_bulk_urb(data->urb, udev, usb_sndbulkpipe(udev, BCM203X_OUT_EP),
  221          data->buffer, firmware->size, bcm203x_complete, data);
  222 
  223    release_firmware(firmware);
  224 
- 225    if (request_firmware(&firmware, "BCM2033-FW.bin", &udev->dev) < 0) {
  226       BT_ERR("Firmware request failed");
  227       usb_free_urb(data->urb);
  228       kfree(data->buffer);
  229       kfree(data);
 - 230       return -EIO;
  231    }
  232 
  233    BT_DBG("firmware data %p size %d", firmware->data, firmware->size);
  234 
  235    data->fw_data = kmalloc(firmware->size, GFP_KERNEL);
- 236    if (!data->fw_data) {
  237       BT_ERR("Can't allocate memory for firmware image");
  238       usb_free_urb(data->urb);
  239       kfree(data->buffer);
  240       kfree(data);
 - 241       return -ENOMEM;
  242    }
  243 
  244    memcpy(data->fw_data, firmware->data, firmware->size);
  245    data->fw_size = firmware->size;
  246    data->fw_sent = 0;
  247 
  248    release_firmware(firmware);
  249 
  250    init_timer(&data->timer);
  251    data->timer.function = bcm203x_timer;
  252    data->timer.data = (unsigned long) data;
  253 
  254    usb_set_intfdata(intf, data);
  255 
  256    mod_timer(&data->timer, jiffies + HZ);
  257 
 - 258    return 0;
  259 }
  260 
 
- 261 static void bcm203x_disconnect(struct usb_interface *intf)
  262 {
  263    struct bcm203x_data *data = usb_get_intfdata(intf);
  264 
  265    BT_DBG("intf %p", intf);
  266 
  267    usb_kill_urb(data->urb);
  268 
  269    usb_set_intfdata(intf, NULL);
  270 
  271    usb_free_urb(data->urb);
  272    kfree(data->fw_data);
  273    kfree(data->buffer);
  274    kfree(data);
  275 }
  276 
  277 static struct usb_driver bcm203x_driver = {
  278    .name      = "bcm203x",
  279    .probe      = bcm203x_probe,
  280    .disconnect   = bcm203x_disconnect,
  281    .id_table   = bcm203x_table,
  282 };
  283 
 
- 284 static int __init bcm203x_init(void)
  285 {
  286    int err;
  287 
  288    BT_INFO("Broadcom Blutonium firmware driver ver %s", VERSION);
  289 
  290    err = usb_register(&bcm203x_driver);
- 291    if (err < 0)
  292       BT_ERR("Failed to register USB driver");
  293 
 - 294    return err;
  295 }
  296 
 
- 297 static void __exit bcm203x_exit(void)
  298 {
  299    usb_deregister(&bcm203x_driver);
  300 }
  301 
 
- 302 module_init(bcm203x_init);
 - 302 return bcm203x_init
 
- 303 module_exit(bcm203x_exit);
 - 303 return bcm203x_exit
  304 
 
- 305 module_param(ignore, bool, 0644);
 - 305 return ( & ( ignore ) )
  306 MODULE_PARM_DESC(ignore, "Ignore devices from the matching table");
  307 
  308 MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
  309 MODULE_DESCRIPTION("Broadcom Blutonium firmware driver ver " VERSION);
  310 MODULE_VERSION(VERSION);
  311 MODULE_LICENSE("GPL");
***TER 0% (0/66) of SOURCE FILE bcm203x.c

Files Summary | Functions Summary | Execution Profile | Index | No Index
First | Previous | Next | Last | Top