Version:  2.0.40 2.2.26 2.4.37 2.6.39 3.0 3.1 3.2 3.3 3.4 3.5 3.6 3.7 3.8 3.9 3.10 3.11 3.12 3.13 3.14 3.15

Linux/drivers/staging/bcm/InterfaceInit.c

  1 #include "headers.h"
  2 #include <linux/usb/ch9.h>
  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_T3, BCM_USB_PRODUCT_ID_SYM) },
  8         { USB_DEVICE(BCM_USB_VENDOR_ID_ZTE, BCM_USB_PRODUCT_ID_226) },
  9         { USB_DEVICE(BCM_USB_VENDOR_ID_FOXCONN, BCM_USB_PRODUCT_ID_1901) },
 10         { USB_DEVICE(BCM_USB_VENDOR_ID_ZTE, BCM_USB_PRODUCT_ID_ZTE_TU25) },
 11         { USB_DEVICE(BCM_USB_VENDOR_ID_ZTE, BCM_USB_PRODUCT_ID_ZTE_226) },
 12         { USB_DEVICE(BCM_USB_VENDOR_ID_ZTE, BCM_USB_PRODUCT_ID_ZTE_326) },
 13         { }
 14 };
 15 MODULE_DEVICE_TABLE(usb, InterfaceUsbtable);
 16 
 17 static int debug = -1;
 18 module_param(debug, uint, 0600);
 19 MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)");
 20 
 21 static const u32 default_msg =
 22         NETIF_MSG_DRV | NETIF_MSG_PROBE | NETIF_MSG_LINK
 23         | NETIF_MSG_TIMER | NETIF_MSG_TX_ERR | NETIF_MSG_RX_ERR
 24         | NETIF_MSG_IFUP | NETIF_MSG_IFDOWN;
 25 
 26 static int InterfaceAdapterInit(struct bcm_interface_adapter *Adapter);
 27 
 28 static void InterfaceAdapterFree(struct bcm_interface_adapter *psIntfAdapter)
 29 {
 30         int i = 0;
 31 
 32         /* Wake up the wait_queue... */
 33         if (psIntfAdapter->psAdapter->LEDInfo.led_thread_running &
 34                         BCM_LED_THREAD_RUNNING_ACTIVELY) {
 35                 psIntfAdapter->psAdapter->DriverState = DRIVER_HALT;
 36                 wake_up(&psIntfAdapter->psAdapter->LEDInfo.notify_led_event);
 37         }
 38         reset_card_proc(psIntfAdapter->psAdapter);
 39 
 40         /*
 41          * worst case time taken by the RDM/WRM will be 5 sec. will check after
 42          * every 100 ms to accertain the device is not being accessed. After
 43          * this No RDM/WRM should be made.
 44          */
 45         while (psIntfAdapter->psAdapter->DeviceAccess) {
 46                 BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_INITEXIT,
 47                                 DRV_ENTRY, DBG_LVL_ALL,
 48                                 "Device is being accessed.\n");
 49                 msleep(100);
 50         }
 51         /* Free interrupt URB */
 52         /* psIntfAdapter->psAdapter->device_removed = TRUE; */
 53         usb_free_urb(psIntfAdapter->psInterruptUrb);
 54 
 55         /* Free transmit URBs */
 56         for (i = 0; i < MAXIMUM_USB_TCB; i++) {
 57                 if (psIntfAdapter->asUsbTcb[i].urb  != NULL) {
 58                         usb_free_urb(psIntfAdapter->asUsbTcb[i].urb);
 59                         psIntfAdapter->asUsbTcb[i].urb = NULL;
 60                 }
 61         }
 62         /* Free receive URB and buffers */
 63         for (i = 0; i < MAXIMUM_USB_RCB; i++) {
 64                 if (psIntfAdapter->asUsbRcb[i].urb != NULL) {
 65                         kfree(psIntfAdapter->asUsbRcb[i].urb->transfer_buffer);
 66                         usb_free_urb(psIntfAdapter->asUsbRcb[i].urb);
 67                         psIntfAdapter->asUsbRcb[i].urb = NULL;
 68                 }
 69         }
 70         AdapterFree(psIntfAdapter->psAdapter);
 71 }
 72 
 73 static void ConfigureEndPointTypesThroughEEPROM(struct bcm_mini_adapter *Adapter)
 74 {
 75         u32 ulReg;
 76         int bytes;
 77         struct bcm_interface_adapter *interfaceAdapter;
 78 
 79         /* Program EP2 MAX_PKT_SIZE */
 80         ulReg = ntohl(EP2_MPS_REG);
 81         BeceemEEPROMBulkWrite(Adapter, (PUCHAR)&ulReg, 0x128, 4, TRUE);
 82         ulReg = ntohl(EP2_MPS);
 83         BeceemEEPROMBulkWrite(Adapter, (PUCHAR)&ulReg, 0x12C, 4, TRUE);
 84 
 85         ulReg = ntohl(EP2_CFG_REG);
 86         BeceemEEPROMBulkWrite(Adapter, (PUCHAR)&ulReg, 0x132, 4, TRUE);
 87         interfaceAdapter =
 88                 (struct bcm_interface_adapter *)(Adapter->pvInterfaceAdapter);
 89         if (interfaceAdapter->bHighSpeedDevice) {
 90                 ulReg = ntohl(EP2_CFG_INT);
 91                 BeceemEEPROMBulkWrite(Adapter, (PUCHAR)&ulReg, 0x136, 4, TRUE);
 92         } else {
 93                 /* USE BULK EP as TX in FS mode. */
 94                 ulReg = ntohl(EP2_CFG_BULK);
 95                 BeceemEEPROMBulkWrite(Adapter, (PUCHAR)&ulReg, 0x136, 4, TRUE);
 96         }
 97 
 98         /* Program EP4 MAX_PKT_SIZE. */
 99         ulReg = ntohl(EP4_MPS_REG);
100         BeceemEEPROMBulkWrite(Adapter, (PUCHAR)&ulReg, 0x13C, 4, TRUE);
101         ulReg = ntohl(EP4_MPS);
102         BeceemEEPROMBulkWrite(Adapter, (PUCHAR)&ulReg, 0x140, 4, TRUE);
103 
104         /* Program TX EP as interrupt(Alternate Setting) */
105         bytes = rdmalt(Adapter, 0x0F0110F8, &ulReg, sizeof(u32));
106         if (bytes < 0) {
107                 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, DRV_ENTRY,
108                                 DBG_LVL_ALL, "reading of Tx EP failed\n");
109                 return;
110         }
111         ulReg |= 0x6;
112 
113         ulReg = ntohl(ulReg);
114         BeceemEEPROMBulkWrite(Adapter, (PUCHAR)&ulReg, 0x1CC, 4, TRUE);
115 
116         ulReg = ntohl(EP4_CFG_REG);
117         BeceemEEPROMBulkWrite(Adapter, (PUCHAR)&ulReg, 0x1C8, 4, TRUE);
118         /* Program ISOCHRONOUS EP size to zero. */
119         ulReg = ntohl(ISO_MPS_REG);
120         BeceemEEPROMBulkWrite(Adapter, (PUCHAR)&ulReg, 0x1D2, 4, TRUE);
121         ulReg = ntohl(ISO_MPS);
122         BeceemEEPROMBulkWrite(Adapter, (PUCHAR)&ulReg, 0x1D6, 4, TRUE);
123 
124         /*
125          * Update EEPROM Version.
126          * Read 4 bytes from 508 and modify 511 and 510.
127          */
128         ReadBeceemEEPROM(Adapter, 0x1FC, &ulReg);
129         ulReg &= 0x0101FFFF;
130         BeceemEEPROMBulkWrite(Adapter, (PUCHAR)&ulReg, 0x1FC, 4, TRUE);
131 
132         /* Update length field if required. Also make the string NULL terminated. */
133 
134         ReadBeceemEEPROM(Adapter, 0xA8, &ulReg);
135         if ((ulReg&0x00FF0000)>>16 > 0x30) {
136                 ulReg = (ulReg&0xFF00FFFF)|(0x30<<16);
137                 BeceemEEPROMBulkWrite(Adapter, (PUCHAR)&ulReg, 0xA8, 4, TRUE);
138         }
139         ReadBeceemEEPROM(Adapter, 0x148, &ulReg);
140         if ((ulReg&0x00FF0000)>>16 > 0x30) {
141                 ulReg = (ulReg&0xFF00FFFF)|(0x30<<16);
142                 BeceemEEPROMBulkWrite(Adapter, (PUCHAR)&ulReg, 0x148, 4, TRUE);
143         }
144         ulReg = 0;
145         BeceemEEPROMBulkWrite(Adapter, (PUCHAR)&ulReg, 0x122, 4, TRUE);
146         ulReg = 0;
147         BeceemEEPROMBulkWrite(Adapter, (PUCHAR)&ulReg, 0x1C2, 4, TRUE);
148 }
149 
150 static int usbbcm_device_probe(struct usb_interface *intf, const struct usb_device_id *id)
151 {
152         struct usb_device *udev = interface_to_usbdev(intf);
153         int retval;
154         struct bcm_mini_adapter *psAdapter;
155         struct bcm_interface_adapter *psIntfAdapter;
156         struct net_device *ndev;
157 
158         /* Reserve one extra queue for the bit-bucket */
159         ndev = alloc_etherdev_mq(sizeof(struct bcm_mini_adapter),
160                         NO_OF_QUEUES + 1);
161         if (ndev == NULL) {
162                 dev_err(&udev->dev, DRV_NAME ": no memory for device\n");
163                 return -ENOMEM;
164         }
165 
166         SET_NETDEV_DEV(ndev, &intf->dev);
167 
168         psAdapter = netdev_priv(ndev);
169         psAdapter->dev = ndev;
170         psAdapter->msg_enable = netif_msg_init(debug, default_msg);
171 
172         /* Init default driver debug state */
173 
174         psAdapter->stDebugState.debug_level = DBG_LVL_CURR;
175         psAdapter->stDebugState.type = DBG_TYPE_INITEXIT;
176 
177         /*
178          * Technically, one can start using BCM_DEBUG_PRINT after this point.
179          * However, realize that by default the Type/Subtype bitmaps are all
180          * zero now; so no prints will actually appear until the TestApp turns
181          * on debug paths via the ioctl(); so practically speaking, in early
182          * init, no logging happens.
183          *
184          * A solution (used below): we explicitly set the bitmaps to 1 for
185          * Type=DBG_TYPE_INITEXIT and ALL subtype's of the same. Now all bcm
186          * debug statements get logged, enabling debug during early init.
187          * Further, we turn this OFF once init_module() completes.
188          */
189 
190         psAdapter->stDebugState.subtype[DBG_TYPE_INITEXIT] = 0xff;
191         BCM_SHOW_DEBUG_BITMAP(psAdapter);
192 
193         retval = InitAdapter(psAdapter);
194         if (retval) {
195                 dev_err(&udev->dev, DRV_NAME ": InitAdapter Failed\n");
196                 AdapterFree(psAdapter);
197                 return retval;
198         }
199 
200         /* Allocate interface adapter structure */
201         psIntfAdapter = kzalloc(sizeof(struct bcm_interface_adapter),
202                         GFP_KERNEL);
203         if (psIntfAdapter == NULL) {
204                 AdapterFree(psAdapter);
205                 return -ENOMEM;
206         }
207 
208         psAdapter->pvInterfaceAdapter = psIntfAdapter;
209         psIntfAdapter->psAdapter = psAdapter;
210 
211         /* Store usb interface in Interface Adapter */
212         psIntfAdapter->interface = intf;
213         usb_set_intfdata(intf, psIntfAdapter);
214 
215         BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL,
216                         "psIntfAdapter 0x%p\n", psIntfAdapter);
217         retval = InterfaceAdapterInit(psIntfAdapter);
218         if (retval) {
219                 /* If the Firmware/Cfg File is not present
220                  * then return success, let the application
221                  * download the files.
222                  */
223                 if (-ENOENT == retval) {
224                         BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_INITEXIT, DRV_ENTRY,
225                                         DBG_LVL_ALL,
226                                         "File Not Found.  Use app to download.\n");
227                         return STATUS_SUCCESS;
228                 }
229                 BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_INITEXIT, DRV_ENTRY,
230                                 DBG_LVL_ALL, "InterfaceAdapterInit failed.\n");
231                 usb_set_intfdata(intf, NULL);
232                 udev = interface_to_usbdev(intf);
233                 usb_put_dev(udev);
234                 InterfaceAdapterFree(psIntfAdapter);
235                 return retval;
236         }
237         if (psAdapter->chip_id > T3) {
238                 uint32_t uiNackZeroLengthInt = 4;
239 
240                 retval =
241                         wrmalt(psAdapter, DISABLE_USB_ZERO_LEN_INT,
242                                         &uiNackZeroLengthInt,
243                                         sizeof(uiNackZeroLengthInt));
244                 if (retval)
245                         return retval;
246         }
247 
248         /* Check whether the USB-Device Supports remote Wake-Up */
249         if (USB_CONFIG_ATT_WAKEUP & udev->actconfig->desc.bmAttributes) {
250                 /* If Suspend then only support dynamic suspend */
251                 if (psAdapter->bDoSuspend) {
252 #ifdef CONFIG_PM
253                         pm_runtime_set_autosuspend_delay(&udev->dev, 0);
254                         intf->needs_remote_wakeup = 1;
255                         usb_enable_autosuspend(udev);
256                         device_init_wakeup(&intf->dev, 1);
257                         INIT_WORK(&psIntfAdapter->usbSuspendWork,
258                                         putUsbSuspend);
259                         BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_INITEXIT, DRV_ENTRY,
260                                         DBG_LVL_ALL,
261                                         "Enabling USB Auto-Suspend\n");
262 #endif
263                 } else {
264                         intf->needs_remote_wakeup = 0;
265                         usb_disable_autosuspend(udev);
266                 }
267         }
268 
269         psAdapter->stDebugState.subtype[DBG_TYPE_INITEXIT] = 0x0;
270         return retval;
271 }
272 
273 static void usbbcm_disconnect(struct usb_interface *intf)
274 {
275         struct bcm_interface_adapter *psIntfAdapter = usb_get_intfdata(intf);
276         struct bcm_mini_adapter *psAdapter;
277         struct usb_device  *udev = interface_to_usbdev(intf);
278 
279         if (psIntfAdapter == NULL)
280                 return;
281 
282         psAdapter = psIntfAdapter->psAdapter;
283         netif_device_detach(psAdapter->dev);
284 
285         if (psAdapter->bDoSuspend)
286                 intf->needs_remote_wakeup = 0;
287 
288         psAdapter->device_removed = TRUE;
289         usb_set_intfdata(intf, NULL);
290         InterfaceAdapterFree(psIntfAdapter);
291         usb_put_dev(udev);
292 }
293 
294 static int AllocUsbCb(struct bcm_interface_adapter *psIntfAdapter)
295 {
296         int i = 0;
297 
298         for (i = 0; i < MAXIMUM_USB_TCB; i++) {
299                 psIntfAdapter->asUsbTcb[i].urb = usb_alloc_urb(0, GFP_KERNEL);
300 
301                 if (psIntfAdapter->asUsbTcb[i].urb == NULL) {
302                         BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,
303                                         DBG_TYPE_PRINTK, 0, 0,
304                                         "Can't allocate Tx urb for index %d\n",
305                                         i);
306                         return -ENOMEM;
307                 }
308         }
309 
310         for (i = 0; i < MAXIMUM_USB_RCB; i++) {
311                 psIntfAdapter->asUsbRcb[i].urb = usb_alloc_urb(0, GFP_KERNEL);
312 
313                 if (psIntfAdapter->asUsbRcb[i].urb == NULL) {
314                         BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,
315                                         DBG_TYPE_PRINTK, 0, 0,
316                                         "Can't allocate Rx urb for index %d\n",
317                                         i);
318                         return -ENOMEM;
319                 }
320 
321                 psIntfAdapter->asUsbRcb[i].urb->transfer_buffer =
322                         kmalloc(MAX_DATA_BUFFER_SIZE, GFP_KERNEL);
323 
324                 if (psIntfAdapter->asUsbRcb[i].urb->transfer_buffer == NULL) {
325                         BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,
326                                         DBG_TYPE_PRINTK, 0, 0,
327                                         "Can't allocate Rx buffer for index %d\n",
328                                         i);
329                         return -ENOMEM;
330                 }
331                 psIntfAdapter->asUsbRcb[i].urb->transfer_buffer_length =
332                         MAX_DATA_BUFFER_SIZE;
333         }
334         return 0;
335 }
336 
337 static int device_run(struct bcm_interface_adapter *psIntfAdapter)
338 {
339         int value = 0;
340         UINT status = STATUS_SUCCESS;
341 
342         status = InitCardAndDownloadFirmware(psIntfAdapter->psAdapter);
343         if (status != STATUS_SUCCESS) {
344                 pr_err(DRV_NAME "InitCardAndDownloadFirmware failed.\n");
345                 return status;
346         }
347         if (psIntfAdapter->psAdapter->fw_download_done) {
348                 if (StartInterruptUrb(psIntfAdapter)) {
349                         BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,
350                                         DBG_TYPE_INITEXIT, DRV_ENTRY,
351                                         DBG_LVL_ALL,
352                                         "Cannot send interrupt in URB\n");
353                 }
354 
355                 /*
356                  * now register the cntrl interface.  after downloading the f/w
357                  * waiting for 5 sec to get the mailbox interrupt.
358                  */
359                 psIntfAdapter->psAdapter->waiting_to_fw_download_done = false;
360                 value = wait_event_timeout(
361                                 psIntfAdapter->psAdapter->ioctl_fw_dnld_wait_queue,
362                                 psIntfAdapter->psAdapter->waiting_to_fw_download_done,
363                                 5 * HZ);
364 
365                 if (value == 0)
366                         pr_err(DRV_NAME ": Timeout waiting for mailbox interrupt.\n");
367 
368                 if (register_control_device_interface(
369                                         psIntfAdapter->psAdapter) < 0) {
370                         pr_err(DRV_NAME ": Register Control Device failed.\n");
371                         return -EIO;
372                 }
373         }
374         return 0;
375 }
376 
377 static int InterfaceAdapterInit(struct bcm_interface_adapter *psIntfAdapter)
378 {
379         struct usb_host_interface *iface_desc;
380         struct usb_endpoint_descriptor *endpoint;
381         size_t buffer_size;
382         unsigned long value;
383         int retval = 0;
384         int usedIntOutForBulkTransfer = 0;
385         bool bBcm16 = false;
386         UINT uiData = 0;
387         int bytes;
388 
389         /* Store the usb dev into interface adapter */
390         psIntfAdapter->udev =
391                 usb_get_dev(interface_to_usbdev(psIntfAdapter->interface));
392 
393         psIntfAdapter->bHighSpeedDevice =
394                 (psIntfAdapter->udev->speed == USB_SPEED_HIGH);
395         psIntfAdapter->psAdapter->interface_rdm = BcmRDM;
396         psIntfAdapter->psAdapter->interface_wrm = BcmWRM;
397 
398         bytes = rdmalt(psIntfAdapter->psAdapter, CHIP_ID_REG,
399                         (u32 *) &(psIntfAdapter->psAdapter->chip_id),
400                         sizeof(u32));
401         if (bytes < 0) {
402                 retval = bytes;
403                 BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_PRINTK, 0, 0,
404                                 "CHIP ID Read Failed\n");
405                 return retval;
406         }
407 
408         if (0xbece3200 == (psIntfAdapter->psAdapter->chip_id & ~(0xF0)))
409                 psIntfAdapter->psAdapter->chip_id &= ~0xF0;
410 
411         dev_info(&psIntfAdapter->udev->dev, "RDM Chip ID 0x%lx\n",
412                         psIntfAdapter->psAdapter->chip_id);
413 
414         iface_desc = psIntfAdapter->interface->cur_altsetting;
415 
416         if (psIntfAdapter->psAdapter->chip_id == T3B) {
417                 /* T3B device will have EEPROM, check if EEPROM is proper and
418                  * BCM16 can be done or not. */
419                 BeceemEEPROMBulkRead(psIntfAdapter->psAdapter, &uiData, 0x0, 4);
420                 if (uiData == BECM)
421                         bBcm16 = TRUE;
422 
423                 dev_info(&psIntfAdapter->udev->dev,
424                                 "number of alternate setting %d\n",
425                                 psIntfAdapter->interface->num_altsetting);
426 
427                 if (bBcm16 == TRUE) {
428                         /* selecting alternate setting one as a default setting
429                          * for High Speed  modem. */
430                         if (psIntfAdapter->bHighSpeedDevice)
431                                 retval = usb_set_interface(psIntfAdapter->udev,
432                                                 DEFAULT_SETTING_0,
433                                                 ALTERNATE_SETTING_1);
434                         BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,
435                                         DBG_TYPE_INITEXIT, DRV_ENTRY,
436                                         DBG_LVL_ALL,
437                                         "BCM16 is applicable on this dongle\n");
438                         if (retval || !psIntfAdapter->bHighSpeedDevice) {
439                                 usedIntOutForBulkTransfer = EP2;
440                                 endpoint = &iface_desc->endpoint[EP2].desc;
441                                 BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,
442                                                 DBG_TYPE_INITEXIT, DRV_ENTRY,
443                                                 DBG_LVL_ALL,
444                                                 "Interface altsetting failed or modem is configured to Full Speed, hence will work on default setting 0\n");
445                                 /*
446                                  * If Modem is high speed device EP2 should be
447                                  * INT OUT End point
448                                  *
449                                  * If Mode is FS then EP2 should be bulk end
450                                  * point
451                                  */
452                                 if ((psIntfAdapter->bHighSpeedDevice &&
453                                                         !usb_endpoint_is_int_out(endpoint)) ||
454                                                 (!psIntfAdapter->bHighSpeedDevice &&
455                                                  !usb_endpoint_is_bulk_out(endpoint))) {
456                                         BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,
457                                                         DBG_TYPE_INITEXIT,
458                                                         DRV_ENTRY, DBG_LVL_ALL,
459                                                         "Configuring the EEPROM\n");
460                                         /* change the EP2, EP4 to INT OUT end point */
461                                         ConfigureEndPointTypesThroughEEPROM(
462                                                         psIntfAdapter->psAdapter);
463 
464                                         /*
465                                          * It resets the device and if any thing
466                                          * gets changed in USB descriptor it
467                                          * will show fail and re-enumerate the
468                                          * device
469                                          */
470                                         retval = usb_reset_device(
471                                                         psIntfAdapter->udev);
472                                         if (retval) {
473                                                 BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,
474                                                                 DBG_TYPE_INITEXIT,
475                                                                 DRV_ENTRY,
476                                                                 DBG_LVL_ALL,
477                                                                 "reset failed.  Re-enumerating the device.\n");
478                                                 return retval;
479                                         }
480 
481                                 }
482                                 if (!psIntfAdapter->bHighSpeedDevice &&
483                                     usb_endpoint_is_bulk_out(endpoint)) {
484                                         /* Once BULK is selected in FS mode. Revert it back to INT. Else USB_IF will fail. */
485                                         UINT _uiData = ntohl(EP2_CFG_INT);
486                                         BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,
487                                                         DBG_TYPE_INITEXIT,
488                                                         DRV_ENTRY, DBG_LVL_ALL,
489                                                         "Reverting Bulk to INT as it is in Full Speed mode.\n");
490                                         BeceemEEPROMBulkWrite(
491                                                         psIntfAdapter->psAdapter,
492                                                         (PUCHAR) & _uiData,
493                                                         0x136, 4, TRUE);
494                                 }
495                         } else {
496                                 usedIntOutForBulkTransfer = EP4;
497                                 endpoint = &iface_desc->endpoint[EP4].desc;
498                                 BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,
499                                                 DBG_TYPE_INITEXIT, DRV_ENTRY,
500                                                 DBG_LVL_ALL,
501                                                 "Choosing AltSetting as a default setting.\n");
502                                 if (!usb_endpoint_is_int_out(endpoint)) {
503                                         BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,
504                                                         DBG_TYPE_INITEXIT,
505                                                         DRV_ENTRY, DBG_LVL_ALL,
506                                                         "Dongle does not have BCM16 Fix.\n");
507                                         /* change the EP2, EP4 to INT OUT end point and use EP4 in altsetting */
508                                         ConfigureEndPointTypesThroughEEPROM(
509                                                         psIntfAdapter->psAdapter);
510 
511                                         /*
512                                          * It resets the device and if any thing
513                                          * gets changed in USB descriptor it
514                                          * will show fail and re-enumerate the
515                                          * device
516                                          */
517                                         retval = usb_reset_device(
518                                                         psIntfAdapter->udev);
519                                         if (retval) {
520                                                 BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,
521                                                                 DBG_TYPE_INITEXIT,
522                                                                 DRV_ENTRY,
523                                                                 DBG_LVL_ALL,
524                                                                 "reset failed.  Re-enumerating the device.\n");
525                                                 return retval;
526                                         }
527 
528                                 }
529                         }
530                 }
531         }
532 
533         iface_desc = psIntfAdapter->interface->cur_altsetting;
534 
535         for (value = 0; value < iface_desc->desc.bNumEndpoints; ++value) {
536                 endpoint = &iface_desc->endpoint[value].desc;
537 
538                 if (!psIntfAdapter->sBulkIn.bulk_in_endpointAddr &&
539                                 usb_endpoint_is_bulk_in(endpoint)) {
540                         buffer_size = le16_to_cpu(endpoint->wMaxPacketSize);
541                         psIntfAdapter->sBulkIn.bulk_in_size = buffer_size;
542                         psIntfAdapter->sBulkIn.bulk_in_endpointAddr =
543                                 endpoint->bEndpointAddress;
544                         psIntfAdapter->sBulkIn.bulk_in_pipe = usb_rcvbulkpipe(
545                                         psIntfAdapter->udev,
546                                         psIntfAdapter->sBulkIn.bulk_in_endpointAddr);
547                 }
548 
549                 if (!psIntfAdapter->sBulkOut.bulk_out_endpointAddr &&
550                                 usb_endpoint_is_bulk_out(endpoint)) {
551                         psIntfAdapter->sBulkOut.bulk_out_endpointAddr =
552                                 endpoint->bEndpointAddress;
553                         psIntfAdapter->sBulkOut.bulk_out_pipe = usb_sndbulkpipe(
554                                         psIntfAdapter->udev,
555                                         psIntfAdapter->sBulkOut.bulk_out_endpointAddr);
556                 }
557 
558                 if (!psIntfAdapter->sIntrIn.int_in_endpointAddr &&
559                                 usb_endpoint_is_int_in(endpoint)) {
560                         buffer_size = le16_to_cpu(endpoint->wMaxPacketSize);
561                         psIntfAdapter->sIntrIn.int_in_size = buffer_size;
562                         psIntfAdapter->sIntrIn.int_in_endpointAddr =
563                                 endpoint->bEndpointAddress;
564                         psIntfAdapter->sIntrIn.int_in_interval =
565                                 endpoint->bInterval;
566                         psIntfAdapter->sIntrIn.int_in_buffer =
567                                 kmalloc(buffer_size, GFP_KERNEL);
568                         if (!psIntfAdapter->sIntrIn.int_in_buffer)
569                                 return -EINVAL;
570                 }
571 
572                 if (!psIntfAdapter->sIntrOut.int_out_endpointAddr &&
573                                 usb_endpoint_is_int_out(endpoint)) {
574                         if (!psIntfAdapter->sBulkOut.bulk_out_endpointAddr &&
575                                         (psIntfAdapter->psAdapter->chip_id == T3B) &&
576                                         (value == usedIntOutForBulkTransfer)) {
577                                 /* use first intout end point as a bulk out end point */
578                                 buffer_size =
579                                         le16_to_cpu(endpoint->wMaxPacketSize);
580                                 psIntfAdapter->sBulkOut.bulk_out_size =
581                                         buffer_size;
582                                 psIntfAdapter->sBulkOut.bulk_out_endpointAddr =
583                                         endpoint->bEndpointAddress;
584                                 psIntfAdapter->sBulkOut.bulk_out_pipe =
585                                         usb_sndintpipe(psIntfAdapter->udev,
586                                                         psIntfAdapter->sBulkOut
587                                                         .bulk_out_endpointAddr);
588                                 psIntfAdapter->sBulkOut.int_out_interval =
589                                         endpoint->bInterval;
590                         } else if (value == EP6) {
591                                 buffer_size =
592                                         le16_to_cpu(endpoint->wMaxPacketSize);
593                                 psIntfAdapter->sIntrOut.int_out_size =
594                                         buffer_size;
595                                 psIntfAdapter->sIntrOut.int_out_endpointAddr =
596                                         endpoint->bEndpointAddress;
597                                 psIntfAdapter->sIntrOut.int_out_interval =
598                                         endpoint->bInterval;
599                                 psIntfAdapter->sIntrOut.int_out_buffer =
600                                         kmalloc(buffer_size, GFP_KERNEL);
601                                 if (!psIntfAdapter->sIntrOut.int_out_buffer)
602                                         return -EINVAL;
603                         }
604                 }
605         }
606 
607         usb_set_intfdata(psIntfAdapter->interface, psIntfAdapter);
608 
609         psIntfAdapter->psAdapter->bcm_file_download = InterfaceFileDownload;
610         psIntfAdapter->psAdapter->bcm_file_readback_from_chip =
611                 InterfaceFileReadbackFromChip;
612         psIntfAdapter->psAdapter->interface_transmit = InterfaceTransmitPacket;
613 
614         retval = CreateInterruptUrb(psIntfAdapter);
615 
616         if (retval) {
617                 BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_PRINTK, 0, 0,
618                                 "Cannot create interrupt urb\n");
619                 return retval;
620         }
621 
622         retval = AllocUsbCb(psIntfAdapter);
623         if (retval)
624                 return retval;
625 
626         return device_run(psIntfAdapter);
627 }
628 
629 static int InterfaceSuspend(struct usb_interface *intf, pm_message_t message)
630 {
631         struct bcm_interface_adapter *psIntfAdapter = usb_get_intfdata(intf);
632 
633         psIntfAdapter->bSuspended = TRUE;
634 
635         if (psIntfAdapter->bPreparingForBusSuspend) {
636                 psIntfAdapter->bPreparingForBusSuspend = false;
637 
638                 if (psIntfAdapter->psAdapter->LinkStatus == LINKUP_DONE) {
639                         psIntfAdapter->psAdapter->IdleMode = TRUE;
640                         BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,
641                                         DBG_TYPE_INITEXIT, DRV_ENTRY,
642                                         DBG_LVL_ALL,
643                                         "Host Entered in PMU Idle Mode.\n");
644                 } else {
645                         psIntfAdapter->psAdapter->bShutStatus = TRUE;
646                         BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,
647                                         DBG_TYPE_INITEXIT, DRV_ENTRY,
648                                         DBG_LVL_ALL,
649                                         "Host Entered in PMU Shutdown Mode.\n");
650                 }
651         }
652         psIntfAdapter->psAdapter->bPreparingForLowPowerMode = false;
653 
654         /* Signaling the control pkt path */
655         wake_up(&psIntfAdapter->psAdapter->lowpower_mode_wait_queue);
656 
657         return 0;
658 }
659 
660 static int InterfaceResume(struct usb_interface *intf)
661 {
662         struct bcm_interface_adapter *psIntfAdapter = usb_get_intfdata(intf);
663 
664         mdelay(100);
665         psIntfAdapter->bSuspended = false;
666 
667         StartInterruptUrb(psIntfAdapter);
668         InterfaceRx(psIntfAdapter);
669         return 0;
670 }
671 
672 static struct usb_driver usbbcm_driver = {
673         .name = "usbbcm",
674         .probe = usbbcm_device_probe,
675         .disconnect = usbbcm_disconnect,
676         .suspend = InterfaceSuspend,
677         .resume = InterfaceResume,
678         .id_table = InterfaceUsbtable,
679         .supports_autosuspend = 1,
680 };
681 
682 struct class *bcm_class;
683 
684 static __init int bcm_init(void)
685 {
686         int retval;
687 
688         pr_info("%s: %s, %s\n", DRV_NAME, DRV_DESCRIPTION, DRV_VERSION);
689         pr_info("%s\n", DRV_COPYRIGHT);
690 
691         bcm_class = class_create(THIS_MODULE, DRV_NAME);
692         if (IS_ERR(bcm_class)) {
693                 pr_err(DRV_NAME ": could not create class\n");
694                 return PTR_ERR(bcm_class);
695         }
696 
697         retval = usb_register(&usbbcm_driver);
698         if (retval < 0) {
699                 pr_err(DRV_NAME ": could not register usb driver\n");
700                 class_destroy(bcm_class);
701                 return retval;
702         }
703         return 0;
704 }
705 
706 static __exit void bcm_exit(void)
707 {
708         usb_deregister(&usbbcm_driver);
709         class_destroy(bcm_class);
710 }
711 
712 module_init(bcm_init);
713 module_exit(bcm_exit);
714 
715 MODULE_DESCRIPTION(DRV_DESCRIPTION);
716 MODULE_VERSION(DRV_VERSION);
717 MODULE_LICENSE("GPL");
718 

This page was automatically generated by LXR 0.3.1 (source).  •  Linux is a registered trademark of Linus Torvalds  •  Contact us