Beispiel #1
0
/**
 * udc_cable_event - called from cradle interrupt handler
 */
void udc_cable_event(void)
{
    struct usb_bus_instance *bus;
    struct usb_device_instance *device;
    struct bi_data *data;

    dbgENTER(dbgflg_usbdbi_init,1);

    // sanity check
    if (!(device = device_array[0]) || !(bus = device->bus) || !(data = bus->privdata)) {
        return;
    }

    {
        unsigned long flags;
        local_irq_save(flags);
        if (udc_connected()) {
            dbg_init(1, "state: %d connected: %d", device->device_state, 1);;
            if (device->device_state == STATE_ATTACHED) {
                dbg_init(1, "LOADING");
                usbd_device_event_irq(device, DEVICE_HUB_CONFIGURED, 0);
                usbd_device_event_irq(device, DEVICE_RESET, 0);
            }
        }
        else {
            dbg_init(1, "state: %d connected: %d", device->device_state, 0);;
            if (device->device_state != STATE_ATTACHED) {
                dbg_init(1, "UNLOADING");
                usbd_device_event_irq(device, DEVICE_RESET, 0);
                usbd_device_event_irq(device, DEVICE_POWER_INTERRUPTION, 0);
                usbd_device_event_irq(device, DEVICE_HUB_RESET, 0);
            }
        }
        local_irq_restore(flags);
    }
    dbgLEAVE(dbgflg_usbdbi_init,1);
}
Beispiel #2
0
/* bi_modexit - decommission bus interface driver
 */
void __exit bi_modexit(void)
{
    struct usb_bus_instance *bus;
    struct usb_device_instance *device;
    struct bi_data *data;

    dbgENTER(dbgflg_usbdbi_init,1);

    if ((device = device_array[0])) {

        // XXX moved to usbd_deregister_device()
        //device->status = USBD_CLOSING;

        udc_disconnect();
        udc_disable();

        // XXX XXX
        if (dbgflg_usbdbi_tick > 0) {
            ticker_killoff();
        }

        bus = device->bus;
        data = bus->privdata;

        // XXX
        usbd_device_event(device, DEVICE_RESET, 0);
        usbd_device_event(device, DEVICE_POWER_INTERRUPTION, 0);
        usbd_device_event(device, DEVICE_HUB_RESET, 0);

        dbg_init(1,"DEVICE_DESTROY");
        usbd_device_event(device, DEVICE_DESTROY, 0);

        dbg_init(1,"DISABLE ENDPOINTS");
        bi_disable_endpoints(device);

        dbg_init(1,"UDC_DISABLE");
        //udc_disable();

        dbg_init(1,"BI_UDC_EXIT");
        bi_udc_exit();

        device_array[0] = NULL;
        bus->privdata = NULL;


#ifdef CONFIG_PM
        dbg_init(1,"PM_UNREGISTER(pm_dev#%p)",pm_dev);
        if (pm_dev) {
            pm_unregister(pm_dev);
        }
#endif
        dbg_init(1,"DEREGISTER DEVICE");
        usbd_deregister_device(device);
        bus->device = NULL;

        dbg_init(1,"kfree(data#%p)",data);
        if (data) {
            kfree(data);
        }

        if (bus->serial_number_str) {
            kfree(bus->serial_number_str);
        }

        dbg_init(1,"DEREGISTER BUS");
        usbd_deregister_bus(bus);

    }
    else {
        dbg_init(0,"device is NULL");
    }
    dbg_init(1,"BI_EXIT");
    bi_exit();
    dbgLEAVE(dbgflg_usbdbi_init,1);
}
Beispiel #3
0
/* bi_modinit - commission bus interface driver
 */
int __init bi_modinit(void)
{
    struct usb_bus_instance * bus;
    struct usb_device_instance * device;
    //extern const char __usbd_module_info[];

    //printk(KERN_INFO "%s (dbg=\"%s\")\n", __usbd_module_info, dbg?dbg:"");

    if (0 != scan_debug_options("usb-bus",dbg_table,dbg)) {
        printk("Failed to scan dbg in bi_modinit\n");
    }

    if (bi_udc_init()) {
        return(-EINVAL);
    }

    // register this bus interface driver and create the device driver instance
    if ((bus = usbd_register_bus(&bi_driver))==NULL) {
        bi_udc_exit();
        return -EINVAL;
    }

    // see if we can scrounge up something to set a sort of unique device
    // address
    if (!udc_serial_init(bus)) {
        dbg_init(1,"serial: %s %04x", bus->serial_number_str,
                 bus->serial_number);
    }

    if ((device = usbd_register_device(NULL, bus, 8))==NULL) {
        usbd_deregister_bus(bus);
        bi_udc_exit();
        return -EINVAL;
    }

#ifdef CONFIG_PM
    // register with power management
    pm_dev = pm_register(PM_USB_DEV, PM_SYS_UNKNOWN, bi_pm_event);
    pm_dev->data = device;
#endif

    bus->device = device;
    device_array[0] = device;

    // initialize the device
    {
        struct usb_endpoint_instance *endpoint = device->bus->endpoint_array + 0;

        // setup endpoint zero

        endpoint->endpoint_address = 0;

        endpoint->tx_attributes = 0;
        endpoint->tx_transferSize = 255;
        endpoint->tx_packetSize = udc_ep0_packetsize();

        endpoint->rcv_attributes = 0;
        endpoint->rcv_transferSize = 0x8;
        endpoint->rcv_packetSize = udc_ep0_packetsize();

        udc_setup_ep(device, 0, endpoint);
    }

    // hopefully device enumeration will finish this process
    udc_startup_events(device);

#ifdef CONFIG_PM
    dbg_pm(0,"pm_dev->callback#%p",pm_dev->callback);
    if (!udc_connected()) {
       /* Fake a call from the PM system to suspend the UDC until it
           is needed (cable connect, etc) */
        (void) bi_pm_event(pm_dev,PM_SUSPEND,NULL);
    /* There appears to be no constant for this, but inspection
           of arch/arm/mach-l7200/apm.c:send_event() shows that the
           suspended state is 3 (i.e. pm_send_all(PM_SUSPEND, (void *)3))
           corresponding to ACPI_D3. */
    pm_dev->state = 3;
    }
#endif
    if (dbgflg_usbdbi_tick > 0) {
        // start ticker
        ticker_kickoff();
    }

    dbgLEAVE(dbgflg_usbdbi_init,1);
    return 0;
}
Beispiel #4
0
/* bi_modinit - commission bus interface driver
 */
