[lantiq] move files/ -> files-3.3/
[openwrt/svn-archive/archive.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