staging: ft1000-usb: Add correct procedure for fw image downloading.
[deliverable/linux.git] / drivers / staging / ft1000 / ft1000-usb / ft1000_usb.c
CommitLineData
f7c1be0c
MB
1//=====================================================
2// CopyRight (C) 2007 Qualcomm Inc. All Rights Reserved.
3//
4//
5// This file is part of Express Card USB Driver
6//
7// $Id:
8//====================================================
9// 20090926; aelias; removed all compiler warnings; ubuntu 9.04; 2.6.28-15-generic
10#include <linux/init.h>
11#include <linux/kernel.h>
12#include <linux/module.h>
13#include <linux/usb.h>
14#include <linux/netdevice.h>
15#include <linux/etherdevice.h>
ada541f0 16#include <linux/firmware.h>
f7c1be0c
MB
17#include "ft1000_usb.h"
18
19//#include <linux/sched.h>
20//#include <linux/ptrace.h>
21//#include <linux/slab.h>
22//#include <linux/string.h>
23//#include <linux/timer.h>
24//#include <linux/netdevice.h>
25//#include <linux/ioport.h>
26//#include <linux/delay.h>
27//#include <asm/io.h>
28//#include <asm/system.h>
29#include <linux/kthread.h>
30
31MODULE_DESCRIPTION("FT1000 EXPRESS CARD DRIVER");
32MODULE_LICENSE("Dual MPL/GPL");
33MODULE_SUPPORTED_DEVICE("QFT FT1000 Express Cards");
34
35
36void *pFileStart;
2a953cfd 37size_t FileLength;
f7c1be0c
MB
38
39#define VENDOR_ID 0x1291 /* Qualcomm vendor id */
40#define PRODUCT_ID 0x11 /* fake product id */
41
42/* table of devices that work with this driver */
43static struct usb_device_id id_table[] = {
44 {USB_DEVICE(VENDOR_ID, PRODUCT_ID) },
45 { },
46};
47
48MODULE_DEVICE_TABLE (usb, id_table);
49
2a953cfd 50static BOOLEAN gPollingfailed = FALSE;
f7c1be0c
MB
51int ft1000_poll_thread(void *arg)
52{
53 int ret = STATUS_SUCCESS;
54
55 while(!kthread_should_stop() )
56 {
57 msleep(10);
58 if ( ! gPollingfailed )
59 {
bf3146c8 60 ret = ft1000_poll(arg);
f7c1be0c
MB
61 if ( ret != STATUS_SUCCESS )
62 {
63 DEBUG("ft1000_poll_thread: polling failed\n");
64 gPollingfailed = TRUE;
65 }
66 }
67 }
68 //DEBUG("returned from polling thread\n");
bf3146c8 69 return STATUS_SUCCESS;
f7c1be0c
MB
70}
71
72
73
74//---------------------------------------------------------------------------
75// Function: ft1000_probe
76//
77// Parameters: struct usb_interface *interface - passed by USB core
78// struct usb_device_id *id - passed by USB core
79// Returns: 0 - success
80//
81// Description: This function is invoked when the express card is plugged in
82//
83// Notes:
84//
85//---------------------------------------------------------------------------
86static int ft1000_probe(struct usb_interface *interface, const struct usb_device_id *id)
87{
88 struct usb_host_interface *iface_desc;
89 struct usb_endpoint_descriptor *endpoint;
90 struct usb_device *dev;
bf3146c8 91 unsigned numaltsetting;
ada541f0 92 int i, ret = 0, size;
f7c1be0c
MB
93
94 struct ft1000_device *ft1000dev;
95 FT1000_INFO *pft1000info;
ada541f0
MB
96 const struct firmware *dsp_fw;
97
f7c1be0c
MB
98
99 if(!(ft1000dev = kmalloc(sizeof(struct ft1000_device), GFP_KERNEL)))
100 {
101 printk("out of memory allocating device structure\n");
102 return 0;
103 }
104
105 memset(ft1000dev, 0, sizeof(*ft1000dev));
bf3146c8 106
f7c1be0c
MB
107 //get usb device
108 dev = interface_to_usbdev(interface);
109 DEBUG("ft1000_probe: usb device descriptor info:\n");
110 DEBUG("ft1000_probe: number of configuration is %d\n", dev->descriptor.bNumConfigurations);
111
112 ft1000dev->dev = dev;
113 ft1000dev->status = 0;
114 ft1000dev->net = NULL;
115 //ft1000dev->device_lock = SPIN_LOCK_UNLOCKED;
116 spin_lock_init(&ft1000dev->device_lock);
117 ft1000dev->tx_urb = usb_alloc_urb(0, GFP_ATOMIC);
118 ft1000dev->rx_urb = usb_alloc_urb(0, GFP_ATOMIC);
119
120
121 DEBUG("ft1000_probe is called\n");
122 numaltsetting = interface->num_altsetting;
bf3146c8 123 DEBUG("ft1000_probe: number of alt settings is :%d\n",numaltsetting);
f7c1be0c 124 iface_desc = interface->cur_altsetting;
bf3146c8 125 DEBUG("ft1000_probe: number of endpoints is %d\n", iface_desc->desc.bNumEndpoints);
f7c1be0c
MB
126 DEBUG("ft1000_probe: descriptor type is %d\n", iface_desc->desc.bDescriptorType);
127 DEBUG("ft1000_probe: interface number is %d\n", iface_desc->desc.bInterfaceNumber);
128 DEBUG("ft1000_probe: alternatesetting is %d\n", iface_desc->desc.bAlternateSetting);
129 DEBUG("ft1000_probe: interface class is %d\n", iface_desc->desc.bInterfaceClass);
130 DEBUG("ft1000_probe: control endpoint info:\n");
131 DEBUG("ft1000_probe: descriptor0 type -- %d\n", iface_desc->endpoint[0].desc.bmAttributes);
132 DEBUG("ft1000_probe: descriptor1 type -- %d\n", iface_desc->endpoint[1].desc.bmAttributes);
133 DEBUG("ft1000_probe: descriptor2 type -- %d\n", iface_desc->endpoint[2].desc.bmAttributes);
134
135 for (i=0; i< iface_desc->desc.bNumEndpoints;i++ )
136 {
137 endpoint = (struct usb_endpoint_descriptor *)&iface_desc->endpoint[i].desc;
138 DEBUG("endpoint %d\n", i);
139 DEBUG("bEndpointAddress=%x, bmAttributes=%x\n", endpoint->bEndpointAddress, endpoint->bmAttributes);
bf3146c8 140 if ( (endpoint->bEndpointAddress & USB_DIR_IN) && ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_BULK))
f7c1be0c
MB
141 {
142 ft1000dev->bulk_in_endpointAddr = endpoint->bEndpointAddress;
143 DEBUG("ft1000_probe: in: %d\n", endpoint->bEndpointAddress);
144 }
145
146 if (!(endpoint->bEndpointAddress & USB_DIR_IN) && ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_BULK))
147 {
148 ft1000dev->bulk_out_endpointAddr = endpoint->bEndpointAddress;
149 DEBUG("ft1000_probe: out: %d\n", endpoint->bEndpointAddress);
150 }
151 }
bf3146c8 152
f7c1be0c
MB
153 DEBUG("bulk_in=%d, bulk_out=%d\n", ft1000dev->bulk_in_endpointAddr, ft1000dev->bulk_out_endpointAddr);
154
ada541f0
MB
155 ret = request_firmware(&dsp_fw, "ft3000.img", &dev->dev);
156 if (ret < 0) {
157 printk(KERN_ERR "Error request_firmware().\n");
158 goto err_fw;
159 }
f7c1be0c 160
ada541f0
MB
161 size = max_t(uint, dsp_fw->size, 4096);
162 pFileStart = kmalloc(size, GFP_KERNEL);
163
164 if (!pFileStart) {
165 release_firmware(dsp_fw);
166 ret = -ENOMEM;
167 goto err_fw;
168 }
169
170 memcpy(pFileStart, dsp_fw->data, dsp_fw->size);
171 FileLength = dsp_fw->size;
172 release_firmware(dsp_fw);
f7c1be0c
MB
173
174 //for ( i=0; i< MAX_NUM_CARDS+2; i++)
175 // pdevobj[i] = NULL;
bf3146c8 176
f7c1be0c
MB
177 //download dsp image
178 DEBUG("ft1000_probe: start downloading dsp image...\n");
179 init_ft1000_netdev(ft1000dev);
180 pft1000info = (FT1000_INFO *) netdev_priv (ft1000dev->net);
181
bf3146c8 182// DEBUG("In probe: pft1000info=%x\n", pft1000info); // aelias [-] reason: warning: format ???%x??? expects type ???unsigned int???, but argument 2 has type ???struct FT1000_INFO *???
7cfd8a37 183 DEBUG("In probe: pft1000info=%p\n", pft1000info); // aelias [+] reason: up
bf3146c8 184
f7c1be0c
MB
185 dsp_reload(ft1000dev);
186 gPollingfailed = FALSE; //mbelian
187 pft1000info->pPollThread = kthread_run(ft1000_poll_thread, ft1000dev, "ft1000_poll");
188 msleep(500); //mbelian
bf3146c8
GKH
189
190
f7c1be0c
MB
191 if ( pft1000info->DSP_loading )
192 {
193 DEBUG("ERROR!!!! RETURN FROM ft1000_probe **********************\n");
194 return 0;
195 }
bf3146c8 196
f7c1be0c
MB
197 while (!pft1000info->CardReady)
198 {
199 if ( gPollingfailed )
200 {
201 if ( pft1000info->pPollThread )
202 {
203 kthread_stop(pft1000info->pPollThread );
204 }
205 return 0;
206 }
207 msleep(100);
208 DEBUG("ft1000_probe::Waiting for Card Ready\n");
209 }
bf3146c8
GKH
210
211
f7c1be0c
MB
212 //initialize network device
213 DEBUG("ft1000_probe::Card Ready!!!! Registering network device\n");
214
215 reg_ft1000_netdev(ft1000dev, interface);
bf3146c8 216
f7c1be0c
MB
217 pft1000info->NetDevRegDone = 1;
218
bf3146c8 219 ft1000InitProc(ft1000dev->net);// +mbelian
f7c1be0c
MB
220
221 return 0;
ada541f0
MB
222
223err_fw:
224 kfree(ft1000dev);
225 return ret;
f7c1be0c
MB
226}
227
228//---------------------------------------------------------------------------
229// Function: ft1000_disconnect
230//
231// Parameters: struct usb_interface *interface - passed by USB core
bf3146c8 232//
f7c1be0c
MB
233// Returns: 0 - success
234//
235// Description: This function is invoked when the express card is plugged out
236//
237// Notes:
238//
239//---------------------------------------------------------------------------
240static void ft1000_disconnect(struct usb_interface *interface)
241{
242 FT1000_INFO *pft1000info;
bf3146c8 243
f7c1be0c 244 DEBUG("ft1000_disconnect is called\n");
bf3146c8 245
f7c1be0c 246 pft1000info = (PFT1000_INFO)usb_get_intfdata(interface);
bf3146c8 247// DEBUG("In disconnect pft1000info=%x\n", pft1000info); // aelias [-] reason: warning: format ???%x??? expects type ???unsigned int???, but argument 2 has type ???struct FT1000_INFO *???
7cfd8a37 248 DEBUG("In disconnect pft1000info=%p\n", pft1000info); // aelias [+] reason: up
f7c1be0c
MB
249
250
251
252 if (pft1000info)
253 {
254 ft1000CleanupProc(pft1000info); //+mbelian
255 if ( pft1000info->pPollThread )
256 {
257 kthread_stop(pft1000info->pPollThread );
258 }
bf3146c8 259
f7c1be0c 260 DEBUG("ft1000_disconnect: threads are terminated\n");
bf3146c8 261
f7c1be0c
MB
262 if (pft1000info->pFt1000Dev->net)
263 {
264 DEBUG("ft1000_disconnect: destroy char driver\n");
265 ft1000_DestroyDevice(pft1000info->pFt1000Dev->net);
266 //DEBUG("ft1000_disconnect: calling ft1000_close\n");
267 //ft1000_close(pft1000info->pFt1000Dev->net);
268 //DEBUG("ft1000_disconnect: ft1000_close is called\n");
269 unregister_netdev(pft1000info->pFt1000Dev->net);
270 DEBUG("ft1000_disconnect: network device unregisterd\n");
271 free_netdev(pft1000info->pFt1000Dev->net);
272
273 }
bf3146c8 274
f7c1be0c
MB
275 usb_free_urb(pft1000info->pFt1000Dev->rx_urb);
276 usb_free_urb(pft1000info->pFt1000Dev->tx_urb);
bf3146c8 277
f7c1be0c
MB
278 DEBUG("ft1000_disconnect: urb freed\n");
279
280 kfree(pft1000info->pFt1000Dev); //+mbelian
281 }
ada541f0 282 kfree(pFileStart);
f7c1be0c 283 //terminate other kernel threads
bf3146c8 284 //in multiple instances case, first find the device
f7c1be0c
MB
285 //in the link list
286 /**if (pPollThread)
287 {
288 kthread_stop(pPollThread);
289 DEBUG("Polling thread is killed \n");
290 }**/
291
292 return;
293}
294
295static struct usb_driver ft1000_usb_driver = {
296 //.owner = THIS_MODULE,
297 .name = "ft1000usb",
298 .probe = ft1000_probe,
299 .disconnect = ft1000_disconnect,
300 .id_table = id_table,
301};
302
303//---------------------------------------------------------------------------
304// Function: usb_ft1000_init
305//
306// Parameters: none
bf3146c8 307//
f7c1be0c
MB
308// Returns: 0 - success
309//
310// Description: The entry point of the module, register the usb driver
311//
312// Notes:
313//
314//---------------------------------------------------------------------------
315static int __init usb_ft1000_init(void)
316{
317 int ret = 0;
bf3146c8 318
f7c1be0c
MB
319 DEBUG("Initialize and register the driver\n");
320
321 ret = usb_register(&ft1000_usb_driver);
322 if (ret)
323 err("usb_register failed. Error number %d", ret);
324
325 return ret;
326}
327
328//---------------------------------------------------------------------------
329// Function: usb_ft1000_exit
330//
bf3146c8
GKH
331// Parameters:
332//
333// Returns:
f7c1be0c
MB
334//
335// Description: Moudle unload function, deregister usb driver
336//
337// Notes:
338//
339//---------------------------------------------------------------------------
340static void __exit usb_ft1000_exit(void)
341{
342 DEBUG("Deregister the driver\n");
343 usb_deregister(&ft1000_usb_driver);
344}
345
346module_init (usb_ft1000_init);
347module_exit (usb_ft1000_exit);
348
349
This page took 0.046743 seconds and 5 git commands to generate.