/** * usb_reset_configuration - lightweight device reset * @dev: the device whose configuration is being reset * * This issues a standard SET_CONFIGURATION request to the device using * the current configuration. The effect is to reset most USB-related * state in the device, including interface altsettings (reset to zero), * endpoint halts (cleared), and data toggle (only for bulk and interrupt * endpoints). Other usbcore state is unchanged, including bindings of * usb device drivers to interfaces. * * Because this affects multiple interfaces, avoid using this with composite * (multi-interface) devices. Instead, the driver for each interface may * use usb_set_interface() on the interfaces it claims. Be careful though; * some devices don't support the SET_INTERFACE request, and others won't * reset all the interface state (notably data toggles). Resetting the whole * configuration would affect other drivers' interfaces. * * The caller must own the device lock. * * Returns zero on success, else a negative error code. */ int usb_reset_configuration(struct usb_device *dev) { int i, retval; struct usb_host_config *config; if (dev->state == USB_STATE_SUSPENDED) return -EHOSTUNREACH; /* caller must have locked the device and must own * the usb bus readlock (so driver bindings are stable); * calls during probe() are fine */ for (i = 1; i < 16; ++i) { usb_disable_endpoint(dev, i); usb_disable_endpoint(dev, i + USB_DIR_IN); } config = dev->actconfig; retval = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), USB_REQ_SET_CONFIGURATION, 0, config->desc.bConfigurationValue, 0, NULL, 0, USB_CTRL_SET_TIMEOUT); if (retval < 0) return retval; dev->toggle[0] = dev->toggle[1] = 0; /* re-init hc/hcd interface/endpoint state */ for (i = 0; i < config->desc.bNumInterfaces; i++) { struct usb_interface *intf = config->interface[i]; struct usb_host_interface *alt; if (device_is_registered(&intf->dev)) usb_remove_sysfs_intf_files(intf); alt = usb_altnum_to_altsetting(intf, 0); /* No altsetting 0? We'll assume the first altsetting. * We could use a GetInterface call, but if a device is * so non-compliant that it doesn't have altsetting 0 * then I wouldn't trust its reply anyway. */ if (!alt) alt = &intf->altsetting[0]; intf->cur_altsetting = alt; usb_enable_interface(dev, intf); if (device_is_registered(&intf->dev)) usb_create_sysfs_intf_files(intf); } return 0; }
/** * usb_reset_configuration - lightweight device reset * @dev: the device whose configuration is being reset * * This issues a standard SET_CONFIGURATION request to the device using * the current configuration. The effect is to reset most USB-related * state in the device, including interface altsettings (reset to zero), * endpoint halts (cleared), and data toggle (only for bulk and interrupt * endpoints). Other usbcore state is unchanged, including bindings of * usb device drivers to interfaces. * * Because this affects multiple interfaces, avoid using this with composite * (multi-interface) devices. Instead, the driver for each interface may * use usb_set_interface() on the interfaces it claims. Resetting the whole * configuration would affect other drivers' interfaces. * * Returns zero on success, else a negative error code. */ int usb_reset_configuration(struct usb_device *dev) { int i, retval; struct usb_host_config *config; /* caller must own dev->serialize (config won't change) * and the usb bus readlock (so driver bindings are stable); * so calls during probe() are fine */ for (i = 1; i < 16; ++i) { usb_disable_endpoint(dev, i); usb_disable_endpoint(dev, i + USB_DIR_IN); } config = dev->actconfig; retval = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), USB_REQ_SET_CONFIGURATION, 0, config->desc.bConfigurationValue, 0, NULL, 0, HZ * USB_CTRL_SET_TIMEOUT); if (retval < 0) { usb_set_device_state(dev, USB_STATE_ADDRESS); return retval; } dev->toggle[0] = dev->toggle[1] = 0; dev->halted[0] = dev->halted[1] = 0; /* re-init hc/hcd interface/endpoint state */ for (i = 0; i < config->desc.bNumInterfaces; i++) { struct usb_interface *intf = config->interface[i]; struct usb_host_interface *alt; alt = usb_altnum_to_altsetting(intf, 0); /* No altsetting 0? We'll assume the first altsetting. * We could use a GetInterface call, but if a device is * so non-compliant that it doesn't have altsetting 0 * then I wouldn't trust its reply anyway. */ if (!alt) alt = &intf->altsetting[0]; intf->cur_altsetting = alt; usb_enable_interface(dev, intf); } return 0; }
// see usb_hw_layer.h for documentation void usb_disable_endpoints(void) { int8 i; for (i=1; i<USB_NUM_UEP; i++) usb_disable_endpoint(i); //__usb_kbhit_status=0; }
/** * usb_disable_interface -- Disable all endpoints for an interface * @dev: the device whose interface is being disabled * @intf: pointer to the interface descriptor * * Disables all the endpoints for the interface's current altsetting. */ void usb_disable_interface(struct usb_device *dev, struct usb_interface *intf) { struct usb_host_interface *alt = intf->cur_altsetting; int i; for (i = 0; i < alt->desc.bNumEndpoints; ++i) { usb_disable_endpoint(dev, alt->endpoint[i].desc.bEndpointAddress); } }
static void usb_setup_set_configuration(int value) { switch (value) { case 0: usb_disable_endpoint(ep_index(1, DIR_RX)); usb_disable_endpoint(ep_index(1, DIR_TX)); usb_state = STATE_ADDRESS; usb_status_ack(DIR_TX); break; case 1: usb_setup_interface(); usb_state = STATE_CONFIGURED; usb_status_ack(DIR_TX); break; default: usb_request_error(); } }
/* * usb_disable_device - Disable all the endpoints for a USB device * @dev: the device whose endpoints are being disabled * @skip_ep0: 0 to disable endpoint 0, 1 to skip it. * * Disables all the device's endpoints, potentially including endpoint 0. * Deallocates hcd/hardware state for the endpoints (nuking all or most * pending urbs) and usbcore state for the interfaces, so that usbcore * must usb_set_configuration() before any interfaces could be used. */ void usb_disable_device(struct usb_device *dev, int skip_ep0) { int i; dev_dbg(&dev->dev, "%s nuking %s URBs\n", __FUNCTION__, skip_ep0 ? "non-ep0" : "all"); for (i = skip_ep0; i < 16; ++i) { usb_disable_endpoint(dev, i); usb_disable_endpoint(dev, i + USB_DIR_IN); } dev->toggle[0] = dev->toggle[1] = 0; /* getting rid of interfaces will disconnect * any drivers bound to them (a key side effect) */ if (dev->actconfig) { for (i = 0; i < dev->actconfig->desc.bNumInterfaces; i++) { struct usb_interface *interface; /* remove this interface if it has been registered */ interface = dev->actconfig->interface[i]; if (!klist_node_attached(&interface->dev.knode_bus)) continue; dev_dbg (&dev->dev, "unregistering interface %s\n", interface->dev.bus_id); usb_remove_sysfs_intf_files(interface); kfree(interface->cur_altsetting->string); interface->cur_altsetting->string = NULL; device_del (&interface->dev); } /* Now that the interfaces are unbound, nobody should * try to access them. */ for (i = 0; i < dev->actconfig->desc.bNumInterfaces; i++) { put_device (&dev->actconfig->interface[i]->dev); dev->actconfig->interface[i] = NULL; } dev->actconfig = NULL; if (dev->state == USB_STATE_CONFIGURED) usb_set_device_state(dev, USB_STATE_ADDRESS); } }
// see usb_hw_layer.h for documentation void usb_set_configured(int8 config) { int8 en; int16 addy; int8 new_uep; int16 len; int8 i; /*if (config == 0) { // if config=0 then set addressed state usb_state = USB_STATE_ADDRESS; usb_disable_endpoints(); } else */ { // else set configed state usb_state = USB_STATE_CONFIGURED; addy = (int16)USB_DATA_BUFFER_LOCATION+(2*USB_MAX_EP0_PACKET_LENGTH); for (en=1; en<USB_NUM_UEP; en++) { // enable and config endpoints based upon user configuration usb_disable_endpoint(en); new_uep = 0; if (usb_ep_rx_type[en] != USB_ENABLE_DISABLED) { new_uep = 0x04; len = usb_ep_rx_size[en]; EP_BDxCNT_O(en) = len; EP_BDxADR_O(en) = addy; addy += usb_ep_rx_size[en]; #if USB_IGNORE_RX_DTS i = 0x80; #else i = 0x88; #endif if (bit_test(len,8)) {bit_set(i,0);} if (bit_test(len,9)) {bit_set(i,1);} EP_BDxST_O(en) = i; } if (usb_ep_tx_type[en] != USB_ENABLE_DISABLED) { new_uep |= 0x02; EP_BDxADR_I(en) = addy; addy += usb_ep_tx_size[en]; EP_BDxST_I(en) = 0x40; } if (new_uep == 0x06) {new_uep = 0x0E;} if (usb_ep_tx_type[en] != USB_ENABLE_ISOCHRONOUS) {new_uep |= 0x10;} UEP(en) = new_uep; } } }
PROCESS_THREAD(usb_eth_process, ev , data) { PROCESS_BEGIN(); usb_register_request_handler(&cdc_eth_request_hook); usb_setup(); usb_set_ep_event_process(DATA_OUT, process_current); usb_set_global_event_process(process_current); uip_fw_default(&usbethif); uip_setethaddr(default_uip_ethaddr); uip_arp_init(); while(1) { PROCESS_WAIT_EVENT(); if (ev == PROCESS_EVENT_EXIT) break; if (ev == PROCESS_EVENT_POLL) { unsigned int events = usb_get_global_events(); if (events) { if (events & USB_EVENT_CONFIG) { if (usb_get_current_configuration() != 0) { printf("Configured\n"); usb_setup_bulk_endpoint(DATA_IN); usb_setup_bulk_endpoint(DATA_OUT); usb_setup_interrupt_endpoint(INTERRUPT_IN); init_recv_buffer(); usb_submit_recv_buffer(DATA_OUT, &recv_buffer); #if 0 { static const uint8_t foo[4] = {0x12,0x34,0x56,0x78}; xmit_buffer[0].next = NULL; xmit_buffer[0].left = sizeof(foo); xmit_buffer[0].flags = USB_BUFFER_SHORT_END; xmit_buffer[0].data = &foo; usb_submit_xmit_buffer(DATA_IN, &xmit_buffer[0]); } #endif } else { usb_disable_endpoint(DATA_IN); usb_disable_endpoint(DATA_OUT); usb_disable_endpoint(INTERRUPT_IN); } } } events = usb_get_ep_events(DATA_OUT); if (events & USB_EP_EVENT_NOTIFICATION) { uip_len = sizeof(recv_data) - recv_buffer.left; /* printf("Received: %d bytes\n", uip_len); */ memcpy(uip_buf, recv_data, uip_len); #if UIP_CONF_IPV6 if(BUF->type == uip_htons(UIP_ETHTYPE_IPV6)) { uip_neighbor_add(&IPBUF->srcipaddr, &BUF->src); tcpip_input(); } else #endif /* UIP_CONF_IPV6 */ if(BUF->type == uip_htons(UIP_ETHTYPE_IP)) { uip_len -= sizeof(struct uip_eth_hdr); tcpip_input(); } else if(BUF->type == uip_htons(UIP_ETHTYPE_ARP)) { uip_arp_arpin(); /* If the above function invocation resulted in data that should be sent out on the network, the global variable uip_len is set to a value > 0. */ if (uip_len > 0) { memcpy(xmit_data, uip_buf, uip_len); xmit_buffer[0].next = NULL; xmit_buffer[0].data = xmit_data; xmit_buffer[0].left = uip_len; xmit_buffer[0].flags = USB_BUFFER_SHORT_END; usb_submit_xmit_buffer(DATA_IN, &xmit_buffer[0]); /* printf("Sent: %d bytes\n", uip_len); */ } } init_recv_buffer(); usb_submit_recv_buffer(DATA_OUT, &recv_buffer); } } } PROCESS_END(); }
PROCESS_THREAD(eriks_process, ev , data) { static struct etimer timer; uip_ipaddr_t myaddr; uip_ipaddr_t hostaddr; uip_ipaddr_t netmask; #if 0 struct dhcps_client_lease dhleases[3]; struct dhcps_config dhconfig; #endif PROCESS_BEGIN(); printf("Eriks super process\n\r"); uip_init(); #if 0 dhconfig.leases = &dhleases[0]; dhconfig.num_leases = 3; dhconfig.default_lease_time = 3600; uip_ipaddr(&dhconfig.netmask, 255,255,255,255); uip_ipaddr(&dhconfig.dnsaddr, 1,2,3,4); uip_ipaddr(&dhconfig.dnsaddr, 1,0,0,1); dhconfig.flags = DHCP_CONF_NETMASK | DHCP_CONF_DEFAULT_ROUTER; #endif /* usb_set_user_process(process_current); */ uip_ipaddr(&myaddr, 10,0,0,2); uip_sethostaddr(&hostaddr); uip_ipaddr(&netmask, 255,0,0,0); uip_sethostaddr(&hostaddr); uip_ipaddr(&myaddr, 10,0,0,1); uip_ipaddr(&netmask, 255,255,0,0); usb_setup(); #if 0 usb_cdc_eth_set_ifaddr(&myaddr); usb_cdc_eth_setup(); dhcps_init(&dhconfig); while(ev != PROCESS_EVENT_EXIT) { PROCESS_WAIT_EVENT(); printf("EVENT\n\r"); } #else usb_cdc_acm_setup(); while(ev != PROCESS_EVENT_EXIT) { PROCESS_WAIT_EVENT(); if (ev == PROCESS_EVENT_TIMER) { leds_toggle(LEDS_YELLOW); /* printf("FIFOP: %d\n", FIFOP_IS_1); */ etimer_restart(&timer); } else if (ev == PROCESS_EVENT_MSG) { const struct usb_user_msg * const msg = data; switch(msg->type) { case USB_USER_MSG_TYPE_CONFIG: printf("User config\n"); if (msg->data.config != 0) { #if 0 usb_setup_bulk_endpoint(DEV_TO_HOST, input_buffer, sizeof(input_buffer)); usb_setup_bulk_endpoint(HOST_TO_DEV, output_buffer, sizeof(output_buffer)); usb_setup_interrupt_endpoint(0x83,interrupt_buffer, sizeof(interrupt_buffer)); etimer_set(&timer, CLOCK_SECOND); #endif } else { #if 0 etimer_stop(&timer); usb_disable_endpoint(DEV_TO_HOST); usb_disable_endpoint(HOST_TO_DEV); usb_disable_endpoint(0x83); #endif } break; case USB_USER_MSG_TYPE_EP_OUT(2): { #if 0 /*unsigned int len = msg->data.length; printf("Received %d:\n", len); */ { unsigned char ch; unsigned int xfer; /* while((xfer = usb_recv_data(HOST_TO_DEV, &ch, 1)) > 0) { printf(" %02x",ch); */ /* if (slip_input_byte(ch)) break; */ } #endif /* printf("\n"); */ } break; } } } #endif printf("Exiting USB process\n\r"); PROCESS_END(); }
PROCESS_THREAD(gateway_process, ev , data) { static struct etimer timer; PROCESS_BEGIN(); usb_set_user_process(process_current); usb_setup(); usb_cdc_acm_setup(); uip_fw_default(&slipif); uip_over_mesh_set_gateway_netif(&slipif); process_start(&slip_process, NULL); set_gateway(); while(ev != PROCESS_EVENT_EXIT) { PROCESS_WAIT_EVENT(); if (ev == PROCESS_EVENT_TIMER) { leds_toggle(LEDS_YELLOW); /* printf("FIFOP: %d\n", FIFOP_IS_1); */ etimer_restart(&timer); } else if (ev == PROCESS_EVENT_MSG) { const struct usb_user_msg * const msg = data; switch(msg->type) { case USB_USER_MSG_TYPE_CONFIG: printf("User config\n"); if (msg->data.config != 0) { usb_setup_bulk_endpoint(DEV_TO_HOST, input_buffer, sizeof(input_buffer)); usb_setup_bulk_endpoint(HOST_TO_DEV, output_buffer, sizeof(output_buffer)); usb_setup_interrupt_endpoint(0x83,interrupt_buffer, sizeof(interrupt_buffer)); etimer_set(&timer, CLOCK_SECOND); } else { etimer_stop(&timer); usb_disable_endpoint(DEV_TO_HOST); usb_disable_endpoint(HOST_TO_DEV); usb_disable_endpoint(0x83); } break; case USB_USER_MSG_TYPE_EP_OUT(2): { /*unsigned int len = msg->data.length; printf("Received %d:\n", len); */ { unsigned char ch; unsigned int xfer; while((xfer = usb_recv_data(HOST_TO_DEV, &ch, 1)) > 0) { /* printf(" %02x",ch); */ if (slip_input_byte(ch)) break; } /* printf("\n"); */ } } break; } } } printf("USB test process exited\n"); PROCESS_END(); }