static int __init bi_modinit (void)
{
	extern const char __usbd_module_info[];
	struct usb_bus_instance *bus;
	struct usb_device_instance *device;
	struct bi_data *data;


	printk (KERN_INFO "%s (dbg=\"%s\")\n", __usbd_module_info, dbg ? dbg : "");

	// process debug options
	if (0 != scan_debug_options ("usbd-bi", dbg_table, dbg)) {
		return -EINVAL;
	}
	// check if we can see the UDC
	if (bi_udc_init ()) {
		return -EINVAL;
	}
	// allocate a bi private data structure
	if ((data = kmalloc (sizeof (struct bi_data), GFP_KERNEL)) == NULL) {
		bi_udc_exit ();
		return -EINVAL;
	}
	memset (data, 0, sizeof (struct bi_data));

	// register this bus interface driver and create the device driver instance
	if ((bus = usbd_register_bus (&bi_driver)) == NULL) {
		kfree (data);
		bi_udc_exit ();
		return -EINVAL;
	}

	bus->privdata = data;

	// see if we can scrounge up something to set a sort of unique device address
	if (!udc_serial_init (bus)) {
		dbg_init (1, "serial: %s %04x\n", bus->serial_number_str, bus->serial_number);
	}


	if ((device = usbd_register_device (NULL, bus, 8)) == NULL) {
		usbd_deregister_bus (bus);
		kfree (data);
		bi_udc_exit ();
		return -EINVAL;
	}
#if defined(CONFIG_PM) && !defined(CONFIG_USBD_MONITOR) && !defined(CONFIG_USBD_MONITOR_MODULE)
	// register with power management 
	pm_dev = pm_register (PM_USB_DEV, PM_SYS_UNKNOWN, bi_pm_event);
	pm_dev->data = device;
#endif

#ifdef CONFIG_DPM	/* MVL-CEE */
	bi_udc_ldm_driver_register();
	bi_udc_ldm_device_register();
#endif

	bus->device = device;
	device_array[0] = device;

	// initialize the device
	{
		struct usb_endpoint_instance *endpoint = device->bus->endpoint_array + 0;

		// setup endpoint zero

		endpoint->endpoint_address = 0;

		endpoint->tx_attributes = 0;
		endpoint->tx_transferSize = 255;
		endpoint->tx_packetSize = udc_ep0_packetsize ();

		endpoint->rcv_attributes = 0;
		endpoint->rcv_transferSize = 0x8;
		endpoint->rcv_packetSize = udc_ep0_packetsize ();

		udc_setup_ep (device, 0, endpoint);
	}

	// hopefully device enumeration will finish this process
        printk(KERN_INFO"bi_modinit: call udc_startup_events\n");
	udc_startup_events (device);

#if defined(CONFIG_PM) && !defined(CONFIG_USBD_MONITOR) && !defined(CONFIG_USBD_MONITOR_MODULE)
	dbg_pm (0, "pm_dev->callback#%p", pm_dev->callback);
	if (!udc_connected ()) {
		/* Fake a call from the PM system to suspend the UDC until it
		   is needed (cable connect, etc) */
		(void) bi_pm_event (pm_dev, PM_SUSPEND, NULL);
		/* There appears to be no constant for this, but inspection
		   of arch/arm/mach-l7200/apm.c:send_event() shows that the
		   suspended state is 3 (i.e. pm_send_all(PM_SUSPEND, (void *)3))
		   corresponding to ACPI_D3. */
		pm_dev->state = 3;
	}
#endif
	if (dbgflg_usbdbi_tick > 0) {
		// start ticker
		ticker_kickoff ();
	}

#ifdef CONFIG_USBD_PROCFS
	{
		struct proc_dir_entry *p;

		// create proc filesystem entries
		if ((p = create_proc_entry ("usbd", 0, 0)) == NULL) {
			return -ENOMEM;
		}
		p->proc_fops = &usbd_proc_operations_functions;
	}
#endif
	dbgLEAVE (dbgflg_usbdbi_init, 1);
	return 0;
}