• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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  */
10 #include <linux/kernel.h>
11 #include <linux/module.h>
12 #include <linux/usb.h>
13 #include <linux/netdevice.h>
14 #include <linux/etherdevice.h>
15 #include <linux/firmware.h>
16 #include "ft1000_usb.h"
17 
18 #include <linux/kthread.h>
19 
20 MODULE_DESCRIPTION("FT1000 EXPRESS CARD DRIVER");
21 MODULE_LICENSE("Dual MPL/GPL");
22 MODULE_SUPPORTED_DEVICE("QFT FT1000 Express Cards");
23 
24 void *pFileStart;
25 size_t FileLength;
26 
27 #define VENDOR_ID 0x1291	/* Qualcomm vendor id */
28 #define PRODUCT_ID 0x11		/* fake product id */
29 
30 /* table of devices that work with this driver */
31 static struct usb_device_id id_table[] = {
32 	{USB_DEVICE(VENDOR_ID, PRODUCT_ID)},
33 	{},
34 };
35 
36 MODULE_DEVICE_TABLE(usb, id_table);
37 
38 static bool gPollingfailed;
ft1000_poll_thread(void * arg)39 static int ft1000_poll_thread(void *arg)
40 {
41 	int ret;
42 
43 	while (!kthread_should_stop()) {
44 		usleep_range(10000, 11000);
45 		if (!gPollingfailed) {
46 			ret = ft1000_poll(arg);
47 			if (ret != 0) {
48 				DEBUG("ft1000_poll_thread: polling failed\n");
49 				gPollingfailed = true;
50 			}
51 		}
52 	}
53 	return 0;
54 }
55 
ft1000_probe(struct usb_interface * interface,const struct usb_device_id * id)56 static int ft1000_probe(struct usb_interface *interface,
57 			const struct usb_device_id *id)
58 {
59 	struct usb_host_interface *iface_desc;
60 	struct usb_endpoint_descriptor *endpoint;
61 	struct usb_device *dev;
62 	unsigned numaltsetting;
63 	int i, ret = 0, size;
64 
65 	struct ft1000_usb *ft1000dev;
66 	struct ft1000_info *pft1000info = NULL;
67 	const struct firmware *dsp_fw;
68 
69 	ft1000dev = kzalloc(sizeof(struct ft1000_usb), GFP_KERNEL);
70 	if (!ft1000dev)
71 		return -ENOMEM;
72 
73 	dev = interface_to_usbdev(interface);
74 	DEBUG("ft1000_probe: usb device descriptor info:\n");
75 	DEBUG("ft1000_probe: number of configuration is %d\n",
76 	      dev->descriptor.bNumConfigurations);
77 
78 	ft1000dev->dev = dev;
79 	ft1000dev->status = 0;
80 	ft1000dev->net = NULL;
81 	ft1000dev->tx_urb = usb_alloc_urb(0, GFP_KERNEL);
82 	ft1000dev->rx_urb = usb_alloc_urb(0, GFP_KERNEL);
83 	if (!ft1000dev->tx_urb || !ft1000dev->rx_urb) {
84 		ret = -ENOMEM;
85 		goto err_fw;
86 	}
87 
88 	DEBUG("ft1000_probe is called\n");
89 	numaltsetting = interface->num_altsetting;
90 	DEBUG("ft1000_probe: number of alt settings is :%d\n", numaltsetting);
91 	iface_desc = interface->cur_altsetting;
92 	DEBUG("ft1000_probe: number of endpoints is %d\n",
93 	      iface_desc->desc.bNumEndpoints);
94 	DEBUG("ft1000_probe: descriptor type is %d\n",
95 	      iface_desc->desc.bDescriptorType);
96 	DEBUG("ft1000_probe: interface number is %d\n",
97 	      iface_desc->desc.bInterfaceNumber);
98 	DEBUG("ft1000_probe: alternatesetting is %d\n",
99 	      iface_desc->desc.bAlternateSetting);
100 	DEBUG("ft1000_probe: interface class is %d\n",
101 	      iface_desc->desc.bInterfaceClass);
102 	DEBUG("ft1000_probe: control endpoint info:\n");
103 	DEBUG("ft1000_probe: descriptor0 type -- %d\n",
104 	      iface_desc->endpoint[0].desc.bmAttributes);
105 	DEBUG("ft1000_probe: descriptor1 type -- %d\n",
106 	      iface_desc->endpoint[1].desc.bmAttributes);
107 	DEBUG("ft1000_probe: descriptor2 type -- %d\n",
108 	      iface_desc->endpoint[2].desc.bmAttributes);
109 
110 	for (i = 0; i < iface_desc->desc.bNumEndpoints; i++) {
111 		endpoint =
112 		    (struct usb_endpoint_descriptor *)&iface_desc->
113 		    endpoint[i].desc;
114 		DEBUG("endpoint %d\n", i);
115 		DEBUG("bEndpointAddress=%x, bmAttributes=%x\n",
116 		      endpoint->bEndpointAddress, endpoint->bmAttributes);
117 		if ((endpoint->bEndpointAddress & USB_DIR_IN)
118 		    && ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
119 			USB_ENDPOINT_XFER_BULK)) {
120 			ft1000dev->bulk_in_endpointAddr =
121 			    endpoint->bEndpointAddress;
122 			DEBUG("ft1000_probe: in: %d\n",
123 			      endpoint->bEndpointAddress);
124 		}
125 
126 		if (!(endpoint->bEndpointAddress & USB_DIR_IN)
127 		    && ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
128 			USB_ENDPOINT_XFER_BULK)) {
129 			ft1000dev->bulk_out_endpointAddr =
130 			    endpoint->bEndpointAddress;
131 			DEBUG("ft1000_probe: out: %d\n",
132 			      endpoint->bEndpointAddress);
133 		}
134 	}
135 
136 	DEBUG("bulk_in=%d, bulk_out=%d\n", ft1000dev->bulk_in_endpointAddr,
137 	      ft1000dev->bulk_out_endpointAddr);
138 
139 	ret = request_firmware(&dsp_fw, "ft3000.img", &dev->dev);
140 	if (ret < 0) {
141 		pr_err("Error request_firmware().\n");
142 		goto err_fw;
143 	}
144 
145 	size = max_t(uint, dsp_fw->size, 4096);
146 	pFileStart = kmalloc(size, GFP_KERNEL);
147 
148 	if (!pFileStart) {
149 		release_firmware(dsp_fw);
150 		ret = -ENOMEM;
151 		goto err_fw;
152 	}
153 
154 	memcpy(pFileStart, dsp_fw->data, dsp_fw->size);
155 	FileLength = dsp_fw->size;
156 	release_firmware(dsp_fw);
157 
158 	DEBUG("ft1000_probe: start downloading dsp image...\n");
159 
160 	ret = init_ft1000_netdev(ft1000dev);
161 	if (ret)
162 		goto err_load;
163 
164 	pft1000info = netdev_priv(ft1000dev->net);
165 
166 	DEBUG("In probe: pft1000info=%p\n", pft1000info);
167 	ret = dsp_reload(ft1000dev);
168 	if (ret) {
169 		pr_err("Problem with DSP image loading\n");
170 		goto err_load;
171 	}
172 
173 	gPollingfailed = false;
174 	ft1000dev->pPollThread =
175 	    kthread_run(ft1000_poll_thread, ft1000dev, "ft1000_poll");
176 
177 	if (IS_ERR(ft1000dev->pPollThread)) {
178 		ret = PTR_ERR(ft1000dev->pPollThread);
179 		goto err_load;
180 	}
181 
182 	msleep(500);
183 
184 	while (!pft1000info->CardReady) {
185 		if (gPollingfailed) {
186 			ret = -EIO;
187 			goto err_thread;
188 		}
189 		msleep(100);
190 		DEBUG("ft1000_probe::Waiting for Card Ready\n");
191 	}
192 
193 	DEBUG("ft1000_probe::Card Ready!!!! Registering network device\n");
194 
195 	ret = reg_ft1000_netdev(ft1000dev, interface);
196 	if (ret)
197 		goto err_thread;
198 
199 	ft1000dev->NetDevRegDone = 1;
200 
201 	return 0;
202 
203 err_thread:
204 	kthread_stop(ft1000dev->pPollThread);
205 err_load:
206 	kfree(pFileStart);
207 err_fw:
208 	usb_free_urb(ft1000dev->rx_urb);
209 	usb_free_urb(ft1000dev->tx_urb);
210 	kfree(ft1000dev);
211 	return ret;
212 }
213 
ft1000_disconnect(struct usb_interface * interface)214 static void ft1000_disconnect(struct usb_interface *interface)
215 {
216 	struct ft1000_info *pft1000info;
217 	struct ft1000_usb *ft1000dev;
218 
219 	DEBUG("ft1000_disconnect is called\n");
220 
221 	pft1000info = (struct ft1000_info *) usb_get_intfdata(interface);
222 	DEBUG("In disconnect pft1000info=%p\n", pft1000info);
223 
224 	if (pft1000info) {
225 		ft1000dev = pft1000info->priv;
226 		if (ft1000dev->pPollThread)
227 			kthread_stop(ft1000dev->pPollThread);
228 
229 		DEBUG("ft1000_disconnect: threads are terminated\n");
230 
231 		if (ft1000dev->net) {
232 			DEBUG("ft1000_disconnect: destroy char driver\n");
233 			ft1000_destroy_dev(ft1000dev->net);
234 			unregister_netdev(ft1000dev->net);
235 			DEBUG
236 			    ("ft1000_disconnect: network device unregistered\n");
237 			free_netdev(ft1000dev->net);
238 
239 		}
240 
241 		usb_free_urb(ft1000dev->rx_urb);
242 		usb_free_urb(ft1000dev->tx_urb);
243 
244 		DEBUG("ft1000_disconnect: urb freed\n");
245 
246 		kfree(ft1000dev);
247 	}
248 	kfree(pFileStart);
249 }
250 
251 static struct usb_driver ft1000_usb_driver = {
252 	.name = "ft1000usb",
253 	.probe = ft1000_probe,
254 	.disconnect = ft1000_disconnect,
255 	.id_table = id_table,
256 };
257 
258 module_usb_driver(ft1000_usb_driver);
259