/* * * usbd_proc_write - implement proc file system write. * @file * @buf * @count * @pos * * Proc file system write function, used to signal monitor actions complete. * (Hotplug script (or whatever) writes to the file to signal the completion * of the script.) An ugly hack. */ static ssize_t usbd_proc_write (struct file *file, const char *buf, size_t count, loff_t * pos) { struct usb_device_instance *device; size_t n = count; char command[64]; char *cp = command; int i = 0; MOD_INC_USE_COUNT; //printk(KERN_DEBUG "%s: count=%u\n",__FUNCTION__,count); while ((n > 0) && (i < 64)) { // Not too efficient, but it shouldn't matter if (copy_from_user (cp++, buf + (count - n), 1)) { count = -EFAULT; break; } *cp = '\0'; i++; n -= 1; //printk(KERN_DEBUG "%s: %u/%u %02x\n",__FUNCTION__,count-n,count,c); } if (!strncmp (command, "plug", 4)) { udc_connect (); } else if (!strncmp (command, "unplug", 6)) { udc_disconnect (); if ((device = device_array[0])) { usbd_device_event (device, DEVICE_RESET, 0); } } MOD_DEC_USE_COUNT; return (count); }
static int bi_udc_resume(struct device *dev, u32 level) { int ret = 0; struct usb_device_instance *device = device_array[0]; switch (level) { case RESUME_POWER_ON: dbg_pm (0, "RESUME_POWER_ON"); if (udc_init ()) { dbg_init (0, "udc_init failed"); } if (device) { udc_enable (device); /* enable UDC */ udc_all_interrupts (device); /* enable interrupts */ } udc_connect (); /* enable USB pullup */ dbg_init (1, "MOD_INC_USE_COUNT %d", GET_USE_COUNT (THIS_MODULE)); dbg_pm (0, "RESUME_POWER_ON: finished"); break; } return ret; }
/* * usbd_pm_callback * @dev: * @rqst: * @unused: * * Used to signal power management events. */ static int bi_pm_event (struct pm_dev *pm_dev, pm_request_t request, void *unused) { struct usb_device_instance *device; dbg_pm (0, "request: %d pm_dev: %p data: %p", request, pm_dev, pm_dev->data); if (!(device = pm_dev->data)) { dbg_pm (0, "DATA NULL, NO DEVICE"); return 0; } switch (request) { #if defined(CONFIG_IRIS) case PM_STANDBY: case PM_BLANK: #endif case PM_SUSPEND: dbg_pm (0, "PM_SUSPEND"); if (!pm_suspended) { pm_suspended = 1; dbg_init (1, "MOD_INC_USE_COUNT %d", GET_USE_COUNT (THIS_MODULE)); udc_disconnect (); // disable USB pullup if we can udc_disable_interrupts (device); // disable interupts udc_disable (); // disable UDC dbg_pm (0, "PM_SUSPEND: finished"); } break; #if defined(CONFIG_IRIS) case PM_UNBLANK: #endif case PM_RESUME: dbg_pm (0, "PM_RESUME"); if (pm_suspended) { // probe for device if (udc_init ()) { dbg_init (0, "udc_init failed"); //return -EINVAL; } udc_enable (device); // enable UDC udc_all_interrupts (device); // enable interrupts udc_connect (); // enable USB pullup if we can //udc_set_address(device->address); //udc_reset_ep(0); pm_suspended = 0; dbg_init (1, "MOD_INC_USE_COUNT %d", GET_USE_COUNT (THIS_MODULE)); dbg_pm (0, "PM_RESUME: finished"); } break; } return 0; }
static void usb_udc_init(void) { DBG("usb init start\n"); usbotg_init_ext(); usbotg_clock_gate(1); usb_phy_init(); usb_set_mode_device(); //mxc_init_usb_qh(); //usb_init_eps(); //mxc_init_ep_struct(); //ep0_setup(); //mxc_ep_qh_setup(0, USB_RECV, USB_ENDPOINT_XFER_CONTROL, // USB_MAX_CTRL_PAYLOAD, 0, 0); udc_connect(); }
int do_neo1973 ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) { int i; if (!strcmp(argv[1], "info")) { printf("FIC Neo1973 Hardware Revision 0x%04x\n", get_board_rev()); } else if (!strcmp(argv[1], "power-off")) { neo1973_poweroff(); } else if (!strcmp(argv[1], "charger") || !strcmp(argv[1], "charge")) { if (argc < 3) goto out_help; if (!strcmp(argv[2], "status") || !strcmp(argv[2], "state")) { printf("%s\n", neo1973_get_charge_status()); } else if (!strcmp(argv[2], "autofast")) { neo1973_set_charge_mode(NEO1973_CHGCMD_AUTOFAST); } else if (!strcmp(argv[2], "!autofast")) { neo1973_set_charge_mode(NEO1973_CHGCMD_NO_AUTOFAST); } else if (!strcmp(argv[2], "off")) { neo1973_set_charge_mode(NEO1973_CHGCMD_OFF); } else if (!strcmp(argv[2], "fast")) { neo1973_set_charge_mode(NEO1973_CHGCMD_FAST); } else goto out_help; } else if (!strcmp(argv[1], "backlight")) { if (argc < 3) goto out_help; if (!strcmp(argv[2], "on")) neo1973_backlight(1); else neo1973_backlight(0); } else if (!strcmp(argv[1], "led")) { long led = simple_strtol(argv[2], NULL, 10); if (argc < 4) goto out_help; if (!strcmp(argv[3], "on")) neo1973_led(led, 1); else neo1973_led(led, 0); } else if (!strcmp(argv[1], "vibrator")) { if (argc < 3) goto out_help; if (!strcmp(argv[2], "on")) neo1973_vibrator(1); else neo1973_vibrator(0); } else if (!strcmp(argv[1], "gsm")) { if (argc < 3) goto out_help; if (!strcmp(argv[2], "on")) neo1973_gsm(1); else if (!strcmp(argv[2], "off")) neo1973_gsm(0); else if (!strcmp(argv[2], "version")) neo1973_gsmver(); } else if (!strcmp(argv[1], "gps")) { if (argc < 3) goto out_help; if (!strcmp(argv[2], "on")) neo1973_gps(1); else neo1973_gps(0); } else if (!strcmp(argv[1], "udc")) { if (argc < 3) goto out_help; if (!strcmp(argv[2], "pullup")) { if (argc < 4) goto out_help; if (!strcmp(argv[3], "on")) udc_connect(); else udc_disconnect(); } else goto out_help; } else { out_help: printf("Usage:\n%s\n", cmdtp->usage); return 1; } 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) { 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; }
/** * 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; }
int ticker_thread (void *data) { struct timer_list ticker; // detach lock_kernel (); exit_mm (current); exit_files (current); exit_fs (current); // setsid equivalent, used at start of kernel thread, no error checks needed, or at least none made :). current->leader = 1; current->session = current->pgrp = current->pid; current->tty = NULL; current->tty_old_pgrp = 0; // Name this thread sprintf (current->comm, "usbd-bi"); // setup signal handler current->exit_signal = SIGCHLD; spin_lock (¤t->sigmask_lock); flush_signals (current); spin_unlock (¤t->sigmask_lock); // XXX Run at a high priority, ahead of sync and friends // current->nice = -20; current->policy = SCHED_OTHER; unlock_kernel (); // setup timer init_timer (&ticker); ticker.data = 0; ticker.function = ticker_tick; // let startup continue up (&ticker_sem_start); // process loop for (ticker_timer_set = ticker_terminating = 0; !ticker_terminating;) { char buf[100]; char *cp; if (!ticker_timer_set) { mod_timer (&ticker, jiffies + HZ * RETRYTIME); } // wait for someone to tell us to do something down (&ticker_sem_work); if (udc_interrupts != udc_interrupts_last) { dbg_tick (3, "--------------"); } // do some work memset (buf, 0, sizeof (buf)); cp = buf; if (dbgflg_usbdbi_tick) { unsigned long flags; local_irq_save (flags); dbg_tick (2, "[%d]", udc_interrupts); udc_regs (); local_irq_restore (flags); } #if 0 // XXX #if defined(CONFIG_SA1110_CALYPSO) && defined(CONFIG_PM) && defined(CONFIG_USBD_TRAFFIC_KEEPAWAKE) /* Check for rx/tx activity, and reset the sleep timer if present */ if (device->usbd_rxtx_timestamp != device->usbd_last_rxtx_timestamp) { extern void resetSleepTimer (void); dbg_tick (7, "resetting sleep timer"); resetSleepTimer (); device->usbd_last_rxtx_timestamp = device->usbd_rxtx_timestamp; } #endif #endif #if 0 /* Check for TX endpoint stall. If the endpoint has stalled, we have probably run into the DMA/TCP window problem, and the only thing we can do is disconnect from the bus, then reconnect (and re-enumerate...). */ if (reconnect > 0 && 0 >= --reconnect) { dbg_init (0, "TX stall disconnect finished"); udc_connect (); } else if (0 != USBD_STALL_TIMEOUT_SECONDS) { // Stall watchdog unleashed unsigned long now, tx_waiting; now = jiffies; tx_waiting = (now - tx_queue_head_timestamp (now)) / HZ; if (tx_waiting > USBD_STALL_TIMEOUT_SECONDS) { /* The URB at the head of the queue has waited too long */ reconnect = USBD_STALL_DISCONNECT_DURATION; dbg_init (0, "TX stalled, disconnecting for %d seconds", reconnect); udc_disconnect (); } } #endif } // remove timer del_timer (&ticker); // let the process stopping us know we are done and return up (&ticker_sem_start); return 0; }
int fastboot_init(struct cmd_fastboot_interface *interface) { fastboot_interface = interface; return udc_connect(); }