static s32 __usbstorage_clearerrors(usbstorage_handle *dev, u8 lun)
{
	s32 retval;
	u8 cmd[16];
	u8 *sense= USB_Alloc(SCSI_SENSE_REPLY_SIZE);
	u8 status = 0;
	memset(cmd, 0, sizeof(cmd));
	cmd[0] = SCSI_TEST_UNIT_READY;
    
	retval = __cycle(dev, lun, NULL, 0, cmd, 1, 1, &status, NULL);
	if(retval < 0) return retval;
    
	if(status != 0)
	{
		cmd[0] = SCSI_REQUEST_SENSE;
		cmd[1] = lun << 5;
		cmd[4] = SCSI_SENSE_REPLY_SIZE;
		cmd[5] = 0;
		memset(sense, 0, SCSI_SENSE_REPLY_SIZE);
		retval = __cycle(dev, lun, sense, SCSI_SENSE_REPLY_SIZE, cmd, 6, 0, NULL, NULL);
		if(retval < 0) goto error;
        
		status = sense[2] & 0x0F;
		if(status == SCSI_SENSE_NOT_READY || status == SCSI_SENSE_MEDIUM_ERROR || status == SCSI_SENSE_HARDWARE_ERROR)
            retval = USBSTORAGE_ESENSE;
	}
error:
    USB_Free(sense);
	return retval;
}
Example #2
0
static s32 __usbstorage_clearerrors(struct ehci_hcd * ehci, usbstorage_handle *dev, u8 lun) {
	s32 retval;
	u8 cmd[16];
	u8 *sense = USB_Alloc(SCSI_SENSE_REPLY_SIZE);
	u8 status = 0;
	memset(cmd, 0, sizeof (cmd));
	cmd[0] = SCSI_TEST_UNIT_READY;
	int n;

	if (!sense) return -ENOMEM;



	for (n = 0; n < 5; n++) {

		retval = __cycle(ehci, dev, lun, NULL, 0, cmd, 6, 1, &status, NULL);

#ifdef MEM_PRINT
		s_printf("    SCSI_TEST_UNIT_READY %i# ret %i\n", n, retval);
#endif

		if (retval == -ENODEV) goto error;


		if (retval == 0) break;
	}
	if (retval < 0) goto error;


	if (status != 0) {
		cmd[0] = SCSI_REQUEST_SENSE;
		cmd[1] = lun << 5;
		cmd[4] = SCSI_SENSE_REPLY_SIZE;
		cmd[5] = 0;
		memset(sense, 0, SCSI_SENSE_REPLY_SIZE);
		retval = __cycle(ehci, dev, lun, sense, SCSI_SENSE_REPLY_SIZE, cmd, 6, 0, NULL, NULL);

#ifdef MEM_PRINT
		s_printf("    SCSI_REQUEST_SENSE ret %i\n", retval);
#endif

		if (retval < 0) goto error;

		status = sense[2] & 0x0F;

#ifdef MEM_PRINT
		s_printf("    SCSI_REQUEST_SENSE status %x\n", status);
#endif


		if (status == SCSI_SENSE_NOT_READY || status == SCSI_SENSE_MEDIUM_ERROR || status == SCSI_SENSE_HARDWARE_ERROR)
			retval = USBSTORAGE_ESENSE;
	}
error:
	USB_Free(sense);
	return retval;
}
s32 USBStorage_Open(usbstorage_handle *dev, struct ehci_device *fd)
{
    dev->ep_in = bulkInNumber;
    dev->ep_out = bulkOutNumber;
    dev->max_lun = fMaxLogicalUnitNumber;
    dev->altInterface = gAlt_Interface;
    dev->interface = gInterface;
    dev->buffer = USB_Alloc(512);
	return 0;
}
s32 USBStorage_Inquiry(usbstorage_handle *dev, u8 lun)
{
	s32 retval;
	u8 cmd[] = {SCSI_INQUIRY, lun << 5,0,0,36,0};
	u8 *response = USB_Alloc(36);
    USB_LOG("Inquiring about SCSI drive\n");
	retval = __cycle(dev, lun, response, 36, cmd, 6, 0, NULL, NULL);
    //print_hex_dump_bytes("inquiry result:",DUMP_PREFIX_OFFSET,response,36);
    USB_Free(response);
	return retval;
}
Example #5
0
s32 USBStorage_Inquiry(struct ehci_hcd * ehci, usbstorage_handle *dev, u8 lun) {
	s32 retval;
	u8 cmd[] = {SCSI_INQUIRY, lun << 5, 0, 0, 36, 0};
	u8 *response = USB_Alloc(36);

	if (!response) return -ENOMEM;

	retval = __cycle(ehci, dev, lun, response, 36, cmd, 6, 0, NULL, NULL);
	//print_hex_dump_bytes("inquiry result:",DUMP_PREFIX_OFFSET,response,36);
	USB_Free(response);
	return retval;
}
void init_thread_ehci(void)
{
	disable_EHCI_IRQ();


	ehci1_queuehandle= os_message_queue_create( USB_Alloc(4*32)/*os_heap_alloc(heaphandle, 4*32)*/, 32);

	os_unregister_event_handler(DEV_EHCI);
	os_register_event_handler(DEV_EHCI, ehci1_queuehandle, 0); // register interrupt event handler

	enable_EHCI_IRQ();
	os_software_IRQ(DEV_EHCI);

}
Example #7
0
s32 USB_GetConfiguration(struct ehci_hcd * ehci,struct ehci_device *fd, u8 *configuration)
{
	u8 *_configuration;
	s32 retval;

	_configuration = USB_Alloc( 1);
	if(_configuration == NULL)
		return -ENOMEM;

	retval = __usb_control_message(ehci, fd, (USB_CTRLTYPE_DIR_DEVICE2HOST | USB_CTRLTYPE_TYPE_STANDARD | USB_CTRLTYPE_REC_DEVICE), USB_REQ_GETCONFIG, 0, 0, 1, _configuration, NULL, NULL);
	if(retval >= 0)
		*configuration = *_configuration;
	USB_Free( _configuration);

	return retval;
}
Example #8
0
s32 USBStorage_ReadCapacity(struct ehci_hcd * ehci, usbstorage_handle *dev, u8 lun, u32 *sector_size, u32 *n_sectors) {
	s32 retval;
	u8 cmd[] = {SCSI_READ_CAPACITY, lun << 5};
	u8 *response = USB_Alloc(8);
	u32 val;
	if (!response) return -ENOMEM;

	retval = __cycle(ehci, dev, lun, response, 8, cmd, 2, 0, NULL, NULL);
	if (retval >= 0) {

		memcpy(&val, response, 4);
		if (n_sectors != NULL)
			*n_sectors = be32_to_cpu(val);
		memcpy(&val, response + 4, 4);
		if (sector_size != NULL)
			*sector_size = be32_to_cpu(val);
		retval = USBSTORAGE_OK;
	}
	USB_Free(response);
	return retval;
}
Example #9
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;
}
Example #10
0
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;
}
Example #11
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;
}