[lantiq] move files/ -> files-3.3/
[openwrt.git] / target / linux / lantiq / files-3.3 / drivers / usb / ifxhcd / ifxhcd.c
1 /*****************************************************************************
2  **   FILE NAME       : ifxhcd.c
3  **   PROJECT         : IFX USB sub-system V3
4  **   MODULES         : IFX USB sub-system Host and Device driver
5  **   SRC VERSION     : 1.0
6  **   DATE            : 1/Jan/2009
7  **   AUTHOR          : Chen, Howard
8  **   DESCRIPTION     : This file contains the structures, constants, and interfaces for
9  **                     the Host Contoller Driver (HCD).
10  **
11  **                     The Host Controller Driver (HCD) is responsible for translating requests
12  **                     from the USB Driver into the appropriate actions on the IFXUSB controller.
13  **                     It isolates the USBD from the specifics of the controller by providing an
14  **                     API to the USBD.
15  *****************************************************************************/
16
17 /*!
18   \file ifxhcd.c
19   \ingroup IFXUSB_DRIVER_V3
20   \brief This file contains the implementation of the HCD. In Linux,
21    the HCD implements the hc_driver API.
22 */
23
24 #include <linux/version.h>
25 #include "ifxusb_version.h"
26
27 #include <linux/kernel.h>
28 #include <linux/module.h>
29 #include <linux/moduleparam.h>
30 #include <linux/init.h>
31
32 #include <linux/device.h>
33
34 #include <linux/errno.h>
35 #include <linux/list.h>
36 #include <linux/interrupt.h>
37 #include <linux/string.h>
38
39 #include <linux/dma-mapping.h>
40
41
42 #include "ifxusb_plat.h"
43 #include "ifxusb_regs.h"
44 #include "ifxusb_cif.h"
45 #include "ifxhcd.h"
46
47 #include <asm/irq.h>
48
49 #ifdef CONFIG_AVM_POWERMETER
50 #include <linux/avm_power.h>
51 #endif /*--- #ifdef CONFIG_AVM_POWERMETER ---*/
52
53 #ifdef __DEBUG__
54         static void dump_urb_info(struct urb *_urb, char* _fn_name);
55         static void dump_channel_info(ifxhcd_hcd_t *_ifxhcd, ifxhcd_epqh_t *_epqh);
56 #endif
57
58
59 /*!
60  \brief Sets the final status of an URB and returns it to the device driver. Any
61   required cleanup of the URB is performed.
62  */
63 void ifxhcd_complete_urb(ifxhcd_hcd_t *_ifxhcd, ifxhcd_urbd_t *_urbd,  int _status)
64 {
65         struct urb *urb=NULL;
66         unsigned long flags = 0;
67
68         /*== AVM/BC 20101111 Function called with Lock ==*/
69         //SPIN_LOCK_IRQSAVE(&_ifxhcd->lock, flags);
70
71         if (!list_empty(&_urbd->urbd_list_entry))
72                 list_del_init (&_urbd->urbd_list_entry);
73
74         if(!_urbd->urb)
75         {
76                 IFX_ERROR("%s: invalid urb\n",__func__);
77                 /*== AVM/BC 20101111 Function called with Lock ==*/
78                 //SPIN_UNLOCK_IRQRESTORE(&_ifxhcd->lock, flags);
79                 return;
80         }
81
82         urb=_urbd->urb;
83
84         #ifdef __DEBUG__
85                 if (CHK_DEBUG_LEVEL(DBG_HCDV | DBG_HCD_URB))
86                 {
87                         IFX_PRINT("%s: _urbd %p, urb %p, device %d, ep %d %s/%s, status=%d\n",
88                                   __func__, _urbd,_urbd->urb, usb_pipedevice(_urbd->urb->pipe),
89                                   usb_pipeendpoint(_urbd->urb->pipe),
90                                   usb_pipein(_urbd->urb->pipe) ? "IN" : "OUT",
91                                   (_urbd->is_in) ? "IN" : "OUT",
92                                    _status);
93                         if (_urbd->epqh->ep_type == IFXUSB_EP_TYPE_ISOC)
94                         {
95                                 int i;
96                                 for (i = 0; i < _urbd->urb->number_of_packets; i++)
97                                         IFX_PRINT("  ISO Desc %d status: %d\n", i, _urbd->urb->iso_frame_desc[i].status);
98                         }
99                 }
100         #endif
101
102         if (!_urbd->epqh)
103                 IFX_ERROR("%s: invalid epqd\n",__func__);
104
105         #if   defined(__UNALIGNED_BUFFER_ADJ__)
106                 else if(_urbd->is_active)
107                 {
108                         if( _urbd->epqh->aligned_checked   &&
109                             _urbd->epqh->using_aligned_buf &&
110                             _urbd->xfer_buff &&
111                             _urbd->is_in )
112                                 memcpy(_urbd->xfer_buff,_urbd->epqh->aligned_buf,_urbd->xfer_len);
113                         _urbd->epqh->using_aligned_buf=0;
114                         _urbd->epqh->using_aligned_setup=0;
115                         _urbd->epqh->aligned_checked=0;
116                 }
117         #endif
118
119         urb->status = _status;
120         urb->hcpriv=NULL;
121         kfree(_urbd);
122
123         usb_hcd_unlink_urb_from_ep(ifxhcd_to_syshcd(_ifxhcd), urb);
124         SPIN_UNLOCK_IRQRESTORE(&_ifxhcd->lock, flags);
125
126 //    usb_hcd_giveback_urb(ifxhcd_to_syshcd(_ifxhcd), urb);
127     usb_hcd_giveback_urb(ifxhcd_to_syshcd(_ifxhcd), urb, _status);
128
129     /*== AVM/BC 20100630 - 2.6.28 needs HCD link/unlink URBs ==*/
130         SPIN_LOCK_IRQSAVE(&_ifxhcd->lock, flags);
131 }
132
133 /*== AVM/BC 20101111 URB Complete deferred
134  * Must be called with Spinlock
135  */
136
137 /*!
138  \brief Inserts an urbd structur in the completion list. The urbd will be
139   later completed by select_eps_sub
140  */
141 void defer_ifxhcd_complete_urb(ifxhcd_hcd_t *_ifxhcd, ifxhcd_urbd_t *_urbd,  int _status)
142 {
143
144         _urbd->status = _status;
145
146         //Unlink Urbd from epqh / Insert it into the complete list
147         list_move_tail(&_urbd->urbd_list_entry, &_ifxhcd->urbd_complete_list);
148
149 }
150
151 /*!
152  \brief Processes all the URBs in a single EPQHs. Completes them with
153         status and frees the URBD.
154  */
155 //static
156 void kill_all_urbs_in_epqh(ifxhcd_hcd_t *_ifxhcd, ifxhcd_epqh_t *_epqh, int _status)
157 {
158         struct list_head *urbd_item;
159         ifxhcd_urbd_t    *urbd;
160
161         if(!_epqh)
162                 return;
163
164         for (urbd_item  =  _epqh->urbd_list.next;
165              urbd_item != &_epqh->urbd_list;
166              urbd_item  =  _epqh->urbd_list.next)
167         {
168                 urbd = list_entry(urbd_item, ifxhcd_urbd_t, urbd_list_entry);
169                 ifxhcd_complete_urb(_ifxhcd, urbd, _status);
170         }
171 }
172
173
174 /*!
175  \brief Free all EPS in one Processes all the URBs in a single list of EPQHs. Completes them with
176         -ETIMEDOUT and frees the URBD.
177  */
178 //static
179 void epqh_list_free(ifxhcd_hcd_t *_ifxhcd, struct list_head *_epqh_list)
180 {
181                 struct list_head *item;
182                 ifxhcd_epqh_t    *epqh;
183
184                 if (!_epqh_list)
185                         return;
186                 if (_epqh_list->next == NULL) /* The list hasn't been initialized yet. */
187                         return;
188
189         /* Ensure there are no URBDs or URBs left. */
190         for (item = _epqh_list->next; item != _epqh_list; item = _epqh_list->next)
191         {
192                 epqh = list_entry(item, ifxhcd_epqh_t, epqh_list_entry);
193                 kill_all_urbs_in_epqh(_ifxhcd, epqh, -ETIMEDOUT);
194                 ifxhcd_epqh_free(epqh);
195         }
196 }
197
198
199
200 //static
201 void epqh_list_free_all(ifxhcd_hcd_t *_ifxhcd)
202 {
203         unsigned long flags;
204
205         /*== AVM/BC 20101111 - 2.6.28 Needs Spinlock ==*/
206         SPIN_LOCK_IRQSAVE(&_ifxhcd->lock, flags);
207
208         epqh_list_free(_ifxhcd, &_ifxhcd->epqh_np_active   );
209         epqh_list_free(_ifxhcd, &_ifxhcd->epqh_np_ready    );
210         epqh_list_free(_ifxhcd, &_ifxhcd->epqh_intr_active );
211         epqh_list_free(_ifxhcd, &_ifxhcd->epqh_intr_ready  );
212         #ifdef __EN_ISOC__
213                 epqh_list_free(_ifxhcd, &_ifxhcd->epqh_isoc_active );
214                 epqh_list_free(_ifxhcd, &_ifxhcd->epqh_isoc_ready  );
215         #endif
216         epqh_list_free(_ifxhcd, &_ifxhcd->epqh_stdby       );
217
218         SPIN_UNLOCK_IRQRESTORE(&_ifxhcd->lock, flags);
219
220 }
221
222
223 /*!
224    \brief This function is called to handle the disconnection of host port.
225  */
226 int32_t ifxhcd_disconnect(ifxhcd_hcd_t *_ifxhcd)
227 {
228         IFX_DEBUGPL(DBG_HCDV, "%s(%p)\n", __func__, _ifxhcd);
229
230         /* Set status flags for the hub driver. */
231         _ifxhcd->flags.b.port_connect_status_change = 1;
232         _ifxhcd->flags.b.port_connect_status = 0;
233
234         /*
235          * Shutdown any transfers in process by clearing the Tx FIFO Empty
236          * interrupt mask and status bits and disabling subsequent host
237          * channel interrupts.
238          */
239          {
240                 gint_data_t intr = { .d32 = 0 };
241                 intr.b.nptxfempty = 1;
242                 intr.b.ptxfempty  = 1;
243                 intr.b.hcintr     = 1;
244                 ifxusb_mreg (&_ifxhcd->core_if.core_global_regs->gintmsk, intr.d32, 0);
245                 ifxusb_mreg (&_ifxhcd->core_if.core_global_regs->gintsts, intr.d32, 0);
246         }
247
248         /* Respond with an error status to all URBs in the schedule. */
249         epqh_list_free_all(_ifxhcd);
250
251         /* Clean up any host channels that were in use. */
252         {
253                 int               num_channels;
254                 ifxhcd_hc_t      *channel;
255                 ifxusb_hc_regs_t *hc_regs;
256                 hcchar_data_t     hcchar;
257                 int                   i;
258
259                 num_channels = _ifxhcd->core_if.params.host_channels;
260
261                 for (i = 0; i < num_channels; i++)
262                 {
263                         channel = &_ifxhcd->ifxhc[i];
264                         if (list_empty(&channel->hc_list_entry))
265                         {
266                                 hc_regs = _ifxhcd->core_if.hc_regs[i];
267                                 hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
268                                 if (hcchar.b.chen)
269                                 {
270                                         /* Halt the channel. */
271                                         hcchar.b.chdis = 1;
272                                         ifxusb_wreg(&hc_regs->hcchar, hcchar.d32);
273                                 }
274                                 list_add_tail(&channel->hc_list_entry, &_ifxhcd->free_hc_list);
275                                 ifxhcd_hc_cleanup(&_ifxhcd->core_if, channel);
276                         }
277                 }
278         }
279         return 1;
280 }
281
282
283 /*!
284    \brief Frees secondary storage associated with the ifxhcd_hcd structure contained
285           in the struct usb_hcd field.
286  */
287 static void ifxhcd_freeextra(struct usb_hcd *_syshcd)
288 {
289         ifxhcd_hcd_t    *ifxhcd = syshcd_to_ifxhcd(_syshcd);
290
291         IFX_DEBUGPL(DBG_HCD, "IFXUSB HCD FREE\n");
292
293         /* Free memory for EPQH/URBD lists */
294         epqh_list_free_all(ifxhcd);
295
296         /* Free memory for the host channels. */
297         ifxusb_free_buf(ifxhcd->status_buf);
298         return;
299 }
300 #ifdef __USE_TIMER_4_SOF__
301 static enum hrtimer_restart ifxhcd_timer_func(struct hrtimer *timer) {
302         ifxhcd_hcd_t    *ifxhcd = container_of(timer, ifxhcd_hcd_t, hr_timer);
303         
304         ifxhcd_handle_intr(ifxhcd);
305
306     return HRTIMER_NORESTART;
307 }
308 #endif
309
310 /*!
311    \brief Initializes the HCD. This function allocates memory for and initializes the
312   static parts of the usb_hcd and ifxhcd_hcd structures. It also registers the
313   USB bus with the core and calls the hc_driver->start() function. It returns
314   a negative error on failure.
315  */
316 int ifxhcd_init(ifxhcd_hcd_t *_ifxhcd)
317 {
318         int retval = 0;
319         struct usb_hcd *syshcd = NULL;
320
321         IFX_DEBUGPL(DBG_HCD, "IFX USB HCD INIT\n");
322
323         spin_lock_init(&_ifxhcd->lock);
324 #ifdef __USE_TIMER_4_SOF__
325         hrtimer_init(&_ifxhcd->hr_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
326         _ifxhcd->hr_timer.function = ifxhcd_timer_func;
327 #endif
328         _ifxhcd->hc_driver.description      = _ifxhcd->core_if.core_name;
329         _ifxhcd->hc_driver.product_desc     = "IFX USB Controller";
330         //_ifxhcd->hc_driver.hcd_priv_size    = sizeof(ifxhcd_hcd_t);
331         _ifxhcd->hc_driver.hcd_priv_size    = sizeof(unsigned long);
332         _ifxhcd->hc_driver.irq              = ifxhcd_irq;
333         _ifxhcd->hc_driver.flags            = HCD_MEMORY | HCD_USB2;
334         _ifxhcd->hc_driver.start            = ifxhcd_start;
335         _ifxhcd->hc_driver.stop             = ifxhcd_stop;
336         //_ifxhcd->hc_driver.reset          =
337         //_ifxhcd->hc_driver.suspend        =
338         //_ifxhcd->hc_driver.resume         =
339         _ifxhcd->hc_driver.urb_enqueue      = ifxhcd_urb_enqueue;
340         _ifxhcd->hc_driver.urb_dequeue      = ifxhcd_urb_dequeue;
341         _ifxhcd->hc_driver.endpoint_disable = ifxhcd_endpoint_disable;
342         _ifxhcd->hc_driver.get_frame_number = ifxhcd_get_frame_number;
343         _ifxhcd->hc_driver.hub_status_data  = ifxhcd_hub_status_data;
344         _ifxhcd->hc_driver.hub_control      = ifxhcd_hub_control;
345         //_ifxhcd->hc_driver.hub_suspend    =
346         //_ifxhcd->hc_driver.hub_resume     =
347
348         /* Allocate memory for and initialize the base HCD and  */
349 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32)
350         syshcd = usb_create_hcd(&_ifxhcd->hc_driver, _ifxhcd->dev, _ifxhcd->core_if.core_name);
351 #else
352         syshcd = usb_create_hcd(&_ifxhcd->hc_driver, _ifxhcd->dev, _ifxhcd->dev->bus_id);
353 #endif
354
355         if (syshcd == NULL)
356         {
357                 retval = -ENOMEM;
358                 goto error1;
359         }
360         
361 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32)
362         syshcd->has_tt = 1;
363 #endif
364
365         syshcd->rsrc_start = (unsigned long)_ifxhcd->core_if.core_global_regs;
366         syshcd->regs       = (void *)_ifxhcd->core_if.core_global_regs;
367         syshcd->self.otg_port = 0;
368
369         //*((unsigned long *)(&(syshcd->hcd_priv)))=(unsigned long)_ifxhcd;
370         //*((unsigned long *)(&(syshcd->hcd_priv[0])))=(unsigned long)_ifxhcd;
371         syshcd->hcd_priv[0]=(unsigned long)_ifxhcd;
372         _ifxhcd->syshcd=syshcd;
373
374         INIT_LIST_HEAD(&_ifxhcd->epqh_np_active   );
375         INIT_LIST_HEAD(&_ifxhcd->epqh_np_ready    );
376         INIT_LIST_HEAD(&_ifxhcd->epqh_intr_active );
377         INIT_LIST_HEAD(&_ifxhcd->epqh_intr_ready  );
378         #ifdef __EN_ISOC__
379                 INIT_LIST_HEAD(&_ifxhcd->epqh_isoc_active );
380                 INIT_LIST_HEAD(&_ifxhcd->epqh_isoc_ready  );
381         #endif
382         INIT_LIST_HEAD(&_ifxhcd->epqh_stdby       );
383         INIT_LIST_HEAD(&_ifxhcd->urbd_complete_list);
384
385         /*
386          * Create a host channel descriptor for each host channel implemented
387          * in the controller. Initialize the channel descriptor array.
388          */
389         INIT_LIST_HEAD(&_ifxhcd->free_hc_list);
390         {
391                 int          num_channels = _ifxhcd->core_if.params.host_channels;
392                 int i;
393                 for (i = 0; i < num_channels; i++)
394                 {
395                         _ifxhcd->ifxhc[i].hc_num = i;
396                         IFX_DEBUGPL(DBG_HCDV, "HCD Added channel #%d\n", i);
397                 }
398         }
399
400         /* Set device flags indicating whether the HCD supports DMA. */
401         if(_ifxhcd->dev->dma_mask)
402                 *(_ifxhcd->dev->dma_mask) = ~0;
403         _ifxhcd->dev->coherent_dma_mask = ~0;
404
405         /*
406          * Finish generic HCD initialization and start the HCD. This function
407          * allocates the DMA buffer pool, registers the USB bus, requests the
408          * IRQ line, and calls ifxusb_hcd_start method.
409          */
410 //      retval = usb_add_hcd(syshcd, _ifxhcd->core_if.irq, SA_INTERRUPT|SA_SHIRQ);
411         retval = usb_add_hcd(syshcd, _ifxhcd->core_if.irq, IRQF_DISABLED | IRQF_SHARED );
412         if (retval < 0)
413                 goto error2;
414
415         /*
416          * Allocate space for storing data on status transactions. Normally no
417          * data is sent, but this space acts as a bit bucket. This must be
418          * done after usb_add_hcd since that function allocates the DMA buffer
419          * pool.
420          */
421         _ifxhcd->status_buf = ifxusb_alloc_buf(IFXHCD_STATUS_BUF_SIZE, 1);
422
423         if (_ifxhcd->status_buf)
424         {
425 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32)
426                 IFX_DEBUGPL(DBG_HCD, "IFX USB HCD Initialized, bus=%s, usbbus=%d\n", _ifxhcd->core_if.core_name, syshcd->self.busnum);
427 #else
428                 IFX_DEBUGPL(DBG_HCD, "IFX USB HCD Initialized, bus=%s, usbbus=%d\n", _ifxhcd->dev->bus_id, syshcd->self.busnum);
429 #endif
430                 return 0;
431         }
432         IFX_ERROR("%s: status_buf allocation failed\n", __func__);
433
434         /* Error conditions */
435         usb_remove_hcd(syshcd);
436 error2:
437         ifxhcd_freeextra(syshcd);
438         usb_put_hcd(syshcd);
439 error1:
440         return retval;
441 }
442
443 /*!
444    \brief Removes the HCD.
445   Frees memory and resources associated with the HCD and deregisters the bus.
446  */
447 void ifxhcd_remove(ifxhcd_hcd_t *_ifxhcd)
448 {
449         struct usb_hcd *syshcd = ifxhcd_to_syshcd(_ifxhcd);
450
451         IFX_DEBUGPL(DBG_HCD, "IFX USB HCD REMOVE\n");
452
453 /* == AVM/WK 20100709 - Fix: Order changed, disable IRQs not before remove_hcd == */
454
455         usb_remove_hcd(syshcd);
456
457         /* Turn off all interrupts */
458         ifxusb_wreg (&_ifxhcd->core_if.core_global_regs->gintmsk, 0);
459         ifxusb_mreg (&_ifxhcd->core_if.core_global_regs->gahbcfg, 1, 0);
460
461         ifxhcd_freeextra(syshcd);
462
463         usb_put_hcd(syshcd);
464
465         return;
466 }
467
468
469 /* =========================================================================
470  *  Linux HC Driver Functions
471  * ========================================================================= */
472
473 /*!
474    \brief Initializes the IFXUSB controller and its root hub and prepares it for host
475  mode operation. Activates the root port. Returns 0 on success and a negative
476  error code on failure.
477  Called by USB stack.
478  */
479 int ifxhcd_start(struct usb_hcd *_syshcd)
480 {
481         ifxhcd_hcd_t *ifxhcd = syshcd_to_ifxhcd (_syshcd);
482         ifxusb_core_if_t *core_if = &ifxhcd->core_if;
483         struct usb_bus *bus;
484
485         IFX_DEBUGPL(DBG_HCD, "IFX USB HCD START\n");
486
487         bus = hcd_to_bus(_syshcd);
488
489         /* Initialize the bus state.  */
490         _syshcd->state = HC_STATE_RUNNING;
491
492         /* Initialize and connect root hub if one is not already attached */
493         if (bus->root_hub)
494         {
495                 IFX_DEBUGPL(DBG_HCD, "IFX USB HCD Has Root Hub\n");
496                 /* Inform the HUB driver to resume. */
497                 usb_hcd_resume_root_hub(_syshcd);
498         }
499
500         ifxhcd->flags.d32 = 0;
501
502         /* Put all channels in the free channel list and clean up channel states.*/
503         {
504                 struct list_head        *item;
505                 item = ifxhcd->free_hc_list.next;
506                 while (item != &ifxhcd->free_hc_list)
507                 {
508                         list_del(item);
509                         item = ifxhcd->free_hc_list.next;
510                 }
511         }
512         {
513                 int num_channels = ifxhcd->core_if.params.host_channels;
514                 int i;
515                 for (i = 0; i < num_channels; i++)
516                 {
517                         ifxhcd_hc_t      *channel;
518                         channel = &ifxhcd->ifxhc[i];
519                         list_add_tail(&channel->hc_list_entry, &ifxhcd->free_hc_list);
520                         ifxhcd_hc_cleanup(&ifxhcd->core_if, channel);
521                 }
522         }
523         /* Initialize the USB core for host mode operation. */
524
525         ifxusb_host_enable_interrupts(core_if);
526         ifxusb_enable_global_interrupts(core_if);
527         ifxusb_phy_power_on (core_if);
528
529         ifxusb_vbus_init(core_if);
530
531         /* Turn on the vbus power. */
532         {
533                 hprt0_data_t hprt0;
534                 hprt0.d32 = ifxusb_read_hprt0(core_if);
535
536                 IFX_PRINT("Init: Power Port (%d)\n", hprt0.b.prtpwr);
537                 if (hprt0.b.prtpwr == 0 )
538                 {
539                         hprt0.b.prtpwr = 1;
540                         ifxusb_wreg(core_if->hprt0, hprt0.d32);
541                         ifxusb_vbus_on(core_if);
542                 }
543         }
544         return 0;
545 }
546
547
548 /*!
549    \brief Halts the IFXUSB  host mode operations in a clean manner. USB transfers are
550  stopped.
551  */
552 void ifxhcd_stop(struct usb_hcd *_syshcd)
553 {
554         ifxhcd_hcd_t *ifxhcd = syshcd_to_ifxhcd(_syshcd);
555         hprt0_data_t  hprt0 = { .d32=0 };
556
557         IFX_DEBUGPL(DBG_HCD, "IFX USB HCD STOP\n");
558
559         /* Turn off all interrupts. */
560         ifxusb_disable_global_interrupts(&ifxhcd->core_if );
561         ifxusb_host_disable_interrupts(&ifxhcd->core_if );
562 #ifdef __USE_TIMER_4_SOF__
563         hrtimer_cancel(&ifxhcd->hr_timer);
564 #endif
565         /*
566          * The root hub should be disconnected before this function is called.
567          * The disconnect will clear the URBD lists (via ..._hcd_urb_dequeue)
568          * and the EPQH lists (via ..._hcd_endpoint_disable).
569          */
570
571         /* Turn off the vbus power */
572         IFX_PRINT("PortPower off\n");
573
574         ifxusb_vbus_off(&ifxhcd->core_if );
575
576         ifxusb_vbus_free(&ifxhcd->core_if );
577
578         hprt0.b.prtpwr = 0;
579         ifxusb_wreg(ifxhcd->core_if.hprt0, hprt0.d32);
580         return;
581 }
582
583 /*!
584    \brief Returns the current frame number
585  */
586 int ifxhcd_get_frame_number(struct usb_hcd *_syshcd)
587 {
588         ifxhcd_hcd_t    *ifxhcd = syshcd_to_ifxhcd(_syshcd);
589         hfnum_data_t hfnum;
590
591         hfnum.d32 = ifxusb_rreg(&ifxhcd->core_if.host_global_regs->hfnum);
592
593         return hfnum.b.frnum;
594 }
595
596 /*!
597    \brief Starts processing a USB transfer request specified by a USB Request Block
598   (URB). mem_flags indicates the type of memory allocation to use while
599   processing this URB.
600  */
601 int ifxhcd_urb_enqueue( struct usb_hcd           *_syshcd,
602                         /*--- struct usb_host_endpoint *_sysep, Parameter im 2.6.28 entfallen ---*/
603                         struct urb               *_urb,
604                         gfp_t                     _mem_flags)
605 {
606         int retval = 0;
607         ifxhcd_hcd_t *ifxhcd = syshcd_to_ifxhcd (_syshcd);
608         struct usb_host_endpoint *_sysep = ifxhcd_urb_to_endpoint(_urb);
609         ifxhcd_epqh_t *epqh;
610
611         #ifdef __DEBUG__
612                 if (CHK_DEBUG_LEVEL(DBG_HCDV | DBG_HCD_URB))
613                         dump_urb_info(_urb, "ifxusb_hcd_urb_enqueue");
614         #endif //__DEBUG__
615
616         if (!ifxhcd->flags.b.port_connect_status)  /* No longer connected. */
617                 return -ENODEV;
618
619         #ifndef __EN_ISOC__
620                 if(usb_pipetype(_urb->pipe) == PIPE_ISOCHRONOUS)
621                 {
622                         IFX_ERROR("ISOC transfer not supported!!!\n");
623                         return -ENODEV;
624                 }
625         #endif
626
627         retval=ifxhcd_urbd_create (ifxhcd,_urb);
628
629         if (retval)
630         {
631                 IFX_ERROR("IFXUSB HCD URB Enqueue failed creating URBD\n");
632                 return retval;
633         }
634         epqh = (ifxhcd_epqh_t *) _sysep->hcpriv;
635         ifxhcd_epqh_ready(ifxhcd, epqh);
636
637         select_eps(ifxhcd);
638         //enable_sof(ifxhcd);
639         {
640                 gint_data_t gintsts;
641                 gintsts.d32=0;
642                 gintsts.b.sofintr = 1;
643                 ifxusb_mreg(&ifxhcd->core_if.core_global_regs->gintmsk, 0,gintsts.d32);
644         }
645
646         return retval;
647 }
648
649 /*!
650    \brief Aborts/cancels a USB transfer request. Always returns 0 to indicate
651   success.
652  */
653 int ifxhcd_urb_dequeue( struct usb_hcd *_syshcd,
654                         struct urb *_urb, int status /* Parameter neu in 2.6.28 */)
655 {
656         unsigned long flags;
657         ifxhcd_hcd_t  *ifxhcd;
658         ifxhcd_urbd_t *urbd;
659         ifxhcd_epqh_t *epqh;
660         int is_active=0;
661         int rc;
662
663         struct usb_host_endpoint *_sysep;
664
665         IFX_DEBUGPL(DBG_HCD, "IFXUSB HCD URB Dequeue\n");
666
667         #ifndef __EN_ISOC__
668                 if(usb_pipetype(_urb->pipe) == PIPE_ISOCHRONOUS)
669                         return 0;
670         #endif
671
672         _sysep = ifxhcd_urb_to_endpoint(_urb);
673
674         ifxhcd = syshcd_to_ifxhcd(_syshcd);
675
676         SPIN_LOCK_IRQSAVE(&ifxhcd->lock, flags);
677
678         /*== AVM/BC 20100630 - 2.6.28 needs HCD link/unlink URBs ==*/
679         rc = usb_hcd_check_unlink_urb(_syshcd, _urb, status);
680         if (rc) {
681                 SPIN_UNLOCK_IRQRESTORE(&ifxhcd->lock, flags);
682                 return rc;
683         }
684
685         urbd = (ifxhcd_urbd_t *) _urb->hcpriv;
686
687         if(_sysep)
688                 epqh = (ifxhcd_epqh_t *) _sysep->hcpriv;
689         else
690                 epqh = (ifxhcd_epqh_t *) urbd->epqh;
691
692         if(epqh!=urbd->epqh)
693                 IFX_ERROR("%s inconsistant epqh %p %p\n",__func__,epqh,urbd->epqh);
694
695         #ifdef __DEBUG__
696                 if (CHK_DEBUG_LEVEL(DBG_HCDV | DBG_HCD_URB))
697                 {
698                         dump_urb_info(_urb, "ifxhcd_urb_dequeue");
699                         if (epqh->is_active)
700                                 dump_channel_info(ifxhcd, epqh);
701                 }
702         #endif //__DEBUG__
703
704         if(!epqh->hc)
705                 epqh->is_active=0;
706         else if (!ifxhcd->flags.b.port_connect_status)
707                         epqh->is_active=0;
708         else if (epqh->is_active && urbd->is_active)
709         {
710                 /*== AVM/WK 20100709 - halt channel only if really started ==*/
711                 //if (epqh->hc->xfer_started && !epqh->hc->wait_for_sof) {
712                 /*== AVM/WK 20101112 - halt channel if started ==*/
713                 if (epqh->hc->xfer_started) {
714                         /*
715                          * If still connected (i.e. in host mode), halt the
716                          * channel so it can be used for other transfers. If
717                          * no longer connected, the host registers can't be
718                          * written to halt the channel since the core is in
719                          * device mode.
720                          */
721                         /* == 20110803 AVM/WK FIX propagate status == */
722                         if (_urb->status == -EINPROGRESS) {
723                                 _urb->status = status;
724                         }
725                         ifxhcd_hc_halt(&ifxhcd->core_if, epqh->hc, HC_XFER_URB_DEQUEUE);
726                         epqh->hc = NULL;
727                         is_active=1;
728                 }
729         }
730
731         if(is_active)
732         {
733                 SPIN_UNLOCK_IRQRESTORE(&ifxhcd->lock, flags);
734         }
735         else
736         {
737                 list_del_init(&urbd->urbd_list_entry);
738                 kfree (urbd);
739
740                 /*== AVM/BC 20100630 - 2.6.28 needs HCD link/unlink URBs ==*/
741                 usb_hcd_unlink_urb_from_ep(_syshcd, _urb);
742
743                 SPIN_UNLOCK_IRQRESTORE(&ifxhcd->lock, flags);
744                 _urb->hcpriv = NULL;
745 //              usb_hcd_giveback_urb(_syshcd, _urb);
746                 usb_hcd_giveback_urb(_syshcd, _urb, status /* neu in 2.6.28 */);
747                 select_eps(ifxhcd);
748         }
749
750         return 0;
751 }
752
753
754
755 /*!
756    \brief Frees resources in the IFXUSB controller related to a given endpoint. Also
757   clears state in the HCD related to the endpoint. Any URBs for the endpoint
758   must already be dequeued.
759  */
760 void ifxhcd_endpoint_disable( struct usb_hcd *_syshcd,
761                               struct usb_host_endpoint *_sysep)
762 {
763         ifxhcd_epqh_t *epqh;
764         ifxhcd_hcd_t  *ifxhcd = syshcd_to_ifxhcd(_syshcd);
765         unsigned long flags;
766
767         int retry = 0;
768
769         IFX_DEBUGPL(DBG_HCD, "IFXUSB HCD EP DISABLE: _bEndpointAddress=0x%02x, "
770             "endpoint=%d\n", _sysep->desc.bEndpointAddress,
771                     ifxhcd_ep_addr_to_endpoint(_sysep->desc.bEndpointAddress));
772
773         SPIN_LOCK_IRQSAVE(&ifxhcd->lock, flags);
774         if((uint32_t)_sysep>=0x80000000 && (uint32_t)_sysep->hcpriv>=(uint32_t)0x80000000)
775         {
776                 epqh = (ifxhcd_epqh_t *)(_sysep->hcpriv);
777                 if (epqh && epqh->sysep==_sysep)
778                 {
779
780 #if 1  /*== AVM/BC 20101111 CHG Option active: Kill URBs when disabling EP  ==*/
781                         while (!list_empty(&epqh->urbd_list))
782                         {
783                                 if (retry++ > 250)
784                                 {
785                                         IFX_WARN("IFXUSB HCD EP DISABLE:"
786                                                  " URBD List for this endpoint is not empty\n");
787                                         break;
788                                 }
789                                 kill_all_urbs_in_epqh(ifxhcd, epqh, -ETIMEDOUT);
790                         }
791 #else
792                         while (!list_empty(&epqh->urbd_list))
793                         {
794                                 /** Check that the QTD list is really empty */
795                                 if (retry++ > 250)
796                                 {
797                                         IFX_WARN("IFXUSB HCD EP DISABLE:"
798                                                  " URBD List for this endpoint is not empty\n");
799                                         break;
800                                 }
801                                 SPIN_UNLOCK_IRQRESTORE(&ifxhcd->lock, flags);
802                                 schedule_timeout_uninterruptible(1);
803                                 SPIN_LOCK_IRQSAVE(&ifxhcd->lock, flags);
804                         }
805 #endif
806
807                         ifxhcd_epqh_free(epqh);
808                         _sysep->hcpriv = NULL;
809                 }
810         }
811         SPIN_UNLOCK_IRQRESTORE(&ifxhcd->lock, flags);
812 }
813
814
815 /*!
816    \brief Handles host mode interrupts for the IFXUSB controller. Returns IRQ_NONE if
817  * there was no interrupt to handle. Returns IRQ_HANDLED if there was a valid
818  * interrupt.
819  *
820  * This function is called by the USB core when an interrupt occurs
821  */
822 irqreturn_t ifxhcd_irq(struct usb_hcd *_syshcd)
823 {
824         ifxhcd_hcd_t *ifxhcd = syshcd_to_ifxhcd (_syshcd);
825     int32_t retval=0;
826
827         //mask_and_ack_ifx_irq (ifxhcd->core_if.irq);
828         retval = ifxhcd_handle_intr(ifxhcd);
829         return IRQ_RETVAL(retval);
830 }
831
832
833 /*!
834    \brief Handles host mode Over Current Interrupt
835  */
836 irqreturn_t ifxhcd_oc_irq(int _irq , void *_dev)
837 {
838         ifxhcd_hcd_t *ifxhcd = _dev;
839         int32_t retval=1;
840
841         ifxhcd->flags.b.port_over_current_change = 1;
842         ifxusb_vbus_off(&ifxhcd->core_if);
843         IFX_DEBUGP("OC INTERRUPT # %d\n",ifxhcd->core_if.core_no);
844
845         //mask_and_ack_ifx_irq (_irq);
846         return IRQ_RETVAL(retval);
847 }
848
849 /*!
850  \brief Creates Status Change bitmap for the root hub and root port. The bitmap is
851   returned in buf. Bit 0 is the status change indicator for the root hub. Bit 1
852   is the status change indicator for the single root port. Returns 1 if either
853   change indicator is 1, otherwise returns 0.
854  */
855 int ifxhcd_hub_status_data(struct usb_hcd *_syshcd, char *_buf)
856 {
857         ifxhcd_hcd_t *ifxhcd = syshcd_to_ifxhcd (_syshcd);
858
859         _buf[0] = 0;
860         _buf[0] |= (ifxhcd->flags.b.port_connect_status_change ||
861                     ifxhcd->flags.b.port_reset_change ||
862                     ifxhcd->flags.b.port_enable_change ||
863                     ifxhcd->flags.b.port_suspend_change ||
864                     ifxhcd->flags.b.port_over_current_change) << 1;
865
866         #ifdef __DEBUG__
867                 if (_buf[0])
868                 {
869                         IFX_DEBUGPL(DBG_HCD, "IFXUSB HCD HUB STATUS DATA:"
870                                     " Root port status changed\n");
871                         IFX_DEBUGPL(DBG_HCDV, "  port_connect_status_change: %d\n",
872                                     ifxhcd->flags.b.port_connect_status_change);
873                         IFX_DEBUGPL(DBG_HCDV, "  port_reset_change: %d\n",
874                                     ifxhcd->flags.b.port_reset_change);
875                         IFX_DEBUGPL(DBG_HCDV, "  port_enable_change: %d\n",
876                                     ifxhcd->flags.b.port_enable_change);
877                         IFX_DEBUGPL(DBG_HCDV, "  port_suspend_change: %d\n",
878                                     ifxhcd->flags.b.port_suspend_change);
879                         IFX_DEBUGPL(DBG_HCDV, "  port_over_current_change: %d\n",
880                                     ifxhcd->flags.b.port_over_current_change);
881                 }
882         #endif //__DEBUG__
883         return (_buf[0] != 0);
884 }
885
886 #ifdef __WITH_HS_ELECT_TST__
887         extern void do_setup(ifxusb_core_if_t *_core_if) ;
888         extern void do_in_ack(ifxusb_core_if_t *_core_if);
889 #endif //__WITH_HS_ELECT_TST__
890
891 /*!
892  \brief Handles hub class-specific requests.
893  */
894 int ifxhcd_hub_control( struct usb_hcd *_syshcd,
895                         u16             _typeReq,
896                         u16             _wValue,
897                         u16             _wIndex,
898                         char           *_buf,
899                         u16             _wLength)
900 {
901         int retval = 0;
902
903         ifxhcd_hcd_t              *ifxhcd  = syshcd_to_ifxhcd (_syshcd);
904         ifxusb_core_if_t          *core_if = &ifxhcd->core_if;
905         struct usb_hub_descriptor *desc;
906         hprt0_data_t               hprt0 = {.d32 = 0};
907
908         uint32_t port_status;
909
910         switch (_typeReq)
911         {
912                 case ClearHubFeature:
913                         IFX_DEBUGPL (DBG_HCD, "IFXUSB HCD HUB CONTROL - "
914                                  "ClearHubFeature 0x%x\n", _wValue);
915                         switch (_wValue)
916                         {
917                                 case C_HUB_LOCAL_POWER:
918                                 case C_HUB_OVER_CURRENT:
919                                         /* Nothing required here */
920                                         break;
921                                 default:
922                                         retval = -EINVAL;
923                                         IFX_ERROR ("IFXUSB HCD - "
924                                                    "ClearHubFeature request %xh unknown\n", _wValue);
925                         }
926                         break;
927                 case ClearPortFeature:
928                         if (!_wIndex || _wIndex > 1)
929                                 goto error;
930
931                         switch (_wValue)
932                         {
933                                 case USB_PORT_FEAT_ENABLE:
934                                         IFX_DEBUGPL (DBG_ANY, "IFXUSB HCD HUB CONTROL - "
935                                                      "ClearPortFeature USB_PORT_FEAT_ENABLE\n");
936                                         hprt0.d32 = ifxusb_read_hprt0 (core_if);
937                                         hprt0.b.prtena = 1;
938                                         ifxusb_wreg(core_if->hprt0, hprt0.d32);
939                                         break;
940                                 case USB_PORT_FEAT_SUSPEND:
941                                         IFX_DEBUGPL (DBG_HCD, "IFXUSB HCD HUB CONTROL - "
942                                                      "ClearPortFeature USB_PORT_FEAT_SUSPEND\n");
943                                         hprt0.d32 = ifxusb_read_hprt0 (core_if);
944                                         hprt0.b.prtres = 1;
945                                         ifxusb_wreg(core_if->hprt0, hprt0.d32);
946                                         /* Clear Resume bit */
947                                         mdelay (100);
948                                         hprt0.b.prtres = 0;
949                                         ifxusb_wreg(core_if->hprt0, hprt0.d32);
950                                         break;
951                                 case USB_PORT_FEAT_POWER:
952                                         IFX_DEBUGPL (DBG_HCD, "IFXUSB HCD HUB CONTROL - "
953                                                      "ClearPortFeature USB_PORT_FEAT_POWER\n");
954                                         #ifdef __IS_DUAL__
955                                                 ifxusb_vbus_off(core_if);
956                                         #else
957                                                 ifxusb_vbus_off(core_if);
958                                         #endif
959                                         hprt0.d32 = ifxusb_read_hprt0 (core_if);
960                                         hprt0.b.prtpwr = 0;
961                                         ifxusb_wreg(core_if->hprt0, hprt0.d32);
962                                         break;
963                                 case USB_PORT_FEAT_INDICATOR:
964                                         IFX_DEBUGPL (DBG_HCD, "IFXUSB HCD HUB CONTROL - "
965                                                      "ClearPortFeature USB_PORT_FEAT_INDICATOR\n");
966                                         /* Port inidicator not supported */
967                                         break;
968                                 case USB_PORT_FEAT_C_CONNECTION:
969                                         /* Clears drivers internal connect status change
970                                          * flag */
971                                         IFX_DEBUGPL (DBG_HCD, "IFXUSB HCD HUB CONTROL - "
972                                                      "ClearPortFeature USB_PORT_FEAT_C_CONNECTION\n");
973                                         ifxhcd->flags.b.port_connect_status_change = 0;
974                                         break;
975                                 case USB_PORT_FEAT_C_RESET:
976                                         /* Clears the driver's internal Port Reset Change
977                                          * flag */
978                                         IFX_DEBUGPL (DBG_HCD, "IFXUSB HCD HUB CONTROL - "
979                                                      "ClearPortFeature USB_PORT_FEAT_C_RESET\n");
980                                         ifxhcd->flags.b.port_reset_change = 0;
981                                         break;
982                                 case USB_PORT_FEAT_C_ENABLE:
983                                         /* Clears the driver's internal Port
984                                          * Enable/Disable Change flag */
985                                         IFX_DEBUGPL (DBG_HCD, "IFXUSB HCD HUB CONTROL - "
986                                                      "ClearPortFeature USB_PORT_FEAT_C_ENABLE\n");
987                                         ifxhcd->flags.b.port_enable_change = 0;
988                                         break;
989                                 case USB_PORT_FEAT_C_SUSPEND:
990                                         /* Clears the driver's internal Port Suspend
991                                          * Change flag, which is set when resume signaling on
992                                          * the host port is complete */
993                                         IFX_DEBUGPL (DBG_HCD, "IFXUSB HCD HUB CONTROL - "
994                                                      "ClearPortFeature USB_PORT_FEAT_C_SUSPEND\n");
995                                         ifxhcd->flags.b.port_suspend_change = 0;
996                                         break;
997                                 case USB_PORT_FEAT_C_OVER_CURRENT:
998                                         IFX_DEBUGPL (DBG_HCD, "IFXUSB HCD HUB CONTROL - "
999                                                      "ClearPortFeature USB_PORT_FEAT_C_OVER_CURRENT\n");
1000                                         ifxhcd->flags.b.port_over_current_change = 0;
1001                                         break;
1002                                 default:
1003                                         retval = -EINVAL;
1004                                         IFX_ERROR ("IFXUSB HCD - "
1005                                                  "ClearPortFeature request %xh "
1006                                                  "unknown or unsupported\n", _wValue);
1007                         }
1008                         break;
1009                 case GetHubDescriptor:
1010                         IFX_DEBUGPL (DBG_HCD, "IFXUSB HCD HUB CONTROL - "
1011                                  "GetHubDescriptor\n");
1012                         desc = (struct usb_hub_descriptor *)_buf;
1013                         desc->bDescLength = 9;
1014                         desc->bDescriptorType = 0x29;
1015                         desc->bNbrPorts = 1;
1016                         desc->wHubCharacteristics = 0x08;
1017                         desc->bPwrOn2PwrGood = 1;
1018                         desc->bHubContrCurrent = 0;
1019 //                      desc->bitmap[0] = 0;
1020 //                      desc->bitmap[1] = 0xff;
1021                         break;
1022                 case GetHubStatus:
1023                         IFX_DEBUGPL (DBG_HCD, "IFXUSB HCD HUB CONTROL - "
1024                                  "GetHubStatus\n");
1025                         memset (_buf, 0, 4);
1026                         break;
1027                 case GetPortStatus:
1028                         IFX_DEBUGPL (DBG_HCD, "IFXUSB HCD HUB CONTROL - "
1029                                  "GetPortStatus\n");
1030                         if (!_wIndex || _wIndex > 1)
1031                                 goto error;
1032
1033 #               ifdef CONFIG_AVM_POWERMETER
1034                         {
1035                                 /* first port only, but 2 Hosts */
1036                                 static unsigned char ucOldPower1 = 255;
1037                                 static unsigned char ucOldPower2 = 255;
1038
1039                                 unsigned char ucNewPower = 0;
1040                                 struct usb_device *childdev = _syshcd->self.root_hub->children[0];
1041
1042                                 if (childdev != NULL) {
1043                                         ucNewPower = (childdev->actconfig != NULL)
1044                                                                         ? childdev->actconfig->desc.bMaxPower
1045                                                                         : 50;/* default: 50 means 100 mA*/
1046                                 }
1047                                 if (_syshcd->self.busnum == 1) {
1048                                         if (ucOldPower1 != ucNewPower) {
1049                                                 ucOldPower1 = ucNewPower;
1050                                                 printk (KERN_INFO "IFXHCD#1: AVM Powermeter changed to %u mA\n", ucNewPower*2);
1051                                                 PowerManagmentRessourceInfo(powerdevice_usb_host, ucNewPower*2);
1052                                         }
1053                                 } else {
1054                                         if (ucOldPower2 != ucNewPower) {
1055                                                 ucOldPower2 = ucNewPower;
1056                                                 printk (KERN_INFO "IFXHCD#2: AVM Powermeter changed to %u mA\n", ucNewPower*2);
1057                                                 PowerManagmentRessourceInfo(powerdevice_usb_host2, ucNewPower*2);
1058                                         }
1059                                 }
1060                         }
1061 #               endif  /*--- #ifdef CONFIG_AVM_POWERMETER ---*/
1062
1063                         port_status = 0;
1064                         if (ifxhcd->flags.b.port_connect_status_change)
1065                                 port_status |= (1 << USB_PORT_FEAT_C_CONNECTION);
1066                         if (ifxhcd->flags.b.port_enable_change)
1067                                 port_status |= (1 << USB_PORT_FEAT_C_ENABLE);
1068                         if (ifxhcd->flags.b.port_suspend_change)
1069                                 port_status |= (1 << USB_PORT_FEAT_C_SUSPEND);
1070                         if (ifxhcd->flags.b.port_reset_change)
1071                                 port_status |= (1 << USB_PORT_FEAT_C_RESET);
1072                         if (ifxhcd->flags.b.port_over_current_change)
1073                         {
1074                                 IFX_ERROR("Device Not Supported\n");
1075                                 port_status |= (1 << USB_PORT_FEAT_C_OVER_CURRENT);
1076                         }
1077                         if (!ifxhcd->flags.b.port_connect_status)
1078                         {
1079                                 /*
1080                                  * The port is disconnected, which means the core is
1081                                  * either in device mode or it soon will be. Just
1082                                  * return 0's for the remainder of the port status
1083                                  * since the port register can't be read if the core
1084                                  * is in device mode.
1085                                  */
1086                                 *((u32 *) _buf) = cpu_to_le32(port_status);
1087                                 break;
1088                         }
1089
1090                         hprt0.d32 = ifxusb_rreg(core_if->hprt0);
1091                         IFX_DEBUGPL(DBG_HCDV, "  HPRT0: 0x%08x\n", hprt0.d32);
1092                         if (hprt0.b.prtconnsts)
1093                                 port_status |= (1 << USB_PORT_FEAT_CONNECTION);
1094                         if (hprt0.b.prtena)
1095                                 port_status |= (1 << USB_PORT_FEAT_ENABLE);
1096                         if (hprt0.b.prtsusp)
1097                                 port_status |= (1 << USB_PORT_FEAT_SUSPEND);
1098                         if (hprt0.b.prtovrcurract)
1099                                 port_status |= (1 << USB_PORT_FEAT_OVER_CURRENT);
1100                         if (hprt0.b.prtrst)
1101                                 port_status |= (1 << USB_PORT_FEAT_RESET);
1102                         if (hprt0.b.prtpwr)
1103                                 port_status |= (1 << USB_PORT_FEAT_POWER);
1104 /*                      if (hprt0.b.prtspd == IFXUSB_HPRT0_PRTSPD_HIGH_SPEED)
1105                                 port_status |= (1 << USB_PORT_FEAT_HIGHSPEED);
1106                         else if (hprt0.b.prtspd == IFXUSB_HPRT0_PRTSPD_LOW_SPEED)
1107                                 port_status |= (1 << USB_PORT_FEAT_LOWSPEED);*/
1108                         if (hprt0.b.prttstctl)
1109                                 port_status |= (1 << USB_PORT_FEAT_TEST);
1110                         /* USB_PORT_FEAT_INDICATOR unsupported always 0 */
1111                         *((u32 *) _buf) = cpu_to_le32(port_status);
1112                         break;
1113                 case SetHubFeature:
1114                         IFX_DEBUGPL (DBG_HCD, "IFXUSB HCD HUB CONTROL - "
1115                                  "SetHubFeature\n");
1116                         /* No HUB features supported */
1117                         break;
1118                 case SetPortFeature:
1119                         if (_wValue != USB_PORT_FEAT_TEST && (!_wIndex || _wIndex > 1))
1120                                 goto error;
1121                         /*
1122                          * The port is disconnected, which means the core is
1123                          * either in device mode or it soon will be. Just
1124                          * return without doing anything since the port
1125                          * register can't be written if the core is in device
1126                          * mode.
1127                          */
1128                         if (!ifxhcd->flags.b.port_connect_status)
1129                                 break;
1130                         switch (_wValue)
1131                         {
1132                                 case USB_PORT_FEAT_SUSPEND:
1133                                         IFX_DEBUGPL (DBG_HCD, "IFXUSB HCD HUB CONTROL - "
1134                                                      "SetPortFeature - USB_PORT_FEAT_SUSPEND\n");
1135                                         hprt0.d32 = ifxusb_read_hprt0 (core_if);
1136                                         hprt0.b.prtsusp = 1;
1137                                         ifxusb_wreg(core_if->hprt0, hprt0.d32);
1138                                         //IFX_PRINT( "SUSPEND: HPRT0=%0x\n", hprt0.d32);
1139                                         /* Suspend the Phy Clock */
1140                                         {
1141                                                 pcgcctl_data_t pcgcctl = {.d32=0};
1142                                                 pcgcctl.b.stoppclk = 1;
1143                                                 ifxusb_wreg(core_if->pcgcctl, pcgcctl.d32);
1144                                         }
1145                                         break;
1146                                 case USB_PORT_FEAT_POWER:
1147                                         IFX_DEBUGPL (DBG_HCD, "IFXUSB HCD HUB CONTROL - "
1148                                              "SetPortFeature - USB_PORT_FEAT_POWER\n");
1149                                         ifxusb_vbus_on (core_if);
1150                                         hprt0.d32 = ifxusb_read_hprt0 (core_if);
1151                                         hprt0.b.prtpwr = 1;
1152                                         ifxusb_wreg(core_if->hprt0, hprt0.d32);
1153                                         break;
1154                                 case USB_PORT_FEAT_RESET:
1155                                         IFX_DEBUGPL (DBG_HCD, "IFXUSB HCD HUB CONTROL - "
1156                                                      "SetPortFeature - USB_PORT_FEAT_RESET\n");
1157                                         hprt0.d32 = ifxusb_read_hprt0 (core_if);
1158                                         hprt0.b.prtrst = 1;
1159                                         ifxusb_wreg(core_if->hprt0, hprt0.d32);
1160                                         /* Clear reset bit in 10ms (FS/LS) or 50ms (HS) */
1161                                         MDELAY (60);
1162                                         hprt0.b.prtrst = 0;
1163                                         ifxusb_wreg(core_if->hprt0, hprt0.d32);
1164                                         break;
1165                         #ifdef __WITH_HS_ELECT_TST__
1166                                 case USB_PORT_FEAT_TEST:
1167                                         {
1168                                                 uint32_t t;
1169                                                 gint_data_t gintmsk;
1170                                                 t = (_wIndex >> 8); /* MSB wIndex USB */
1171                                                 IFX_DEBUGPL (DBG_HCD, "IFXUSB HCD HUB CONTROL - "
1172                                                              "SetPortFeature - USB_PORT_FEAT_TEST %d\n", t);
1173                                                 warn("USB_PORT_FEAT_TEST %d\n", t);
1174                                                 if (t < 6)
1175                                                 {
1176                                                         hprt0.d32 = ifxusb_read_hprt0 (core_if);
1177                                                         hprt0.b.prttstctl = t;
1178                                                         ifxusb_wreg(core_if->hprt0, hprt0.d32);
1179                                                 }
1180                                                 else if (t == 6)  /* HS_HOST_PORT_SUSPEND_RESUME */
1181                                                 {
1182                                                         /* Save current interrupt mask */
1183                                                         gintmsk.d32 = ifxusb_rreg(&core_if->core_global_regs->gintmsk);
1184
1185                                                         /* Disable all interrupts while we muck with
1186                                                          * the hardware directly
1187                                                          */
1188                                                         ifxusb_wreg(&core_if->core_global_regs->gintmsk, 0);
1189
1190                                                         /* 15 second delay per the test spec */
1191                                                         mdelay(15000);
1192
1193                                                         /* Drive suspend on the root port */
1194                                                         hprt0.d32 = ifxusb_read_hprt0 (core_if);
1195                                                         hprt0.b.prtsusp = 1;
1196                                                         hprt0.b.prtres = 0;
1197                                                         ifxusb_wreg(core_if->hprt0, hprt0.d32);
1198
1199                                                         /* 15 second delay per the test spec */
1200                                                         mdelay(15000);
1201
1202                                                         /* Drive resume on the root port */
1203                                                         hprt0.d32 = ifxusb_read_hprt0 (core_if);
1204                                                         hprt0.b.prtsusp = 0;
1205                                                         hprt0.b.prtres = 1;
1206                                                         ifxusb_wreg(core_if->hprt0, hprt0.d32);
1207                                                         mdelay(100);
1208
1209                                                         /* Clear the resume bit */
1210                                                         hprt0.b.prtres = 0;
1211                                                         ifxusb_wreg(core_if->hprt0, hprt0.d32);
1212
1213                                                         /* Restore interrupts */
1214                                                         ifxusb_wreg(&core_if->core_global_regs->gintmsk, gintmsk.d32);
1215                                                 }
1216                                                 else if (t == 7)  /* SINGLE_STEP_GET_DEVICE_DESCRIPTOR setup */
1217                                                 {
1218                                                         /* Save current interrupt mask */
1219                                                         gintmsk.d32 = ifxusb_rreg(&core_if->core_global_regs->gintmsk);
1220
1221                                                         /* Disable all interrupts while we muck with
1222                                                          * the hardware directly
1223                                                          */
1224                                                         ifxusb_wreg(&core_if->core_global_regs->gintmsk, 0);
1225
1226                                                         /* 15 second delay per the test spec */
1227                                                         mdelay(15000);
1228
1229                                                         /* Send the Setup packet */
1230                                                         do_setup(core_if);
1231
1232                                                         /* 15 second delay so nothing else happens for awhile */
1233                                                         mdelay(15000);
1234
1235                                                         /* Restore interrupts */
1236                                                         ifxusb_wreg(&core_if->core_global_regs->gintmsk, gintmsk.d32);
1237                                                 }
1238
1239                                                 else if (t == 8)  /* SINGLE_STEP_GET_DEVICE_DESCRIPTOR execute */
1240                                                 {
1241                                                         /* Save current interrupt mask */
1242                                                         gintmsk.d32 = ifxusb_rreg(&core_if->core_global_regs->gintmsk);
1243
1244                                                         /* Disable all interrupts while we muck with
1245                                                          * the hardware directly
1246                                                          */
1247                                                         ifxusb_wreg(&core_if->core_global_regs->gintmsk, 0);
1248
1249                                                         /* Send the Setup packet */
1250                                                         do_setup(core_if);
1251
1252                                                         /* 15 second delay so nothing else happens for awhile */
1253                                                         mdelay(15000);
1254
1255                                                         /* Send the In and Ack packets */
1256                                                         do_in_ack(core_if);
1257
1258                                                         /* 15 second delay so nothing else happens for awhile */
1259                                                         mdelay(15000);
1260
1261                                                         /* Restore interrupts */
1262                                                         ifxusb_wreg(&core_if->core_global_regs->gintmsk, gintmsk.d32);
1263                                                 }
1264                                         }
1265                                         break;
1266                         #endif //__WITH_HS_ELECT_TST__
1267                                 case USB_PORT_FEAT_INDICATOR:
1268                                         IFX_DEBUGPL (DBG_HCD, "IFXUSB HCD HUB CONTROL - "
1269                                                      "SetPortFeature - USB_PORT_FEAT_INDICATOR\n");
1270                                         /* Not supported */
1271                                         break;
1272                                 default:
1273                                         retval = -EINVAL;
1274                                         IFX_ERROR ("IFXUSB HCD - "
1275                                                    "SetPortFeature request %xh "
1276                                                    "unknown or unsupported\n", _wValue);
1277                         }
1278                         break;
1279                 default:
1280                 error:
1281                         retval = -EINVAL;
1282                         IFX_WARN ("IFXUSB HCD - "
1283                                   "Unknown hub control request type or invalid typeReq: %xh wIndex: %xh wValue: %xh\n",
1284                                   _typeReq, _wIndex, _wValue);
1285         }
1286         return retval;
1287 }
1288
1289
1290 /*!
1291  \brief Assigns transactions from a URBD to a free host channel and initializes the
1292  host channel to perform the transactions. The host channel is removed from
1293  the free list.
1294  \param _ifxhcd The HCD state structure.
1295  \param _epqh Transactions from the first URBD for this EPQH are selected and assigned to a free host channel.
1296  */
1297 static int assign_and_init_hc(ifxhcd_hcd_t *_ifxhcd, ifxhcd_epqh_t *_epqh)
1298 {
1299         ifxhcd_hc_t   *ifxhc;
1300         ifxhcd_urbd_t *urbd;
1301         struct urb    *urb;
1302
1303         IFX_DEBUGPL(DBG_HCDV, "%s(%p,%p)\n", __func__, _ifxhcd, _epqh);
1304
1305         if(list_empty(&_epqh->urbd_list))
1306                 return 0;
1307
1308         ifxhc = list_entry(_ifxhcd->free_hc_list.next, ifxhcd_hc_t, hc_list_entry);
1309         /* Remove the host channel from the free list. */
1310         list_del_init(&ifxhc->hc_list_entry);
1311
1312         urbd = list_entry(_epqh->urbd_list.next, ifxhcd_urbd_t, urbd_list_entry);
1313         urb  = urbd->urb;
1314
1315         _epqh->hc   = ifxhc;
1316         _epqh->urbd = urbd;
1317         ifxhc->epqh = _epqh;
1318
1319         urbd->is_active=1;
1320
1321         /*
1322          * Use usb_pipedevice to determine device address. This address is
1323          * 0 before the SET_ADDRESS command and the correct address afterward.
1324          */
1325         ifxhc->dev_addr = usb_pipedevice(urb->pipe);
1326         ifxhc->ep_num   = usb_pipeendpoint(urb->pipe);
1327
1328         ifxhc->xfer_started   = 0;
1329
1330         if      (urb->dev->speed == USB_SPEED_LOW)  ifxhc->speed = IFXUSB_EP_SPEED_LOW;
1331         else if (urb->dev->speed == USB_SPEED_FULL) ifxhc->speed = IFXUSB_EP_SPEED_FULL;
1332         else                                        ifxhc->speed = IFXUSB_EP_SPEED_HIGH;
1333
1334         ifxhc->mps         = _epqh->mps;
1335         ifxhc->halt_status = HC_XFER_NO_HALT_STATUS;
1336
1337         ifxhc->ep_type = _epqh->ep_type;
1338
1339         if(_epqh->ep_type==IFXUSB_EP_TYPE_CTRL)
1340         {
1341                 ifxhc->control_phase=IFXHCD_CONTROL_SETUP;
1342                 ifxhc->is_in          = 0;
1343                 ifxhc->data_pid_start = IFXUSB_HC_PID_SETUP;
1344                 ifxhc->xfer_buff      = urbd->setup_buff;
1345                 ifxhc->xfer_len       = 8;
1346                 ifxhc->xfer_count     = 0;
1347                 ifxhc->short_rw       =(urb->transfer_flags & URB_ZERO_PACKET)?1:0;
1348         }
1349         else
1350         {
1351                 ifxhc->is_in          = urbd->is_in;
1352                 ifxhc->xfer_buff      = urbd->xfer_buff;
1353                 ifxhc->xfer_len       = urbd->xfer_len;
1354                 ifxhc->xfer_count     = 0;
1355                 /* == AVM/WK 20100710 Fix - Use toggle of usbcore ==*/
1356                 //ifxhc->data_pid_start = _epqh->data_toggle;
1357                 ifxhc->data_pid_start = usb_gettoggle (urb->dev, usb_pipeendpoint(urb->pipe), usb_pipeout (urb->pipe))
1358                                                                 ? IFXUSB_HC_PID_DATA1
1359                                                                 : IFXUSB_HC_PID_DATA0;
1360                 if(ifxhc->is_in)
1361                         ifxhc->short_rw       =0;
1362                 else
1363                         ifxhc->short_rw       =(urb->transfer_flags & URB_ZERO_PACKET)?1:0;
1364
1365                 #ifdef __EN_ISOC__
1366                         if(_epqh->ep_type==IFXUSB_EP_TYPE_ISOC)
1367                         {
1368                                 struct usb_iso_packet_descriptor *frame_desc;
1369                                 frame_desc = &urb->iso_frame_desc[urbd->isoc_frame_index];
1370                                 ifxhc->xfer_buff += frame_desc->offset + urbd->isoc_split_offset;
1371                                 ifxhc->xfer_len   = frame_desc->length - urbd->isoc_split_offset;
1372                                 if (ifxhc->isoc_xact_pos == IFXUSB_HCSPLIT_XACTPOS_ALL)
1373                                 {
1374                                         if (ifxhc->xfer_len <= 188)
1375                                                 ifxhc->isoc_xact_pos = IFXUSB_HCSPLIT_XACTPOS_ALL;
1376                                         else
1377                                                 ifxhc->isoc_xact_pos = IFXUSB_HCSPLIT_XACTPOS_BEGIN;
1378                                 }
1379                         }
1380                 #endif
1381         }
1382
1383         ifxhc->do_ping=0;
1384         if (_ifxhcd->core_if.snpsid < 0x4f54271a && ifxhc->speed == IFXUSB_EP_SPEED_HIGH)
1385                 ifxhc->do_ping=1;
1386
1387
1388         /* Set the split attributes */
1389         ifxhc->split = 0;
1390         if (_epqh->need_split) {
1391                 ifxhc->split = 1;
1392                 ifxhc->hub_addr       = urb->dev->tt->hub->devnum;
1393                 ifxhc->port_addr      = urb->dev->ttport;
1394         }
1395
1396         //ifxhc->uint16_t pkt_count_limit
1397
1398         {
1399                 hcint_data_t      hc_intr_mask;
1400                 uint8_t           hc_num = ifxhc->hc_num;
1401                 ifxusb_hc_regs_t *hc_regs = _ifxhcd->core_if.hc_regs[hc_num];
1402
1403                 /* Clear old interrupt conditions for this host channel. */
1404                 hc_intr_mask.d32 = 0xFFFFFFFF;
1405                 hc_intr_mask.b.reserved = 0;
1406                 ifxusb_wreg(&hc_regs->hcint, hc_intr_mask.d32);
1407
1408                 /* Enable channel interrupts required for this transfer. */
1409                 hc_intr_mask.d32 = 0;
1410                 hc_intr_mask.b.chhltd = 1;
1411                 hc_intr_mask.b.ahberr = 1;
1412
1413                 ifxusb_wreg(&hc_regs->hcintmsk, hc_intr_mask.d32);
1414
1415                 /* Enable the top level host channel interrupt. */
1416                 {
1417                         uint32_t          intr_enable;
1418                         intr_enable = (1 << hc_num);
1419                         ifxusb_mreg(&_ifxhcd->core_if.host_global_regs->haintmsk, 0, intr_enable);
1420                 }
1421
1422                 /* Make sure host channel interrupts are enabled. */
1423                 {
1424                         gint_data_t       gintmsk ={.d32 = 0};
1425                         gintmsk.b.hcintr = 1;
1426                         ifxusb_mreg(&_ifxhcd->core_if.core_global_regs->gintmsk, 0, gintmsk.d32);
1427                 }
1428
1429                 /*
1430                  * Program the HCCHARn register with the endpoint characteristics for
1431                  * the current transfer.
1432                  */
1433                 {
1434                         hcchar_data_t     hcchar;
1435
1436                         hcchar.d32 = 0;
1437                         hcchar.b.devaddr   =  ifxhc->dev_addr;
1438                         hcchar.b.epnum     =  ifxhc->ep_num;
1439                         hcchar.b.lspddev   = (ifxhc->speed == IFXUSB_EP_SPEED_LOW);
1440                         hcchar.b.eptype    =  ifxhc->ep_type;
1441                         hcchar.b.mps       =  ifxhc->mps;
1442                         ifxusb_wreg(&hc_regs->hcchar, hcchar.d32);
1443
1444                         IFX_DEBUGPL(DBG_HCDV, "%s: Channel %d\n", __func__, ifxhc->hc_num);
1445                         IFX_DEBUGPL(DBG_HCDV, "  Dev Addr: %d\n"    , hcchar.b.devaddr);
1446                         IFX_DEBUGPL(DBG_HCDV, "  Ep Num: %d\n"      , hcchar.b.epnum);
1447                         IFX_DEBUGPL(DBG_HCDV, "  Is Low Speed: %d\n", hcchar.b.lspddev);
1448                         IFX_DEBUGPL(DBG_HCDV, "  Ep Type: %d\n"     , hcchar.b.eptype);
1449                         IFX_DEBUGPL(DBG_HCDV, "  Max Pkt: %d\n"     , hcchar.b.mps);
1450                         IFX_DEBUGPL(DBG_HCDV, "  Multi Cnt: %d\n"   , hcchar.b.multicnt);
1451                 }
1452                 /* Program the HCSPLIT register for SPLITs */
1453                 {
1454                         hcsplt_data_t     hcsplt;
1455
1456                         hcsplt.d32 = 0;
1457                         if (ifxhc->split)
1458                         {
1459                                 IFX_DEBUGPL(DBG_HCDV, "Programming HC %d with split --> %s\n", ifxhc->hc_num,
1460                                            (ifxhc->split==2) ? "CSPLIT" : "SSPLIT");
1461                                 hcsplt.b.spltena  = 1;
1462                                 hcsplt.b.compsplt = (ifxhc->split==2);
1463                                 #ifdef __EN_ISOC__
1464                                         if(_epqh->ep_type==IFXUSB_EP_TYPE_ISOC)
1465                                                 hcsplt.b.xactpos  = ifxhc->isoc_xact_pos;
1466                                         else
1467                                 #endif
1468                                         hcsplt.b.xactpos  = IFXUSB_HCSPLIT_XACTPOS_ALL;
1469                                 hcsplt.b.hubaddr  = ifxhc->hub_addr;
1470                                 hcsplt.b.prtaddr  = ifxhc->port_addr;
1471                                 IFX_DEBUGPL(DBG_HCDV, "   comp split %d\n" , hcsplt.b.compsplt);
1472                                 IFX_DEBUGPL(DBG_HCDV, "   xact pos %d\n"   , hcsplt.b.xactpos);
1473                                 IFX_DEBUGPL(DBG_HCDV, "   hub addr %d\n"   , hcsplt.b.hubaddr);
1474                                 IFX_DEBUGPL(DBG_HCDV, "   port addr %d\n"  , hcsplt.b.prtaddr);
1475                                 IFX_DEBUGPL(DBG_HCDV, "   is_in %d\n"      , ifxhc->is_in);
1476                                 IFX_DEBUGPL(DBG_HCDV, "   Max Pkt: %d\n"   , ifxhc->mps);
1477                                 IFX_DEBUGPL(DBG_HCDV, "   xferlen: %d\n"   , ifxhc->xfer_len);
1478                         }
1479                         ifxusb_wreg(&hc_regs->hcsplt, hcsplt.d32);
1480                 }
1481         }
1482
1483         ifxhc->nak_retry_r=ifxhc->nak_retry=0;
1484         ifxhc->nak_countdown_r=ifxhc->nak_countdown=0;
1485
1486         if (ifxhc->split)
1487         {
1488                 if(ifxhc->is_in)
1489                 {
1490                 }
1491                 else
1492                 {
1493                 }
1494         }
1495         else if(_epqh->ep_type==IFXUSB_EP_TYPE_CTRL)
1496         {
1497                 if(ifxhc->is_in)
1498                 {
1499                 }
1500                 else
1501                 {
1502                 }
1503         }
1504         else if(_epqh->ep_type==IFXUSB_EP_TYPE_BULK)
1505         {
1506                 if(ifxhc->is_in)
1507                 {
1508 //                      ifxhc->nak_retry_r=ifxhc->nak_retry=nak_retry_max;
1509 //                      ifxhc->nak_countdown_r=ifxhc->nak_countdown=nak_countdown_max;
1510                 }
1511                 else
1512                 {
1513                 }
1514         }
1515         else if(_epqh->ep_type==IFXUSB_EP_TYPE_INTR)
1516         {
1517                 if(ifxhc->is_in)
1518                 {
1519                 }
1520                 else
1521                 {
1522                 }
1523         }
1524         else if(_epqh->ep_type==IFXUSB_EP_TYPE_ISOC)
1525         {
1526                 if(ifxhc->is_in)
1527                 {
1528                 }
1529                 else
1530                 {
1531                 }
1532         }
1533
1534         return 1;
1535 }
1536
1537 /*!
1538  \brief This function selects transactions from the HCD transfer schedule and
1539   assigns them to available host channels. It is called from HCD interrupt
1540   handler functions.
1541  */
1542 static void select_eps_sub(ifxhcd_hcd_t *_ifxhcd)
1543 {
1544         struct list_head *epqh_ptr;
1545         struct list_head *urbd_ptr;
1546         ifxhcd_epqh_t    *epqh;
1547         ifxhcd_urbd_t    *urbd;
1548         int               ret_val=0;
1549
1550         /*== AVM/BC 20101111 Function called with Lock ==*/
1551
1552 //      #ifdef __DEBUG__
1553 //              IFX_DEBUGPL(DBG_HCD, "  ifxhcd_select_ep\n");
1554 //      #endif
1555
1556         /* Process entries in the periodic ready list. */
1557         #ifdef __EN_ISOC__
1558                 epqh_ptr       = _ifxhcd->epqh_isoc_ready.next;
1559                 while (epqh_ptr != &_ifxhcd->epqh_isoc_ready && !list_empty(&_ifxhcd->free_hc_list))
1560                 {
1561                         epqh = list_entry(epqh_ptr, ifxhcd_epqh_t, epqh_list_entry);
1562                         epqh_ptr = epqh_ptr->next;
1563                         if(epqh->period_do)
1564                         {
1565                                 if(assign_and_init_hc(_ifxhcd, epqh))
1566                                 {
1567                                         IFX_DEBUGPL(DBG_HCD, "  select_eps ISOC\n");
1568                                         list_move_tail(&epqh->epqh_list_entry, &_ifxhcd->epqh_isoc_active);
1569                                         epqh->is_active=1;
1570                                         ret_val=1;
1571                                         epqh->period_do=0;
1572                                 }
1573                         }
1574                 }
1575         #endif
1576
1577         epqh_ptr       = _ifxhcd->epqh_intr_ready.next;
1578         while (epqh_ptr != &_ifxhcd->epqh_intr_ready && !list_empty(&_ifxhcd->free_hc_list))
1579         {
1580                 epqh = list_entry(epqh_ptr, ifxhcd_epqh_t, epqh_list_entry);
1581                 epqh_ptr = epqh_ptr->next;
1582                 if(epqh->period_do)
1583                 {
1584                         if(assign_and_init_hc(_ifxhcd, epqh))
1585                         {
1586                                 IFX_DEBUGPL(DBG_HCD, "  select_eps INTR\n");
1587                                 list_move_tail(&epqh->epqh_list_entry, &_ifxhcd->epqh_intr_active);
1588                                 epqh->is_active=1;
1589                                 ret_val=1;
1590                                 epqh->period_do=0;
1591                         }
1592                 }
1593         }
1594
1595         epqh_ptr       = _ifxhcd->epqh_np_ready.next;
1596         while (epqh_ptr != &_ifxhcd->epqh_np_ready && !list_empty(&_ifxhcd->free_hc_list))  // may need to preserve at lease one for period
1597         {
1598                 epqh = list_entry(epqh_ptr, ifxhcd_epqh_t, epqh_list_entry);
1599                 epqh_ptr = epqh_ptr->next;
1600                 if(assign_and_init_hc(_ifxhcd, epqh))
1601                 {
1602                         IFX_DEBUGPL(DBG_HCD, "  select_eps CTRL/BULK\n");
1603                         list_move_tail(&epqh->epqh_list_entry, &_ifxhcd->epqh_np_active);
1604                         epqh->is_active=1;
1605                         ret_val=1;
1606                 }
1607         }
1608         if(ret_val)
1609                 /*== AVM/BC 20101111 Function called with Lock ==*/
1610                 process_channels_sub(_ifxhcd);
1611
1612         /* AVM/BC 20101111 Urbds completion loop */
1613         while (!list_empty(&_ifxhcd->urbd_complete_list))
1614         {
1615                 urbd_ptr = _ifxhcd->urbd_complete_list.next;
1616                 list_del_init(urbd_ptr);
1617
1618                 urbd = list_entry(urbd_ptr, ifxhcd_urbd_t, urbd_list_entry);
1619
1620                 ifxhcd_complete_urb(_ifxhcd, urbd, urbd->status);
1621
1622         }
1623
1624 }
1625
1626 static void select_eps_func(unsigned long data)
1627 {
1628         unsigned long flags;
1629
1630         ifxhcd_hcd_t *ifxhcd;
1631         ifxhcd=((ifxhcd_hcd_t *)data);
1632
1633         /* AVM/BC 20101111 select_eps_in_use flag removed */
1634
1635         SPIN_LOCK_IRQSAVE(&ifxhcd->lock, flags);
1636
1637         /*if(ifxhcd->select_eps_in_use){
1638                 SPIN_UNLOCK_IRQRESTORE(&ifxhcd->lock, flags);
1639                 return;
1640         }
1641         ifxhcd->select_eps_in_use=1;
1642         */
1643
1644         select_eps_sub(ifxhcd);
1645
1646         //ifxhcd->select_eps_in_use=0;
1647
1648         SPIN_UNLOCK_IRQRESTORE(&ifxhcd->lock, flags);
1649 }
1650
1651 void select_eps(ifxhcd_hcd_t *_ifxhcd)
1652 {
1653         if(in_irq())
1654         {
1655                 if(!_ifxhcd->select_eps.func)
1656                 {
1657                         _ifxhcd->select_eps.next = NULL;
1658                         _ifxhcd->select_eps.state = 0;
1659                         atomic_set( &_ifxhcd->select_eps.count, 0);
1660                         _ifxhcd->select_eps.func = select_eps_func;
1661                         _ifxhcd->select_eps.data = (unsigned long)_ifxhcd;
1662                 }
1663                 tasklet_schedule(&_ifxhcd->select_eps);
1664         }
1665         else
1666         {
1667                 unsigned long flags;
1668
1669                 /* AVM/BC 20101111 select_eps_in_use flag removed */
1670
1671                 SPIN_LOCK_IRQSAVE(&_ifxhcd->lock, flags);
1672
1673                 /*if(_ifxhcd->select_eps_in_use){
1674                         printk ("select_eps non_irq: busy\n");
1675                         SPIN_UNLOCK_IRQRESTORE(&_ifxhcd->lock, flags);
1676                         return;
1677                 }
1678                 _ifxhcd->select_eps_in_use=1;
1679                 */
1680
1681                 select_eps_sub(_ifxhcd);
1682
1683                 //_ifxhcd->select_eps_in_use=0;
1684
1685                 SPIN_UNLOCK_IRQRESTORE(&_ifxhcd->lock, flags);
1686         }
1687 }
1688
1689 /*!
1690  \brief
1691  */
1692 static void process_unaligned( ifxhcd_epqh_t *_epqh)
1693 {
1694         #if   defined(__UNALIGNED_BUFFER_ADJ__)
1695                 if(!_epqh->aligned_checked)
1696                 {
1697                         uint32_t xfer_len;
1698                         xfer_len=_epqh->urbd->xfer_len;
1699                         if(_epqh->urbd->is_in && xfer_len<_epqh->mps)
1700                                 xfer_len = _epqh->mps;
1701                         _epqh->using_aligned_buf=0;
1702
1703                         if(xfer_len > 0 && ((unsigned long)_epqh->urbd->xfer_buff) & 3)
1704                         {
1705                                 if(   _epqh->aligned_buf
1706                                    && _epqh->aligned_buf_len > 0
1707                                    && _epqh->aligned_buf_len < xfer_len
1708                                   )
1709                                 {
1710                                         ifxusb_free_buf(_epqh->aligned_buf);
1711                                         _epqh->aligned_buf=NULL;
1712                                         _epqh->aligned_buf_len=0;
1713                                 }
1714                                 if(! _epqh->aligned_buf || ! _epqh->aligned_buf_len)
1715                                 {
1716                                         _epqh->aligned_buf = ifxusb_alloc_buf(xfer_len, _epqh->urbd->is_in);
1717                                         if(_epqh->aligned_buf)
1718                                                 _epqh->aligned_buf_len = xfer_len;
1719                                 }
1720                                 if(_epqh->aligned_buf)
1721                                 {
1722                                         if(!_epqh->urbd->is_in)
1723                                                 memcpy(_epqh->aligned_buf, _epqh->urbd->xfer_buff, xfer_len);
1724                                         _epqh->using_aligned_buf=1;
1725                                         _epqh->hc->xfer_buff = _epqh->aligned_buf;
1726                                 }
1727                                 else
1728                                         IFX_WARN("%s():%d\n",__func__,__LINE__);
1729                         }
1730                         if(_epqh->ep_type==IFXUSB_EP_TYPE_CTRL)
1731                         {
1732                                 _epqh->using_aligned_setup=0;
1733                                 if(((unsigned long)_epqh->urbd->setup_buff) & 3)
1734                                 {
1735                                         if(! _epqh->aligned_setup)
1736                                                 _epqh->aligned_setup = ifxusb_alloc_buf(8,0);
1737                                         if(_epqh->aligned_setup)
1738                                         {
1739                                                 memcpy(_epqh->aligned_setup, _epqh->urbd->setup_buff, 8);
1740                                                 _epqh->using_aligned_setup=1;
1741                                         }
1742                                         else
1743                                                 IFX_WARN("%s():%d\n",__func__,__LINE__);
1744                                         _epqh->hc->xfer_buff = _epqh->aligned_setup;
1745                                 }
1746                         }
1747                 }
1748         #elif defined(__UNALIGNED_BUFFER_CHK__)
1749                 if(!_epqh->aligned_checked)
1750                 {
1751                         if(_epqh->urbd->is_in)
1752                         {
1753                                 if(_epqh->urbd->xfer_len==0)
1754                                         IFX_WARN("%s():%d IN xfer while length is zero \n",__func__,__LINE__);
1755                                 else{
1756                                         if(_epqh->urbd->xfer_len < _epqh->mps)
1757                                                 IFX_WARN("%s():%d IN xfer while length < mps \n",__func__,__LINE__);
1758
1759                                         if(((unsigned long)_epqh->urbd->xfer_buff) & 3)
1760                                                 IFX_WARN("%s():%d IN xfer Buffer UNALIGNED\n",__func__,__LINE__);
1761                                 }
1762                         }
1763                         else
1764                         {
1765                                 if(_epqh->urbd->xfer_len > 0 && (((unsigned long)_epqh->urbd->xfer_buff) & 3) )
1766                                         IFX_WARN("%s():%d OUT xfer Buffer UNALIGNED\n",__func__,__LINE__);
1767                         }
1768
1769                         if(_epqh->ep_type==IFXUSB_EP_TYPE_CTRL)
1770                         {
1771                                 if(((unsigned long)_epqh->urbd->setup_buff) & 3)
1772                                         IFX_WARN("%s():%d SETUP xfer Buffer UNALIGNED\n",__func__,__LINE__);
1773                         }
1774                 }
1775         #endif
1776         _epqh->aligned_checked=1;
1777 }
1778
1779
1780 /*!
1781  \brief
1782  */
1783 void process_channels_sub(ifxhcd_hcd_t *_ifxhcd)
1784 {
1785         ifxhcd_epqh_t    *epqh;
1786         struct list_head *epqh_item;
1787         struct ifxhcd_hc *hc;
1788
1789         #ifdef __EN_ISOC__
1790                 if (!list_empty(&_ifxhcd->epqh_isoc_active))
1791                 {
1792                         for (epqh_item  =  _ifxhcd->epqh_isoc_active.next;
1793                              epqh_item != &_ifxhcd->epqh_isoc_active;
1794                              )
1795                         {
1796                                 epqh = list_entry(epqh_item, ifxhcd_epqh_t, epqh_list_entry);
1797                                 epqh_item  =  epqh_item->next;
1798                                 hc=epqh->hc;
1799                                 if(hc && !hc->xfer_started && epqh->period_do)
1800                                 {
1801                                         if(hc->split==0
1802                                             || hc->split==1
1803                                            )
1804                                         {
1805                                                 //epqh->ping_state = 0;
1806                                                 process_unaligned(epqh);
1807                                                 hc->wait_for_sof=epqh->wait_for_sof;
1808                                                 epqh->wait_for_sof=0;
1809                                                 ifxhcd_hc_start(&_ifxhcd->core_if, hc);
1810                                                 epqh->period_do=0;
1811                                                 {
1812                                                         gint_data_t gintsts = {.d32 = 0};
1813                                                         gintsts.b.sofintr = 1;
1814                                                         ifxusb_mreg(&_ifxhcd->core_if.core_global_regs->gintmsk,0, gintsts.d32);
1815                                                 }
1816                                         }
1817                                 }
1818                         }
1819                 }
1820         #endif
1821
1822         if (!list_empty(&_ifxhcd->epqh_intr_active))
1823         {
1824                 for (epqh_item  =  _ifxhcd->epqh_intr_active.next;
1825                      epqh_item != &_ifxhcd->epqh_intr_active;
1826                      )
1827                 {
1828                         epqh = list_entry(epqh_item, ifxhcd_epqh_t, epqh_list_entry);
1829                         epqh_item  =  epqh_item->next;
1830                         hc=epqh->hc;
1831                         if(hc && !hc->xfer_started && epqh->period_do)
1832                         {
1833                                 if(hc->split==0
1834                                     || hc->split==1
1835                                    )
1836                                 {
1837                                         //epqh->ping_state = 0;
1838                                         process_unaligned(epqh);
1839                                         hc->wait_for_sof=epqh->wait_for_sof;
1840                                         epqh->wait_for_sof=0;
1841                                         ifxhcd_hc_start(&_ifxhcd->core_if, hc);
1842                                         epqh->period_do=0;
1843 #ifdef __USE_TIMER_4_SOF__
1844                                         /* AVM/WK change: let hc_start decide, if irq is needed */
1845 #else
1846                                         {
1847                                                 gint_data_t gintsts = {.d32 = 0};
1848                                                 gintsts.b.sofintr = 1;
1849                                                 ifxusb_mreg(&_ifxhcd->core_if.core_global_regs->gintmsk,0, gintsts.d32);
1850                                         }
1851 #endif
1852                                 }
1853                         }
1854
1855                 }
1856         }
1857
1858         if (!list_empty(&_ifxhcd->epqh_np_active))
1859         {
1860                 for (epqh_item  =  _ifxhcd->epqh_np_active.next;
1861                      epqh_item != &_ifxhcd->epqh_np_active;
1862                      )
1863                 {
1864                         epqh = list_entry(epqh_item, ifxhcd_epqh_t, epqh_list_entry);
1865                         epqh_item  =  epqh_item->next;
1866                         hc=epqh->hc;
1867                         if(hc)
1868                         {
1869                                 if(!hc->xfer_started)
1870                                 {
1871                                         if(hc->split==0
1872                                             || hc->split==1
1873                                           //|| hc->split_counter == 0
1874                                            )
1875                                         {
1876                                                 //epqh->ping_state = 0;
1877                                                 process_unaligned(epqh);
1878                                                 hc->wait_for_sof=epqh->wait_for_sof;
1879                                                 epqh->wait_for_sof=0;
1880                                                 ifxhcd_hc_start(&_ifxhcd->core_if, hc);
1881                                         }
1882                                 }
1883                         }
1884                 }
1885         }
1886 }
1887
1888 void process_channels(ifxhcd_hcd_t *_ifxhcd)
1889 {
1890         unsigned long flags;
1891
1892         /* AVM/WK Fix: use spin_lock instead busy flag
1893         **/
1894         SPIN_LOCK_IRQSAVE(&_ifxhcd->lock, flags);
1895
1896         //if(_ifxhcd->process_channels_in_use)
1897         //      return;
1898         //_ifxhcd->process_channels_in_use=1;
1899
1900         process_channels_sub(_ifxhcd);
1901         //_ifxhcd->process_channels_in_use=0;
1902         SPIN_UNLOCK_IRQRESTORE(&_ifxhcd->lock, flags);
1903 }
1904
1905
1906 #ifdef __HC_XFER_TIMEOUT__
1907         static void hc_xfer_timeout(unsigned long _ptr)
1908         {
1909                 hc_xfer_info_t *xfer_info = (hc_xfer_info_t *)_ptr;
1910                 int hc_num = xfer_info->hc->hc_num;
1911                 IFX_WARN("%s: timeout on channel %d\n", __func__, hc_num);
1912                 IFX_WARN("  start_hcchar_val 0x%08x\n", xfer_info->hc->start_hcchar_val);
1913         }
1914 #endif
1915
1916 void ifxhcd_hc_dumb_rx(ifxusb_core_if_t *_core_if, ifxhcd_hc_t *_ifxhc,uint8_t   *dump_buf)
1917 {
1918         ifxusb_hc_regs_t *hc_regs = _core_if->hc_regs[_ifxhc->hc_num];
1919         hctsiz_data_t hctsiz= { .d32=0 };
1920         hcchar_data_t hcchar;
1921
1922
1923         _ifxhc->xfer_len = _ifxhc->mps;
1924         hctsiz.b.xfersize = _ifxhc->mps;
1925         hctsiz.b.pktcnt   = 0;
1926         hctsiz.b.pid      = _ifxhc->data_pid_start;
1927         ifxusb_wreg(&hc_regs->hctsiz, hctsiz.d32);
1928
1929         ifxusb_wreg(&hc_regs->hcdma, (uint32_t)(CPHYSADDR( ((uint32_t)(dump_buf)))));
1930
1931         {
1932                 hcint_data_t hcint= { .d32=0 };
1933 //              hcint.b.nak =1;
1934 //              hcint.b.nyet=1;
1935 //              hcint.b.ack =1;
1936                 hcint.d32 =0xFFFFFFFF;
1937                 ifxusb_wreg(&hc_regs->hcint, hcint.d32);
1938         }
1939
1940         /* Set host channel enable after all other setup is complete. */
1941         hcchar.b.chen  = 1;
1942         hcchar.b.chdis = 0;
1943         hcchar.b.epdir = 1;
1944         IFX_DEBUGPL(DBG_HCDV, "  HCCHART: 0x%08x\n", hcchar.d32);
1945         ifxusb_wreg(&hc_regs->hcchar, hcchar.d32);
1946 }
1947
1948 /*!
1949    \brief This function trigger a data transfer for a host channel and
1950   starts the transfer.
1951
1952   For a PING transfer in Slave mode, the Do Ping bit is set in the HCTSIZ
1953   register along with a packet count of 1 and the channel is enabled. This
1954   causes a single PING transaction to occur. Other fields in HCTSIZ are
1955   simply set to 0 since no data transfer occurs in this case.
1956
1957   For a PING transfer in DMA mode, the HCTSIZ register is initialized with
1958   all the information required to perform the subsequent data transfer. In
1959   addition, the Do Ping bit is set in the HCTSIZ register. In this case, the
1960   controller performs the entire PING protocol, then starts the data
1961   transfer.
1962   \param _core_if        Pointer of core_if structure
1963   \param _ifxhc Information needed to initialize the host channel. The xfer_len
1964   value may be reduced to accommodate the max widths of the XferSize and
1965   PktCnt fields in the HCTSIZn register. The multi_count value may be changed
1966   to reflect the final xfer_len value.
1967  */
1968 void ifxhcd_hc_start(ifxusb_core_if_t *_core_if, ifxhcd_hc_t *_ifxhc)
1969 {
1970         hctsiz_data_t hctsiz= { .d32=0 };
1971         hcchar_data_t hcchar;
1972         uint32_t max_hc_xfer_size = _core_if->params.max_transfer_size;
1973         uint16_t max_hc_pkt_count = _core_if->params.max_packet_count;
1974         ifxusb_hc_regs_t *hc_regs = _core_if->hc_regs[_ifxhc->hc_num];
1975         hfnum_data_t hfnum;
1976
1977         hctsiz.b.dopng = 0;
1978 //      if(_ifxhc->do_ping && !_ifxhc->is_in) hctsiz.b.dopng = 1;
1979
1980         _ifxhc->nak_countdown=_ifxhc->nak_countdown_r;
1981
1982         /* AVM/BC 20101111 Workaround: Always PING if HI-Speed Out and xfer_len > 0 */
1983         if(/*_ifxhc->do_ping &&*/
1984                 (!_ifxhc->is_in) &&
1985                 (_ifxhc->speed == IFXUSB_EP_SPEED_HIGH) &&
1986                 ((_ifxhc->ep_type == IFXUSB_EP_TYPE_BULK) || ((_ifxhc->ep_type == IFXUSB_EP_TYPE_CTRL) && (_ifxhc->control_phase != IFXHCD_CONTROL_SETUP))) &&
1987                 _ifxhc->xfer_len
1988                 )
1989                 hctsiz.b.dopng = 1;
1990
1991         _ifxhc->xfer_started = 1;
1992
1993         if(_ifxhc->epqh->pkt_count_limit > 0 && _ifxhc->epqh->pkt_count_limit < max_hc_pkt_count )
1994         {
1995                 max_hc_pkt_count=_ifxhc->epqh->pkt_count_limit;
1996                 if(max_hc_pkt_count * _ifxhc->mps <  max_hc_xfer_size)
1997                         max_hc_xfer_size = max_hc_pkt_count * _ifxhc->mps;
1998         }
1999         if (_ifxhc->split > 0)
2000         {
2001                 {
2002                         gint_data_t gintsts = {.d32 = 0};
2003                         gintsts.b.sofintr = 1;
2004                         ifxusb_mreg(&_core_if->core_global_regs->gintmsk,0, gintsts.d32);
2005                 }
2006
2007                 _ifxhc->start_pkt_count = 1;
2008                 if(!_ifxhc->is_in && _ifxhc->split>1) // OUT CSPLIT
2009                         _ifxhc->xfer_len = 0;
2010                 if (_ifxhc->xfer_len > _ifxhc->mps)
2011                         _ifxhc->xfer_len = _ifxhc->mps;
2012                 if (_ifxhc->xfer_len > 188)
2013                         _ifxhc->xfer_len = 188;
2014         }
2015         else if(_ifxhc->is_in)
2016         {
2017                 _ifxhc->short_rw = 0;
2018                 if (_ifxhc->xfer_len > 0)
2019                 {
2020                         if (_ifxhc->xfer_len > max_hc_xfer_size)
2021                                 _ifxhc->xfer_len = max_hc_xfer_size - _ifxhc->mps + 1;
2022                         _ifxhc->start_pkt_count = (_ifxhc->xfer_len + _ifxhc->mps - 1) / _ifxhc->mps;
2023                         if (_ifxhc->start_pkt_count > max_hc_pkt_count)
2024                                 _ifxhc->start_pkt_count = max_hc_pkt_count;
2025                 }
2026                 else /* Need 1 packet for transfer length of 0. */
2027                         _ifxhc->start_pkt_count = 1;
2028                 _ifxhc->xfer_len = _ifxhc->start_pkt_count * _ifxhc->mps;
2029         }
2030         else //non-split out
2031         {
2032                 if (_ifxhc->xfer_len == 0)
2033                 {
2034                         /*== AVM/BC WK 20110421 ZERO PACKET Workaround: Is not an error ==*/
2035                         //if(_ifxhc->short_rw==0)
2036                         //      printk(KERN_INFO "%s() line %d: ZLP write without short_rw set!\n",__func__,__LINE__);
2037                         _ifxhc->start_pkt_count = 1;
2038                 }
2039                 else
2040                 {
2041                         if (_ifxhc->xfer_len > max_hc_xfer_size)
2042                         {
2043                                 _ifxhc->start_pkt_count = (max_hc_xfer_size / _ifxhc->mps);
2044                                 _ifxhc->xfer_len = _ifxhc->start_pkt_count * _ifxhc->mps;
2045                         }
2046                         else
2047                         {
2048                                 _ifxhc->start_pkt_count = (_ifxhc->xfer_len+_ifxhc->mps-1)  / _ifxhc->mps;
2049 //                              if(_ifxhc->start_pkt_count * _ifxhc->mps == _ifxhc->xfer_len )
2050 //                                      _ifxhc->start_pkt_count += _ifxhc->short_rw;
2051                                 /*== AVM/BC WK 20110421 ZERO PACKET Workaround / check if short_rw is needed ==*/
2052                                 if(_ifxhc->start_pkt_count * _ifxhc->mps != _ifxhc->xfer_len )
2053                                         _ifxhc->short_rw = 0;
2054                         }
2055                 }
2056         }
2057
2058         #ifdef __EN_ISOC__
2059                 if (_ifxhc->ep_type == IFXUSB_EP_TYPE_ISOC)
2060                 {
2061                         /* Set up the initial PID for the transfer. */
2062                         #if 1
2063                                 _ifxhc->data_pid_start = IFXUSB_HC_PID_DATA0;
2064                         #else
2065                                 if (_ifxhc->speed == IFXUSB_EP_SPEED_HIGH)
2066                                 {
2067                                         if (_ifxhc->is_in)
2068                                         {
2069                                                 if      (_ifxhc->multi_count == 1)
2070                                                         _ifxhc->data_pid_start = IFXUSB_HC_PID_DATA0;
2071                                                 else if (_ifxhc->multi_count == 2)
2072                                                         _ifxhc->data_pid_start = IFXUSB_HC_PID_DATA1;
2073                                                 else
2074                                                         _ifxhc->data_pid_start = IFXUSB_HC_PID_DATA2;
2075                                         }
2076                                         else
2077                                         {
2078                                                 if (_ifxhc->multi_count == 1)
2079                                                         _ifxhc->data_pid_start = IFXUSB_HC_PID_DATA0;
2080                                                 else
2081                                                         _ifxhc->data_pid_start = IFXUSB_HC_PID_MDATA;
2082                                         }
2083                                 }
2084                                 else
2085                                         _ifxhc->data_pid_start = IFXUSB_HC_PID_DATA0;
2086                         #endif
2087                 }
2088         #endif
2089
2090         hctsiz.b.xfersize = _ifxhc->xfer_len;
2091         hctsiz.b.pktcnt   = _ifxhc->start_pkt_count;
2092         hctsiz.b.pid      = _ifxhc->data_pid_start;
2093
2094         ifxusb_wreg(&hc_regs->hctsiz, hctsiz.d32);
2095
2096
2097         IFX_DEBUGPL(DBG_HCDV, "%s: Channel %d\n", __func__, _ifxhc->hc_num);
2098         IFX_DEBUGPL(DBG_HCDV, "  Xfer Size: %d\n", hctsiz.b.xfersize);
2099         IFX_DEBUGPL(DBG_HCDV, "  Num Pkts: %d\n" , hctsiz.b.pktcnt);
2100         IFX_DEBUGPL(DBG_HCDV, "  Start PID: %d\n", hctsiz.b.pid);
2101         IFX_DEBUGPL(DBG_HCDV, "  DMA: 0x%08x\n", (uint32_t)(CPHYSADDR( ((uint32_t)(_ifxhc->xfer_buff))+ _ifxhc->xfer_count )));
2102         ifxusb_wreg(&hc_regs->hcdma, (uint32_t)(CPHYSADDR( ((uint32_t)(_ifxhc->xfer_buff))+ _ifxhc->xfer_count )));
2103
2104         /* Start the split */
2105         if (_ifxhc->split>0)
2106         {
2107                 hcsplt_data_t hcsplt;
2108                 hcsplt.d32 = ifxusb_rreg (&hc_regs->hcsplt);
2109                 hcsplt.b.spltena = 1;
2110                 if (_ifxhc->split>1)
2111                         hcsplt.b.compsplt = 1;
2112                 else
2113                         hcsplt.b.compsplt = 0;
2114
2115                 #ifdef __EN_ISOC__
2116                         if (_ifxhc->ep_type == IFXUSB_EP_TYPE_ISOC)
2117                                 hcsplt.b.xactpos = _ifxhc->isoc_xact_pos;
2118                         else
2119                 #endif
2120                 hcsplt.b.xactpos = IFXUSB_HCSPLIT_XACTPOS_ALL;// if not ISO
2121                 ifxusb_wreg(&hc_regs->hcsplt, hcsplt.d32);
2122                 IFX_DEBUGPL(DBG_HCDV, "  SPLIT: XACT_POS:0x%08x\n", hcsplt.d32);
2123         }
2124
2125         hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
2126 //      hcchar.b.multicnt = _ifxhc->multi_count;
2127         hcchar.b.multicnt = 1;
2128
2129         #ifdef __DEBUG__
2130                 _ifxhc->start_hcchar_val = hcchar.d32;
2131                 if (hcchar.b.chdis)
2132                         IFX_WARN("%s: chdis set, channel %d, hcchar 0x%08x\n",
2133                                  __func__, _ifxhc->hc_num, hcchar.d32);
2134         #endif
2135
2136         /* Set host channel enable after all other setup is complete. */
2137         hcchar.b.chen  = 1;
2138         hcchar.b.chdis = 0;
2139         hcchar.b.epdir =  _ifxhc->is_in;
2140         _ifxhc->hcchar=hcchar.d32;
2141
2142         IFX_DEBUGPL(DBG_HCDV, "  HCCHART: 0x%08x\n", _ifxhc->hcchar);
2143
2144         /* == 20110901 AVM/WK Fix: Clear IRQ flags in any case ==*/
2145         {
2146                 hcint_data_t hcint= { .d32=0 };
2147                 hcint.d32 =0xFFFFFFFF;
2148                 ifxusb_wreg(&hc_regs->hcint, hcint.d32);
2149         }
2150
2151         if(_ifxhc->wait_for_sof==0)
2152         {
2153                 hcint_data_t hcint;
2154
2155                 hcint.d32=ifxusb_rreg(&hc_regs->hcintmsk);
2156
2157                 hcint.b.nak =0;
2158                 hcint.b.ack =0;
2159                 /* == 20110901 AVM/WK Fix: We don't need NOT YET IRQ ==*/
2160                 hcint.b.nyet=0;
2161                 if(_ifxhc->nak_countdown_r)
2162                         hcint.b.nak =1;
2163                 ifxusb_wreg(&hc_regs->hcintmsk, hcint.d32);
2164
2165                 /* AVM WK / BC 20100827
2166                  * MOVED. Oddframe updated inmediatly before write HCChar Register.
2167                  */
2168                 if (_ifxhc->ep_type == IFXUSB_EP_TYPE_INTR || _ifxhc->ep_type == IFXUSB_EP_TYPE_ISOC)
2169                 {
2170                         hfnum.d32 = ifxusb_rreg(&_core_if->host_global_regs->hfnum);
2171                         /* 1 if _next_ frame is odd, 0 if it's even */
2172                         hcchar.b.oddfrm = (hfnum.b.frnum & 0x1) ? 0 : 1;
2173                         _ifxhc->hcchar=hcchar.d32;
2174                 }
2175
2176                 ifxusb_wreg(&hc_regs->hcchar, _ifxhc->hcchar);
2177 #ifdef __USE_TIMER_4_SOF__
2178         } else {
2179                 //activate SOF IRQ
2180                 gint_data_t gintsts = {.d32 = 0};
2181                 gintsts.b.sofintr = 1;
2182                 ifxusb_mreg(&_core_if->core_global_regs->gintmsk,0, gintsts.d32);
2183 #endif
2184         }
2185
2186         #ifdef __HC_XFER_TIMEOUT__
2187                 /* Start a timer for this transfer. */
2188                 init_timer(&_ifxhc->hc_xfer_timer);
2189                 _ifxhc->hc_xfer_timer.function = hc_xfer_timeout;
2190                 _ifxhc->hc_xfer_timer.core_if = _core_if;
2191                 _ifxhc->hc_xfer_timer.hc = _ifxhc;
2192                 _ifxhc->hc_xfer_timer.data = (unsigned long)(&_ifxhc->hc_xfer_info);
2193                 _ifxhc->hc_xfer_timer.expires = jiffies + (HZ*10);
2194                 add_timer(&_ifxhc->hc_xfer_timer);
2195         #endif
2196 }
2197
2198 /*!
2199    \brief Attempts to halt a host channel. This function should only be called
2200   to abort a transfer in DMA mode. Under normal circumstances in DMA mode, the
2201   controller halts the channel when the transfer is complete or a condition
2202   occurs that requires application intervention.
2203
2204   In DMA mode, always sets the Channel Enable and Channel Disable bits of the
2205   HCCHARn register. The controller ensures there is space in the request
2206   queue before submitting the halt request.
2207
2208   Some time may elapse before the core flushes any posted requests for this
2209   host channel and halts. The Channel Halted interrupt handler completes the
2210   deactivation of the host channel.
2211  */
2212 void ifxhcd_hc_halt(ifxusb_core_if_t *_core_if,
2213                     ifxhcd_hc_t *_ifxhc,
2214                     ifxhcd_halt_status_e _halt_status)
2215 {
2216         hcchar_data_t   hcchar;
2217         ifxusb_hc_regs_t           *hc_regs;
2218
2219         hc_regs          = _core_if->hc_regs[_ifxhc->hc_num];
2220
2221         WARN_ON(_halt_status == HC_XFER_NO_HALT_STATUS);
2222
2223         if (_halt_status == HC_XFER_URB_DEQUEUE ||
2224             _halt_status == HC_XFER_AHB_ERR)
2225         {
2226                 /*
2227                  * Disable all channel interrupts except Ch Halted. The URBD
2228                  * and EPQH state associated with this transfer has been cleared
2229                  * (in the case of URB_DEQUEUE), so the channel needs to be
2230                  * shut down carefully to prevent crashes.
2231                  */
2232                 hcint_data_t hcintmsk;
2233                 hcintmsk.d32 = 0;
2234                 hcintmsk.b.chhltd = 1;
2235                 ifxusb_wreg(&hc_regs->hcintmsk, hcintmsk.d32);
2236
2237                 /*
2238                  * Make sure no other interrupts besides halt are currently
2239                  * pending. Handling another interrupt could cause a crash due
2240                  * to the URBD and EPQH state.
2241                  */
2242                 ifxusb_wreg(&hc_regs->hcint, ~hcintmsk.d32);
2243
2244                 /*
2245                  * Make sure the halt status is set to URB_DEQUEUE or AHB_ERR
2246                  * even if the channel was already halted for some other
2247                  * reason.
2248                  */
2249                 _ifxhc->halt_status = _halt_status;
2250
2251                 hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
2252                 if (hcchar.b.chen == 0)
2253                 {
2254                         /*
2255                          * The channel is either already halted or it hasn't
2256                          * started yet. In DMA mode, the transfer may halt if
2257                          * it finishes normally or a condition occurs that
2258                          * requires driver intervention. Don't want to halt
2259                          * the channel again. In either Slave or DMA mode,
2260                          * it's possible that the transfer has been assigned
2261                          * to a channel, but not started yet when an URB is
2262                          * dequeued. Don't want to halt a channel that hasn't
2263                          * started yet.
2264                          */
2265                         return;
2266                 }
2267         }
2268
2269         if (_ifxhc->halting)
2270         {
2271                 /*
2272                  * A halt has already been issued for this channel. This might
2273                  * happen when a transfer is aborted by a higher level in
2274                  * the stack.
2275                  */
2276                 #ifdef __DEBUG__
2277                         IFX_PRINT("*** %s: Channel %d, _hc->halting already set ***\n",
2278                                   __func__, _ifxhc->hc_num);
2279                 #endif
2280                 //ifxusb_dump_global_registers(_core_if); */
2281                 //ifxusb_dump_host_registers(_core_if); */
2282                 return;
2283         }
2284         hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
2285         /* == AVM/WK 20100709 halt channel only if enabled ==*/
2286         if (hcchar.b.chen) {
2287                 _ifxhc->halting = 1;
2288                 hcchar.b.chdis = 1;
2289
2290                 ifxusb_wreg(&hc_regs->hcchar, hcchar.d32);
2291                 _ifxhc->halt_status = _halt_status;
2292         }
2293
2294         IFX_DEBUGPL(DBG_HCDV, "%s: Channel %d\n" , __func__, _ifxhc->hc_num);
2295         IFX_DEBUGPL(DBG_HCDV, "  hcchar: 0x%08x\n"   , hcchar.d32);
2296         IFX_DEBUGPL(DBG_HCDV, "  halting: %d\n" , _ifxhc->halting);
2297         IFX_DEBUGPL(DBG_HCDV, "  halt_status: %d\n"  , _ifxhc->halt_status);
2298
2299         return;
2300 }
2301
2302 /*!
2303    \brief Clears a host channel.
2304  */
2305 void ifxhcd_hc_cleanup(ifxusb_core_if_t *_core_if, ifxhcd_hc_t *_ifxhc)
2306 {
2307         ifxusb_hc_regs_t *hc_regs;
2308
2309         _ifxhc->xfer_started = 0;
2310         /*
2311          * Clear channel interrupt enables and any unhandled channel interrupt
2312          * conditions.
2313          */
2314         hc_regs = _core_if->hc_regs[_ifxhc->hc_num];
2315         ifxusb_wreg(&hc_regs->hcintmsk, 0);
2316         ifxusb_wreg(&hc_regs->hcint, 0xFFFFFFFF);
2317
2318         #ifdef __HC_XFER_TIMEOUT__
2319                 del_timer(&_ifxhc->hc_xfer_timer);
2320         #endif
2321         #ifdef __DEBUG__
2322                 {
2323                         hcchar_data_t hcchar;
2324                         hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
2325                         if (hcchar.b.chdis)
2326                                 IFX_WARN("%s: chdis set, channel %d, hcchar 0x%08x\n", __func__, _ifxhc->hc_num, hcchar.d32);
2327                 }
2328         #endif
2329 }
2330
2331
2332
2333
2334
2335
2336
2337
2338 #ifdef __DEBUG__
2339         static void dump_urb_info(struct urb *_urb, char* _fn_name)
2340         {
2341                 IFX_PRINT("%s, urb %p\n"          , _fn_name, _urb);
2342                 IFX_PRINT("  Device address: %d\n", usb_pipedevice(_urb->pipe));
2343                 IFX_PRINT("  Endpoint: %d, %s\n"  , usb_pipeendpoint(_urb->pipe),
2344                                                     (usb_pipein(_urb->pipe) ? "IN" : "OUT"));
2345                 IFX_PRINT("  Endpoint type: %s\n",
2346                     ({  char *pipetype;
2347                         switch (usb_pipetype(_urb->pipe)) {
2348                                 case PIPE_CONTROL:     pipetype = "CONTROL"; break;
2349                                 case PIPE_BULK:        pipetype = "BULK"; break;
2350                                 case PIPE_INTERRUPT:   pipetype = "INTERRUPT"; break;
2351                                 case PIPE_ISOCHRONOUS: pipetype = "ISOCHRONOUS"; break;
2352                                 default:               pipetype = "UNKNOWN"; break;
2353                         };
2354                         pipetype;
2355                     }));
2356                 IFX_PRINT("  Speed: %s\n",
2357                     ({  char *speed;
2358                         switch (_urb->dev->speed) {
2359                                 case USB_SPEED_HIGH: speed = "HIGH"; break;
2360                                 case USB_SPEED_FULL: speed = "FULL"; break;
2361                                 case USB_SPEED_LOW:  speed = "LOW"; break;
2362                                 default:             speed = "UNKNOWN"; break;
2363                         };
2364                         speed;
2365                     }));
2366                 IFX_PRINT("  Max packet size: %d\n",
2367                           usb_maxpacket(_urb->dev, _urb->pipe, usb_pipeout(_urb->pipe)));
2368                 IFX_PRINT("  Data buffer length: %d\n", _urb->transfer_buffer_length);
2369                 IFX_PRINT("  Transfer buffer: %p, Transfer DMA: %p\n",
2370                           _urb->transfer_buffer, (void *)_urb->transfer_dma);
2371                 IFX_PRINT("  Setup buffer: %p, Setup DMA: %p\n",
2372                           _urb->setup_packet, (void *)_urb->setup_dma);
2373                 IFX_PRINT("  Interval: %d\n", _urb->interval);
2374                 if (usb_pipetype(_urb->pipe) == PIPE_ISOCHRONOUS)
2375                 {
2376                         int i;
2377                         for (i = 0; i < _urb->number_of_packets;  i++)
2378                         {
2379                                 IFX_PRINT("  ISO Desc %d:\n", i);
2380                                 IFX_PRINT("    offset: %d, length %d\n",
2381                                     _urb->iso_frame_desc[i].offset,
2382                                     _urb->iso_frame_desc[i].length);
2383                         }
2384                 }
2385         }
2386
2387         static void dump_channel_info(ifxhcd_hcd_t *_ifxhcd, ifxhcd_epqh_t *_epqh)
2388         {
2389                 if (_epqh->hc != NULL)
2390                 {
2391                         ifxhcd_hc_t      *hc = _epqh->hc;
2392                         struct list_head *item;
2393                         ifxhcd_epqh_t      *epqh_item;
2394
2395                         ifxusb_hc_regs_t *hc_regs;
2396
2397                         hcchar_data_t  hcchar;
2398                         hcsplt_data_t  hcsplt;
2399                         hctsiz_data_t  hctsiz;
2400                         uint32_t       hcdma;
2401
2402                         hc_regs = _ifxhcd->core_if.hc_regs[hc->hc_num];
2403                         hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
2404                         hcsplt.d32 = ifxusb_rreg(&hc_regs->hcsplt);
2405                         hctsiz.d32 = ifxusb_rreg(&hc_regs->hctsiz);
2406                         hcdma      = ifxusb_rreg(&hc_regs->hcdma);
2407
2408                         IFX_PRINT("  Assigned to channel %d:\n"       , hc->hc_num);
2409                         IFX_PRINT("    hcchar 0x%08x, hcsplt 0x%08x\n", hcchar.d32, hcsplt.d32);
2410                         IFX_PRINT("    hctsiz 0x%08x, hcdma 0x%08x\n" , hctsiz.d32, hcdma);
2411                         IFX_PRINT("    dev_addr: %d, ep_num: %d, is_in: %d\n",
2412                            hc->dev_addr, hc->ep_num, hc->is_in);
2413                         IFX_PRINT("    ep_type: %d\n"        , hc->ep_type);
2414                         IFX_PRINT("    max_packet_size: %d\n", hc->mps);
2415                         IFX_PRINT("    data_pid_start: %d\n" , hc->data_pid_start);
2416                         IFX_PRINT("    xfer_started: %d\n"   , hc->xfer_started);
2417                         IFX_PRINT("    halt_status: %d\n"    , hc->halt_status);
2418                         IFX_PRINT("    xfer_buff: %p\n"      , hc->xfer_buff);
2419                         IFX_PRINT("    xfer_len: %d\n"       , hc->xfer_len);
2420                         IFX_PRINT("    epqh: %p\n"           , hc->epqh);
2421                         IFX_PRINT("  NP Active:\n");
2422                         list_for_each(item, &_ifxhcd->epqh_np_active)
2423                         {
2424                                 epqh_item = list_entry(item, ifxhcd_epqh_t, epqh_list_entry);
2425                                 IFX_PRINT("    %p\n", epqh_item);
2426                         }
2427                         IFX_PRINT("  NP Ready:\n");
2428                         list_for_each(item, &_ifxhcd->epqh_np_ready)
2429                         {
2430                                 epqh_item = list_entry(item, ifxhcd_epqh_t, epqh_list_entry);
2431                                 IFX_PRINT("    %p\n", epqh_item);
2432                         }
2433                         IFX_PRINT("  INTR Active:\n");
2434                         list_for_each(item, &_ifxhcd->epqh_intr_active)
2435                         {
2436                                 epqh_item = list_entry(item, ifxhcd_epqh_t, epqh_list_entry);
2437                                 IFX_PRINT("    %p\n", epqh_item);
2438                         }
2439                         IFX_PRINT("  INTR Ready:\n");
2440                         list_for_each(item, &_ifxhcd->epqh_intr_ready)
2441                         {
2442                                 epqh_item = list_entry(item, ifxhcd_epqh_t, epqh_list_entry);
2443                                 IFX_PRINT("    %p\n", epqh_item);
2444                         }
2445                         #ifdef __EN_ISOC__
2446                                 IFX_PRINT("  ISOC Active:\n");
2447                                 list_for_each(item, &_ifxhcd->epqh_isoc_active)
2448                                 {
2449                                         epqh_item = list_entry(item, ifxhcd_epqh_t, epqh_list_entry);
2450                                         IFX_PRINT("    %p\n", epqh_item);
2451                                 }
2452                                 IFX_PRINT("  ISOC Ready:\n");
2453                                 list_for_each(item, &_ifxhcd->epqh_isoc_ready)
2454                                 {
2455                                         epqh_item = list_entry(item, ifxhcd_epqh_t, epqh_list_entry);
2456                                         IFX_PRINT("    %p\n", epqh_item);
2457                                 }
2458                         #endif
2459                         IFX_PRINT("  Standby:\n");
2460                         list_for_each(item, &_ifxhcd->epqh_stdby)
2461                         {
2462                                 epqh_item = list_entry(item, ifxhcd_epqh_t, epqh_list_entry);
2463                                 IFX_PRINT("    %p\n", epqh_item);
2464                         }
2465                 }
2466         }
2467 #endif //__DEBUG__
2468
2469
2470 /*!
2471    \brief This function writes a packet into the Tx FIFO associated with the Host
2472   Channel. For a channel associated with a non-periodic EP, the non-periodic
2473   Tx FIFO is written. For a channel associated with a periodic EP, the
2474   periodic Tx FIFO is written. This function should only be called in Slave
2475   mode.
2476
2477   Upon return the xfer_buff and xfer_count fields in _hc are incremented by
2478   then number of bytes written to the Tx FIFO.
2479  */
2480
2481 #ifdef __ENABLE_DUMP__
2482         void ifxhcd_dump_state(ifxhcd_hcd_t *_ifxhcd)
2483         {
2484                 int num_channels;
2485                 int i;
2486                 num_channels = _ifxhcd->core_if.params.host_channels;
2487                 IFX_PRINT("\n");
2488                 IFX_PRINT("************************************************************\n");
2489                 IFX_PRINT("HCD State:\n");
2490                 IFX_PRINT("  Num channels: %d\n", num_channels);
2491                 for (i = 0; i < num_channels; i++) {
2492                         ifxhcd_hc_t *hc = &_ifxhcd->ifxhc[i];
2493                         IFX_PRINT("  Channel %d:\n", hc->hc_num);
2494                         IFX_PRINT("    dev_addr: %d, ep_num: %d, ep_is_in: %d\n",
2495                                   hc->dev_addr, hc->ep_num, hc->is_in);
2496                         IFX_PRINT("    speed: %d\n"          , hc->speed);
2497                         IFX_PRINT("    ep_type: %d\n"        , hc->ep_type);
2498                         IFX_PRINT("    mps: %d\n", hc->mps);
2499                         IFX_PRINT("    data_pid_start: %d\n" , hc->data_pid_start);
2500                         IFX_PRINT("    xfer_started: %d\n"   , hc->xfer_started);
2501                         IFX_PRINT("    xfer_buff: %p\n"      , hc->xfer_buff);
2502                         IFX_PRINT("    xfer_len: %d\n"       , hc->xfer_len);
2503                         IFX_PRINT("    xfer_count: %d\n"     , hc->xfer_count);
2504                         IFX_PRINT("    halting: %d\n"   , hc->halting);
2505                         IFX_PRINT("    halt_status: %d\n"    , hc->halt_status);
2506                         IFX_PRINT("    split: %d\n"          , hc->split);
2507                         IFX_PRINT("    hub_addr: %d\n"       , hc->hub_addr);
2508                         IFX_PRINT("    port_addr: %d\n"      , hc->port_addr);
2509                         #ifdef __EN_ISOC__
2510                                 IFX_PRINT("    isoc_xact_pos: %d\n"       , hc->isoc_xact_pos);
2511                         #endif
2512                         IFX_PRINT("    epqh: %p\n"           , hc->epqh);
2513                         IFX_PRINT("    short_rw: %d\n"       , hc->short_rw);
2514                         IFX_PRINT("    do_ping: %d\n"        , hc->do_ping);
2515                         IFX_PRINT("    control_phase: %d\n"  , hc->control_phase);
2516                         IFX_PRINT("    pkt_count_limit: %d\n", hc->epqh->pkt_count_limit);
2517                         IFX_PRINT("    start_pkt_count: %d\n"       , hc->start_pkt_count);
2518                 }
2519                 IFX_PRINT("************************************************************\n");
2520                 IFX_PRINT("\n");
2521         }
2522 #endif //__ENABLE_DUMP__
2523