static int wii_find_mouse() { s32 fd=0; static u8 *buffer = 0; if (!buffer) { buffer = (u8*)memalign(32, DEVLIST_MAXSIZE << 3); } if(buffer == NULL) { return -1; } memset(buffer, 0, DEVLIST_MAXSIZE << 3); u8 dummy; u16 vid,pid; if (USB_GetDeviceList("/dev/usb/oh0", buffer, DEVLIST_MAXSIZE, 0, &dummy) < 0) { free(buffer); buffer =0; return -2; } u8 mouseep; u32 mouseep_size; int i; for(i = 0; i < DEVLIST_MAXSIZE; i++) { memcpy(&vid, (buffer + (i << 3) + 4), 2); memcpy(&pid, (buffer + (i << 3) + 6), 2); if ((vid==0)&&(pid==0)) continue; fd =0; int err = USB_OpenDevice("oh0",vid,pid,&fd); if (err<0) { continue; } else { //fprintf(stderr, "ok open %04x:%04x\n", vid, pid); //SDL_Delay(1000); } u32 iConf, iInterface, iEp; usb_devdesc udd; usb_configurationdesc *ucd; usb_interfacedesc *uid; usb_endpointdesc *ued; USB_GetDescriptors(fd, &udd); for(iConf = 0; iConf < udd.bNumConfigurations; iConf++) { ucd = &udd.configurations[iConf]; for(iInterface = 0; iInterface < ucd->bNumInterfaces; iInterface++) { uid = &ucd->interfaces[iInterface]; if ( (uid->bInterfaceClass == USB_CLASS_HID) && (uid->bInterfaceSubClass == USB_SUBCLASS_BOOT) && (uid->bInterfaceProtocol== USB_PROTOCOL_MOUSE)) { int iEp; for(iEp = 0; iEp < uid->bNumEndpoints; iEp++) { ued = &uid->endpoints[iEp]; mouse_vid = vid; mouse_pid = pid; mouseep = ued->bEndpointAddress; mouseep_size = ued->wMaxPacketSize; mouseconfiguration = ucd->bConfigurationValue; mouseinterface = uid->bInterfaceNumber; mousealtInterface = uid->bAlternateSetting; } break; } } } USB_FreeDescriptors(&udd); USB_CloseDevice(&fd); } if (mouse_pid!=0 || mouse_vid!=0) return 0; return -1; }
static int wiiusb_hid_add_adapter(void *data, usb_device_entry *dev) { usb_devdesc desc; const char *device_name = NULL; wiiusb_hid_t *hid = (wiiusb_hid_t*)data; struct wiiusb_adapter *adapter = (struct wiiusb_adapter*) calloc(1, sizeof(struct wiiusb_adapter)); if (!adapter) return -1; if (!hid) { free(adapter); RARCH_ERR("Allocation of adapter failed.\n"); return -1; } if (USB_OpenDevice(dev->device_id, dev->vid, dev->pid, &adapter->handle) < 0) { RARCH_ERR("Error opening device 0x%p (VID/PID: %04x:%04x).\n", dev->device_id, dev->vid, dev->pid); free(adapter); return -1; } adapter->device_id = dev->device_id; USB_GetDescriptors(adapter->handle, &desc); wiiusb_get_description(dev, adapter, &desc); if (adapter->endpoint_in == 0) { RARCH_ERR("Could not find HID config for device.\n"); goto error; } /* Allocate mem for the send control buffer, 32bit aligned */ adapter->send_control_type = WIIUSB_SC_NONE; adapter->send_control_buffer = memalign(32, 128); if (!adapter->send_control_buffer) { RARCH_ERR("Error creating send control buffer.\n"); goto error; } /* Sent the pad name as dummy, we don't know the * control name until we get its interface */ adapter->slot = pad_connection_pad_init(hid->connections, "hid", desc.idVendor, desc.idProduct, adapter, &wiiusb_hid); if (adapter->slot == -1) goto error; if (!pad_connection_has_interface(hid->connections, adapter->slot)) { RARCH_ERR(" Interface not found.\n"); goto error; } adapter->data = memalign(32, 128); adapter->hid = hid; adapter->next = hid->adapters_head; hid->adapters_head = adapter; /* Get the name from the interface */ device_name = wiiusb_hid_joypad_name(hid, adapter->slot); RARCH_LOG("Interface found: [%s].\n", device_name); RARCH_LOG("Device 0x%p attached (VID/PID: %04x:%04x).\n", adapter->device_id, desc.idVendor, desc.idProduct); wiiusb_hid_device_add_autodetect(adapter->slot, device_name, wiiusb_hid.ident, desc.idVendor, desc.idProduct); USB_FreeDescriptors(&desc); USB_DeviceRemovalNotifyAsync(adapter->handle, wiiusb_hid_removal_cb, adapter); return 0; error: if (adapter->send_control_buffer) free(adapter->send_control_buffer); if (adapter) free(adapter); USB_FreeDescriptors(&desc); USB_CloseDevice(&adapter->handle); return -1; }
s32 USB_GetDescriptors(struct ehci_hcd * ehci,struct ehci_device * fd, usb_devdesc *udd) { u8 *buffer = NULL; u8 *ptr = NULL; usb_configurationdesc *ucd = NULL; usb_interfacedesc *uid = NULL; usb_endpointdesc *ued = NULL; s32 retval = 0; u32 size,i; u32 iConf, iInterface, iEndpoint; buffer = USB_Alloc(sizeof(*udd)); if(buffer == NULL) { retval = -ENOMEM; goto free_and_error; } retval = __usb_getdesc(ehci, fd, buffer, USB_DT_DEVICE, 0, USB_DT_DEVICE_SIZE); if(retval < 0) goto free_and_error; memcpy(udd, buffer, USB_DT_DEVICE_SIZE); USB_Free(buffer); udd->bcdUSB = cpu_to_le16(udd->bcdUSB); udd->idVendor = cpu_to_le16(udd->idVendor); udd->idProduct = cpu_to_le16(udd->idProduct); udd->bcdDevice = cpu_to_le16(udd->bcdDevice); udd->configurations = USB_Alloc(udd->bNumConfigurations* sizeof(*udd->configurations)); if(udd->configurations == NULL) { retval = -ENOMEM; goto free_and_error; } memset(udd->configurations,0,udd->bNumConfigurations* sizeof(*udd->configurations)); for(iConf = 0; iConf < udd->bNumConfigurations; iConf++) { buffer = USB_Alloc( USB_DT_CONFIG_SIZE); if(buffer == NULL) { retval = -ENOMEM; goto free_and_error; } retval = __usb_getdesc(ehci, fd, buffer, USB_DT_CONFIG, iConf, USB_DT_CONFIG_SIZE); ucd = &udd->configurations[iConf]; memcpy(ucd, buffer, USB_DT_CONFIG_SIZE); USB_Free( buffer); ucd->wTotalLength = cpu_to_le16(ucd->wTotalLength); size = ucd->wTotalLength; buffer = USB_Alloc( ucd->wTotalLength); if(buffer == NULL) { retval = -ENOMEM; goto free_and_error; } retval = __usb_getdesc(ehci, fd, buffer, USB_DT_CONFIG, iConf, ucd->wTotalLength); if(retval < 0) goto free_and_error; ptr = buffer; ptr += ucd->bLength; size -= ucd->bLength; retval = -ENOMEM; ucd->interfaces = USB_Alloc(ucd->bNumInterfaces* sizeof(*ucd->interfaces)); if(ucd->interfaces == NULL) goto free_and_error; memset(ucd->interfaces,0,ucd->bNumInterfaces* sizeof(*ucd->interfaces)); for(iInterface = 0; iInterface < ucd->bNumInterfaces; iInterface++) { uid = &ucd->interfaces[iInterface]; memcpy(uid, ptr, USB_DT_INTERFACE_SIZE); ptr += uid->bLength; size -= uid->bLength; uid->endpoints = USB_Alloc(uid->bNumEndpoints* sizeof(*uid->endpoints)); if(uid->endpoints == NULL) goto free_and_error; memset(uid->endpoints,0,uid->bNumEndpoints* sizeof(*uid->endpoints)); // This skips vendor and class specific descriptors i = __find_next_endpoint(ptr, size); uid->extra_size = i; if(i>0) { uid->extra = USB_Alloc(i); if(uid->extra == NULL) goto free_and_error; memcpy(uid->extra, ptr, i); ptr += i; size -= i; } for(iEndpoint = 0; iEndpoint < uid->bNumEndpoints; iEndpoint++) { ued = &uid->endpoints[iEndpoint]; memcpy(ued, ptr, USB_DT_ENDPOINT_SIZE); ptr += ued->bLength; ued->wMaxPacketSize = cpu_to_le16(ued->wMaxPacketSize); } } USB_Free( buffer); buffer = NULL; } retval = 0; free_and_error: if(buffer != NULL) USB_Free(buffer); if(retval < 0) USB_FreeDescriptors(udd); return retval; }
s32 USB_GetDescriptors(s32 fd, usb_devdesc *udd) { u8 *buffer = NULL; u8 *ptr = NULL; usb_configurationdesc *ucd = NULL; usb_interfacedesc *uid = NULL; usb_endpointdesc *ued = NULL; s32 retval = 0; u32 iConf, iInterface, iEndpoint; buffer = iosAlloc(hId, sizeof(*udd)); if(buffer == NULL) { retval = IPC_ENOHEAP; goto free_and_error; } retval = __usb_getdesc(fd, buffer, USB_DT_DEVICE, 0, USB_DT_DEVICE_SIZE); if(retval < 0) goto free_and_error; memcpy(udd, buffer, USB_DT_DEVICE_SIZE); iosFree(hId, buffer); udd->bcdUSB = bswap16(udd->bcdUSB); udd->idVendor = bswap16(udd->idVendor); udd->idProduct = bswap16(udd->idProduct); udd->bcdDevice = bswap16(udd->bcdDevice); udd->configurations = calloc(udd->bNumConfigurations, sizeof(*udd->configurations)); if(udd->configurations == NULL) { retval = IPC_ENOMEM; goto free_and_error; } for(iConf = 0; iConf < udd->bNumConfigurations; iConf++) { buffer = iosAlloc(hId, USB_DT_CONFIG_SIZE); if(buffer == NULL) { retval = IPC_ENOHEAP; goto free_and_error; } retval = __usb_getdesc(fd, buffer, USB_DT_CONFIG, iConf, USB_DT_CONFIG_SIZE); ucd = &udd->configurations[iConf]; memcpy(ucd, buffer, USB_DT_CONFIG_SIZE); iosFree(hId, buffer); ucd->wTotalLength = bswap16(ucd->wTotalLength); buffer = iosAlloc(hId, ucd->wTotalLength); if(buffer == NULL) { retval = IPC_ENOHEAP; goto free_and_error; } retval = __usb_getdesc(fd, buffer, USB_DT_CONFIG, iConf, ucd->wTotalLength); if(retval < 0) goto free_and_error; ptr = buffer; ptr += ucd->bLength; retval = IPC_ENOMEM; ucd->interfaces = calloc(ucd->bNumInterfaces, sizeof(*ucd->interfaces)); if(ucd->interfaces == NULL) goto free_and_error; for(iInterface = 0; iInterface < ucd->bNumInterfaces; iInterface++) { uid = &ucd->interfaces[iInterface]; memcpy(uid, ptr, USB_DT_INTERFACE_SIZE); ptr += uid->bLength; uid->endpoints = calloc(uid->bNumEndpoints, sizeof(*uid->endpoints)); if(uid->endpoints == NULL) goto free_and_error; for(iEndpoint = 0; iEndpoint < uid->bNumEndpoints; iEndpoint++) { ued = &uid->endpoints[iEndpoint]; memcpy(ued, ptr, USB_DT_ENDPOINT_SIZE); ptr += ued->bLength; ued->wMaxPacketSize = bswap16(ued->wMaxPacketSize); } } iosFree(hId, buffer); buffer = NULL; } retval = IPC_OK; free_and_error: if(buffer != NULL) iosFree(hId, buffer); if(retval < 0) USB_FreeDescriptors(udd); return retval; }
static int add_adapter(void *data, usb_device_entry *dev) { int rc; usb_devdesc desc; const char *device_name = NULL; struct wiiusb_adapter *old_head = NULL; struct wiiusb_hid *hid = (struct wiiusb_hid*)data; struct wiiusb_adapter *adapter = (struct wiiusb_adapter*) calloc(1, sizeof(struct wiiusb_adapter)); (void)rc; if (!adapter) return -1; if (!hid) { free(adapter); RARCH_ERR("Allocation of adapter failed.\n"); return -1; } if (USB_OpenDevice(dev->device_id, dev->vid, dev->pid, &adapter->handle) < 0) { RARCH_ERR("Error opening device 0x%p (VID/PID: %04x:%04x).\n", (void*)&adapter->device, dev->vid, dev->pid); free(adapter); return -1; } adapter->device = *dev; USB_GetDescriptors(adapter->handle, &desc); wiiusb_get_description(&adapter->device, adapter, &desc); if (adapter->endpoint_in == 0) { RARCH_ERR("Could not find HID config for device.\n"); goto error; } if (desc.iManufacturer) { USB_GetAsciiString(adapter->handle, desc.iManufacturer, 0, sizeof(adapter->manufacturer_name), adapter->manufacturer_name); #if 0 RARCH_ERR(" Adapter Manufacturer name: %s\n", adapter->manufacturer_name); #endif } if (desc.iProduct) { USB_GetAsciiString(adapter->handle, desc.iProduct, 0, sizeof(adapter->name), adapter->name); #if 0 RARCH_ERR(" Adapter name: %s\n", adapter->name); #endif } device_name = (const char *)adapter->name; adapter->send_control_lock = slock_new(); adapter->send_control_buffer = fifo_new(4096); if (!adapter->send_control_lock || !adapter->send_control_buffer) { RARCH_ERR("Error creating send control buffer.\n"); goto error; } adapter->slot = pad_connection_pad_init(hid->slots, device_name, desc.idVendor, desc.idProduct, adapter, &wiiusb_hid_device_send_control); if (adapter->slot == -1) goto error; if (!pad_connection_has_interface(hid->slots, adapter->slot)) { RARCH_ERR(" Interface not found (%s).\n", adapter->name); goto error; } RARCH_LOG("Interface found: [%s].\n", adapter->name); RARCH_LOG("Device 0x%p attached (VID/PID: %04x:%04x).\n", adapter->device, desc.idVendor, desc.idProduct); wiiusb_hid_device_add_autodetect(adapter->slot, device_name, wiiusb_hid.ident, desc.idVendor, desc.idProduct); adapter->hid = hid; adapter->thread = sthread_create(adapter_thread, adapter); if (!adapter->thread) { RARCH_ERR("Error initializing adapter thread.\n"); goto error; } adapter->data = memalign(32, 2048); old_head = adapters.next; adapters.next = adapter; adapter->next = old_head; USB_FreeDescriptors(&desc); USB_DeviceRemovalNotifyAsync(adapter->handle, wiiusb_hid_removalnotify_cb, (void *)hid); return 0; error: if (adapter->thread) sthread_join(adapter->thread); if (adapter->send_control_lock) slock_free(adapter->send_control_lock); if (adapter->send_control_buffer) fifo_free(adapter->send_control_buffer); if (adapter) free(adapter); USB_FreeDescriptors(&desc); USB_CloseDevice(&adapter->handle); return -1; }
s32 USBStorage_Open(ehci_device_data * device_data) { s32 retval = -1; u8 conf, *max_lun = NULL; u32 iConf, iInterface, iEp; static usb_devdesc udd; usb_configurationdesc *ucd; usb_interfacedesc *uid; usb_endpointdesc *ued; struct ehci_hcd * ehci = device_data->__ehci; usbstorage_handle *dev = &device_data->__usbfd; struct ehci_device *fd = device_data->__dev; device_data->__lun = 16; // select bad LUN max_lun = USB_Alloc(1); if (max_lun == NULL) return -ENOMEM; memset(dev, 0, sizeof (*dev)); dev->tag = TAG_START; dev->usb_fd = fd; retval = USB_GetDescriptors(ehci, dev->usb_fd, &udd); #ifdef MEM_PRINT s_printf("USBStorage_Open(): USB_GetDescriptors %i\n", retval); #ifdef MEM_PRINT log_status(ehci, "after USB_GetDescriptors"); #endif #endif if (retval < 0) goto free_and_return; /* // test device changed without unmount (prevent device write corruption) if (ums_init_done) { if (my_memcmp((void *) &_old_udd, (void *) &udd, sizeof (usb_devdesc) - 4)) { USB_Free(max_lun); USB_FreeDescriptors(&udd); #ifdef MEM_PRINT s_printf("USBStorage_Open(): device changed!!!\n"); #endif return -ENODEV; } } */ _old_udd = udd; try_status = -128; for (iConf = 0; iConf < udd.bNumConfigurations; iConf++) { ucd = &udd.configurations[iConf]; for (iInterface = 0; iInterface < ucd->bNumInterfaces; iInterface++) { uid = &ucd->interfaces[iInterface]; // debug_printf("interface %d, class:%x subclass %x protocol %x\n",iInterface,uid->bInterfaceClass,uid->bInterfaceSubClass, uid->bInterfaceProtocol); if (uid->bInterfaceClass == USB_CLASS_MASS_STORAGE && (uid->bInterfaceSubClass == MASS_STORAGE_SCSI_COMMANDS || uid->bInterfaceSubClass == MASS_STORAGE_RBC_COMMANDS || uid->bInterfaceSubClass == MASS_STORAGE_ATA_COMMANDS || uid->bInterfaceSubClass == MASS_STORAGE_QIC_COMMANDS || uid->bInterfaceSubClass == MASS_STORAGE_UFI_COMMANDS || uid->bInterfaceSubClass == MASS_STORAGE_SFF8070_COMMANDS) && uid->bInterfaceProtocol == MASS_STORAGE_BULK_ONLY && uid->bNumEndpoints >= 2) { dev->ata_protocol = 0; if (uid->bInterfaceSubClass != MASS_STORAGE_SCSI_COMMANDS || uid->bInterfaceSubClass != MASS_STORAGE_RBC_COMMANDS) dev->ata_protocol = 1; #ifdef MEM_PRINT s_printf("USBStorage_Open(): interface subclass %i ata_prot %i \n", uid->bInterfaceSubClass, dev->ata_protocol); #endif dev->ep_in = dev->ep_out = 0; for (iEp = 0; iEp < uid->bNumEndpoints; iEp++) { ued = &uid->endpoints[iEp]; if (ued->bmAttributes != USB_ENDPOINT_BULK) continue; if (ued->bEndpointAddress & USB_ENDPOINT_IN) dev->ep_in = ued->bEndpointAddress; else dev->ep_out = ued->bEndpointAddress; } if (dev->ep_in != 0 && dev->ep_out != 0) { dev->configuration = ucd->bConfigurationValue; dev->interface = uid->bInterfaceNumber; dev->altInterface = uid->bAlternateSetting; goto found; } } else { if (uid->endpoints != NULL) USB_Free(uid->endpoints); uid->endpoints = NULL; if (uid->extra != NULL) USB_Free(uid->extra); uid->extra = NULL; if (uid->bInterfaceClass == USB_CLASS_HUB) { retval = USBSTORAGE_ENOINTERFACE; try_status = -20000; USB_FreeDescriptors(&udd); goto free_and_return; } if (uid->bInterfaceClass == USB_CLASS_MASS_STORAGE && uid->bInterfaceProtocol == MASS_STORAGE_BULK_ONLY && uid->bNumEndpoints >= 2) { try_status = -(10000 + uid->bInterfaceSubClass); } } } } #ifdef MEM_PRINT s_printf("USBStorage_Open(): cannot find any interface!!!\n"); #endif USB_FreeDescriptors(&udd); retval = USBSTORAGE_ENOINTERFACE; debug_printf("cannot find any interface\n"); goto free_and_return; found: USB_FreeDescriptors(&udd); retval = USBSTORAGE_EINIT; try_status = -1201; #ifdef MEM_PRINT s_printf("USBStorage_Open(): conf: %x altInterface: %x\n", dev->configuration, dev->altInterface); #endif if (USB_GetConfiguration(ehci, dev->usb_fd, &conf) < 0) goto free_and_return; try_status = -1202; #ifdef MEM_PRINT log_status(ehci, "after USB_GetConfiguration"); #endif #ifdef MEM_PRINT if (conf != dev->configuration) s_printf("USBStorage_Open(): changing conf from %x\n", conf); #endif if (/*conf != dev->configuration &&*/ USB_SetConfiguration(ehci, dev->usb_fd, dev->configuration) < 0) goto free_and_return; try_status = -1203; if (dev->altInterface != 0 && USB_SetAlternativeInterface(ehci, dev->usb_fd, dev->interface, dev->altInterface) < 0) goto free_and_return; try_status = -1204; #ifdef MEM_PRINT log_status(ehci, "Before USBStorage_Reset"); #endif retval = USBStorage_Reset(ehci, dev); #ifdef MEM_PRINT log_status(ehci, "After USBStorage_Reset"); #endif if (retval < 0) goto free_and_return; /* retval = __USB_CtrlMsgTimeout(dev, (USB_CTRLTYPE_DIR_DEVICE2HOST | USB_CTRLTYPE_TYPE_CLASS | USB_CTRLTYPE_REC_INTERFACE), USBSTORAGE_GET_MAX_LUN, 0, dev->interface, 1, max_lun); if(retval < 0 ) dev->max_lun = 1; else dev->max_lun = (*max_lun+1); if(retval == USBSTORAGE_ETIMEDOUT)*/ /* NOTE: from usbmassbulk_10.pdf "Devices that do not support multiple LUNs may STALL this command." */ dev->max_lun = 8; // max_lun can be from 1 to 16, but some devices do not support lun retval = USBSTORAGE_OK; /*if(dev->max_lun == 0) dev->max_lun++;*/ /* taken from linux usbstorage module (drivers/usb/storage/transport.c) */ /* * Some devices (i.e. Iomega Zip100) need this -- apparently * the bulk pipes get STALLed when the GetMaxLUN request is * processed. This is, in theory, harmless to all other devices * (regardless of if they stall or not). */ //USB_ClearHalt(dev->usb_fd, dev->ep_in); //USB_ClearHalt(dev->usb_fd, dev->ep_out); dev->buffer = USB_Alloc(MAX_TRANSFER_SIZE + 16); if (dev->buffer == NULL) { retval = -ENOMEM; try_status = -1205; } else retval = USBSTORAGE_OK; free_and_return: if (max_lun != NULL) USB_Free(max_lun); if (retval < 0) { if (dev->buffer != NULL) USB_Free(dev->buffer); memset(dev, 0, sizeof (*dev)); #ifdef MEM_PRINT s_printf("USBStorage_Open(): try_status %i\n", try_status); #endif return retval; } #ifdef MEM_PRINT s_printf("USBStorage_Open(): return 0\n"); #endif return 0; }
s32 USBStorage_Open(usbstorage_handle *dev, s32 device_id, u16 vid, u16 pid) { s32 retval = -1; u8 conf = -1; u8 *max_lun; u32 iConf, iInterface, iEp; usb_devdesc udd; usb_configurationdesc *ucd; usb_interfacedesc *uid; usb_endpointdesc *ued; bool reset_flag = false; max_lun = __lwp_heap_allocate(&__heap, 1); if (!max_lun) return IPC_ENOMEM; memset(dev, 0, sizeof(*dev)); dev->usb_fd = -1; dev->tag = TAG_START; usb_log("USBStorage_Open id: %i\n",device_id); if (LWP_MutexInit(&dev->lock, false) < 0) goto free_and_return; if (SYS_CreateAlarm(&dev->alarm) < 0) goto free_and_return; retry_init: retval = USB_OpenDevice(device_id, vid, pid, &dev->usb_fd); usb_log("USB_OpenDevice, ret: %i\n",retval); if (retval < 0) goto free_and_return; retval = USB_GetDescriptors(dev->usb_fd, &udd); if (retval < 0) { usb_log("USB_GetDescriptors error, ret: %i\n",retval); goto free_and_return; } else usb_log("USB_GetDescriptors OK, configurations: %i\n",udd.bNumConfigurations); for (iConf = 0; iConf < udd.bNumConfigurations; iConf++) { ucd = &udd.configurations[iConf]; usb_log(" Configuration: %i\n",iConf); for (iInterface = 0; iInterface < ucd->bNumInterfaces; iInterface++) { uid = &ucd->interfaces[iInterface]; usb_log(" Interface: %i InterfaceClass: 0x%x numendpoints: %i\n",iInterface,uid->bInterfaceClass,uid->bNumEndpoints); if(uid->bInterfaceClass == USB_CLASS_MASS_STORAGE && /* (uid->bInterfaceSubClass == MASS_STORAGE_SCSI_COMMANDS || uid->bInterfaceSubClass == MASS_STORAGE_RBC_COMMANDS || uid->bInterfaceSubClass == MASS_STORAGE_ATA_COMMANDS || uid->bInterfaceSubClass == MASS_STORAGE_QIC_COMMANDS || uid->bInterfaceSubClass == MASS_STORAGE_UFI_COMMANDS || uid->bInterfaceSubClass == MASS_STORAGE_SFF8070_COMMANDS) &&*/ uid->bInterfaceProtocol == MASS_STORAGE_BULK_ONLY) { if (uid->bNumEndpoints < 2) continue; dev->ep_in = dev->ep_out = 0; for (iEp = 0; iEp < uid->bNumEndpoints; iEp++) { ued = &uid->endpoints[iEp]; if (ued->bmAttributes != USB_ENDPOINT_BULK) continue; usb_log(" USB_ENDPOINT_BULK found: 0x%x MaxPacketSize: %i\n",ued->bEndpointAddress,ued->wMaxPacketSize); if (ued->bEndpointAddress & USB_ENDPOINT_IN) { dev->ep_in = ued->bEndpointAddress; } else { dev->ep_out = ued->bEndpointAddress; if(ued->wMaxPacketSize > 64 && (dev->usb_fd>=0x20 || dev->usb_fd<-1)) usb2_mode=true; else usb2_mode=false; } } if (dev->ep_in != 0 && dev->ep_out != 0) { dev->configuration = ucd->bConfigurationValue; dev->interface = uid->bInterfaceNumber; dev->altInterface = uid->bAlternateSetting; goto found; } } } } usb_log("Device not found device\n"); USB_FreeDescriptors(&udd); retval = USBSTORAGE_ENOINTERFACE; goto free_and_return; found: usb_log("Found device, InterfaceSubClass: %i\n",uid->bInterfaceSubClass); dev->bInterfaceSubClass = uid->bInterfaceSubClass; USB_FreeDescriptors(&udd); retval = USBSTORAGE_EINIT; // some devices return an error, ignore it USB_GetConfiguration(dev->usb_fd, &conf); if(method==0 || method==4) { if (conf != dev->configuration && USB_SetConfiguration(dev->usb_fd, dev->configuration) < 0) { usb_log("Error USB_SetConfiguration\n"); goto free_and_return; } else usb_log("USB_SetConfiguration ok\n"); if (dev->altInterface !=0 && USB_SetAlternativeInterface(dev->usb_fd, dev->interface, dev->altInterface) < 0) { usb_log("Error USB_SetAlternativeInterface, alt: %i int: %i\n",dev->altInterface,dev->interface); goto free_and_return; } else usb_log("USB_SetAlternativeInterface ok, alt: %i int: %i\n",dev->altInterface,dev->interface); dev->suspended = 0; if(!reset_flag && dev->bInterfaceSubClass == MASS_STORAGE_SCSI_COMMANDS) { reset_flag = true; retval = USBStorage_Reset(dev); usb_log("USBStorage_Open, USBStorage_Reset: %i\n",retval); if (retval < 0) { USB_CloseDevice(&dev->usb_fd); goto retry_init; } } } else if(method==1) { if ( USB_SetConfiguration(dev->usb_fd, dev->configuration) < 0) { usb_log("Error USB_SetConfiguration\n"); } else usb_log("USB_SetConfiguration ok\n"); if (USB_SetAlternativeInterface(dev->usb_fd, dev->interface, dev->altInterface) < 0) { usb_log("Error USB_SetAlternativeInterface, alt: %i int: %i\n",dev->altInterface,dev->interface); } else usb_log("USB_SetAlternativeInterface ok, alt: %i int: %i\n",dev->altInterface,dev->interface); dev->suspended = 0; } else if(method==2) { if ( USB_SetConfiguration(dev->usb_fd, dev->configuration) < 0) { usb_log("Error USB_SetConfiguration\n"); } else usb_log("USB_SetConfiguration ok\n"); if (USB_SetAlternativeInterface(dev->usb_fd, dev->interface, dev->altInterface) < 0) { usb_log("Error USB_SetAlternativeInterface, alt: %i int: %i\n",dev->altInterface,dev->interface); } else usb_log("USB_SetAlternativeInterface ok, alt: %i int: %i\n",dev->altInterface,dev->interface); dev->suspended = 0; if(!reset_flag && dev->bInterfaceSubClass == MASS_STORAGE_SCSI_COMMANDS) { reset_flag = true; retval = USBStorage_Reset(dev); usb_log("USBStorage_Open, USBStorage_Reset: %i\n",retval); if (retval < 0) { USB_CloseDevice(&dev->usb_fd); goto retry_init; } } } else if(method==3) { if (USB_SetConfiguration(dev->usb_fd, dev->configuration) < 0) { usb_log("Error USB_SetConfiguration\n"); goto free_and_return; } else usb_log("USB_SetConfiguration ok\n"); if (dev->altInterface !=0 && USB_SetAlternativeInterface(dev->usb_fd, dev->interface, dev->altInterface) < 0) { usb_log("Error USB_SetAlternativeInterface, alt: %i int: %i\n",dev->altInterface,dev->interface); goto free_and_return; } else usb_log("USB_SetAlternativeInterface ok, alt: %i int: %i\n",dev->altInterface,dev->interface); dev->suspended = 0; retval = USBStorage_Reset(dev); usb_log("USBStorage_Open, USBStorage_Reset: %i\n",retval); } else if(method==5 || method==6) { if (conf != dev->configuration && USB_SetConfiguration(dev->usb_fd, dev->configuration) < 0) { usb_log("Error USB_SetConfiguration\n"); //goto free_and_return; } else usb_log("USB_SetConfiguration ok\n"); if (dev->altInterface !=0 && USB_SetAlternativeInterface(dev->usb_fd, dev->interface, dev->altInterface) < 0) { usb_log("Error USB_SetAlternativeInterface, alt: %i int: %i\n",dev->altInterface,dev->interface); //goto free_and_return; } else usb_log("USB_SetAlternativeInterface ok, alt: %i int: %i\n",dev->altInterface,dev->interface); if(!usb2_mode) { retval = USBStorage_Reset(dev); usb_log("USBStorage_Open, USBStorage_Reset: %i\n",retval); } dev->suspended = 0; } if(method==6) { dev->max_lun = 2; usb_log("No get max lun call, max_lun: %i\n",dev->max_lun); } else { LWP_MutexLock(dev->lock); retval = __USB_CtrlMsgTimeout(dev, (USB_CTRLTYPE_DIR_DEVICE2HOST | USB_CTRLTYPE_TYPE_CLASS | USB_CTRLTYPE_REC_INTERFACE), USBSTORAGE_GET_MAX_LUN, 0, dev->interface, 1, max_lun); LWP_MutexUnlock(dev->lock); if (retval < 0) dev->max_lun = 1; else dev->max_lun = *max_lun + 1; usb_log("USBSTORAGE_GET_MAX_LUN, ret: %i max_lun: %i\n",retval,dev->max_lun); } if (retval == USBSTORAGE_ETIMEDOUT) goto free_and_return; retval = USBSTORAGE_OK; dev->sector_size = (u32 *) calloc(dev->max_lun, sizeof(u32)); if(!dev->sector_size) { retval = IPC_ENOMEM; goto free_and_return; } /* taken from linux usbstorage module (drivers/usb/storage/transport.c) * * Some devices (i.e. Iomega Zip100) need this -- apparently * the bulk pipes get STALLed when the GetMaxLUN request is * processed. This is, in theory, harmless to all other devices * (regardless of if they stall or not). * * 8/9/10: If anyone wants to actually use a Zip100, they can add this back. * But for now, it seems to be breaking things more than it is helping. */ //USB_ClearHalt(dev->usb_fd, dev->ep_in); //USB_ClearHalt(dev->usb_fd, dev->ep_out); if(!dev->buffer) dev->buffer = __lwp_heap_allocate(&__heap, MAX_TRANSFER_SIZE_V5); if(!dev->buffer) { retval = IPC_ENOMEM; } else { USB_DeviceRemovalNotifyAsync(dev->usb_fd,__usb_deviceremoved_cb,dev); retval = USBSTORAGE_OK; } free_and_return: if (max_lun) __lwp_heap_free(&__heap, max_lun); if (retval < 0) { USBStorage_Close(dev); return retval; } return 0; }
s32 USBStorage_Open(usbstorage_handle *dev, struct ehci_device *fd) { s32 retval = -1; u8 conf,*max_lun = NULL; u32 iConf, iInterface, iEp; usb_devdesc udd; usb_configurationdesc *ucd; usb_interfacedesc *uid; usb_endpointdesc *ued; max_lun = USB_Alloc(1); if(max_lun==NULL) return -ENOMEM; memset(dev, 0, sizeof(*dev)); dev->tag = TAG_START; dev->usb_fd = fd; retval = USB_GetDescriptors(dev->usb_fd, &udd); if(retval < 0) goto free_and_return; for(iConf = 0; iConf < udd.bNumConfigurations; iConf++) { ucd = &udd.configurations[iConf]; for(iInterface = 0; iInterface < ucd->bNumInterfaces; iInterface++) { uid = &ucd->interfaces[iInterface]; if(uid->bInterfaceClass == USB_CLASS_MASS_STORAGE && uid->bInterfaceSubClass == MASS_STORAGE_SCSI_COMMANDS && uid->bInterfaceProtocol == MASS_STORAGE_BULK_ONLY) { if(uid->bNumEndpoints < 2) continue; dev->ep_in = dev->ep_out = 0; for(iEp = 0; iEp < uid->bNumEndpoints; iEp++) { ued = &uid->endpoints[iEp]; if(ued->bmAttributes != USB_ENDPOINT_BULK) continue; if(ued->bEndpointAddress & USB_ENDPOINT_IN) dev->ep_in = ued->bEndpointAddress; else dev->ep_out = ued->bEndpointAddress; } if(dev->ep_in != 0 && dev->ep_out != 0) { dev->configuration = ucd->bConfigurationValue; dev->interface = uid->bInterfaceNumber; dev->altInterface = uid->bAlternateSetting; goto found; } } } } USB_FreeDescriptors(&udd); retval = USBSTORAGE_ENOINTERFACE; goto free_and_return; found: USB_FreeDescriptors(&udd); retval = USBSTORAGE_EINIT; if(USB_GetConfiguration(dev->usb_fd, &conf) < 0) goto free_and_return; if(conf != dev->configuration && USB_SetConfiguration(dev->usb_fd, dev->configuration) < 0) goto free_and_return; if(dev->altInterface != 0 && USB_SetAlternativeInterface(dev->usb_fd, dev->interface, dev->altInterface) < 0) goto free_and_return; dev->suspended = 0; retval = USBStorage_Reset(dev); if(retval < 0) goto free_and_return; retval = __USB_CtrlMsgTimeout(dev, (USB_CTRLTYPE_DIR_DEVICE2HOST | USB_CTRLTYPE_TYPE_CLASS | USB_CTRLTYPE_REC_INTERFACE), USBSTORAGE_GET_MAX_LUN, 0, dev->interface, 1, max_lun); if(retval < 0) dev->max_lun = 1; else dev->max_lun = *max_lun; if(retval == USBSTORAGE_ETIMEDOUT) goto free_and_return; retval = USBSTORAGE_OK; if(dev->max_lun == 0) dev->max_lun++; /* taken from linux usbstorage module (drivers/usb/storage/transport.c) */ /* * Some devices (i.e. Iomega Zip100) need this -- apparently * the bulk pipes get STALLed when the GetMaxLUN request is * processed. This is, in theory, harmless to all other devices * (regardless of if they stall or not). */ USB_ClearHalt(dev->usb_fd, dev->ep_in); USB_ClearHalt(dev->usb_fd, dev->ep_out); dev->buffer = USB_Alloc(MAX_TRANSFER_SIZE); if(dev->buffer == NULL) retval = -ENOMEM; else retval = USBSTORAGE_OK; free_and_return: if(max_lun!=NULL) USB_Free(max_lun); if(retval < 0) { if(dev->buffer != NULL) USB_Free(dev->buffer); memset(dev, 0, sizeof(*dev)); return retval; } return 0; }