--- zzzz-none-000/linux-2.6.28.10/drivers/usb/core/hcd.c 2009-05-02 18:54:43.000000000 +0000 +++ fusiv-7390-686/linux-2.6.28.10/drivers/usb/core/hcd.c 2012-02-14 14:37:49.000000000 +0000 @@ -275,6 +275,10 @@ /*-------------------------------------------------------------------------*/ +#if defined (CONFIG_FUSIV_VX185) && defined (CONFIG_CPU_MIPSR2_IRQ_VI) +fusiv_irq_params_t usb_fusiv_irq[2]; +#endif + /* * helper routine for returning string descriptors in UTF-16LE * input can actually be ISO-8859-1; ASCII is its 7-bit subset @@ -1313,6 +1317,9 @@ atomic_inc(&urb->use_count); atomic_inc(&urb->dev->urbnum); usbmon_urb_submit(&hcd->self, urb); +#ifdef AVM_USB_TRACE + avm_usb_trace_submit(hcd, urb); +#endif /* NOTE requirements on root-hub callers (usbfs and the hub * driver, for now): URBs' urb->transfer_buffer must be @@ -1324,6 +1331,9 @@ status = map_urb_for_dma(hcd, urb, mem_flags); if (unlikely(status)) { usbmon_urb_submit_error(&hcd->self, urb, status); +#ifdef AVM_USB_TRACE + avm_usb_trace_error(hcd, urb, status); +#endif goto error; } @@ -1334,6 +1344,9 @@ if (unlikely(status)) { usbmon_urb_submit_error(&hcd->self, urb, status); +#ifdef AVM_USB_TRACE + avm_usb_trace_error(hcd, urb, status); +#endif unmap_urb_for_dma(hcd, urb); error: urb->hcpriv = NULL; @@ -1438,6 +1451,10 @@ unmap_urb_for_dma(hcd, urb); usbmon_urb_complete(&hcd->self, urb, status); +#ifdef AVM_USB_TRACE + avm_usb_trace_complete(hcd, urb, status); +#endif + usb_unanchor_urb(urb); /* pass ownership to the completion handler */ @@ -1713,11 +1730,20 @@ * If the controller isn't HALTed, calls the driver's irq handler. * Checks whether the controller is now dead. */ +#if defined (CONFIG_FUSIV_VX185) && defined (CONFIG_CPU_MIPSR2_IRQ_VI) +irqreturn_t usb_hcd_irq (int irq, fusiv_irq_params_t *fusiv_irq) +{ + struct usb_hcd *hcd = (struct usb_hcd *) fusiv_irq->priv; + unsigned long flags; + irqreturn_t rc; + +#else irqreturn_t usb_hcd_irq (int irq, void *__hcd) { struct usb_hcd *hcd = __hcd; unsigned long flags; irqreturn_t rc; +#endif /* IRQF_DISABLED doesn't work correctly with shared IRQs * when the first handler doesn't use it. So let's just @@ -1913,8 +1939,31 @@ snprintf(hcd->irq_descr, sizeof(hcd->irq_descr), "%s:usb%d", hcd->driver->description, hcd->self.busnum); + +#if defined (CONFIG_FUSIV_VX185) && defined (CONFIG_CPU_MIPSR2_IRQ_VI) + if(strcmp(hcd->driver->description, "ohci_hcd") == 0) + { + usb_fusiv_irq[0].ipc_src = USBO_INT; + usb_fusiv_irq[0].priv = hcd; + retval = request_irq(irqnum, &usb_hcd_irq, irqflags, + hcd->irq_descr, &usb_fusiv_irq[0]); + } + else if(strcmp(hcd->driver->description, "ehci_hcd") == 0) + { + usb_fusiv_irq[1].ipc_src = USBE_INT; + usb_fusiv_irq[1].priv = hcd; + retval = request_irq(irqnum, &usb_hcd_irq, irqflags, + hcd->irq_descr, &usb_fusiv_irq[1]); + } + else + printk("%s:ERROR unhandled interrupt request for IPC source...\n",__FUNCTION__); + + if (retval != 0) +#else if ((retval = request_irq(irqnum, &usb_hcd_irq, irqflags, - hcd->irq_descr, hcd)) != 0) { + hcd->irq_descr, hcd)) != 0) +#endif + { dev_err(hcd->self.controller, "request interrupt %d failed\n", irqnum); goto err_request_irq; @@ -1951,6 +2000,11 @@ } if (hcd->uses_new_polling && hcd->poll_rh) usb_hcd_poll_rh_status(hcd); + +#ifdef AVM_USB_TRACE + avm_usb_register_trace_device (hcd); +#endif + return retval; error_create_attr_group: @@ -2011,6 +2065,11 @@ if (hcd->irq >= 0) free_irq(hcd->irq, hcd); + +#ifdef AVM_USB_TRACE + avm_usb_deregister_trace_device (hcd); +#endif + usb_deregister_bus(&hcd->self); hcd_buffer_destroy(hcd); } @@ -2063,5 +2122,97 @@ mb(); } EXPORT_SYMBOL_GPL (usb_mon_deregister); +#ifdef CONFIG_FUSIV_USB_LED +#include +fusiv_led_t fusiv_leds[FUSIV_USB_MAX_LEDS]; +struct timer_list fusiv_led_timer; +void fusiv_usb_led_set( unsigned int portnum,unsigned int bit) +{ + if ( portnum < FUSIV_USB_MAX_LEDS) + { + if ( (bit == FUSIV_USB_LED_ATTCHD_BIT) && (!fusiv_leds[portnum].led_status) ) + { + // turn on the LED + fusiv_leds[portnum].led_status = 1; + gpioApiSetMode(fusiv_leds[portnum].gpio_no,fusiv_leds[portnum].led_status); + } + else if ( !timer_pending(&fusiv_led_timer)) // start timer for blinking + mod_timer(&fusiv_led_timer,jiffies+FUSIV_USB_LED_HALF_PERIOD); + + fusiv_leds[portnum].port_status |=bit; + } +} +EXPORT_SYMBOL(fusiv_usb_led_set); +void fusiv_usb_led_clear( unsigned int portnum,unsigned int bit) +{ + if ( portnum < FUSIV_USB_MAX_LEDS) + { + if ( bit == FUSIV_USB_LED_ATTCHD_BIT) + { + // turn off the LED and clear port_status + if ( fusiv_leds[portnum].led_status ) + { + fusiv_leds[portnum].led_status = 0; + gpioApiSetMode(fusiv_leds[portnum].gpio_no,fusiv_leds[portnum].led_status); + } + fusiv_leds[portnum].port_status = 0; + } + else + fusiv_leds[portnum].port_status &= ~bit; + } +} +EXPORT_SYMBOL(fusiv_usb_led_clear); + +/* Function responsible for blinking LED, otherwise it will not run */ +static void fusiv_led_timer_func (unsigned long data) +{ + unsigned int i; + for (i=0; i < FUSIV_USB_MAX_LEDS; i++) + { + if ( fusiv_leds[i].port_status & FUSIV_USB_LED_ATTCHD_BIT ) + { + if ( fusiv_leds[i].port_status & FUSIV_USB_LED_XTR_BIT ) + { // data tranfer is going on, continue blinking + fusiv_leds[i].port_status &= ~FUSIV_USB_LED_XTR_BIT; + fusiv_leds[i].led_status = !(fusiv_leds[i].led_status); + gpioApiSetMode(fusiv_leds[i].gpio_no,fusiv_leds[i].led_status); + fusiv_leds[i].blink_status = 1; + fusiv_leds[i].count=0; + } + else if ( !(fusiv_leds[i].count++ % 10 )) + { // Make sure that LED is not turn off for longer duration i.e if led was turned off + // and then no data transfer happens + fusiv_leds[i].blink_status = 0; // stops timer + if ( !fusiv_leds[i].led_status ) + { + fusiv_leds[i].led_status = 1; + gpioApiSetMode(fusiv_leds[i].gpio_no,fusiv_leds[i].led_status); + } + } + + } + + } + + for (i=0; i < FUSIV_USB_MAX_LEDS; i++) + if ( fusiv_leds[i].blink_status ) + { + mod_timer(&fusiv_led_timer,jiffies+FUSIV_USB_LED_HALF_PERIOD); + break; + } +} +void fusiv_usb_led_init(void) +{ + memset(&fusiv_leds,0,sizeof(fusiv_leds)); + + fusiv_leds[0].gpio_no=CONFIG_USB_PORT0_STATE; + fusiv_leds[1].gpio_no=CONFIG_USB_PORT1_STATE; + + init_timer(&fusiv_led_timer); + fusiv_led_timer.function = fusiv_led_timer_func; + fusiv_led_timer.data = (unsigned long) NULL; + gpioApiInitialize(); +} +#endif #endif /* CONFIG_USB_MON */