示例#1
0
/* lo_ej = load/eject, controls the tray
*  start = start(1) or stop(0) the motor (or eject(0), load(1))
*  imm = return before the command has completed
* it might be a good idea to call this before STM_ShutdownToStandby() so the USB HDD doesn't stay on
*/
s32 USBStorageOGC_StartStop(usbstorage_handle *dev, u8 lun, u8 lo_ej, u8 start, u8 imm)
{
	u8 status = 0;
	s32 retval = USBSTORAGE_OK;
	u8 cmd[] = {
		SCSI_START_STOP,
		(lun << 5) | (imm&1),
		0,
		0,
		((lo_ej&1)<<1) | (start&1),
		0
	};

	if(lun >= dev->max_lun)
		return IPC_EINVAL;

	LWP_MutexLock(dev->lock);

	retval = __send_cbw(dev, lun, 0, CBW_IN, cmd, sizeof(cmd));

	// if imm==0, wait up to 10secs for spinup to finish
	if (retval >= 0)
		retval = __read_csw(dev, &status, NULL, (imm ? USBSTORAGE_TIMEOUT : 10));

	LWP_MutexUnlock(dev->lock);

	if(retval >=0 && status != 0)
		retval = USBSTORAGE_ESTATUS;

	return retval;
}
示例#2
0
static s32 __cycle(struct ehci_hcd * ehci, usbstorage_handle *dev, u8 lun, u8 *buffer, u32 len, u8 *cb, u8 cbLen, u8 write, u8 *_status, u32 *_dataResidue) {
	s32 retval = USBSTORAGE_OK;

	u8 status = 0;
	u32 dataResidue = 0;
	u32 thisLen;

	u8 *buffer2 = buffer;
	u32 len2 = len;

	s8 retries = USBSTORAGE_CYCLE_RETRIES + 1;

	do {

		if (retval == -ENODEV) {
			unplug_device = 1;
			return -ENODEV;
		}



		if (retval < 0)
			retval = __usbstorage_reset(ehci, dev, retries < USBSTORAGE_CYCLE_RETRIES);

		retries--;
		if (retval < 0) continue; // nuevo

		buffer = buffer2;
		len = len2;

		if (write) {

			retval = __send_cbw(ehci, dev, lun, len, CBW_OUT, cb, cbLen);
			if (retval < 0)
				continue; //reset+retry
			while (len > 0) {
				thisLen = len;
				retval = __USB_BlkMsgTimeout(ehci, dev, dev->ep_out, thisLen, buffer);

				if (retval == -ENODEV || retval == -ETIMEDOUT) break;

				if (retval < 0)
					continue; //reset+retry

				if (retval != thisLen && len > 0) {
					retval = USBSTORAGE_EDATARESIDUE;
					continue; //reset+retry
				}
				len -= retval;
				buffer += retval;
			}

			if (retval < 0)
				continue;
		} else {
			retval = __send_cbw(ehci, dev, lun, len, CBW_IN, cb, cbLen);

			if (retval < 0)
				continue; //reset+retry
			while (len > 0) {
				thisLen = len;

				retval = __USB_BlkMsgTimeout(ehci, dev, dev->ep_in, thisLen, buffer);

				if (retval == -ENODEV || retval == -ETIMEDOUT) break;

				if (retval < 0)
					continue; //reset+retry
				//hexdump(buffer,retval);

				len -= retval;
				buffer += retval;

				if (retval != thisLen) {
					retval = -1;
					continue; //reset+retry
				}
			}

			if (retval < 0)
				continue;
		}

		retval = __read_csw(ehci, dev, &status, &dataResidue);

		if (retval < 0)
			continue;

		retval = USBSTORAGE_OK;
	} while (retval < 0 && retries > 0);

	// force unplug
	if (retval < 0 && retries <= 0 && handshake_mode == 0) {
		unplug_device = 1;
		return -ENODEV;
	}

	if (retval < 0 && retval != USBSTORAGE_ETIMEDOUT) {
		if (__usbstorage_reset(ehci, dev, 0) == USBSTORAGE_ETIMEDOUT)
			retval = USBSTORAGE_ETIMEDOUT;
	}


	if (_status != NULL)
		*_status = status;
	if (_dataResidue != NULL)
		*_dataResidue = dataResidue;

	return retval;
}
示例#3
0
static s32 __cycle(usbstorage_handle *dev, u8 lun, u8 *buffer, u32 len, u8 *cb, u8 cbLen, u8 write, u8 *_status, u32 *_dataResidue)
{
	s32 retval = USBSTORAGE_OK;

	u8 status=0;
	u32 dataResidue = 0;
	u16 max_size;
	u8 ep = write ? dev->ep_out : dev->ep_in;
	s8 retries = USBSTORAGE_CYCLE_RETRIES + 1;
	
	if(usb2_mode)
		max_size=MAX_TRANSFER_SIZE_V5;
	else
		max_size=MAX_TRANSFER_SIZE_V0;

	LWP_MutexLock(dev->lock);
	do
	{
		u8 *_buffer = buffer;
		u32 _len = len;
		retries--;

		if(retval == USBSTORAGE_ETIMEDOUT)
			break;

		retval = __send_cbw(dev, lun, len, (write ? CBW_OUT:CBW_IN), cb, cbLen);

		while(_len > 0 && retval >= 0)
		{
			u32 thisLen = _len > max_size ? max_size : _len;

			if ((u32)_buffer&0x1F || !((u32)_buffer&0x10000000)) {
				if (write) memcpy(dev->buffer, _buffer, thisLen);
				retval = __USB_BlkMsgTimeout(dev, ep, thisLen, dev->buffer, usbtimeout);
				if (!write && retval > 0)
					memcpy(_buffer, dev->buffer, retval);
			} else
				retval = __USB_BlkMsgTimeout(dev, ep, thisLen, _buffer, usbtimeout);

			if (retval == thisLen) {
				_len -= retval;
				_buffer += retval;
			}
			else if (retval != USBSTORAGE_ETIMEDOUT)
				retval = USBSTORAGE_EDATARESIDUE;
		}

		if (retval >= 0)
			retval = __read_csw(dev, &status, &dataResidue, usbtimeout);

		if (retval < 0) {
			if (__usbstorage_reset(dev) == USBSTORAGE_ETIMEDOUT)
				retval = USBSTORAGE_ETIMEDOUT;
		}
	} while (retval < 0 && retries > 0);

	LWP_MutexUnlock(dev->lock);

	if(_status != NULL)
		*_status = status;
	if(_dataResidue != NULL)
		*_dataResidue = dataResidue;

	return retval;
}
static s32 __cycle(usbstorage_handle *dev, u8 lun, u8 *buffer, u32 len, u8 *cb, u8 cbLen, u8 write, u8 *_status, u32 *_dataResidue)
{
	s32 retval = USBSTORAGE_OK;
    
	u8 status = 0;
	u32 dataResidue = 0;
	u32 thisLen;
    
	s8 retries = USBSTORAGE_CYCLE_RETRIES + 1;
    
	do
	{
		retries--;
		if(retval == USBSTORAGE_ETIMEDOUT)
			break;
        
		if(write)
		{
			retval = __send_cbw(dev, lun, len, CBW_OUT, cb, cbLen);
			if(retval == USBSTORAGE_ETIMEDOUT)
				break;
			if(retval < 0)
			{
				if(__usbstorage_reset(dev) == USBSTORAGE_ETIMEDOUT)
					retval = USBSTORAGE_ETIMEDOUT;
				continue;
			}
			while(len > 0)
			{
                thisLen=len;
				retval = __USB_BlkMsgTimeout(dev, dev->ep_out, thisLen, buffer);
                
				if(retval == USBSTORAGE_ETIMEDOUT)
					break;
                
				if(retval < 0)
				{
					retval = USBSTORAGE_EDATARESIDUE;
					break;
				}
                
                
				if(retval != thisLen && len > 0)
				{
					retval = USBSTORAGE_EDATARESIDUE;
					break;
				}
				len -= retval;
				buffer += retval;
			}
            
			if(retval < 0)
			{
				if(__usbstorage_reset(dev) == USBSTORAGE_ETIMEDOUT)
					retval = USBSTORAGE_ETIMEDOUT;
				continue;
			}
		}
		else
		{
			retval = __send_cbw(dev, lun, len, CBW_IN, cb, cbLen);
            
			if(retval == USBSTORAGE_ETIMEDOUT)
				break;
            
			if(retval < 0)
			{
				if(__usbstorage_reset(dev) == USBSTORAGE_ETIMEDOUT)
					retval = USBSTORAGE_ETIMEDOUT;
				continue;
			}
			while(len > 0)
			{
                thisLen=len;
				retval = __USB_BlkMsgTimeout(dev, dev->ep_in, thisLen, buffer);
                //print_hex_dump_bytes("usbs in:",DUMP_PREFIX_OFFSET,dev->buffer,36);
				if(retval < 0)
					break;
                
				len -= retval;
				buffer += retval;
                
				if(retval != thisLen)
					break;
			}
            
			if(retval < 0)
			{
				if(__usbstorage_reset(dev) == USBSTORAGE_ETIMEDOUT)
					retval = USBSTORAGE_ETIMEDOUT;
				continue;
			}
		}
        
		retval = __read_csw(dev, &status, &dataResidue);
        
		if(retval == USBSTORAGE_ETIMEDOUT)
			break;
        
		if(retval < 0)
		{
			if(__usbstorage_reset(dev) == USBSTORAGE_ETIMEDOUT)
				retval = USBSTORAGE_ETIMEDOUT;
			continue;
		}
        
		retval = USBSTORAGE_OK;
	} while(retval < 0 && retries > 0);
    
	if(retval < 0 && retval != USBSTORAGE_ETIMEDOUT)
	{
		if(__usbstorage_reset(dev) == USBSTORAGE_ETIMEDOUT)
			retval = USBSTORAGE_ETIMEDOUT;
	}
    
    
	if(_status != NULL)
		*_status = status;
	if(_dataResidue != NULL)
		*_dataResidue = dataResidue;
    
	return retval;
}