~ubuntu-branches/ubuntu/natty/linux-backports-modules-2.6.38/natty-updates

« back to all changes in this revision

Viewing changes to updates/compat-wireless-2.6.36/drivers/bluetooth/ath3k.c

  • Committer: Bazaar Package Importer
  • Author(s): Tim Gardner, Tim Gardner
  • Date: 2011-06-08 10:44:09 UTC
  • Revision ID: james.westby@ubuntu.com-20110608104409-fnl8carkdo15bwsz
Tags: 2.6.38-10.6
[ Tim Gardner ]

Shorten compat-wireless package name to cw to accomodate
CDROM file name length restrictions.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * Copyright (c) 2008-2009 Atheros Communications Inc.
3
 
 *
4
 
 *  This program is free software; you can redistribute it and/or modify
5
 
 *  it under the terms of the GNU General Public License as published by
6
 
 *  the Free Software Foundation; either version 2 of the License, or
7
 
 *  (at your option) any later version.
8
 
 *
9
 
 *  This program is distributed in the hope that it will be useful,
10
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
 
 *  GNU General Public License for more details.
13
 
 *
14
 
 *  You should have received a copy of the GNU General Public License
15
 
 *  along with this program; if not, write to the Free Software
16
 
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17
 
 *
18
 
 */
19
 
 
20
 
 
21
 
#include <linux/module.h>
22
 
#include <linux/kernel.h>
23
 
#include <linux/init.h>
24
 
#include <linux/slab.h>
25
 
#include <linux/types.h>
26
 
#include <linux/errno.h>
27
 
#include <linux/device.h>
28
 
#include <linux/firmware.h>
29
 
#include <linux/usb.h>
30
 
#include <net/bluetooth/bluetooth.h>
31
 
 
32
 
#define VERSION "1.0"
33
 
 
34
 
 
35
 
static struct usb_device_id ath3k_table[] = {
36
 
        /* Atheros AR3011 */
37
 
        { USB_DEVICE(0x0CF3, 0x3000) },
38
 
        { }     /* Terminating entry */
39
 
};
40
 
 
41
 
MODULE_DEVICE_TABLE(usb, ath3k_table);
42
 
 
43
 
#define USB_REQ_DFU_DNLOAD      1
44
 
#define BULK_SIZE               4096
45
 
 
46
 
struct ath3k_data {
47
 
        struct usb_device *udev;
48
 
        u8 *fw_data;
49
 
        u32 fw_size;
50
 
        u32 fw_sent;
51
 
};
52
 
 
53
 
static int ath3k_load_firmware(struct ath3k_data *data,
54
 
                                unsigned char *firmware,
55
 
                                int count)
56
 
{
57
 
        u8 *send_buf;
58
 
        int err, pipe, len, size, sent = 0;
59
 
 
60
 
        BT_DBG("ath3k %p udev %p", data, data->udev);
61
 
 
62
 
        pipe = usb_sndctrlpipe(data->udev, 0);
63
 
 
64
 
        if ((usb_control_msg(data->udev, pipe,
65
 
                                USB_REQ_DFU_DNLOAD,
66
 
                                USB_TYPE_VENDOR, 0, 0,
67
 
                                firmware, 20, USB_CTRL_SET_TIMEOUT)) < 0) {
68
 
                BT_ERR("Can't change to loading configuration err");
69
 
                return -EBUSY;
70
 
        }
71
 
        sent += 20;
72
 
        count -= 20;
73
 
 
74
 
        send_buf = kmalloc(BULK_SIZE, GFP_ATOMIC);
75
 
        if (!send_buf) {
76
 
                BT_ERR("Can't allocate memory chunk for firmware");
77
 
                return -ENOMEM;
78
 
        }
79
 
 
80
 
        while (count) {
81
 
                size = min_t(uint, count, BULK_SIZE);
82
 
                pipe = usb_sndbulkpipe(data->udev, 0x02);
83
 
                memcpy(send_buf, firmware + sent, size);
84
 
 
85
 
                err = usb_bulk_msg(data->udev, pipe, send_buf, size,
86
 
                                        &len, 3000);
87
 
 
88
 
                if (err || (len != size)) {
89
 
                        BT_ERR("Error in firmware loading err = %d,"
90
 
                                "len = %d, size = %d", err, len, size);
91
 
                        goto error;
92
 
                }
93
 
 
94
 
                sent  += size;
95
 
                count -= size;
96
 
        }
97
 
 
98
 
        kfree(send_buf);
99
 
        return 0;
100
 
 
101
 
error:
102
 
        kfree(send_buf);
103
 
        return err;
104
 
}
105
 
 
106
 
