void MachineS3c6400::hardwareShutdown(struct fbinfo *fbi) { fb_printf(fbi, "\n\n MachineS3c6400::hardwareShutdown USB...\n"); resetUSB(usb_sigmask); fb_printf(fbi, " MachineS3c6400::hardwareShutdown DMA...\n"); s3c6400ShutdownDMA(fbi); fb_printf(fbi, " MachineS3c6400::hardwareShutdown Clear IRQ...\n"); clearIRQS(); }
int main(int argc, char **argv) { //parse the input parameters to get the bus number and device number int l_busNum, l_devNum; int l_ret; printf("program started!\n"); if (argc < 3) { printf("not enough arguments!\n"); printf("usage: ./usbreset <bus number> <dev number>\n"); return 0; } printf("bus number: %s\n", argv[1]); printf("dev number: %s\n", argv[2]); l_busNum = atoi(argv[1]); l_devNum = atoi(argv[2]); printf("bus number: %d; dev number: %d\n", l_busNum, l_devNum); l_ret = libusb_init(NULL); if (l_ret < 0) { return l_ret; } l_ret = libusb_get_device_list(NULL, &devs); if (l_ret < 0) { return (int) l_ret; } dev = search_device(l_busNum, l_devNum); if (dev == NULL) { printf("device not found\n"); return 0; } l_ret = libusb_open(dev, &devh); if (l_ret == 0) { printf("got the usb handle successfully.\n"); } else { printf("error getting usb handle.\n"); } //reset the usb device resetUSB(); //free the device list libusb_free_device_list(devs, 1); libusb_exit(NULL); return 0; }
static void usbIRQHandler(uint32_t token) { // we need to mask because GINTSTS is set for a particular interrupt even if it's masked in GINTMSK (GINTMSK just prevents an interrupt being generated) uint32_t status = GET_REG(USB + GINTSTS) & GET_REG(USB + GINTMSK); int process = FALSE; //uartPrintf("<begin interrupt: %x>\r\n", status); if(status) { process = TRUE; } while(process) { if((status & GINTMSK_OTG) == GINTMSK_OTG) { // acknowledge OTG interrupt (these bits are all R_SS_WC which means Write Clear, a write of 1 clears the bits) SET_REG(USB + GOTGINT, GET_REG(USB + GOTGINT)); // acknowledge interrupt (this bit is actually RO, but should've been cleared when we cleared GOTGINT. Still, iBoot pokes it as if it was WC, so we will too) SET_REG(USB + GINTSTS, GINTMSK_OTG); process = TRUE; } else { // we only care about OTG process = FALSE; } if((status & GINTMSK_RESET) == GINTMSK_RESET) { if(usb_state < USBError) { bufferPrintf("usb: reset detected\r\n"); change_state(USBPowered); } int retval = resetUSB(); SET_REG(USB + GINTSTS, GINTMSK_RESET); if(retval) { bufferPrintf("usb: listening for further usb events\r\n"); return; } process = TRUE; } if(((status & GINTMSK_INEP) == GINTMSK_INEP) || ((status & GINTMSK_OEP) == GINTMSK_OEP)) { // aha, got something on one of the endpoints. Now the real fun begins // first, let's get the interrupt status of individual endpoints getEndpointInterruptStatuses(); if(isSetupPhaseDone()) { // recall our earlier receiveControl calls. We now should have 8 bytes of goodness in controlRecvBuffer. USBSetupPacket* setupPacket = (USBSetupPacket*) controlRecvBuffer; uint16_t length; uint32_t totalLength; USBStringDescriptor* strDesc; if(USBSetupPacketRequestTypeType(setupPacket->bmRequestType) != USBSetupPacketVendor) { switch(setupPacket->bRequest) { case USB_GET_DESCRIPTOR: length = setupPacket->wLength; // descriptor type is high, descriptor index is low switch(setupPacket->wValue >> 8) { case USBDeviceDescriptorType: if(length > sizeof(USBDeviceDescriptor)) length = sizeof(USBDeviceDescriptor); memcpy(controlSendBuffer, usb_get_device_descriptor(), length); break; case USBConfigurationDescriptorType: // hopefully SET_ADDRESS was received beforehand to set the speed totalLength = getConfigurationTree(setupPacket->wValue & 0xFF, usb_speed, controlSendBuffer); if(length > totalLength) length = totalLength; break; case USBStringDescriptorType: strDesc = usb_get_string_descriptor(setupPacket->wValue & 0xFF); if(length > strDesc->bLength) length = strDesc->bLength; memcpy(controlSendBuffer, strDesc, length); break; case USBDeviceQualifierDescriptorType: if(length > sizeof(USBDeviceQualifierDescriptor)) length = sizeof(USBDeviceQualifierDescriptor); memcpy(controlSendBuffer, usb_get_device_qualifier_descriptor(), length); break; default: bufferPrintf("Unknown descriptor request: %d\r\n", setupPacket->wValue >> 8); if(usb_state < USBError) { change_state(USBUnknownDescriptorRequest); } } if(usb_state < USBError) { sendControl(controlSendBuffer, length); } break; case USB_SET_ADDRESS: usb_speed = DSTS_GET_SPEED(GET_REG(USB + DSTS)); usb_max_packet_size = packetsizeFromSpeed(usb_speed); SET_REG(USB + DCFG, (GET_REG(USB + DCFG) & ~DCFG_DEVICEADDRMSK) | ((setupPacket->wValue & DCFG_DEVICEADDR_UNSHIFTED_MASK) << DCFG_DEVICEADDR_SHIFT)); // send an acknowledgement sendControl(controlSendBuffer, 0); if(usb_state < USBError) { change_state(USBAddress); } break; case USB_SET_INTERFACE: // send an acknowledgement sendControl(controlSendBuffer, 0); break; case USB_GET_STATUS: // FIXME: iBoot doesn't really care about this status *((uint16_t*) controlSendBuffer) = 0; sendControl(controlSendBuffer, sizeof(uint16_t)); break; case USB_GET_CONFIGURATION: // FIXME: iBoot just puts out a debug message on console for this request. break; case USB_SET_CONFIGURATION: setConfiguration(0); // send an acknowledgment sendControl(controlSendBuffer, 0); if(usb_state < USBError) { change_state(USBConfigured); startHandler(); } break; default: if(usb_state < USBError) { change_state(USBUnknownRequest); } } // get the next SETUP packet receiveControl(controlRecvBuffer, sizeof(USBSetupPacket)); } } else { //uartPrintf("\t<begin callEndpointHandlers>\r\n"); callEndpointHandlers(); //uartPrintf("\t<end callEndpointHandlers>\r\n"); } process = TRUE; }