コード例 #1
0
/* *
 * usbd_proc_read - implement proc file system read.
 * @file
 * @buf
 * @count
 * @pos
 *
 * Standard proc file system read function.
 */
static ssize_t usbd_proc_read (struct file *file, char *buf, size_t count, loff_t * pos)
{
        struct usb_device_instance *device;
	unsigned long page;
	int len = 0;
	int index;

	MOD_INC_USE_COUNT;
	// get a page, max 4095 bytes of data...
	if (!(page = get_free_page (GFP_KERNEL))) {
		MOD_DEC_USE_COUNT;
		return -ENOMEM;
	}

	len = 0;
	index = (*pos)++;

	switch (index) {
        case 0:
		len += sprintf ((char *) page + len, "USBD Status\n");
                break;

        case 1:
		len += sprintf ((char *) page + len, "Cable: %s\n", udc_connected ()? "Plugged" : "Unplugged");
                break;

        case 2:
                if ((device = device_array[0])) {
                        struct usb_function_instance * function_instance;
                        struct usb_bus_instance * bus;

                        len += sprintf ((char *) page + len, "Device status: %s\n", USBD_DEVICE_STATUS(device->status));
                        len += sprintf ((char *) page + len, "Device state: %s\n", USBD_DEVICE_STATE(device->device_state));

                        if ((function_instance = device->function_instance_array+0)) {
                                len += sprintf ((char *) page + len, "Function: %s\n", 
                                                function_instance->function_driver->name);
                        }
                        if ((bus= device->bus)) {
                                len += sprintf ((char *) page + len, "Bus interface: %s\n", 
                                                bus->driver->name);
                        }
                }
                break;

        default:
                break;
        }


	if (len > count) {
		len = -EINVAL;
	} else if (len > 0 && copy_to_user (buf, (char *) page, len)) {
		len = -EFAULT;
	}
	free_page (page);
	MOD_DEC_USE_COUNT;
	return len;
}
コード例 #2
0
ファイル: usbd-bi.c プロジェクト: robacklin/uclinux-linux
/**
 * 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);
}
コード例 #3
0
ファイル: usbd-bi.c プロジェクト: robacklin/uclinux-linux
/* 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;
}
コード例 #4
0
ファイル: usbd-bi.c プロジェクト: robacklin/uclinux-linux
/**
 * 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)
{
    sie_info * sie_data;
    cy_priv_t * cy_priv;
    otg_t * otg;

    sie_data = (sie_info *) device->bus->privdata;
    cy_priv = (cy_priv_t *) sie_data->cy_priv;
    otg = (otg_t *) cy_priv->otg;

    //printk(KERN_DEBUG "bi_device_event: event: %d\n", event);

    if (!device) {
        return 0;
    }
    switch (event) {
    case DEVICE_UNKNOWN:
        break;
    case DEVICE_INIT:
        break;
    case DEVICE_CREATE:         // XXX should this stuff be in DEVICE_INIT?

        bi_config(device);

        // enable udc, enable interrupts, enable connect
        udc_enable(device);
        udc_all_interrupts(device);
        udc_connect();
        break;

    case DEVICE_HUB_CONFIGURED:
        break;

    case DEVICE_RESET:
        device->address = 0;
        udc_set_address(device->address, device);
        udc_reset_ep(0, device);
        udc_all_interrupts(device); // XXX
        break;


    case DEVICE_ADDRESS_ASSIGNED:
        udc_set_address(device->address, device);
        device->status = USBD_OK;
        break;

    case DEVICE_CONFIGURED:
        bi_config(device);
        break;

    case DEVICE_DE_CONFIGURED:
        udc_reset_ep(1, device);
        udc_reset_ep(2, device);
        udc_reset_ep(3, device);
        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_BUS_REQUEST:
        otg->b_bus_req = TRUE;
        update_otg_state(otg);
        break;

    case DEVICE_BUS_RELEASE:
        otg->b_bus_req = FALSE;
        update_otg_state(otg);
        break;

    case DEVICE_RCV_URB_RECYCLED:
        udc_rcv_urb_recycled();
        break;

    case DEVICE_ACCEPT_HNP:
        otg->b_hnp_en = TRUE;
        update_otg_state(otg);
    break;

    case DEVICE_REQUEST_SRP:
        //otg->srp_start_flag = TRUE;
        otg->b_bus_req = TRUE;
        otg->b_se0_srp = TRUE;
        update_otg_state(otg);
    break;

    case DEVICE_FUNCTION_PRIVATE:
        break;
    }

    return 0;
}
コード例 #5
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;
}
コード例 #6
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;
}