diff options
Diffstat (limited to 'drivers/staging/bcm/InterfaceInit.c')
-rw-r--r-- | drivers/staging/bcm/InterfaceInit.c | 868 |
1 files changed, 868 insertions, 0 deletions
diff --git a/drivers/staging/bcm/InterfaceInit.c b/drivers/staging/bcm/InterfaceInit.c new file mode 100644 index 00000000000..e06f168a52b --- /dev/null +++ b/drivers/staging/bcm/InterfaceInit.c | |||
@@ -0,0 +1,868 @@ | |||
1 | #include "headers.h" | ||
2 | |||
3 | static struct usb_device_id InterfaceUsbtable[] = { | ||
4 | { USB_DEVICE(BCM_USB_VENDOR_ID_T3, BCM_USB_PRODUCT_ID_T3) }, | ||
5 | { USB_DEVICE(BCM_USB_VENDOR_ID_T3, BCM_USB_PRODUCT_ID_T3B) }, | ||
6 | { USB_DEVICE(BCM_USB_VENDOR_ID_T3, BCM_USB_PRODUCT_ID_T3L) }, | ||
7 | { USB_DEVICE(BCM_USB_VENDOR_ID_ZTE, BCM_USB_PRODUCT_ID_226) }, | ||
8 | { USB_DEVICE(BCM_USB_VENDOR_ID_FOXCONN, BCM_USB_PRODUCT_ID_1901) }, | ||
9 | {} | ||
10 | }; | ||
11 | |||
12 | VOID InterfaceAdapterFree(PS_INTERFACE_ADAPTER psIntfAdapter) | ||
13 | { | ||
14 | INT i = 0; | ||
15 | // Wake up the wait_queue... | ||
16 | if(psIntfAdapter->psAdapter->LEDInfo.led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY) | ||
17 | { | ||
18 | psIntfAdapter->psAdapter->DriverState = DRIVER_HALT; | ||
19 | wake_up(&psIntfAdapter->psAdapter->LEDInfo.notify_led_event); | ||
20 | } | ||
21 | reset_card_proc(psIntfAdapter->psAdapter); | ||
22 | |||
23 | //worst case time taken by the RDM/WRM will be 5 sec. will check after every 100 ms | ||
24 | //to accertain the device is not being accessed. After this No RDM/WRM should be made. | ||
25 | while(psIntfAdapter->psAdapter->DeviceAccess) | ||
26 | { | ||
27 | BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL,"Device is being Accessed \n"); | ||
28 | msleep(100); | ||
29 | } | ||
30 | /* Free interrupt URB */ | ||
31 | //psIntfAdapter->psAdapter->device_removed = TRUE; | ||
32 | if(psIntfAdapter->psInterruptUrb) | ||
33 | { | ||
34 | usb_free_urb(psIntfAdapter->psInterruptUrb); | ||
35 | } | ||
36 | |||
37 | /* Free transmit URBs */ | ||
38 | for(i = 0; i < MAXIMUM_USB_TCB; i++) | ||
39 | { | ||
40 | if(psIntfAdapter->asUsbTcb[i].urb != NULL) | ||
41 | { | ||
42 | usb_free_urb(psIntfAdapter->asUsbTcb[i].urb); | ||
43 | psIntfAdapter->asUsbTcb[i].urb = NULL; | ||
44 | } | ||
45 | } | ||
46 | /* Free receive URB and buffers */ | ||
47 | for(i = 0; i < MAXIMUM_USB_RCB; i++) | ||
48 | { | ||
49 | if (psIntfAdapter->asUsbRcb[i].urb != NULL) | ||
50 | { | ||
51 | bcm_kfree(psIntfAdapter->asUsbRcb[i].urb->transfer_buffer); | ||
52 | usb_free_urb(psIntfAdapter->asUsbRcb[i].urb); | ||
53 | psIntfAdapter->asUsbRcb[i].urb = NULL; | ||
54 | } | ||
55 | } | ||
56 | AdapterFree(psIntfAdapter->psAdapter); | ||
57 | } | ||
58 | |||
59 | |||
60 | |||
61 | static int usbbcm_open(struct inode *inode, struct file *file) | ||
62 | { | ||
63 | return 0; | ||
64 | } | ||
65 | |||
66 | static int usbbcm_release(struct inode *inode, struct file *file) | ||
67 | { | ||
68 | return 0; | ||
69 | } | ||
70 | |||
71 | static ssize_t usbbcm_read(struct file *file, char *buffer, size_t count, loff_t *ppos) | ||
72 | { | ||
73 | return 0; | ||
74 | } | ||
75 | |||
76 | static ssize_t usbbcm_write(struct file *file, const char *user_buffer, size_t count, loff_t *ppos) | ||
77 | { | ||
78 | return 0; | ||
79 | } | ||
80 | |||
81 | |||
82 | VOID ConfigureEndPointTypesThroughEEPROM(PMINI_ADAPTER Adapter) | ||
83 | { | ||
84 | ULONG ulReg = 0; | ||
85 | |||
86 | // Program EP2 MAX_PKT_SIZE | ||
87 | ulReg = ntohl(EP2_MPS_REG); | ||
88 | BeceemEEPROMBulkWrite(Adapter,(PUCHAR)&ulReg,0x128,4,TRUE); | ||
89 | ulReg = ntohl(EP2_MPS); | ||
90 | BeceemEEPROMBulkWrite(Adapter,(PUCHAR)&ulReg,0x12C,4,TRUE); | ||
91 | |||
92 | ulReg = ntohl(EP2_CFG_REG); | ||
93 | BeceemEEPROMBulkWrite(Adapter,(PUCHAR)&ulReg,0x132,4,TRUE); | ||
94 | if(((PS_INTERFACE_ADAPTER)(Adapter->pvInterfaceAdapter))->bHighSpeedDevice == TRUE) | ||
95 | { | ||
96 | ulReg = ntohl(EP2_CFG_INT); | ||
97 | BeceemEEPROMBulkWrite(Adapter,(PUCHAR)&ulReg,0x136,4,TRUE); | ||
98 | } | ||
99 | else | ||
100 | { | ||
101 | // USE BULK EP as TX in FS mode. | ||
102 | ulReg = ntohl(EP2_CFG_BULK); | ||
103 | BeceemEEPROMBulkWrite(Adapter,(PUCHAR)&ulReg,0x136,4,TRUE); | ||
104 | } | ||
105 | |||
106 | |||
107 | // Program EP4 MAX_PKT_SIZE. | ||
108 | ulReg = ntohl(EP4_MPS_REG); | ||
109 | BeceemEEPROMBulkWrite(Adapter,(PUCHAR)&ulReg,0x13C,4,TRUE); | ||
110 | ulReg = ntohl(EP4_MPS); | ||
111 | BeceemEEPROMBulkWrite(Adapter,(PUCHAR)&ulReg,0x140,4,TRUE); | ||
112 | |||
113 | // Program TX EP as interrupt (Alternate Setting) | ||
114 | if( rdmalt(Adapter,0x0F0110F8, (PUINT)&ulReg,4)) | ||
115 | { | ||
116 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "reading of Tx EP is failing"); | ||
117 | return ; | ||
118 | } | ||
119 | ulReg |= 0x6; | ||
120 | |||
121 | ulReg = ntohl(ulReg); | ||
122 | BeceemEEPROMBulkWrite(Adapter,(PUCHAR)&ulReg,0x1CC,4,TRUE); | ||
123 | |||
124 | ulReg = ntohl(EP4_CFG_REG); | ||
125 | BeceemEEPROMBulkWrite(Adapter,(PUCHAR)&ulReg,0x1C8,4,TRUE); | ||
126 | // Program ISOCHRONOUS EP size to zero. | ||
127 | ulReg = ntohl(ISO_MPS_REG); | ||
128 | BeceemEEPROMBulkWrite(Adapter,(PUCHAR)&ulReg,0x1D2,4,TRUE); | ||
129 | ulReg = ntohl(ISO_MPS); | ||
130 | BeceemEEPROMBulkWrite(Adapter,(PUCHAR)&ulReg,0x1D6,4,TRUE); | ||
131 | |||
132 | // Update EEPROM Version. | ||
133 | // Read 4 bytes from 508 and modify 511 and 510. | ||
134 | // | ||
135 | ReadBeceemEEPROM(Adapter,0x1FC,(PUINT)&ulReg); | ||
136 | ulReg &= 0x0101FFFF; | ||
137 | BeceemEEPROMBulkWrite(Adapter,(PUCHAR)&ulReg,0x1FC,4,TRUE); | ||
138 | // | ||
139 | //Update length field if required. Also make the string NULL terminated. | ||
140 | // | ||
141 | ReadBeceemEEPROM(Adapter,0xA8,(PUINT)&ulReg); | ||
142 | if((ulReg&0x00FF0000)>>16 > 0x30) | ||
143 | { | ||
144 | ulReg = (ulReg&0xFF00FFFF)|(0x30<<16); | ||
145 | BeceemEEPROMBulkWrite(Adapter,(PUCHAR)&ulReg,0xA8,4,TRUE); | ||
146 | } | ||
147 | ReadBeceemEEPROM(Adapter,0x148,(PUINT)&ulReg); | ||
148 | if((ulReg&0x00FF0000)>>16 > 0x30) | ||
149 | { | ||
150 | ulReg = (ulReg&0xFF00FFFF)|(0x30<<16); | ||
151 | BeceemEEPROMBulkWrite(Adapter,(PUCHAR)&ulReg,0x148,4,TRUE); | ||
152 | } | ||
153 | ulReg = 0; | ||
154 | BeceemEEPROMBulkWrite(Adapter,(PUCHAR)&ulReg,0x122,4,TRUE); | ||
155 | ulReg = 0; | ||
156 | BeceemEEPROMBulkWrite(Adapter,(PUCHAR)&ulReg,0x1C2,4,TRUE); | ||
157 | |||
158 | } | ||
159 | |||
160 | static struct file_operations usbbcm_fops = { | ||
161 | .open = usbbcm_open, | ||
162 | .release = usbbcm_release, | ||
163 | .read = usbbcm_read, | ||
164 | .write = usbbcm_write, | ||
165 | .owner = THIS_MODULE, | ||
166 | }; | ||
167 | |||
168 | static struct usb_class_driver usbbcm_class = { | ||
169 | .name = "usbbcm", | ||
170 | .fops = &usbbcm_fops, | ||
171 | .minor_base = BCM_USB_MINOR_BASE, | ||
172 | }; | ||
173 | |||
174 | static int | ||
175 | usbbcm_device_probe(struct usb_interface *intf, const struct usb_device_id *id) | ||
176 | { | ||
177 | int retval =0 ; | ||
178 | PMINI_ADAPTER psAdapter = NULL; | ||
179 | PS_INTERFACE_ADAPTER psIntfAdapter = NULL; | ||
180 | struct usb_device *udev = NULL; | ||
181 | |||
182 | // BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Usbbcm probe!!"); | ||
183 | if((intf == NULL) || (id == NULL)) | ||
184 | { | ||
185 | // BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "intf or id is NULL"); | ||
186 | return -EINVAL; | ||
187 | } | ||
188 | |||
189 | /* Allocate Adapter structure */ | ||
190 | if((psAdapter = kmalloc(sizeof(MINI_ADAPTER), GFP_KERNEL)) == NULL) | ||
191 | { | ||
192 | //BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_PRINTK, 0, 0, "Out of memory"); | ||
193 | return -ENOMEM; | ||
194 | } | ||
195 | |||
196 | memset(psAdapter, 0, sizeof(MINI_ADAPTER)); | ||
197 | |||
198 | /* Init default driver debug state */ | ||
199 | |||
200 | psAdapter->stDebugState.debug_level = DBG_LVL_CURR; | ||
201 | psAdapter->stDebugState.type = DBG_TYPE_INITEXIT; | ||
202 | memset (psAdapter->stDebugState.subtype, 0, sizeof (psAdapter->stDebugState.subtype)); | ||
203 | |||
204 | /* Technically, one can start using BCM_DEBUG_PRINT after this point. | ||
205 | * However, realize that by default the Type/Subtype bitmaps are all zero now; | ||
206 | * so no prints will actually appear until the TestApp turns on debug paths via | ||
207 | * the ioctl(); so practically speaking, in early init, no logging happens. | ||
208 | * | ||
209 | * A solution (used below): we explicitly set the bitmaps to 1 for Type=DBG_TYPE_INITEXIT | ||
210 | * and ALL subtype's of the same. Now all bcm debug statements get logged, enabling debug | ||
211 | * during early init. | ||
212 | * Further, we turn this OFF once init_module() completes. | ||
213 | */ | ||
214 | |||
215 | psAdapter->stDebugState.subtype[DBG_TYPE_INITEXIT] = 0xff; | ||
216 | BCM_SHOW_DEBUG_BITMAP(psAdapter); | ||
217 | |||
218 | retval = InitAdapter(psAdapter); | ||
219 | if(retval) | ||
220 | { | ||
221 | BCM_DEBUG_PRINT (psAdapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "InitAdapter Failed\n"); | ||
222 | AdapterFree(psAdapter); | ||
223 | return retval; | ||
224 | } | ||
225 | |||
226 | /* Allocate interface adapter structure */ | ||
227 | if((psAdapter->pvInterfaceAdapter = | ||
228 | kmalloc(sizeof(S_INTERFACE_ADAPTER), GFP_KERNEL)) == NULL) | ||
229 | { | ||
230 | BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_PRINTK, 0, 0, "Out of memory"); | ||
231 | AdapterFree (psAdapter); | ||
232 | return -ENOMEM; | ||
233 | } | ||
234 | memset(psAdapter->pvInterfaceAdapter, 0, sizeof(S_INTERFACE_ADAPTER)); | ||
235 | |||
236 | psIntfAdapter = InterfaceAdapterGet(psAdapter); | ||
237 | psIntfAdapter->psAdapter = psAdapter; | ||
238 | |||
239 | /* Store usb interface in Interface Adapter */ | ||
240 | psIntfAdapter->interface = intf; | ||
241 | usb_set_intfdata(intf, psIntfAdapter); | ||
242 | |||
243 | BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "psIntfAdapter 0x%x",(unsigned int)psIntfAdapter); | ||
244 | retval = InterfaceAdapterInit(psIntfAdapter); | ||
245 | if(retval) | ||
246 | { | ||
247 | /* If the Firmware/Cfg File is not present | ||
248 | * then return success, let the application | ||
249 | * download the files. | ||
250 | */ | ||
251 | if(-ENOENT == retval){ | ||
252 | BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "File Not Found, Use App to Download\n"); | ||
253 | return STATUS_SUCCESS; | ||
254 | } | ||
255 | BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "InterfaceAdapterInit Failed \n"); | ||
256 | usb_set_intfdata(intf, NULL); | ||
257 | udev = interface_to_usbdev (intf); | ||
258 | usb_put_dev(udev); | ||
259 | if(psAdapter->bUsbClassDriverRegistered == TRUE) | ||
260 | usb_deregister_dev (intf, &usbbcm_class); | ||
261 | InterfaceAdapterFree(psIntfAdapter); | ||
262 | return retval ; | ||
263 | } | ||
264 | if(psAdapter->chip_id > T3) | ||
265 | { | ||
266 | uint32_t uiNackZeroLengthInt=4; | ||
267 | if(wrmalt(psAdapter, DISABLE_USB_ZERO_LEN_INT, &uiNackZeroLengthInt, sizeof(uiNackZeroLengthInt))) | ||
268 | { | ||
269 | return -EIO;; | ||
270 | } | ||
271 | } | ||
272 | |||
273 | udev = interface_to_usbdev (intf); | ||
274 | /* Check whether the USB-Device Supports remote Wake-Up */ | ||
275 | if(USB_CONFIG_ATT_WAKEUP & udev->actconfig->desc.bmAttributes) | ||
276 | { | ||
277 | /* If Suspend then only support dynamic suspend */ | ||
278 | if(psAdapter->bDoSuspend) | ||
279 | { | ||
280 | udev->autosuspend_delay = 0; | ||
281 | intf->needs_remote_wakeup = 1; | ||
282 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 35) | ||
283 | udev->autosuspend_disabled = 0; | ||
284 | #else | ||
285 | usb_enable_autosuspend(udev); | ||
286 | #endif | ||
287 | device_init_wakeup(&intf->dev,1); | ||
288 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 32) | ||
289 | usb_autopm_disable(intf); | ||
290 | #endif | ||
291 | INIT_WORK(&psIntfAdapter->usbSuspendWork, putUsbSuspend); | ||
292 | BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Enabling USB Auto-Suspend\n"); | ||
293 | } | ||
294 | else | ||
295 | { | ||
296 | intf->needs_remote_wakeup = 0; | ||
297 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 35) | ||
298 | udev->autosuspend_disabled = 1; | ||
299 | #else | ||
300 | usb_disable_autosuspend(udev); | ||
301 | #endif | ||
302 | } | ||
303 | } | ||
304 | |||
305 | psAdapter->stDebugState.subtype[DBG_TYPE_INITEXIT] = 0x0; | ||
306 | return retval; | ||
307 | } | ||
308 | |||
309 | static void usbbcm_disconnect (struct usb_interface *intf) | ||
310 | { | ||
311 | PS_INTERFACE_ADAPTER psIntfAdapter = NULL; | ||
312 | PMINI_ADAPTER psAdapter = NULL; | ||
313 | struct usb_device *udev = NULL; | ||
314 | PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); | ||
315 | |||
316 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Usb disconnected"); | ||
317 | if(intf == NULL) | ||
318 | { | ||
319 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "intf pointer is NULL"); | ||
320 | return; | ||
321 | } | ||
322 | psIntfAdapter = usb_get_intfdata(intf); | ||
323 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "psIntfAdapter 0x%x",(unsigned int)psIntfAdapter); | ||
324 | if(psIntfAdapter == NULL) | ||
325 | { | ||
326 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "InterfaceAdapter pointer is NULL"); | ||
327 | return; | ||
328 | } | ||
329 | psAdapter = psIntfAdapter->psAdapter; | ||
330 | if(psAdapter->bDoSuspend) | ||
331 | intf->needs_remote_wakeup = 0; | ||
332 | |||
333 | psAdapter->device_removed = TRUE ; | ||
334 | usb_set_intfdata(intf, NULL); | ||
335 | InterfaceAdapterFree(psIntfAdapter); | ||
336 | udev = interface_to_usbdev (intf); | ||
337 | usb_put_dev(udev); | ||
338 | usb_deregister_dev (intf, &usbbcm_class); | ||
339 | } | ||
340 | |||
341 | |||
342 | static __inline int AllocUsbCb(PS_INTERFACE_ADAPTER psIntfAdapter) | ||
343 | { | ||
344 | int i = 0; | ||
345 | for(i = 0; i < MAXIMUM_USB_TCB; i++) | ||
346 | { | ||
347 | if((psIntfAdapter->asUsbTcb[i].urb = | ||
348 | usb_alloc_urb(0, GFP_KERNEL)) == NULL) | ||
349 | { | ||
350 | BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_PRINTK, 0, 0, "Cant allocate Tx urb for index %d", i); | ||
351 | return -ENOMEM; | ||
352 | } | ||
353 | } | ||
354 | |||
355 | for(i = 0; i < MAXIMUM_USB_RCB; i++) | ||
356 | { | ||
357 | if ((psIntfAdapter->asUsbRcb[i].urb = | ||
358 | usb_alloc_urb(0, GFP_KERNEL)) == NULL) | ||
359 | { | ||
360 | BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_PRINTK, 0, 0, "Cant allocate Rx urb for index %d", i); | ||
361 | return -ENOMEM; | ||
362 | } | ||
363 | if((psIntfAdapter->asUsbRcb[i].urb->transfer_buffer = | ||
364 | kmalloc(MAX_DATA_BUFFER_SIZE, GFP_KERNEL)) == NULL) | ||
365 | { | ||
366 | BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_PRINTK, 0, 0, "Cant allocate Rx buffer for index %d", i); | ||
367 | return -ENOMEM; | ||
368 | } | ||
369 | psIntfAdapter->asUsbRcb[i].urb->transfer_buffer_length = MAX_DATA_BUFFER_SIZE; | ||
370 | } | ||
371 | return 0; | ||
372 | } | ||
373 | |||
374 | |||
375 | |||
376 | static int device_run(PS_INTERFACE_ADAPTER psIntfAdapter) | ||
377 | { | ||
378 | INT value = 0; | ||
379 | UINT status = STATUS_SUCCESS; | ||
380 | |||
381 | status = InitCardAndDownloadFirmware(psIntfAdapter->psAdapter); | ||
382 | if(status != STATUS_SUCCESS) | ||
383 | { | ||
384 | BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_PRINTK, 0, 0, "InitCardAndDownloadFirmware failed.\n"); | ||
385 | return status; | ||
386 | } | ||
387 | if(TRUE == psIntfAdapter->psAdapter->fw_download_done) | ||
388 | { | ||
389 | |||
390 | BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Sending first interrupt URB down......"); | ||
391 | if(StartInterruptUrb(psIntfAdapter)) | ||
392 | { | ||
393 | BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Cannot send interrupt in URB"); | ||
394 | } | ||
395 | //now register the cntrl interface. | ||
396 | //after downloading the f/w waiting for 5 sec to get the mailbox interrupt. | ||
397 | |||
398 | psIntfAdapter->psAdapter->waiting_to_fw_download_done = FALSE; | ||
399 | value = wait_event_timeout(psIntfAdapter->psAdapter->ioctl_fw_dnld_wait_queue, | ||
400 | psIntfAdapter->psAdapter->waiting_to_fw_download_done, 5*HZ); | ||
401 | |||
402 | if(value == 0) | ||
403 | { | ||
404 | BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL,"Mailbox Interrupt has not reached to Driver.."); | ||
405 | } | ||
406 | else | ||
407 | { | ||
408 | BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL,"Got the mailbox interrupt ...Registering control interface...\n "); | ||
409 | } | ||
410 | if(register_control_device_interface(psIntfAdapter->psAdapter) < 0) | ||
411 | { | ||
412 | BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_PRINTK, 0, 0, "Register Control Device failed..."); | ||
413 | return -EIO; | ||
414 | } | ||
415 | } | ||
416 | return 0; | ||
417 | } | ||
418 | |||
419 | #if 0 | ||
420 | static void print_usb_interface_desc(struct usb_interface_descriptor *usb_intf_desc) | ||
421 | { | ||
422 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "**************** INTERFACE DESCRIPTOR *********************"); | ||
423 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "bLength: %x", usb_intf_desc->bLength); | ||
424 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "bDescriptorType: %x", usb_intf_desc->bDescriptorType); | ||
425 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "bInterfaceNumber: %x", usb_intf_desc->bInterfaceNumber); | ||
426 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "bAlternateSetting: %x", usb_intf_desc->bAlternateSetting); | ||
427 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "bNumEndpoints: %x", usb_intf_desc->bNumEndpoints); | ||
428 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "bInterfaceClass: %x", usb_intf_desc->bInterfaceClass); | ||
429 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "bInterfaceSubClass: %x", usb_intf_desc->bInterfaceSubClass); | ||
430 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "bInterfaceProtocol: %x", usb_intf_desc->bInterfaceProtocol); | ||
431 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "iInterface :%x\n",usb_intf_desc->iInterface); | ||
432 | } | ||
433 | static void print_usb_endpoint_descriptor(struct usb_endpoint_descriptor *usb_ep_desc) | ||
434 | { | ||
435 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "**************** ENDPOINT DESCRIPTOR *********************"); | ||
436 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "bLength :%x ", usb_ep_desc->bLength); | ||
437 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "bDescriptorType :%x ", usb_ep_desc->bDescriptorType); | ||
438 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "bEndpointAddress :%x ", usb_ep_desc->bEndpointAddress); | ||
439 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "bmAttributes :%x ", usb_ep_desc->bmAttributes); | ||
440 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "wMaxPacketSize :%x ",usb_ep_desc->wMaxPacketSize); | ||
441 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "bInterval :%x ",usb_ep_desc->bInterval); | ||
442 | } | ||
443 | |||
444 | #endif | ||
445 | |||
446 | static inline int bcm_usb_endpoint_num(const struct usb_endpoint_descriptor *epd) | ||
447 | { | ||
448 | return epd->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK; | ||
449 | } | ||
450 | |||
451 | static inline int bcm_usb_endpoint_type(const struct usb_endpoint_descriptor *epd) | ||
452 | { | ||
453 | return epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK; | ||
454 | } | ||
455 | |||
456 | static inline int bcm_usb_endpoint_dir_in(const struct usb_endpoint_descriptor *epd) | ||
457 | { | ||
458 | return ((epd->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN); | ||
459 | } | ||
460 | |||
461 | static inline int bcm_usb_endpoint_dir_out(const struct usb_endpoint_descriptor *epd) | ||
462 | { | ||
463 | return ((epd->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT); | ||
464 | } | ||
465 | |||
466 | static inline int bcm_usb_endpoint_xfer_bulk(const struct usb_endpoint_descriptor *epd) | ||
467 | { | ||
468 | return ((epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == | ||
469 | USB_ENDPOINT_XFER_BULK); | ||
470 | } | ||
471 | |||
472 | static inline int bcm_usb_endpoint_xfer_control(const struct usb_endpoint_descriptor *epd) | ||
473 | { | ||
474 | return ((epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == | ||
475 | USB_ENDPOINT_XFER_CONTROL); | ||
476 | } | ||
477 | |||
478 | static inline int bcm_usb_endpoint_xfer_int(const struct usb_endpoint_descriptor *epd) | ||
479 | { | ||
480 | return ((epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == | ||
481 | USB_ENDPOINT_XFER_INT); | ||
482 | } | ||
483 | |||
484 | static inline int bcm_usb_endpoint_xfer_isoc(const struct usb_endpoint_descriptor *epd) | ||
485 | { | ||
486 | return ((epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == | ||
487 | USB_ENDPOINT_XFER_ISOC); | ||
488 | } | ||
489 | |||
490 | static inline int bcm_usb_endpoint_is_bulk_in(const struct usb_endpoint_descriptor *epd) | ||
491 | { | ||
492 | return (bcm_usb_endpoint_xfer_bulk(epd) && bcm_usb_endpoint_dir_in(epd)); | ||
493 | } | ||
494 | |||
495 | static inline int bcm_usb_endpoint_is_bulk_out(const struct usb_endpoint_descriptor *epd) | ||
496 | { | ||
497 | return (bcm_usb_endpoint_xfer_bulk(epd) && bcm_usb_endpoint_dir_out(epd)); | ||
498 | } | ||
499 | |||
500 | static inline int bcm_usb_endpoint_is_int_in(const struct usb_endpoint_descriptor *epd) | ||
501 | { | ||
502 | return (bcm_usb_endpoint_xfer_int(epd) && bcm_usb_endpoint_dir_in(epd)); | ||
503 | } | ||
504 | |||
505 | static inline int bcm_usb_endpoint_is_int_out(const struct usb_endpoint_descriptor *epd) | ||
506 | { | ||
507 | return (bcm_usb_endpoint_xfer_int(epd) && bcm_usb_endpoint_dir_out(epd)); | ||
508 | } | ||
509 | |||
510 | static inline int bcm_usb_endpoint_is_isoc_in(const struct usb_endpoint_descriptor *epd) | ||
511 | { | ||
512 | return (bcm_usb_endpoint_xfer_isoc(epd) && bcm_usb_endpoint_dir_in(epd)); | ||
513 | } | ||
514 | |||
515 | static inline int bcm_usb_endpoint_is_isoc_out(const struct usb_endpoint_descriptor *epd) | ||
516 | { | ||
517 | return (bcm_usb_endpoint_xfer_isoc(epd) && bcm_usb_endpoint_dir_out(epd)); | ||
518 | } | ||
519 | |||
520 | INT InterfaceAdapterInit(PS_INTERFACE_ADAPTER psIntfAdapter) | ||
521 | { | ||
522 | struct usb_host_interface *iface_desc; | ||
523 | struct usb_endpoint_descriptor *endpoint; | ||
524 | size_t buffer_size; | ||
525 | ULONG value; | ||
526 | INT retval = 0; | ||
527 | INT usedIntOutForBulkTransfer = 0 ; | ||
528 | BOOLEAN bBcm16 = FALSE; | ||
529 | UINT uiData = 0; | ||
530 | |||
531 | if(psIntfAdapter == NULL) | ||
532 | { | ||
533 | BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Interface Adapter is NULL"); | ||
534 | return -EINVAL; | ||
535 | } | ||
536 | /* Store the usb dev into interface adapter */ | ||
537 | psIntfAdapter->udev = usb_get_dev(interface_to_usbdev( | ||
538 | psIntfAdapter->interface)); | ||
539 | |||
540 | if((psIntfAdapter->udev->speed == USB_SPEED_HIGH)) | ||
541 | { | ||
542 | psIntfAdapter->bHighSpeedDevice = TRUE ; | ||
543 | BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "MODEM IS CONFIGURED TO HIGH_SPEED "); | ||
544 | } | ||
545 | else | ||
546 | { | ||
547 | psIntfAdapter->bHighSpeedDevice = FALSE ; | ||
548 | BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "MODEM IS CONFIGURED TO FULL_SPEED "); | ||
549 | } | ||
550 | |||
551 | psIntfAdapter->psAdapter->interface_rdm = BcmRDM; | ||
552 | psIntfAdapter->psAdapter->interface_wrm = BcmWRM; | ||
553 | |||
554 | if(rdmalt(psIntfAdapter->psAdapter, CHIP_ID_REG, (PUINT)&(psIntfAdapter->psAdapter->chip_id), sizeof(UINT)) < 0) | ||
555 | { | ||
556 | BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_PRINTK, 0, 0, "CHIP ID Read Failed\n"); | ||
557 | return STATUS_FAILURE; | ||
558 | } | ||
559 | if(0xbece3200==(psIntfAdapter->psAdapter->chip_id&~(0xF0))) | ||
560 | { | ||
561 | psIntfAdapter->psAdapter->chip_id=(psIntfAdapter->psAdapter->chip_id&~(0xF0)); | ||
562 | } | ||
563 | |||
564 | BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "First RDM Chip ID 0x%lx\n", psIntfAdapter->psAdapter->chip_id); | ||
565 | |||
566 | iface_desc = psIntfAdapter->interface->cur_altsetting; | ||
567 | //print_usb_interface_desc(&(iface_desc->desc)); | ||
568 | |||
569 | if(psIntfAdapter->psAdapter->chip_id == T3B) | ||
570 | { | ||
571 | |||
572 | // | ||
573 | //T3B device will have EEPROM,check if EEPROM is proper and BCM16 can be done or not. | ||
574 | // | ||
575 | BeceemEEPROMBulkRead(psIntfAdapter->psAdapter,&uiData,0x0,4); | ||
576 | if(uiData == BECM) | ||
577 | { | ||
578 | bBcm16 = TRUE; | ||
579 | } | ||
580 | BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Number of Altsetting aviailable for This Modem 0x%x\n", psIntfAdapter->interface->num_altsetting); | ||
581 | if(bBcm16 == TRUE) | ||
582 | { | ||
583 | //selecting alternate setting one as a default setting for High Speed modem. | ||
584 | if(psIntfAdapter->bHighSpeedDevice) | ||
585 | retval= usb_set_interface(psIntfAdapter->udev,DEFAULT_SETTING_0,ALTERNATE_SETTING_1); | ||
586 | BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "BCM16 is Applicable on this dongle"); | ||
587 | if(retval || (psIntfAdapter->bHighSpeedDevice == FALSE)) | ||
588 | { | ||
589 | usedIntOutForBulkTransfer = EP2 ; | ||
590 | endpoint = &iface_desc->endpoint[EP2].desc; | ||
591 | BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Interface altsetting got failed or Moemd is configured to FS.hence will work on default setting 0 \n"); | ||
592 | /* | ||
593 | If Modem is high speed device EP2 should be INT OUT End point | ||
594 | If Mode is FS then EP2 should be bulk end point | ||
595 | */ | ||
596 | if(((psIntfAdapter->bHighSpeedDevice ==TRUE ) && (bcm_usb_endpoint_is_int_out(endpoint)== FALSE)) | ||
597 | ||((psIntfAdapter->bHighSpeedDevice == FALSE)&& (bcm_usb_endpoint_is_bulk_out(endpoint)== FALSE))) | ||
598 | { | ||
599 | BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL,"Configuring the EEPROM "); | ||
600 | //change the EP2, EP4 to INT OUT end point | ||
601 | ConfigureEndPointTypesThroughEEPROM(psIntfAdapter->psAdapter); | ||
602 | |||
603 | /* | ||
604 | It resets the device and if any thing gets changed in USB descriptor it will show fail and | ||
605 | re-enumerate the device | ||
606 | */ | ||
607 | retval = usb_reset_device(psIntfAdapter->udev); | ||
608 | if(retval) | ||
609 | { | ||
610 | BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "reset got failed. hence Re-enumerating the device \n"); | ||
611 | return retval ; | ||
612 | } | ||
613 | |||
614 | } | ||
615 | if((psIntfAdapter->bHighSpeedDevice == FALSE) && bcm_usb_endpoint_is_bulk_out(endpoint)) | ||
616 | { | ||
617 | // Once BULK is selected in FS mode. Revert it back to INT. Else USB_IF will fail. | ||
618 | UINT uiData = ntohl(EP2_CFG_INT); | ||
619 | BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL,"Reverting Bulk to INT as it is FS MODE"); | ||
620 | BeceemEEPROMBulkWrite(psIntfAdapter->psAdapter,(PUCHAR)&uiData,0x136,4,TRUE); | ||
621 | } | ||
622 | } | ||
623 | else | ||
624 | { | ||
625 | usedIntOutForBulkTransfer = EP4 ; | ||
626 | endpoint = &iface_desc->endpoint[EP4].desc; | ||
627 | BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Choosing AltSetting as a default setting"); | ||
628 | if( bcm_usb_endpoint_is_int_out(endpoint) == FALSE) | ||
629 | { | ||
630 | BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, " Dongle does not have BCM16 Fix"); | ||
631 | //change the EP2, EP4 to INT OUT end point and use EP4 in altsetting | ||
632 | ConfigureEndPointTypesThroughEEPROM(psIntfAdapter->psAdapter); | ||
633 | |||
634 | /* | ||
635 | It resets the device and if any thing gets changed in USB descriptor it will show fail and | ||
636 | re-enumerate the device | ||
637 | */ | ||
638 | retval = usb_reset_device(psIntfAdapter->udev); | ||
639 | if(retval) | ||
640 | { | ||
641 | BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "reset got failed. hence Re-enumerating the device \n"); | ||
642 | return retval ; | ||
643 | } | ||
644 | |||
645 | } | ||
646 | } | ||
647 | } | ||
648 | } | ||
649 | |||
650 | iface_desc = psIntfAdapter->interface->cur_altsetting; | ||
651 | //print_usb_interface_desc(&(iface_desc->desc)); | ||
652 | BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_PRINTK, 0, 0, "Current number of endpoints :%x \n", iface_desc->desc.bNumEndpoints); | ||
653 | for (value = 0; value < iface_desc->desc.bNumEndpoints; ++value) | ||
654 | { | ||
655 | endpoint = &iface_desc->endpoint[value].desc; | ||
656 | //print_usb_endpoint_descriptor(endpoint); | ||
657 | |||
658 | if (!psIntfAdapter->sBulkIn.bulk_in_endpointAddr && bcm_usb_endpoint_is_bulk_in(endpoint)) | ||
659 | { | ||
660 | buffer_size = le16_to_cpu(endpoint->wMaxPacketSize); | ||
661 | psIntfAdapter->sBulkIn.bulk_in_size = buffer_size; | ||
662 | psIntfAdapter->sBulkIn.bulk_in_endpointAddr = | ||
663 | endpoint->bEndpointAddress; | ||
664 | psIntfAdapter->sBulkIn.bulk_in_pipe = | ||
665 | usb_rcvbulkpipe(psIntfAdapter->udev, | ||
666 | psIntfAdapter->sBulkIn.bulk_in_endpointAddr); | ||
667 | } | ||
668 | |||
669 | if (!psIntfAdapter->sBulkOut.bulk_out_endpointAddr && bcm_usb_endpoint_is_bulk_out(endpoint)) | ||
670 | { | ||
671 | |||
672 | psIntfAdapter->sBulkOut.bulk_out_endpointAddr = | ||
673 | endpoint->bEndpointAddress; | ||
674 | psIntfAdapter->sBulkOut.bulk_out_pipe = | ||
675 | usb_sndbulkpipe(psIntfAdapter->udev, | ||
676 | psIntfAdapter->sBulkOut.bulk_out_endpointAddr); | ||
677 | } | ||
678 | |||
679 | if (!psIntfAdapter->sIntrIn.int_in_endpointAddr && bcm_usb_endpoint_is_int_in(endpoint)) | ||
680 | { | ||
681 | buffer_size = le16_to_cpu(endpoint->wMaxPacketSize); | ||
682 | psIntfAdapter->sIntrIn.int_in_size = buffer_size; | ||
683 | psIntfAdapter->sIntrIn.int_in_endpointAddr = | ||
684 | endpoint->bEndpointAddress; | ||
685 | psIntfAdapter->sIntrIn.int_in_interval = endpoint->bInterval; | ||
686 | psIntfAdapter->sIntrIn.int_in_buffer = | ||
687 | kmalloc(buffer_size, GFP_KERNEL); | ||
688 | if (!psIntfAdapter->sIntrIn.int_in_buffer) { | ||
689 | BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Could not allocate interrupt_in_buffer"); | ||
690 | return -EINVAL; | ||
691 | } | ||
692 | //psIntfAdapter->sIntrIn.int_in_pipe = | ||
693 | } | ||
694 | |||
695 | if (!psIntfAdapter->sIntrOut.int_out_endpointAddr && bcm_usb_endpoint_is_int_out(endpoint)) | ||
696 | { | ||
697 | |||
698 | if( !psIntfAdapter->sBulkOut.bulk_out_endpointAddr && | ||
699 | (psIntfAdapter->psAdapter->chip_id == T3B) && (value == usedIntOutForBulkTransfer)) | ||
700 | { | ||
701 | //use first intout end point as a bulk out end point | ||
702 | buffer_size = le16_to_cpu(endpoint->wMaxPacketSize); | ||
703 | psIntfAdapter->sBulkOut.bulk_out_size = buffer_size; | ||
704 | //printk("\nINT OUT Endpoing buffer size :%x endpoint :%x\n", buffer_size, value +1); | ||
705 | psIntfAdapter->sBulkOut.bulk_out_endpointAddr = | ||
706 | endpoint->bEndpointAddress; | ||
707 | psIntfAdapter->sBulkOut.bulk_out_pipe = | ||
708 | usb_sndintpipe(psIntfAdapter->udev, | ||
709 | psIntfAdapter->sBulkOut.bulk_out_endpointAddr); | ||
710 | psIntfAdapter->sBulkOut.int_out_interval = endpoint->bInterval; | ||
711 | |||
712 | } | ||
713 | else if(value == EP6) | ||
714 | { | ||
715 | buffer_size = le16_to_cpu(endpoint->wMaxPacketSize); | ||
716 | psIntfAdapter->sIntrOut.int_out_size = buffer_size; | ||
717 | psIntfAdapter->sIntrOut.int_out_endpointAddr = | ||
718 | endpoint->bEndpointAddress; | ||
719 | psIntfAdapter->sIntrOut.int_out_interval = endpoint->bInterval; | ||
720 | psIntfAdapter->sIntrOut.int_out_buffer= kmalloc(buffer_size, | ||
721 | GFP_KERNEL); | ||
722 | if (!psIntfAdapter->sIntrOut.int_out_buffer) | ||
723 | { | ||
724 | BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Could not allocate interrupt_out_buffer"); | ||
725 | return -EINVAL; | ||
726 | } | ||
727 | } | ||
728 | } | ||
729 | } | ||
730 | usb_set_intfdata(psIntfAdapter->interface, psIntfAdapter); | ||
731 | retval = usb_register_dev(psIntfAdapter->interface, &usbbcm_class); | ||
732 | if(retval) | ||
733 | { | ||
734 | BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_PRINTK, 0, 0, "usb register dev failed = %d", retval); | ||
735 | psIntfAdapter->psAdapter->bUsbClassDriverRegistered = FALSE; | ||
736 | return retval; | ||
737 | } | ||
738 | else | ||
739 | { | ||
740 | psIntfAdapter->psAdapter->bUsbClassDriverRegistered = TRUE; | ||
741 | BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_PRINTK, 0, 0, "usb dev registered"); | ||
742 | } | ||
743 | |||
744 | psIntfAdapter->psAdapter->bcm_file_download = InterfaceFileDownload; | ||
745 | psIntfAdapter->psAdapter->bcm_file_readback_from_chip = | ||
746 | InterfaceFileReadbackFromChip; | ||
747 | psIntfAdapter->psAdapter->interface_transmit = InterfaceTransmitPacket; | ||
748 | |||
749 | retval = CreateInterruptUrb(psIntfAdapter); | ||
750 | |||
751 | if(retval) | ||
752 | { | ||
753 | BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_PRINTK, 0, 0, "Cannot create interrupt urb"); | ||
754 | return retval; | ||
755 | } | ||
756 | |||
757 | retval = AllocUsbCb(psIntfAdapter); | ||
758 | if(retval) | ||
759 | { | ||
760 | return retval; | ||
761 | } | ||
762 | |||
763 | |||
764 | retval = device_run(psIntfAdapter); | ||
765 | if(retval) | ||
766 | { | ||
767 | return retval; | ||
768 | } | ||
769 | |||
770 | |||
771 | return 0; | ||
772 | } | ||
773 | int InterfaceSuspend (struct usb_interface *intf, pm_message_t message) | ||
774 | { | ||
775 | PS_INTERFACE_ADAPTER psIntfAdapter = usb_get_intfdata(intf); | ||
776 | BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "=================================\n"); | ||
777 | //Bcm_kill_all_URBs(psIntfAdapter); | ||
778 | psIntfAdapter->bSuspended = TRUE; | ||
779 | |||
780 | if(TRUE == psIntfAdapter->bPreparingForBusSuspend) | ||
781 | { | ||
782 | psIntfAdapter->bPreparingForBusSuspend = FALSE; | ||
783 | |||
784 | if(psIntfAdapter->psAdapter->LinkStatus == LINKUP_DONE) | ||
785 | { | ||
786 | psIntfAdapter->psAdapter->IdleMode = TRUE ; | ||
787 | BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Host Entered in PMU Idle Mode.."); | ||
788 | } | ||
789 | else | ||
790 | { | ||
791 | psIntfAdapter->psAdapter->bShutStatus = TRUE; | ||
792 | BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Host Entered in PMU Shutdown Mode.."); | ||
793 | } | ||
794 | } | ||
795 | psIntfAdapter->psAdapter->bPreparingForLowPowerMode = FALSE; | ||
796 | |||
797 | //Signaling the control pkt path | ||
798 | wake_up(&psIntfAdapter->psAdapter->lowpower_mode_wait_queue); | ||
799 | |||
800 | return 0; | ||
801 | } | ||
802 | int InterfaceResume (struct usb_interface *intf) | ||
803 | { | ||
804 | PS_INTERFACE_ADAPTER psIntfAdapter = usb_get_intfdata(intf); | ||
805 | printk("=================================\n"); | ||
806 | mdelay(100); | ||
807 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 32) | ||
808 | intf->pm_usage_cnt =1 ; | ||
809 | #endif | ||
810 | psIntfAdapter->bSuspended = FALSE; | ||
811 | |||
812 | StartInterruptUrb(psIntfAdapter); | ||
813 | InterfaceRx(psIntfAdapter); | ||
814 | return 0; | ||
815 | } | ||
816 | int InterfacePreReset(struct usb_interface *intf) | ||
817 | { | ||
818 | printk("====================>"); | ||
819 | return STATUS_SUCCESS; | ||
820 | } | ||
821 | int InterfacePostReset(struct usb_interface *intf) | ||
822 | { | ||
823 | printk("Do Post chip reset setting here if it is required"); | ||
824 | return STATUS_SUCCESS; | ||
825 | } | ||
826 | static struct usb_driver usbbcm_driver = { | ||
827 | .name = "usbbcm", | ||
828 | .probe = usbbcm_device_probe, | ||
829 | .disconnect = usbbcm_disconnect, | ||
830 | .suspend = InterfaceSuspend, | ||
831 | .resume = InterfaceResume, | ||
832 | .pre_reset=InterfacePreReset, | ||
833 | .post_reset=InterfacePostReset, | ||
834 | .id_table = InterfaceUsbtable, | ||
835 | .supports_autosuspend = 1, | ||
836 | }; | ||
837 | |||
838 | |||
839 | /* | ||
840 | Function: InterfaceInitialize | ||
841 | |||
842 | Description: This is the hardware specific initialization Function. | ||
843 | Registering the driver with NDIS , other device specific NDIS | ||
844 | and hardware initializations are done here. | ||
845 | |||
846 | Input parameters: IN PMINI_ADAPTER Adapter - Miniport Adapter Context | ||
847 | |||
848 | |||
849 | Return: BCM_STATUS_SUCCESS - If Initialization of the | ||
850 | HW Interface was successful. | ||
851 | Other - If an error occured. | ||
852 | */ | ||
853 | INT InterfaceInitialize(void) | ||
854 | { | ||
855 | // BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Registering Usb driver!!"); | ||
856 | return usb_register(&usbbcm_driver); | ||
857 | } | ||
858 | |||
859 | INT InterfaceExit(void) | ||
860 | { | ||
861 | //PMINI_ADAPTER psAdapter = NULL; | ||
862 | int status = 0; | ||
863 | |||
864 | //BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Deregistering Usb driver!!"); | ||
865 | usb_deregister(&usbbcm_driver); | ||
866 | return status; | ||
867 | } | ||
868 | MODULE_LICENSE ("GPL"); | ||