static int ath3k_probe(struct usb_interface *intf,
107
 
                        const struct usb_device_id *id)
108
 
{
109
 
        const struct firmware *firmware;
110
 
        struct usb_device *udev = interface_to_usbdev(intf);
111
 
        struct ath3k_data *data;
112
 
        int size;
113
 
 
114
 
        BT_DBG("intf %p id %p", intf, id);
115
 
 
116
 
        if (intf->cur_altsetting->desc.bInterfaceNumber != 0)
117
 
                return -ENODEV;
118
 
 
119
 
        data = kzalloc(sizeof(*data), GFP_KERNEL);
120
 
        if (!data)
121
 
                return -ENOMEM;
122
 
 
123
 
        data->udev = udev;
124
 
 
125
 
        if (request_firmware(&firmware, "ath3k-1.fw", &udev->dev) < 0) {
126
 
                kfree(data);
127
 
                return -EIO;
128
 
        }
129
 
 
130
 
        size = max_t(uint, firmware->size, 4096);
131
 
        data->fw_data = kmalloc(size, GFP_KERNEL);
132
 
        if (!data->fw_data) {
133
 
                release_firmware(firmware);
134
 
                kfree(data);
135
 
                return -ENOMEM;
136
 
        }
137
 
 
138
 
        memcpy(data->fw_data, firmware->data, firmware->size);
139
 
        data->fw_size = firmware->size;
140
 
        data->fw_sent = 0;
141
 
        release_firmware(firmware);
142
 
 
143
 
        usb_set_intfdata(intf, data);
144
 
        if (ath3k_load_firmware(data, data->fw_data, data->fw_size)) {
145
 
                usb_set_intfdata(intf, NULL);
146
 
                kfree(data->fw_data);
147
 
                kfree(data);
148
 
                return -EIO;
149
 
        }
150
 
 
151
 
        return 0;
152
 
}
153
 
 
154
 
static void ath3k_disconnect(struct usb_interface *intf)
155
 
{
156
 
        struct ath3k_data *data = usb_get_intfdata(intf);
157
 
 
158
 
        BT_DBG("ath3k_disconnect intf %p", intf);
159
 
 
160
 
        kfree(data->fw_data);
161
 
        kfree(data);
162
 
}
163
 
 
164
 
static struct usb_driver ath3k_driver = {
165
 
        .name           = "ath3k",
166
 
        .probe          = ath3k_probe,
167
 
        .disconnect     = ath3k_disconnect,
168
 
        .id_table       = ath3k_table,
169
 
};
170
 
 
171
 
static int __init ath3k_init(void)
172
 
{
173
 
        BT_INFO("Atheros AR30xx firmware driver ver %s", VERSION);
174
 
        return usb_register(&ath3k_driver);
175
 
}
176
 
 
177
 
static void __exit ath3k_exit(void)
178
 
{
179
 
        usb_deregister(&ath3k_driver);
180
 
}
181
 
 
182
 
module_init(ath3k_init);
183
 
module_exit(ath3k_exit);
184
 
 
185
 
MODULE_AUTHOR("Atheros Communications");
186
 
MODULE_DESCRIPTION("Atheros AR30xx firmware driver");
187
 
MODULE_VERSION(VERSION);
188
 
MODULE_LICENSE("GPL");
189
 
MODULE_FIRMWARE("ath3k-1.fw");