Пример #1
0
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;
}
Пример #2
0
Файл: usb.c Проект: comex/libogc
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;
}