1 /*****************************************************************************
2 ** FILE NAME : ifxhcd.c
3 ** PROJECT : IFX USB sub-system V3
4 ** MODULES : IFX USB sub-system Host and Device driver
7 ** AUTHOR : Chen, Howard
8 ** DESCRIPTION : This file contains the structures, constants, and interfaces for
9 ** the Host Contoller Driver (HCD).
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
15 *****************************************************************************/
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.
24 #include <linux/version.h>
25 #include "ifxusb_version.h"
27 #include <linux/kernel.h>
28 #include <linux/module.h>
29 #include <linux/moduleparam.h>
30 #include <linux/init.h>
32 #include <linux/device.h>
34 #include <linux/errno.h>
35 #include <linux/list.h>
36 #include <linux/interrupt.h>
37 #include <linux/string.h>
39 #include <linux/dma-mapping.h>
42 #include "ifxusb_plat.h"
43 #include "ifxusb_regs.h"
44 #include "ifxusb_cif.h"
49 #ifdef CONFIG_AVM_POWERMETER
50 #include <linux/avm_power.h>
51 #endif /*--- #ifdef CONFIG_AVM_POWERMETER ---*/
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);
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.
63 void ifxhcd_complete_urb(ifxhcd_hcd_t *_ifxhcd, ifxhcd_urbd_t *_urbd, int _status)
66 unsigned long flags = 0;
68 /*== AVM/BC 20101111 Function called with Lock ==*/
69 //SPIN_LOCK_IRQSAVE(&_ifxhcd->lock, flags);
71 if (!list_empty(&_urbd->urbd_list_entry))
72 list_del_init (&_urbd->urbd_list_entry);
76 IFX_ERROR("%s: invalid urb\n",__func__);
77 /*== AVM/BC 20101111 Function called with Lock ==*/
78 //SPIN_UNLOCK_IRQRESTORE(&_ifxhcd->lock, flags);
85 if (CHK_DEBUG_LEVEL(DBG_HCDV | DBG_HCD_URB))
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",
93 if (_urbd->epqh->ep_type == IFXUSB_EP_TYPE_ISOC)
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);
103 IFX_ERROR("%s: invalid epqd\n",__func__);
105 #if defined(__UNALIGNED_BUFFER_ADJ__)
106 else if(_urbd->is_active)
108 if( _urbd->epqh->aligned_checked &&
109 _urbd->epqh->using_aligned_buf &&
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;
119 urb->status = _status;
123 usb_hcd_unlink_urb_from_ep(ifxhcd_to_syshcd(_ifxhcd), urb);
124 SPIN_UNLOCK_IRQRESTORE(&_ifxhcd->lock, flags);
126 // usb_hcd_giveback_urb(ifxhcd_to_syshcd(_ifxhcd), urb);
127 usb_hcd_giveback_urb(ifxhcd_to_syshcd(_ifxhcd), urb, _status);
129 /*== AVM/BC 20100630 - 2.6.28 needs HCD link/unlink URBs ==*/
130 SPIN_LOCK_IRQSAVE(&_ifxhcd->lock, flags);
133 /*== AVM/BC 20101111 URB Complete deferred
134 * Must be called with Spinlock
138 \brief Inserts an urbd structur in the completion list. The urbd will be
139 later completed by select_eps_sub
141 void defer_ifxhcd_complete_urb(ifxhcd_hcd_t *_ifxhcd, ifxhcd_urbd_t *_urbd, int _status)
144 _urbd->status = _status;
146 //Unlink Urbd from epqh / Insert it into the complete list
147 list_move_tail(&_urbd->urbd_list_entry, &_ifxhcd->urbd_complete_list);
152 \brief Processes all the URBs in a single EPQHs. Completes them with
153 status and frees the URBD.
156 void kill_all_urbs_in_epqh(ifxhcd_hcd_t *_ifxhcd, ifxhcd_epqh_t *_epqh, int _status)
158 struct list_head *urbd_item;
164 for (urbd_item = _epqh->urbd_list.next;
165 urbd_item != &_epqh->urbd_list;
166 urbd_item = _epqh->urbd_list.next)
168 urbd = list_entry(urbd_item, ifxhcd_urbd_t, urbd_list_entry);
169 ifxhcd_complete_urb(_ifxhcd, urbd, _status);
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.
179 void epqh_list_free(ifxhcd_hcd_t *_ifxhcd, struct list_head *_epqh_list)
181 struct list_head *item;
186 if (_epqh_list->next == NULL) /* The list hasn't been initialized yet. */
189 /* Ensure there are no URBDs or URBs left. */
190 for (item = _epqh_list->next; item != _epqh_list; item = _epqh_list->next)
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);
201 void epqh_list_free_all(ifxhcd_hcd_t *_ifxhcd)
205 /*== AVM/BC 20101111 - 2.6.28 Needs Spinlock ==*/
206 SPIN_LOCK_IRQSAVE(&_ifxhcd->lock, flags);
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 );
213 epqh_list_free(_ifxhcd, &_ifxhcd->epqh_isoc_active );
214 epqh_list_free(_ifxhcd, &_ifxhcd->epqh_isoc_ready );
216 epqh_list_free(_ifxhcd, &_ifxhcd->epqh_stdby );
218 SPIN_UNLOCK_IRQRESTORE(&_ifxhcd->lock, flags);
224 \brief This function is called to handle the disconnection of host port.
226 int32_t ifxhcd_disconnect(ifxhcd_hcd_t *_ifxhcd)
228 IFX_DEBUGPL(DBG_HCDV, "%s(%p)\n", __func__, _ifxhcd);
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;
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.
240 gint_data_t intr = { .d32 = 0 };
241 intr.b.nptxfempty = 1;
242 intr.b.ptxfempty = 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);
248 /* Respond with an error status to all URBs in the schedule. */
249 epqh_list_free_all(_ifxhcd);
251 /* Clean up any host channels that were in use. */
254 ifxhcd_hc_t *channel;
255 ifxusb_hc_regs_t *hc_regs;
256 hcchar_data_t hcchar;
259 num_channels = _ifxhcd->core_if.params.host_channels;
261 for (i = 0; i < num_channels; i++)
263 channel = &_ifxhcd->ifxhc[i];
264 if (list_empty(&channel->hc_list_entry))
266 hc_regs = _ifxhcd->core_if.hc_regs[i];
267 hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
270 /* Halt the channel. */
272 ifxusb_wreg(&hc_regs->hcchar, hcchar.d32);
274 list_add_tail(&channel->hc_list_entry, &_ifxhcd->free_hc_list);
275 ifxhcd_hc_cleanup(&_ifxhcd->core_if, channel);
284 \brief Frees secondary storage associated with the ifxhcd_hcd structure contained
285 in the struct usb_hcd field.
287 static void ifxhcd_freeextra(struct usb_hcd *_syshcd)
289 ifxhcd_hcd_t *ifxhcd = syshcd_to_ifxhcd(_syshcd);
291 IFX_DEBUGPL(DBG_HCD, "IFXUSB HCD FREE\n");
293 /* Free memory for EPQH/URBD lists */
294 epqh_list_free_all(ifxhcd);
296 /* Free memory for the host channels. */
297 ifxusb_free_buf(ifxhcd->status_buf);
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);
304 ifxhcd_handle_intr(ifxhcd);
306 return HRTIMER_NORESTART;
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.
316 int ifxhcd_init(ifxhcd_hcd_t *_ifxhcd)
319 struct usb_hcd *syshcd = NULL;
321 IFX_DEBUGPL(DBG_HCD, "IFX USB HCD INIT\n");
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;
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 =
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);
352 syshcd = usb_create_hcd(&_ifxhcd->hc_driver, _ifxhcd->dev, _ifxhcd->dev->bus_id);
361 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32)
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;
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;
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 );
379 INIT_LIST_HEAD(&_ifxhcd->epqh_isoc_active );
380 INIT_LIST_HEAD(&_ifxhcd->epqh_isoc_ready );
382 INIT_LIST_HEAD(&_ifxhcd->epqh_stdby );
383 INIT_LIST_HEAD(&_ifxhcd->urbd_complete_list);
386 * Create a host channel descriptor for each host channel implemented
387 * in the controller. Initialize the channel descriptor array.
389 INIT_LIST_HEAD(&_ifxhcd->free_hc_list);
391 int num_channels = _ifxhcd->core_if.params.host_channels;
393 for (i = 0; i < num_channels; i++)
395 _ifxhcd->ifxhc[i].hc_num = i;
396 IFX_DEBUGPL(DBG_HCDV, "HCD Added channel #%d\n", i);
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;
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.
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 );
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
421 _ifxhcd->status_buf = ifxusb_alloc_buf(IFXHCD_STATUS_BUF_SIZE, 1);
423 if (_ifxhcd->status_buf)
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);
428 IFX_DEBUGPL(DBG_HCD, "IFX USB HCD Initialized, bus=%s, usbbus=%d\n", _ifxhcd->dev->bus_id, syshcd->self.busnum);
432 IFX_ERROR("%s: status_buf allocation failed\n", __func__);
434 /* Error conditions */
435 usb_remove_hcd(syshcd);
437 ifxhcd_freeextra(syshcd);
444 \brief Removes the HCD.
445 Frees memory and resources associated with the HCD and deregisters the bus.
447 void ifxhcd_remove(ifxhcd_hcd_t *_ifxhcd)
449 struct usb_hcd *syshcd = ifxhcd_to_syshcd(_ifxhcd);
451 IFX_DEBUGPL(DBG_HCD, "IFX USB HCD REMOVE\n");
453 /* == AVM/WK 20100709 - Fix: Order changed, disable IRQs not before remove_hcd == */
455 usb_remove_hcd(syshcd);
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);
461 ifxhcd_freeextra(syshcd);
469 /* =========================================================================
470 * Linux HC Driver Functions
471 * ========================================================================= */
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.
479 int ifxhcd_start(struct usb_hcd *_syshcd)
481 ifxhcd_hcd_t *ifxhcd = syshcd_to_ifxhcd (_syshcd);
482 ifxusb_core_if_t *core_if = &ifxhcd->core_if;
485 IFX_DEBUGPL(DBG_HCD, "IFX USB HCD START\n");
487 bus = hcd_to_bus(_syshcd);
489 /* Initialize the bus state. */
490 _syshcd->state = HC_STATE_RUNNING;
492 /* Initialize and connect root hub if one is not already attached */
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);
500 ifxhcd->flags.d32 = 0;
502 /* Put all channels in the free channel list and clean up channel states.*/
504 struct list_head *item;
505 item = ifxhcd->free_hc_list.next;
506 while (item != &ifxhcd->free_hc_list)
509 item = ifxhcd->free_hc_list.next;
513 int num_channels = ifxhcd->core_if.params.host_channels;
515 for (i = 0; i < num_channels; i++)
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);
523 /* Initialize the USB core for host mode operation. */
525 ifxusb_host_enable_interrupts(core_if);
526 ifxusb_enable_global_interrupts(core_if);
527 ifxusb_phy_power_on (core_if);
529 ifxusb_vbus_init(core_if);
531 /* Turn on the vbus power. */
534 hprt0.d32 = ifxusb_read_hprt0(core_if);
536 IFX_PRINT("Init: Power Port (%d)\n", hprt0.b.prtpwr);
537 if (hprt0.b.prtpwr == 0 )
540 ifxusb_wreg(core_if->hprt0, hprt0.d32);
541 ifxusb_vbus_on(core_if);
549 \brief Halts the IFXUSB host mode operations in a clean manner. USB transfers are
552 void ifxhcd_stop(struct usb_hcd *_syshcd)
554 ifxhcd_hcd_t *ifxhcd = syshcd_to_ifxhcd(_syshcd);
555 hprt0_data_t hprt0 = { .d32=0 };
557 IFX_DEBUGPL(DBG_HCD, "IFX USB HCD STOP\n");
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);
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).
571 /* Turn off the vbus power */
572 IFX_PRINT("PortPower off\n");
574 ifxusb_vbus_off(&ifxhcd->core_if );
576 ifxusb_vbus_free(&ifxhcd->core_if );
579 ifxusb_wreg(ifxhcd->core_if.hprt0, hprt0.d32);
584 \brief Returns the current frame number
586 int ifxhcd_get_frame_number(struct usb_hcd *_syshcd)
588 ifxhcd_hcd_t *ifxhcd = syshcd_to_ifxhcd(_syshcd);
591 hfnum.d32 = ifxusb_rreg(&ifxhcd->core_if.host_global_regs->hfnum);
593 return hfnum.b.frnum;
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
601 int ifxhcd_urb_enqueue( struct usb_hcd *_syshcd,
602 /*--- struct usb_host_endpoint *_sysep, Parameter im 2.6.28 entfallen ---*/
607 ifxhcd_hcd_t *ifxhcd = syshcd_to_ifxhcd (_syshcd);
608 struct usb_host_endpoint *_sysep = ifxhcd_urb_to_endpoint(_urb);
612 if (CHK_DEBUG_LEVEL(DBG_HCDV | DBG_HCD_URB))
613 dump_urb_info(_urb, "ifxusb_hcd_urb_enqueue");
616 if (!ifxhcd->flags.b.port_connect_status) /* No longer connected. */
620 if(usb_pipetype(_urb->pipe) == PIPE_ISOCHRONOUS)
622 IFX_ERROR("ISOC transfer not supported!!!\n");
627 retval=ifxhcd_urbd_create (ifxhcd,_urb);
631 IFX_ERROR("IFXUSB HCD URB Enqueue failed creating URBD\n");
634 epqh = (ifxhcd_epqh_t *) _sysep->hcpriv;
635 ifxhcd_epqh_ready(ifxhcd, epqh);
638 //enable_sof(ifxhcd);
642 gintsts.b.sofintr = 1;
643 ifxusb_mreg(&ifxhcd->core_if.core_global_regs->gintmsk, 0,gintsts.d32);
650 \brief Aborts/cancels a USB transfer request. Always returns 0 to indicate
653 int ifxhcd_urb_dequeue( struct usb_hcd *_syshcd,
654 struct urb *_urb, int status /* Parameter neu in 2.6.28 */)
657 ifxhcd_hcd_t *ifxhcd;
663 struct usb_host_endpoint *_sysep;
665 IFX_DEBUGPL(DBG_HCD, "IFXUSB HCD URB Dequeue\n");
668 if(usb_pipetype(_urb->pipe) == PIPE_ISOCHRONOUS)
672 _sysep = ifxhcd_urb_to_endpoint(_urb);
674 ifxhcd = syshcd_to_ifxhcd(_syshcd);
676 SPIN_LOCK_IRQSAVE(&ifxhcd->lock, flags);
678 /*== AVM/BC 20100630 - 2.6.28 needs HCD link/unlink URBs ==*/
679 rc = usb_hcd_check_unlink_urb(_syshcd, _urb, status);
681 SPIN_UNLOCK_IRQRESTORE(&ifxhcd->lock, flags);
685 urbd = (ifxhcd_urbd_t *) _urb->hcpriv;
688 epqh = (ifxhcd_epqh_t *) _sysep->hcpriv;
690 epqh = (ifxhcd_epqh_t *) urbd->epqh;
693 IFX_ERROR("%s inconsistant epqh %p %p\n",__func__,epqh,urbd->epqh);
696 if (CHK_DEBUG_LEVEL(DBG_HCDV | DBG_HCD_URB))
698 dump_urb_info(_urb, "ifxhcd_urb_dequeue");
700 dump_channel_info(ifxhcd, epqh);
706 else if (!ifxhcd->flags.b.port_connect_status)
708 else if (epqh->is_active && urbd->is_active)
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) {
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
721 /* == 20110803 AVM/WK FIX propagate status == */
722 if (_urb->status == -EINPROGRESS) {
723 _urb->status = status;
725 ifxhcd_hc_halt(&ifxhcd->core_if, epqh->hc, HC_XFER_URB_DEQUEUE);
733 SPIN_UNLOCK_IRQRESTORE(&ifxhcd->lock, flags);
737 list_del_init(&urbd->urbd_list_entry);
740 /*== AVM/BC 20100630 - 2.6.28 needs HCD link/unlink URBs ==*/
741 usb_hcd_unlink_urb_from_ep(_syshcd, _urb);
743 SPIN_UNLOCK_IRQRESTORE(&ifxhcd->lock, flags);
745 // usb_hcd_giveback_urb(_syshcd, _urb);
746 usb_hcd_giveback_urb(_syshcd, _urb, status /* neu in 2.6.28 */);
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.
760 void ifxhcd_endpoint_disable( struct usb_hcd *_syshcd,
761 struct usb_host_endpoint *_sysep)
764 ifxhcd_hcd_t *ifxhcd = syshcd_to_ifxhcd(_syshcd);
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));
773 SPIN_LOCK_IRQSAVE(&ifxhcd->lock, flags);
774 if((uint32_t)_sysep>=0x80000000 && (uint32_t)_sysep->hcpriv>=(uint32_t)0x80000000)
776 epqh = (ifxhcd_epqh_t *)(_sysep->hcpriv);
777 if (epqh && epqh->sysep==_sysep)
780 #if 1 /*== AVM/BC 20101111 CHG Option active: Kill URBs when disabling EP ==*/
781 while (!list_empty(&epqh->urbd_list))
785 IFX_WARN("IFXUSB HCD EP DISABLE:"
786 " URBD List for this endpoint is not empty\n");
789 kill_all_urbs_in_epqh(ifxhcd, epqh, -ETIMEDOUT);
792 while (!list_empty(&epqh->urbd_list))
794 /** Check that the QTD list is really empty */
797 IFX_WARN("IFXUSB HCD EP DISABLE:"
798 " URBD List for this endpoint is not empty\n");
801 SPIN_UNLOCK_IRQRESTORE(&ifxhcd->lock, flags);
802 schedule_timeout_uninterruptible(1);
803 SPIN_LOCK_IRQSAVE(&ifxhcd->lock, flags);
807 ifxhcd_epqh_free(epqh);
808 _sysep->hcpriv = NULL;
811 SPIN_UNLOCK_IRQRESTORE(&ifxhcd->lock, flags);
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
820 * This function is called by the USB core when an interrupt occurs
822 irqreturn_t ifxhcd_irq(struct usb_hcd *_syshcd)
824 ifxhcd_hcd_t *ifxhcd = syshcd_to_ifxhcd (_syshcd);
827 //mask_and_ack_ifx_irq (ifxhcd->core_if.irq);
828 retval = ifxhcd_handle_intr(ifxhcd);
829 return IRQ_RETVAL(retval);
834 \brief Handles host mode Over Current Interrupt
836 irqreturn_t ifxhcd_oc_irq(int _irq , void *_dev)
838 ifxhcd_hcd_t *ifxhcd = _dev;
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);
845 //mask_and_ack_ifx_irq (_irq);
846 return IRQ_RETVAL(retval);
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.
855 int ifxhcd_hub_status_data(struct usb_hcd *_syshcd, char *_buf)
857 ifxhcd_hcd_t *ifxhcd = syshcd_to_ifxhcd (_syshcd);
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;
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);
883 return (_buf[0] != 0);
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__
892 \brief Handles hub class-specific requests.
894 int ifxhcd_hub_control( struct usb_hcd *_syshcd,
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};
908 uint32_t port_status;
912 case ClearHubFeature:
913 IFX_DEBUGPL (DBG_HCD, "IFXUSB HCD HUB CONTROL - "
914 "ClearHubFeature 0x%x\n", _wValue);
917 case C_HUB_LOCAL_POWER:
918 case C_HUB_OVER_CURRENT:
919 /* Nothing required here */
923 IFX_ERROR ("IFXUSB HCD - "
924 "ClearHubFeature request %xh unknown\n", _wValue);
927 case ClearPortFeature:
928 if (!_wIndex || _wIndex > 1)
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);
938 ifxusb_wreg(core_if->hprt0, hprt0.d32);
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);
945 ifxusb_wreg(core_if->hprt0, hprt0.d32);
946 /* Clear Resume bit */
949 ifxusb_wreg(core_if->hprt0, hprt0.d32);
951 case USB_PORT_FEAT_POWER:
952 IFX_DEBUGPL (DBG_HCD, "IFXUSB HCD HUB CONTROL - "
953 "ClearPortFeature USB_PORT_FEAT_POWER\n");
955 ifxusb_vbus_off(core_if);
957 ifxusb_vbus_off(core_if);
959 hprt0.d32 = ifxusb_read_hprt0 (core_if);
961 ifxusb_wreg(core_if->hprt0, hprt0.d32);
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 */
968 case USB_PORT_FEAT_C_CONNECTION:
969 /* Clears drivers internal connect status change
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;
975 case USB_PORT_FEAT_C_RESET:
976 /* Clears the driver's internal Port Reset Change
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;
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;
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;
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;
1004 IFX_ERROR ("IFXUSB HCD - "
1005 "ClearPortFeature request %xh "
1006 "unknown or unsupported\n", _wValue);
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;
1023 IFX_DEBUGPL (DBG_HCD, "IFXUSB HCD HUB CONTROL - "
1025 memset (_buf, 0, 4);
1028 IFX_DEBUGPL (DBG_HCD, "IFXUSB HCD HUB CONTROL - "
1030 if (!_wIndex || _wIndex > 1)
1033 # ifdef CONFIG_AVM_POWERMETER
1035 /* first port only, but 2 Hosts */
1036 static unsigned char ucOldPower1 = 255;
1037 static unsigned char ucOldPower2 = 255;
1039 unsigned char ucNewPower = 0;
1040 struct usb_device *childdev = _syshcd->self.root_hub->children[0];
1042 if (childdev != NULL) {
1043 ucNewPower = (childdev->actconfig != NULL)
1044 ? childdev->actconfig->desc.bMaxPower
1045 : 50;/* default: 50 means 100 mA*/
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);
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);
1061 # endif /*--- #ifdef CONFIG_AVM_POWERMETER ---*/
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)
1074 IFX_ERROR("Device Not Supported\n");
1075 port_status |= (1 << USB_PORT_FEAT_C_OVER_CURRENT);
1077 if (!ifxhcd->flags.b.port_connect_status)
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.
1086 *((u32 *) _buf) = cpu_to_le32(port_status);
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);
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);
1101 port_status |= (1 << USB_PORT_FEAT_RESET);
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);
1114 IFX_DEBUGPL (DBG_HCD, "IFXUSB HCD HUB CONTROL - "
1116 /* No HUB features supported */
1118 case SetPortFeature:
1119 if (_wValue != USB_PORT_FEAT_TEST && (!_wIndex || _wIndex > 1))
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
1128 if (!ifxhcd->flags.b.port_connect_status)
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 */
1141 pcgcctl_data_t pcgcctl = {.d32=0};
1142 pcgcctl.b.stoppclk = 1;
1143 ifxusb_wreg(core_if->pcgcctl, pcgcctl.d32);
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);
1152 ifxusb_wreg(core_if->hprt0, hprt0.d32);
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);
1159 ifxusb_wreg(core_if->hprt0, hprt0.d32);
1160 /* Clear reset bit in 10ms (FS/LS) or 50ms (HS) */
1163 ifxusb_wreg(core_if->hprt0, hprt0.d32);
1165 #ifdef __WITH_HS_ELECT_TST__
1166 case USB_PORT_FEAT_TEST:
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);
1176 hprt0.d32 = ifxusb_read_hprt0 (core_if);
1177 hprt0.b.prttstctl = t;
1178 ifxusb_wreg(core_if->hprt0, hprt0.d32);
1180 else if (t == 6) /* HS_HOST_PORT_SUSPEND_RESUME */
1182 /* Save current interrupt mask */
1183 gintmsk.d32 = ifxusb_rreg(&core_if->core_global_regs->gintmsk);
1185 /* Disable all interrupts while we muck with
1186 * the hardware directly
1188 ifxusb_wreg(&core_if->core_global_regs->gintmsk, 0);
1190 /* 15 second delay per the test spec */
1193 /* Drive suspend on the root port */
1194 hprt0.d32 = ifxusb_read_hprt0 (core_if);
1195 hprt0.b.prtsusp = 1;
1197 ifxusb_wreg(core_if->hprt0, hprt0.d32);
1199 /* 15 second delay per the test spec */
1202 /* Drive resume on the root port */
1203 hprt0.d32 = ifxusb_read_hprt0 (core_if);
1204 hprt0.b.prtsusp = 0;
1206 ifxusb_wreg(core_if->hprt0, hprt0.d32);
1209 /* Clear the resume bit */
1211 ifxusb_wreg(core_if->hprt0, hprt0.d32);
1213 /* Restore interrupts */
1214 ifxusb_wreg(&core_if->core_global_regs->gintmsk, gintmsk.d32);
1216 else if (t == 7) /* SINGLE_STEP_GET_DEVICE_DESCRIPTOR setup */
1218 /* Save current interrupt mask */
1219 gintmsk.d32 = ifxusb_rreg(&core_if->core_global_regs->gintmsk);
1221 /* Disable all interrupts while we muck with
1222 * the hardware directly
1224 ifxusb_wreg(&core_if->core_global_regs->gintmsk, 0);
1226 /* 15 second delay per the test spec */
1229 /* Send the Setup packet */
1232 /* 15 second delay so nothing else happens for awhile */
1235 /* Restore interrupts */
1236 ifxusb_wreg(&core_if->core_global_regs->gintmsk, gintmsk.d32);
1239 else if (t == 8) /* SINGLE_STEP_GET_DEVICE_DESCRIPTOR execute */
1241 /* Save current interrupt mask */
1242 gintmsk.d32 = ifxusb_rreg(&core_if->core_global_regs->gintmsk);
1244 /* Disable all interrupts while we muck with
1245 * the hardware directly
1247 ifxusb_wreg(&core_if->core_global_regs->gintmsk, 0);
1249 /* Send the Setup packet */
1252 /* 15 second delay so nothing else happens for awhile */
1255 /* Send the In and Ack packets */
1258 /* 15 second delay so nothing else happens for awhile */
1261 /* Restore interrupts */
1262 ifxusb_wreg(&core_if->core_global_regs->gintmsk, gintmsk.d32);
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");
1274 IFX_ERROR ("IFXUSB HCD - "
1275 "SetPortFeature request %xh "
1276 "unknown or unsupported\n", _wValue);
1282 IFX_WARN ("IFXUSB HCD - "
1283 "Unknown hub control request type or invalid typeReq: %xh wIndex: %xh wValue: %xh\n",
1284 _typeReq, _wIndex, _wValue);
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
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.
1297 static int assign_and_init_hc(ifxhcd_hcd_t *_ifxhcd, ifxhcd_epqh_t *_epqh)
1300 ifxhcd_urbd_t *urbd;
1303 IFX_DEBUGPL(DBG_HCDV, "%s(%p,%p)\n", __func__, _ifxhcd, _epqh);
1305 if(list_empty(&_epqh->urbd_list))
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);
1312 urbd = list_entry(_epqh->urbd_list.next, ifxhcd_urbd_t, urbd_list_entry);
1317 ifxhc->epqh = _epqh;
1322 * Use usb_pipedevice to determine device address. This address is
1323 * 0 before the SET_ADDRESS command and the correct address afterward.
1325 ifxhc->dev_addr = usb_pipedevice(urb->pipe);
1326 ifxhc->ep_num = usb_pipeendpoint(urb->pipe);
1328 ifxhc->xfer_started = 0;
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;
1334 ifxhc->mps = _epqh->mps;
1335 ifxhc->halt_status = HC_XFER_NO_HALT_STATUS;
1337 ifxhc->ep_type = _epqh->ep_type;
1339 if(_epqh->ep_type==IFXUSB_EP_TYPE_CTRL)
1341 ifxhc->control_phase=IFXHCD_CONTROL_SETUP;
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;
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;
1363 ifxhc->short_rw =(urb->transfer_flags & URB_ZERO_PACKET)?1:0;
1366 if(_epqh->ep_type==IFXUSB_EP_TYPE_ISOC)
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)
1374 if (ifxhc->xfer_len <= 188)
1375 ifxhc->isoc_xact_pos = IFXUSB_HCSPLIT_XACTPOS_ALL;
1377 ifxhc->isoc_xact_pos = IFXUSB_HCSPLIT_XACTPOS_BEGIN;
1384 if (_ifxhcd->core_if.snpsid < 0x4f54271a && ifxhc->speed == IFXUSB_EP_SPEED_HIGH)
1388 /* Set the split attributes */
1390 if (_epqh->need_split) {
1392 ifxhc->hub_addr = urb->dev->tt->hub->devnum;
1393 ifxhc->port_addr = urb->dev->ttport;
1396 //ifxhc->uint16_t pkt_count_limit
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];
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);
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;
1413 ifxusb_wreg(&hc_regs->hcintmsk, hc_intr_mask.d32);
1415 /* Enable the top level host channel interrupt. */
1417 uint32_t intr_enable;
1418 intr_enable = (1 << hc_num);
1419 ifxusb_mreg(&_ifxhcd->core_if.host_global_regs->haintmsk, 0, intr_enable);
1422 /* Make sure host channel interrupts are enabled. */
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);
1430 * Program the HCCHARn register with the endpoint characteristics for
1431 * the current transfer.
1434 hcchar_data_t hcchar;
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);
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);
1452 /* Program the HCSPLIT register for SPLITs */
1454 hcsplt_data_t hcsplt;
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);
1464 if(_epqh->ep_type==IFXUSB_EP_TYPE_ISOC)
1465 hcsplt.b.xactpos = ifxhc->isoc_xact_pos;
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);
1479 ifxusb_wreg(&hc_regs->hcsplt, hcsplt.d32);
1483 ifxhc->nak_retry_r=ifxhc->nak_retry=0;
1484 ifxhc->nak_countdown_r=ifxhc->nak_countdown=0;
1495 else if(_epqh->ep_type==IFXUSB_EP_TYPE_CTRL)
1504 else if(_epqh->ep_type==IFXUSB_EP_TYPE_BULK)
1508 // ifxhc->nak_retry_r=ifxhc->nak_retry=nak_retry_max;
1509 // ifxhc->nak_countdown_r=ifxhc->nak_countdown=nak_countdown_max;
1515 else if(_epqh->ep_type==IFXUSB_EP_TYPE_INTR)
1524 else if(_epqh->ep_type==IFXUSB_EP_TYPE_ISOC)
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
1542 static void select_eps_sub(ifxhcd_hcd_t *_ifxhcd)
1544 struct list_head *epqh_ptr;
1545 struct list_head *urbd_ptr;
1546 ifxhcd_epqh_t *epqh;
1547 ifxhcd_urbd_t *urbd;
1550 /*== AVM/BC 20101111 Function called with Lock ==*/
1553 // IFX_DEBUGPL(DBG_HCD, " ifxhcd_select_ep\n");
1556 /* Process entries in the periodic ready list. */
1558 epqh_ptr = _ifxhcd->epqh_isoc_ready.next;
1559 while (epqh_ptr != &_ifxhcd->epqh_isoc_ready && !list_empty(&_ifxhcd->free_hc_list))
1561 epqh = list_entry(epqh_ptr, ifxhcd_epqh_t, epqh_list_entry);
1562 epqh_ptr = epqh_ptr->next;
1565 if(assign_and_init_hc(_ifxhcd, epqh))
1567 IFX_DEBUGPL(DBG_HCD, " select_eps ISOC\n");
1568 list_move_tail(&epqh->epqh_list_entry, &_ifxhcd->epqh_isoc_active);
1577 epqh_ptr = _ifxhcd->epqh_intr_ready.next;
1578 while (epqh_ptr != &_ifxhcd->epqh_intr_ready && !list_empty(&_ifxhcd->free_hc_list))
1580 epqh = list_entry(epqh_ptr, ifxhcd_epqh_t, epqh_list_entry);
1581 epqh_ptr = epqh_ptr->next;
1584 if(assign_and_init_hc(_ifxhcd, epqh))
1586 IFX_DEBUGPL(DBG_HCD, " select_eps INTR\n");
1587 list_move_tail(&epqh->epqh_list_entry, &_ifxhcd->epqh_intr_active);
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
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))
1602 IFX_DEBUGPL(DBG_HCD, " select_eps CTRL/BULK\n");
1603 list_move_tail(&epqh->epqh_list_entry, &_ifxhcd->epqh_np_active);
1609 /*== AVM/BC 20101111 Function called with Lock ==*/
1610 process_channels_sub(_ifxhcd);
1612 /* AVM/BC 20101111 Urbds completion loop */
1613 while (!list_empty(&_ifxhcd->urbd_complete_list))
1615 urbd_ptr = _ifxhcd->urbd_complete_list.next;
1616 list_del_init(urbd_ptr);
1618 urbd = list_entry(urbd_ptr, ifxhcd_urbd_t, urbd_list_entry);
1620 ifxhcd_complete_urb(_ifxhcd, urbd, urbd->status);
1626 static void select_eps_func(unsigned long data)
1628 unsigned long flags;
1630 ifxhcd_hcd_t *ifxhcd;
1631 ifxhcd=((ifxhcd_hcd_t *)data);
1633 /* AVM/BC 20101111 select_eps_in_use flag removed */
1635 SPIN_LOCK_IRQSAVE(&ifxhcd->lock, flags);
1637 /*if(ifxhcd->select_eps_in_use){
1638 SPIN_UNLOCK_IRQRESTORE(&ifxhcd->lock, flags);
1641 ifxhcd->select_eps_in_use=1;
1644 select_eps_sub(ifxhcd);
1646 //ifxhcd->select_eps_in_use=0;
1648 SPIN_UNLOCK_IRQRESTORE(&ifxhcd->lock, flags);
1651 void select_eps(ifxhcd_hcd_t *_ifxhcd)
1655 if(!_ifxhcd->select_eps.func)
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;
1663 tasklet_schedule(&_ifxhcd->select_eps);
1667 unsigned long flags;
1669 /* AVM/BC 20101111 select_eps_in_use flag removed */
1671 SPIN_LOCK_IRQSAVE(&_ifxhcd->lock, flags);
1673 /*if(_ifxhcd->select_eps_in_use){
1674 printk ("select_eps non_irq: busy\n");
1675 SPIN_UNLOCK_IRQRESTORE(&_ifxhcd->lock, flags);
1678 _ifxhcd->select_eps_in_use=1;
1681 select_eps_sub(_ifxhcd);
1683 //_ifxhcd->select_eps_in_use=0;
1685 SPIN_UNLOCK_IRQRESTORE(&_ifxhcd->lock, flags);
1692 static void process_unaligned( ifxhcd_epqh_t *_epqh)
1694 #if defined(__UNALIGNED_BUFFER_ADJ__)
1695 if(!_epqh->aligned_checked)
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;
1703 if(xfer_len > 0 && ((unsigned long)_epqh->urbd->xfer_buff) & 3)
1705 if( _epqh->aligned_buf
1706 && _epqh->aligned_buf_len > 0
1707 && _epqh->aligned_buf_len < xfer_len
1710 ifxusb_free_buf(_epqh->aligned_buf);
1711 _epqh->aligned_buf=NULL;
1712 _epqh->aligned_buf_len=0;
1714 if(! _epqh->aligned_buf || ! _epqh->aligned_buf_len)
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;
1720 if(_epqh->aligned_buf)
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;
1728 IFX_WARN("%s():%d\n",__func__,__LINE__);
1730 if(_epqh->ep_type==IFXUSB_EP_TYPE_CTRL)
1732 _epqh->using_aligned_setup=0;
1733 if(((unsigned long)_epqh->urbd->setup_buff) & 3)
1735 if(! _epqh->aligned_setup)
1736 _epqh->aligned_setup = ifxusb_alloc_buf(8,0);
1737 if(_epqh->aligned_setup)
1739 memcpy(_epqh->aligned_setup, _epqh->urbd->setup_buff, 8);
1740 _epqh->using_aligned_setup=1;
1743 IFX_WARN("%s():%d\n",__func__,__LINE__);
1744 _epqh->hc->xfer_buff = _epqh->aligned_setup;
1748 #elif defined(__UNALIGNED_BUFFER_CHK__)
1749 if(!_epqh->aligned_checked)
1751 if(_epqh->urbd->is_in)
1753 if(_epqh->urbd->xfer_len==0)
1754 IFX_WARN("%s():%d IN xfer while length is zero \n",__func__,__LINE__);
1756 if(_epqh->urbd->xfer_len < _epqh->mps)
1757 IFX_WARN("%s():%d IN xfer while length < mps \n",__func__,__LINE__);
1759 if(((unsigned long)_epqh->urbd->xfer_buff) & 3)
1760 IFX_WARN("%s():%d IN xfer Buffer UNALIGNED\n",__func__,__LINE__);
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__);
1769 if(_epqh->ep_type==IFXUSB_EP_TYPE_CTRL)
1771 if(((unsigned long)_epqh->urbd->setup_buff) & 3)
1772 IFX_WARN("%s():%d SETUP xfer Buffer UNALIGNED\n",__func__,__LINE__);
1776 _epqh->aligned_checked=1;
1783 void process_channels_sub(ifxhcd_hcd_t *_ifxhcd)
1785 ifxhcd_epqh_t *epqh;
1786 struct list_head *epqh_item;
1787 struct ifxhcd_hc *hc;
1790 if (!list_empty(&_ifxhcd->epqh_isoc_active))
1792 for (epqh_item = _ifxhcd->epqh_isoc_active.next;
1793 epqh_item != &_ifxhcd->epqh_isoc_active;
1796 epqh = list_entry(epqh_item, ifxhcd_epqh_t, epqh_list_entry);
1797 epqh_item = epqh_item->next;
1799 if(hc && !hc->xfer_started && epqh->period_do)
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);
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);
1822 if (!list_empty(&_ifxhcd->epqh_intr_active))
1824 for (epqh_item = _ifxhcd->epqh_intr_active.next;
1825 epqh_item != &_ifxhcd->epqh_intr_active;
1828 epqh = list_entry(epqh_item, ifxhcd_epqh_t, epqh_list_entry);
1829 epqh_item = epqh_item->next;
1831 if(hc && !hc->xfer_started && epqh->period_do)
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);
1843 #ifdef __USE_TIMER_4_SOF__
1844 /* AVM/WK change: let hc_start decide, if irq is needed */
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);
1858 if (!list_empty(&_ifxhcd->epqh_np_active))
1860 for (epqh_item = _ifxhcd->epqh_np_active.next;
1861 epqh_item != &_ifxhcd->epqh_np_active;
1864 epqh = list_entry(epqh_item, ifxhcd_epqh_t, epqh_list_entry);
1865 epqh_item = epqh_item->next;
1869 if(!hc->xfer_started)
1873 //|| hc->split_counter == 0
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);
1888 void process_channels(ifxhcd_hcd_t *_ifxhcd)
1890 unsigned long flags;
1892 /* AVM/WK Fix: use spin_lock instead busy flag
1894 SPIN_LOCK_IRQSAVE(&_ifxhcd->lock, flags);
1896 //if(_ifxhcd->process_channels_in_use)
1898 //_ifxhcd->process_channels_in_use=1;
1900 process_channels_sub(_ifxhcd);
1901 //_ifxhcd->process_channels_in_use=0;
1902 SPIN_UNLOCK_IRQRESTORE(&_ifxhcd->lock, flags);
1906 #ifdef __HC_XFER_TIMEOUT__
1907 static void hc_xfer_timeout(unsigned long _ptr)
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);
1916 void ifxhcd_hc_dumb_rx(ifxusb_core_if_t *_core_if, ifxhcd_hc_t *_ifxhc,uint8_t *dump_buf)
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;
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);
1929 ifxusb_wreg(&hc_regs->hcdma, (uint32_t)(CPHYSADDR( ((uint32_t)(dump_buf)))));
1932 hcint_data_t hcint= { .d32=0 };
1936 hcint.d32 =0xFFFFFFFF;
1937 ifxusb_wreg(&hc_regs->hcint, hcint.d32);
1940 /* Set host channel enable after all other setup is complete. */
1944 IFX_DEBUGPL(DBG_HCDV, " HCCHART: 0x%08x\n", hcchar.d32);
1945 ifxusb_wreg(&hc_regs->hcchar, hcchar.d32);
1949 \brief This function trigger a data transfer for a host channel and
1950 starts the transfer.
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.
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
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.
1968 void ifxhcd_hc_start(ifxusb_core_if_t *_core_if, ifxhcd_hc_t *_ifxhc)
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];
1978 // if(_ifxhc->do_ping && !_ifxhc->is_in) hctsiz.b.dopng = 1;
1980 _ifxhc->nak_countdown=_ifxhc->nak_countdown_r;
1982 /* AVM/BC 20101111 Workaround: Always PING if HI-Speed Out and xfer_len > 0 */
1983 if(/*_ifxhc->do_ping &&*/
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))) &&
1991 _ifxhc->xfer_started = 1;
1993 if(_ifxhc->epqh->pkt_count_limit > 0 && _ifxhc->epqh->pkt_count_limit < max_hc_pkt_count )
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;
1999 if (_ifxhc->split > 0)
2002 gint_data_t gintsts = {.d32 = 0};
2003 gintsts.b.sofintr = 1;
2004 ifxusb_mreg(&_core_if->core_global_regs->gintmsk,0, gintsts.d32);
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;
2015 else if(_ifxhc->is_in)
2017 _ifxhc->short_rw = 0;
2018 if (_ifxhc->xfer_len > 0)
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;
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;
2030 else //non-split out
2032 if (_ifxhc->xfer_len == 0)
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;
2041 if (_ifxhc->xfer_len > max_hc_xfer_size)
2043 _ifxhc->start_pkt_count = (max_hc_xfer_size / _ifxhc->mps);
2044 _ifxhc->xfer_len = _ifxhc->start_pkt_count * _ifxhc->mps;
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;
2059 if (_ifxhc->ep_type == IFXUSB_EP_TYPE_ISOC)
2061 /* Set up the initial PID for the transfer. */
2063 _ifxhc->data_pid_start = IFXUSB_HC_PID_DATA0;
2065 if (_ifxhc->speed == IFXUSB_EP_SPEED_HIGH)
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;
2074 _ifxhc->data_pid_start = IFXUSB_HC_PID_DATA2;
2078 if (_ifxhc->multi_count == 1)
2079 _ifxhc->data_pid_start = IFXUSB_HC_PID_DATA0;
2081 _ifxhc->data_pid_start = IFXUSB_HC_PID_MDATA;
2085 _ifxhc->data_pid_start = IFXUSB_HC_PID_DATA0;
2090 hctsiz.b.xfersize = _ifxhc->xfer_len;
2091 hctsiz.b.pktcnt = _ifxhc->start_pkt_count;
2092 hctsiz.b.pid = _ifxhc->data_pid_start;
2094 ifxusb_wreg(&hc_regs->hctsiz, hctsiz.d32);
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 )));
2104 /* Start the split */
2105 if (_ifxhc->split>0)
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;
2113 hcsplt.b.compsplt = 0;
2116 if (_ifxhc->ep_type == IFXUSB_EP_TYPE_ISOC)
2117 hcsplt.b.xactpos = _ifxhc->isoc_xact_pos;
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);
2125 hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
2126 // hcchar.b.multicnt = _ifxhc->multi_count;
2127 hcchar.b.multicnt = 1;
2130 _ifxhc->start_hcchar_val = hcchar.d32;
2132 IFX_WARN("%s: chdis set, channel %d, hcchar 0x%08x\n",
2133 __func__, _ifxhc->hc_num, hcchar.d32);
2136 /* Set host channel enable after all other setup is complete. */
2139 hcchar.b.epdir = _ifxhc->is_in;
2140 _ifxhc->hcchar=hcchar.d32;
2142 IFX_DEBUGPL(DBG_HCDV, " HCCHART: 0x%08x\n", _ifxhc->hcchar);
2144 /* == 20110901 AVM/WK Fix: Clear IRQ flags in any case ==*/
2146 hcint_data_t hcint= { .d32=0 };
2147 hcint.d32 =0xFFFFFFFF;
2148 ifxusb_wreg(&hc_regs->hcint, hcint.d32);
2151 if(_ifxhc->wait_for_sof==0)
2155 hcint.d32=ifxusb_rreg(&hc_regs->hcintmsk);
2159 /* == 20110901 AVM/WK Fix: We don't need NOT YET IRQ ==*/
2161 if(_ifxhc->nak_countdown_r)
2163 ifxusb_wreg(&hc_regs->hcintmsk, hcint.d32);
2165 /* AVM WK / BC 20100827
2166 * MOVED. Oddframe updated inmediatly before write HCChar Register.
2168 if (_ifxhc->ep_type == IFXUSB_EP_TYPE_INTR || _ifxhc->ep_type == IFXUSB_EP_TYPE_ISOC)
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;
2176 ifxusb_wreg(&hc_regs->hcchar, _ifxhc->hcchar);
2177 #ifdef __USE_TIMER_4_SOF__
2180 gint_data_t gintsts = {.d32 = 0};
2181 gintsts.b.sofintr = 1;
2182 ifxusb_mreg(&_core_if->core_global_regs->gintmsk,0, gintsts.d32);
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);
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.
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.
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.
2212 void ifxhcd_hc_halt(ifxusb_core_if_t *_core_if,
2213 ifxhcd_hc_t *_ifxhc,
2214 ifxhcd_halt_status_e _halt_status)
2216 hcchar_data_t hcchar;
2217 ifxusb_hc_regs_t *hc_regs;
2219 hc_regs = _core_if->hc_regs[_ifxhc->hc_num];
2221 WARN_ON(_halt_status == HC_XFER_NO_HALT_STATUS);
2223 if (_halt_status == HC_XFER_URB_DEQUEUE ||
2224 _halt_status == HC_XFER_AHB_ERR)
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.
2232 hcint_data_t hcintmsk;
2234 hcintmsk.b.chhltd = 1;
2235 ifxusb_wreg(&hc_regs->hcintmsk, hcintmsk.d32);
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.
2242 ifxusb_wreg(&hc_regs->hcint, ~hcintmsk.d32);
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
2249 _ifxhc->halt_status = _halt_status;
2251 hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
2252 if (hcchar.b.chen == 0)
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
2269 if (_ifxhc->halting)
2272 * A halt has already been issued for this channel. This might
2273 * happen when a transfer is aborted by a higher level in
2277 IFX_PRINT("*** %s: Channel %d, _hc->halting already set ***\n",
2278 __func__, _ifxhc->hc_num);
2280 //ifxusb_dump_global_registers(_core_if); */
2281 //ifxusb_dump_host_registers(_core_if); */
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;
2290 ifxusb_wreg(&hc_regs->hcchar, hcchar.d32);
2291 _ifxhc->halt_status = _halt_status;
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);
2303 \brief Clears a host channel.
2305 void ifxhcd_hc_cleanup(ifxusb_core_if_t *_core_if, ifxhcd_hc_t *_ifxhc)
2307 ifxusb_hc_regs_t *hc_regs;
2309 _ifxhc->xfer_started = 0;
2311 * Clear channel interrupt enables and any unhandled channel interrupt
2314 hc_regs = _core_if->hc_regs[_ifxhc->hc_num];
2315 ifxusb_wreg(&hc_regs->hcintmsk, 0);
2316 ifxusb_wreg(&hc_regs->hcint, 0xFFFFFFFF);
2318 #ifdef __HC_XFER_TIMEOUT__
2319 del_timer(&_ifxhc->hc_xfer_timer);
2323 hcchar_data_t hcchar;
2324 hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
2326 IFX_WARN("%s: chdis set, channel %d, hcchar 0x%08x\n", __func__, _ifxhc->hc_num, hcchar.d32);
2339 static void dump_urb_info(struct urb *_urb, char* _fn_name)
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",
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;
2356 IFX_PRINT(" Speed: %s\n",
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;
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)
2377 for (i = 0; i < _urb->number_of_packets; i++)
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);
2387 static void dump_channel_info(ifxhcd_hcd_t *_ifxhcd, ifxhcd_epqh_t *_epqh)
2389 if (_epqh->hc != NULL)
2391 ifxhcd_hc_t *hc = _epqh->hc;
2392 struct list_head *item;
2393 ifxhcd_epqh_t *epqh_item;
2395 ifxusb_hc_regs_t *hc_regs;
2397 hcchar_data_t hcchar;
2398 hcsplt_data_t hcsplt;
2399 hctsiz_data_t hctsiz;
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);
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)
2424 epqh_item = list_entry(item, ifxhcd_epqh_t, epqh_list_entry);
2425 IFX_PRINT(" %p\n", epqh_item);
2427 IFX_PRINT(" NP Ready:\n");
2428 list_for_each(item, &_ifxhcd->epqh_np_ready)
2430 epqh_item = list_entry(item, ifxhcd_epqh_t, epqh_list_entry);
2431 IFX_PRINT(" %p\n", epqh_item);
2433 IFX_PRINT(" INTR Active:\n");
2434 list_for_each(item, &_ifxhcd->epqh_intr_active)
2436 epqh_item = list_entry(item, ifxhcd_epqh_t, epqh_list_entry);
2437 IFX_PRINT(" %p\n", epqh_item);
2439 IFX_PRINT(" INTR Ready:\n");
2440 list_for_each(item, &_ifxhcd->epqh_intr_ready)
2442 epqh_item = list_entry(item, ifxhcd_epqh_t, epqh_list_entry);
2443 IFX_PRINT(" %p\n", epqh_item);
2446 IFX_PRINT(" ISOC Active:\n");
2447 list_for_each(item, &_ifxhcd->epqh_isoc_active)
2449 epqh_item = list_entry(item, ifxhcd_epqh_t, epqh_list_entry);
2450 IFX_PRINT(" %p\n", epqh_item);
2452 IFX_PRINT(" ISOC Ready:\n");
2453 list_for_each(item, &_ifxhcd->epqh_isoc_ready)
2455 epqh_item = list_entry(item, ifxhcd_epqh_t, epqh_list_entry);
2456 IFX_PRINT(" %p\n", epqh_item);
2459 IFX_PRINT(" Standby:\n");
2460 list_for_each(item, &_ifxhcd->epqh_stdby)
2462 epqh_item = list_entry(item, ifxhcd_epqh_t, epqh_list_entry);
2463 IFX_PRINT(" %p\n", epqh_item);
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
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.
2481 #ifdef __ENABLE_DUMP__
2482 void ifxhcd_dump_state(ifxhcd_hcd_t *_ifxhcd)
2486 num_channels = _ifxhcd->core_if.params.host_channels;
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);
2510 IFX_PRINT(" isoc_xact_pos: %d\n" , hc->isoc_xact_pos);
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);
2519 IFX_PRINT("************************************************************\n");
2522 #endif //__ENABLE_DUMP__