/** * bi_udc_exit - Stop using the USB Device Controller * * Stop using the USB Device Controller. * * Shutdown and free dma channels, de-register the interrupt handler. */ void bi_udc_exit(void) { int i; dbg_init(1, "Unloading %s", udc_name()); for (i = 0; i < udc_max_endpoints(); i++) { udc_disable_ep(i); } // free io and irq udc_disconnect(); udc_disable(); udc_release_io(); udc_release_udc_irq(); if (have_cable_irq) { udc_release_cable_irq(); } }
/** * bi_udc_init - initialize USB Device Controller * * Get ready to use the USB Device Controller. * * Register an interrupt handler and IO region. Return non-zero for error. */ int bi_udc_init (void) { dbg_init (1, "Loading %s", udc_name ()); bi_driver.name = udc_name (); bi_driver.max_endpoints = udc_max_endpoints (); bi_driver.maxpacketsize = udc_ep0_packetsize (); dbg_init (1, "name: %s endpoints: %d ep0: %d", bi_driver.name, bi_driver.max_endpoints, bi_driver.maxpacketsize); // request device IRQ if (udc_request_udc_irq ()) { dbg_init (0, "name: %s request udc irq failed", udc_name ()); return -EINVAL; } // request device IO if (udc_request_io ()) { udc_release_udc_irq (); dbg_init (0, "name: %s request udc io failed", udc_name ()); return -EINVAL; } // probe for device if (udc_init ()) { udc_release_udc_irq (); udc_release_io (); dbg_init (1, "name: %s probe failed", udc_name ()); return -EINVAL; } // optional cable IRQ have_cable_irq = !udc_request_cable_irq (); dbg_init (1, "name: %s request cable irq %d", udc_name (), have_cable_irq); return 0; }
/** * bi_device_event - handle generic bus event * @device: device pointer * @event: interrupt event * * Called by usb core layer to inform bus of an event. */ int bi_device_event (struct usb_device_instance *device, usb_device_event_t event, int data) { //printk(KERN_DEBUG "bi_device_event: event: %d\n", event); if (!device) { return 0; } dbg_usbe (1,"%s", USBD_DEVICE_EVENTS(event)); switch (event) { case DEVICE_UNKNOWN: break; case DEVICE_INIT: break; case DEVICE_CREATE: // XXX should this stuff be in DEVICE_INIT? // enable upstream port //ep0_enable(device); // for net_create bi_config (device); // enable udc, enable interrupts, enable connect printk(KERN_INFO"bi_device_event: call udc_enable\n"); udc_enable (device); printk(KERN_INFO"bi_device_event: call udc_all_interrupts\n"); // XXX verify udc_suspended_interrupts (device); //udc_all_interrupts (device); dbg_usbe (1, "CREATE done"); break; case DEVICE_HUB_CONFIGURED: udc_connect (); break; case DEVICE_RESET: device->address = 0; udc_set_address (device->address); udc_reset_ep (0); // XXX verify udc_suspended_interrupts (device); dbg_usbe (1, "DEVICE RESET done: %d", device->address); break; case DEVICE_ADDRESS_ASSIGNED: udc_set_address (device->address); device->status = USBD_OK; // XXX verify udc_all_interrupts (device); // XXX break; case DEVICE_CONFIGURED: device->status = USBD_OK; bi_config (device); break; case DEVICE_DE_CONFIGURED: { int ep; for (ep = 1; ep < udc_max_endpoints (); ep++) udc_reset_ep (ep); } break; case DEVICE_SET_INTERFACE: bi_config (device); break; case DEVICE_SET_FEATURE: break; case DEVICE_CLEAR_FEATURE: break; case DEVICE_BUS_INACTIVE: // disable suspend interrupt udc_suspended_interrupts (device); // XXX check on linkup and sl11 // if we are no longer connected then force a reset if (!udc_connected ()) { usbd_device_event_irq (device, DEVICE_RESET, 0); } break; case DEVICE_BUS_ACTIVITY: // enable suspend interrupt udc_all_interrupts (device); break; case DEVICE_POWER_INTERRUPTION: break; case DEVICE_HUB_RESET: break; case DEVICE_DESTROY: udc_disconnect (); bi_disable_endpoints (device); udc_disable_interrupts (device); udc_disable (); break; case DEVICE_FUNCTION_PRIVATE: break; } return 0; }