コード例 #1
0
ファイル: usbstorage.c プロジェクト: AngelSora/Nintendont
static s32 __send_cbw(usbstorage_handle *dev, u8 lun, u32 len, u8 flags, const u8 *cb, u8 cbLen)
{
	s32 retval = USBSTORAGE_OK;

	if(cbLen == 0 || cbLen > 16)
		return IPC_EINVAL;

	memset(cbw_buffer, 0, CBW_SIZE);

	__stwbrx(cbw_buffer, 0, CBW_SIGNATURE);
	__stwbrx(cbw_buffer, 4, ++dev->tag);
	__stwbrx(cbw_buffer, 8, len);
	cbw_buffer[12] = flags;
	cbw_buffer[13] = lun;
	cbw_buffer[14] = (cbLen > 6 ? 10 : 6);

	memcpy(cbw_buffer + 15, cb, cbLen);

	if(dev->suspended == 1)
	{
		USB_OGC_ResumeDevice(dev->usb_fd);
		dev->suspended = 0;
	}

	retval = __USB_BlkMsgTimeout(dev, dev->ep_out, CBW_SIZE, (void *)cbw_buffer, usbtimeout);

	if(retval == CBW_SIZE) return USBSTORAGE_OK;
	else if(retval > 0) return USBSTORAGE_ESHORTWRITE;

	return retval;
}
コード例 #2
0
ファイル: usbstorage.c プロジェクト: AngelSora/Nintendont
static s32 __read_csw(usbstorage_handle *dev, u8 *status, u32 *dataResidue, u32 timeout)
{
	s32 retval = USBSTORAGE_OK;
	u32 signature, tag, _dataResidue, _status;

	memset(cbw_buffer, 0, CSW_SIZE);

	retval = __USB_BlkMsgTimeout(dev, dev->ep_in, CSW_SIZE, cbw_buffer, timeout);
	if(retval > 0 && retval != CSW_SIZE) return USBSTORAGE_ESHORTREAD;
	else if(retval < 0) return retval;

	signature = __lwbrx(cbw_buffer, 0);
	tag = __lwbrx(cbw_buffer, 4);
	_dataResidue = __lwbrx(cbw_buffer, 8);
	_status = cbw_buffer[12];

	if(signature != CSW_SIGNATURE) return USBSTORAGE_ESIGNATURE;

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

	if(tag != dev->tag) return USBSTORAGE_ETAG;

	return USBSTORAGE_OK;
}
コード例 #3
0
ファイル: usbstorage.c プロジェクト: AirBrowse/libxenon
static s32 __read_csw(struct ehci_hcd * ehci, usbstorage_handle *dev, u8 *status, u32 *dataResidue) {
	s32 retval = USBSTORAGE_OK;
	u32 signature, tag, _dataResidue, _status;

	memset(dev->buffer, 0xff, CSW_SIZE);

	retval = __USB_BlkMsgTimeout(ehci, dev, dev->ep_in, CSW_SIZE, dev->buffer);
	//print_hex_dump_bytes("csv resp:",DUMP_PREFIX_OFFSET,dev->buffer,CSW_SIZE);

	if (retval >= 0 && retval != CSW_SIZE) return USBSTORAGE_ESHORTREAD;
	else if (retval < 0) return retval;

	signature = le32_to_cpu(((u32*) dev->buffer)[0]);
	tag = le32_to_cpu(((u32*) dev->buffer)[1]);
	_dataResidue = le32_to_cpu(((u32*) dev->buffer)[2]);
	_status = dev->buffer[12];
	//debug_printf("csv status: %d\n",_status);
	if (signature != CSW_SIGNATURE) {
		// BUG();
		return USBSTORAGE_ESIGNATURE;
	}

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

	if (tag != dev->tag) return USBSTORAGE_ETAG;
	dev->tag++;

	return USBSTORAGE_OK;
}
コード例 #4
0
ファイル: usbstorage.c プロジェクト: AirBrowse/libxenon
static s32 __send_cbw(struct ehci_hcd * ehci, usbstorage_handle *dev, u8 lun, u32 len, u8 flags, const u8 *cb, u8 cbLen) {
	s32 retval = USBSTORAGE_OK;

	if (cbLen == 0 || cbLen > 16 || !dev->buffer)
		return -EINVAL;
	memset(dev->buffer, 0, CBW_SIZE);

	((u32*) dev->buffer)[0] = cpu_to_le32(CBW_SIGNATURE);
	((u32*) dev->buffer)[1] = cpu_to_le32(dev->tag);
	((u32*) dev->buffer)[2] = cpu_to_le32(len);
	dev->buffer[12] = flags;
	dev->buffer[13] = lun;
	// linux usb/storage/protocol.c seems to say only difference is padding
	// and fixed cw size
	if (dev->ata_protocol)
		dev->buffer[14] = 12;
	else
		dev->buffer[14] = (cbLen > 6 ? 0x10 : 6);
	//debug_printf("send cb of size %d\n",dev->buffer[14]);
	memcpy(dev->buffer + 15, cb, cbLen);
	//hexdump(dev->buffer,CBW_SIZE);
	retval = __USB_BlkMsgTimeout(ehci, dev, dev->ep_out, CBW_SIZE, (void *) dev->buffer);

	if (retval == CBW_SIZE) return USBSTORAGE_OK;
	else if (retval >= 0) return USBSTORAGE_ESHORTWRITE;

	return retval;
}
コード例 #5
0
static s32 __send_cbw(usbstorage_handle *dev, u8 lun, u32 len, u8 flags, const u8 *cb, u8 cbLen)
{
	s32 retval = USBSTORAGE_OK;
    
	if(cbLen == 0 || cbLen > 16)
		return -EINVAL;
	memset(dev->buffer, 0, CBW_SIZE);
    
	((u32*)dev->buffer)[0]=cpu_to_le32(CBW_SIGNATURE);
	((u32*)dev->buffer)[1]=cpu_to_le32(dev->tag);
	((u32*)dev->buffer)[2]=cpu_to_le32(len);
	dev->buffer[12] = flags;
	dev->buffer[13] = lun;
	dev->buffer[14] = (cbLen > 6 ? 0x10 : 6);
    
	memcpy(dev->buffer + 15, cb, cbLen);
    
	retval = __USB_BlkMsgTimeout(dev, dev->ep_out, CBW_SIZE, (void *)dev->buffer);
    
	if(retval == CBW_SIZE) return USBSTORAGE_OK;
	else if(retval >= 0) return USBSTORAGE_ESHORTWRITE;
    
	return retval;
}
コード例 #6
0
ファイル: usbstorage.c プロジェクト: AngelSora/Nintendont
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;
}
コード例 #7
0
ファイル: usbstorage.c プロジェクト: AirBrowse/libxenon
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;
}
コード例 #8
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;
	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;
}