亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來(lái)到蟲(chóng)蟲(chóng)下載站! | ?? 資源下載 ?? 資源專輯 ?? 關(guān)于我們
? 蟲(chóng)蟲(chóng)下載站

?? msc_scsi.c

?? LPC214x USB stack LPC214x usb 協(xié)議
?? C
字號(hào):
/*
	LPCUSB, an USB device driver for LPC microcontrollers	
	Copyright (C) 2006 Bertrik Sikken (bertrik@sikken.nl)

	Redistribution and use in source and binary forms, with or without
	modification, are permitted provided that the following conditions are met:

	1. Redistributions of source code must retain the above copyright
	   notice, this list of conditions and the following disclaimer.
	2. Redistributions in binary form must reproduce the above copyright
	   notice, this list of conditions and the following disclaimer in the
	   documentation and/or other materials provided with the distribution.
	3. The name of the author may not be used to endorse or promote products
	   derived from this software without specific prior written permission.

	THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
	IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
	OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
	IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 
	INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
	NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
	DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
	THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
	(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
	THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

/**
	@file

	This is the SCSI layer of the USB mass storage application example.
	This layer depends directly on the blockdev layer.
	
	Windows peculiarities:
	* Size of REQUEST SENSE CDB is 12 bytes instead of expected 6
	* Windows requires VERIFY(10) command to do a format.
	  This command is not mandatory in the SBC/SBC-2 specification.
*/


#include <string.h>		// memcpy

#include "type.h"
#include "usbdebug.h"

#include "blockdev.h"
#include "msc_scsi.h"


#define BLOCKSIZE		512

// SBC2 mandatory SCSI commands
#define	SCSI_CMD_TEST_UNIT_READY	0x00
#define SCSI_CMD_REQUEST_SENSE		0x03
#define SCSI_CMD_FORMAT_UNIT		0x04
#define SCSI_CMD_READ_6				0x08	/* not implemented yet */
#define SCSI_CMD_INQUIRY			0x12
#define SCSI_CMD_SEND_DIAGNOSTIC	0x1D	/* not implemented yet */
#define SCSI_CMD_READ_CAPACITY_10	0x25
#define SCSI_CMD_READ_10			0x28
#define SCSI_CMD_REPORT_LUNS		0xA0	/* not implemented yet */

// SBC2 optional SCSI commands
#define SCSI_CMD_WRITE_6			0x0A	/* not implemented yet */
#define SCSI_CMD_WRITE_10			0x2A
#define SCSI_CMD_VERIFY_10			0x2F	/* required for windows format */

// sense codes
#define WRITE_ERROR				0x030C00
#define READ_ERROR				0x031100
#define INVALID_CMD_OPCODE		0x052000
#define INVALID_FIELD_IN_CDB	0x052400

//	Sense code, which is set on error conditions
static U32			dwSense;	// hex: 00aabbcc, where aa=KEY, bb=ASC, cc=ASCQ

static const U8		abInquiry[] = {
	0x00,		// PDT = direct-access device
	0x80,		// removeable medium bit = set
	0x05,		// version = complies to SPC3
	0x02,		// response data format = SPC3
	0x1F,		// additional length
	0x00,
	0x00,
	0x00,
	'L','P','C','U','S','B',' ',' ',	// vendor
	'M','a','s','s',' ','s','t','o',	// product
	'r','a','g','e',' ',' ',' ',' ',
	'0','.','1',' '						// revision
};

//	Data for "request sense" command. The 0xFF are filled in later
static const U8 abSense[] = { 0x70, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x0A, 
							  0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00,
							  0x00, 0x00 };

//	Buffer for holding one block of disk data
static U8 abBlockBuf[512];


typedef struct {
	U8		bOperationCode;
	U8		abLBA[3];
	U8		bLength;
	U8		bControl;
} TCDB6;


/*************************************************************************
	SCSIReset
	=========
		Resets any SCSI state
		
**************************************************************************/
void SCSIReset(void)
{
	dwSense = 0;
}


/*************************************************************************
	SCSIHandleCmd
	=============
		Verifies a SCSI CDB and indicates the direction and amount of data
		that the device wants to transfer.
		
	If this call fails, a sense code is set in dwSense.

	IN		pbCDB		Command data block
			iCDBLen		Command data block len
	OUT		*piRspLen	Length of intended response data:
			*pfDevIn	TRUE if data is transferred from device-to-host
	
	Returns a pointer to the data exchange buffer if successful,
	return NULL otherwise.
**************************************************************************/
U8 * SCSIHandleCmd(U8 *pbCDB, U8 iCDBLen, int *piRspLen, BOOL *pfDevIn)
{
	static const U8 aiCDBLen[] = {6, 10, 10, 0, 16, 12, 0, 0};
	int		i;
	TCDB6	*pCDB;
	U32		dwLen, dwLBA;
	U8		bGroupCode;
	
	pCDB = (TCDB6 *)pbCDB;
	
	// default direction is from device to host
	*pfDevIn = TRUE;
	
	// check CDB length
	bGroupCode = (pCDB->bOperationCode >> 5) & 0x7;
	if (iCDBLen < aiCDBLen[bGroupCode]) {
		DBG("Invalid CBD len (expected %d)!\n", aiCDBLen[bGroupCode]);
		return NULL;
	}

	switch (pCDB->bOperationCode) {

	// test unit ready (6)
	case SCSI_CMD_TEST_UNIT_READY:
		DBG("TEST UNIT READY\n");
		*piRspLen = 0;
		break;
	
	// request sense (6)
	case SCSI_CMD_REQUEST_SENSE:
		DBG("REQUEST SENSE (%06X)\n", dwSense);
		// check params
		*piRspLen = MIN(18, pCDB->bLength);
		break;
	
	case SCSI_CMD_FORMAT_UNIT:
		DBG("FORMAT UNIT %02X\n", pbCDB[1]);
		*piRspLen = 0;
		break;
	
	// inquiry (6)
	case SCSI_CMD_INQUIRY:
		DBG("INQUIRY\n");
		// see SPC3r23, 4.3.4.6
		*piRspLen = MIN(36, pCDB->bLength);
		break;
		
	// read capacity (10)
	case SCSI_CMD_READ_CAPACITY_10:
		DBG("READ CAPACITY\n");
		*piRspLen = 8;
		break;
		
	// read (10)
	case SCSI_CMD_READ_10:
		dwLBA = (pbCDB[2] << 24) | (pbCDB[3] << 16) | (pbCDB[4] << 8) | (pbCDB[5]);
		dwLen = (pbCDB[7] << 8) | pbCDB[8];
		DBG("READ10, LBA=%d, len=%d\n", dwLBA, dwLen);
		*piRspLen = dwLen * BLOCKSIZE;
		break;

	// write (10)
	case SCSI_CMD_WRITE_10:
		dwLBA = (pbCDB[2] << 24) | (pbCDB[3] << 16) | (pbCDB[4] << 8) | (pbCDB[5]);
		dwLen = (pbCDB[7] << 8) | pbCDB[8];
		DBG("WRITE10, LBA=%d, len=%d\n", dwLBA, dwLen);
		*piRspLen = dwLen * BLOCKSIZE;
		*pfDevIn = FALSE;
		break;

	case SCSI_CMD_VERIFY_10:
		DBG("VERIFY10\n");
		if ((pbCDB[1] & (1 << 1)) != 0) {
			// we don't support BYTCHK
			DBG("BYTCHK not supported\n");
			return NULL;
		}
		*piRspLen = 0;
		break;
	
	default:
		DBG("Unhandled SCSI: ");		
		for (i = 0; i < iCDBLen; i++) {
			DBG(" %02X", pbCDB[i]);
		}
		DBG("\n");
		// unsupported command
		dwSense = INVALID_CMD_OPCODE;
		*piRspLen = 0;
		return NULL;
	}
	
	
	return abBlockBuf;
}


/*************************************************************************
	SCSIHandleData
	==============
		Handles a block of SCSI data.
		
	IN		pbCDB		Command data block
			iCDBLen		Command data block len
	IN/OUT	pbData		Data buffer
	IN		dwOffset	Offset in data
	
	Returns a pointer to the next data to be exchanged if successful,
	returns NULL otherwise.
**************************************************************************/
U8 * SCSIHandleData(U8 *pbCDB, U8 iCDBLen, U8 *pbData, U32 dwOffset)
{
	TCDB6	*pCDB;
	U32		dwLBA;
	U32		dwBufPos, dwBlockNr;
	U32		dwDevSize, dwMaxBlock;
	
	pCDB = (TCDB6 *)pbCDB;
	
	switch (pCDB->bOperationCode) {

	// test unit ready
	case SCSI_CMD_TEST_UNIT_READY:
		if (dwSense != 0) {
			return NULL;
		}
		break;
	
	// request sense
	case SCSI_CMD_REQUEST_SENSE:
		memcpy(pbData, abSense, 18);
		// fill in KEY/ASC/ASCQ
		pbData[2] = (dwSense >> 16) & 0xFF;
		pbData[12] = (dwSense >> 8) & 0xFF;
		pbData[13] = (dwSense >> 0) & 0xFF;
		// reset sense data
		dwSense = 0;
		break;
	
	case SCSI_CMD_FORMAT_UNIT:
		// nothing to do, ignore this command
		break;
	
	// inquiry
	case SCSI_CMD_INQUIRY:
		memcpy(pbData, abInquiry, sizeof(abInquiry));
		break;
		
	// read capacity
	case SCSI_CMD_READ_CAPACITY_10:
		// get size of drive (bytes)
		BlockDevGetSize(&dwDevSize);
		// calculate highest LBA
		dwMaxBlock = (dwDevSize - 1) / 512;
		
		pbData[0] = (dwMaxBlock >> 24) & 0xFF;
		pbData[1] = (dwMaxBlock >> 16) & 0xFF;
		pbData[2] = (dwMaxBlock >> 8) & 0xFF;
		pbData[3] = (dwMaxBlock >> 0) & 0xFF;
		pbData[4] = (BLOCKSIZE >> 24) & 0xFF;
		pbData[5] = (BLOCKSIZE >> 16) & 0xFF;
		pbData[6] = (BLOCKSIZE >> 8) & 0xFF;
		pbData[7] = (BLOCKSIZE >> 0) & 0xFF;
		break;
		
	// read10
	case SCSI_CMD_READ_10:
		dwLBA = (pbCDB[2] << 24) | (pbCDB[3] << 16) | (pbCDB[4] << 8) | (pbCDB[5]);

		// copy data from block buffer
		dwBufPos = (dwOffset & (BLOCKSIZE - 1));
		if (dwBufPos == 0) {
			// read new block
			dwBlockNr = dwLBA + (dwOffset / BLOCKSIZE);
			DBG("R");
			if (BlockDevRead(dwBlockNr, abBlockBuf) < 0) {
				dwSense = READ_ERROR;
				DBG("BlockDevRead failed\n");
				return NULL;
			}
		}
		// return pointer to data
		return abBlockBuf + dwBufPos;

	// write10
	case SCSI_CMD_WRITE_10:
		dwLBA = (pbCDB[2] << 24) | (pbCDB[3] << 16) | (pbCDB[4] << 8) | (pbCDB[5]);
		
		// copy data to block buffer
		dwBufPos = ((dwOffset + 64) & (BLOCKSIZE - 1));
		if (dwBufPos == 0) {
			// write new block
			dwBlockNr = dwLBA + (dwOffset / BLOCKSIZE);
			DBG("W");
			if (BlockDevWrite(dwBlockNr, abBlockBuf) < 0) {
				dwSense = WRITE_ERROR;
				DBG("BlockDevWrite failed\n");
				return NULL;
			}
		}
		// return pointer to next data
		return abBlockBuf + dwBufPos;
		
	case SCSI_CMD_VERIFY_10:
		// dummy implementation
		break;
		
	default:
		// unsupported command
		dwSense = INVALID_CMD_OPCODE;
		return NULL;
	}
	
	// default: return pointer to start of block buffer
	return abBlockBuf;
}


?? 快捷鍵說(shuō)明

復(fù)制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號(hào) Ctrl + =
減小字號(hào) Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
成人午夜激情在线| 久久综合久久综合九色| av中文字幕亚洲| 成人午夜电影小说| 国产精品 欧美精品| 国产裸体歌舞团一区二区| 国产一区二区三区观看| 国产美女精品一区二区三区| 国产激情一区二区三区桃花岛亚洲| 经典三级在线一区| 国产精品资源站在线| 国产精品一区三区| 国产91富婆露脸刺激对白| 高清在线成人网| 不卡一区二区三区四区| 成人黄色在线看| 97精品久久久久中文字幕| 97久久精品人人做人人爽50路| 色综合久久66| 欧美色图12p| 欧美一级专区免费大片| 精品国产免费一区二区三区香蕉| 精品国产91久久久久久久妲己| 久久影院视频免费| 国产亚洲一区二区三区在线观看| 国产日产亚洲精品系列| 亚洲图片欧美激情| 亚洲成a人片在线观看中文| 免费成人你懂的| 国产精品综合视频| 色老综合老女人久久久| 欧美一区二区精品久久911| www精品美女久久久tv| 中文字幕制服丝袜一区二区三区| 一区二区三区中文字幕在线观看| 日本三级亚洲精品| 国产成人综合在线观看| 日本韩国精品一区二区在线观看| 欧美日韩免费一区二区三区| 日韩精品一区二区三区视频播放| 中文在线一区二区| 天堂va蜜桃一区二区三区 | 成人97人人超碰人人99| 91久久精品日日躁夜夜躁欧美| 555www色欧美视频| 国产女同性恋一区二区| 亚洲主播在线播放| 久久国产剧场电影| 一道本成人在线| 日韩欧美高清在线| 亚洲精品综合在线| 极品少妇xxxx偷拍精品少妇| 91玉足脚交白嫩脚丫在线播放| 91精品国产综合久久香蕉麻豆| 国产三级精品三级在线专区| 亚洲伊人伊色伊影伊综合网| 国产九色sp调教91| 制服丝袜中文字幕一区| 亚洲国产精品高清| 日韩av电影免费观看高清完整版 | 欧美性生活久久| 久久亚洲一区二区三区四区| 亚洲一区二区高清| 成人午夜激情影院| 2021久久国产精品不只是精品| 一区二区三区四区亚洲| 国产电影一区二区三区| 欧美一区二区三区精品| 亚洲日本青草视频在线怡红院| 久久国内精品视频| 在线观看视频一区二区| 国产欧美视频一区二区三区| 美女爽到高潮91| 欧美日韩你懂的| 国产精品久久久久久久久免费桃花| 偷窥国产亚洲免费视频| 色综合天天视频在线观看 | 免费成人小视频| 在线观看视频一区二区欧美日韩| 中文字幕高清一区| 奇米一区二区三区av| 欧美色区777第一页| 亚洲日本欧美天堂| 成人av在线电影| 国产三级欧美三级| 国产一区二区看久久| 日韩一区二区不卡| 亚欧色一区w666天堂| 91久久一区二区| 亚洲人成伊人成综合网小说| 成人黄色免费短视频| 久久欧美一区二区| 国产最新精品免费| 精品久久人人做人人爽| 蜜臀av国产精品久久久久| 69堂成人精品免费视频| 亚洲gay无套男同| 欧美图片一区二区三区| 亚洲电影一区二区| 欧美无人高清视频在线观看| 有码一区二区三区| 在线视频观看一区| 亚洲成人免费看| 欧美日韩在线播放一区| 亚洲国产视频一区二区| 欧美午夜电影在线播放| 亚洲综合成人在线| 欧美性大战久久久久久久蜜臀| 亚洲在线一区二区三区| 欧美日韩一区二区三区在线| 亚洲aaa精品| 日韩一区二区三区精品视频| 日韩成人精品在线| 日韩欧美国产不卡| 国产福利一区二区三区视频在线| 久久中文娱乐网| 成人国产视频在线观看| 中文字幕一区二区三区av| 在线看日韩精品电影| 午夜精品久久一牛影视| 精品久久人人做人人爰| 国产成人在线免费| 综合激情成人伊人| 欧美三级韩国三级日本三斤| 日韩vs国产vs欧美| 欧美tk丨vk视频| 国产精品69久久久久水密桃| 国产精品久久一卡二卡| 在线精品国精品国产尤物884a| 性欧美疯狂xxxxbbbb| 欧美一级二级三级乱码| 国产高清不卡二三区| 亚洲黄色在线视频| 91麻豆精品国产91久久久久久| 激情深爱一区二区| 国产精品人人做人人爽人人添 | 亚洲图片另类小说| 欧美日韩免费在线视频| 久久国产欧美日韩精品| 亚洲国产高清不卡| 欧美日韩免费在线视频| 国产老肥熟一区二区三区| 亚洲精品欧美激情| 欧美一级午夜免费电影| 不卡大黄网站免费看| 香蕉乱码成人久久天堂爱免费| 欧美不卡激情三级在线观看| www.综合网.com| 免费成人在线视频观看| 专区另类欧美日韩| 日韩视频一区二区三区| 99久精品国产| 奇米一区二区三区av| 国产精品久久久久永久免费观看| 欧美精品成人一区二区三区四区| 国产福利电影一区二区三区| 亚洲国产日日夜夜| 国产午夜精品一区二区三区视频| 色吧成人激情小说| 国产一区日韩二区欧美三区| 伊人夜夜躁av伊人久久| 久久女同性恋中文字幕| 欧美日韩你懂的| 成人av高清在线| 国产在线日韩欧美| 亚洲第一主播视频| 中文字幕五月欧美| 日韩欧美aaaaaa| 欧美日韩一本到| 成人免费毛片高清视频| 麻豆成人91精品二区三区| 专区另类欧美日韩| 国产亚洲欧美日韩日本| 欧美精品久久99久久在免费线 | 精品国产一区二区亚洲人成毛片 | 欧美成人精品二区三区99精品| 91在线视频官网| 盗摄精品av一区二区三区| 日韩高清在线不卡| 一区二区三区欧美亚洲| 国产免费观看久久| 精品国产一区二区国模嫣然| 欧美伦理影视网| 99久久精品免费看国产| 国产成人精品亚洲日本在线桃色| 另类小说视频一区二区| 午夜不卡av免费| 亚洲国产日产av| 一区二区免费在线| 亚洲视频在线一区| 国产精品国产三级国产普通话蜜臀| 久久品道一品道久久精品| 日韩美女天天操| 日韩精品一区在线观看| 欧美精品色综合| 91麻豆精品国产无毒不卡在线观看| 在线观看日韩毛片| 色婷婷精品大在线视频| 91色乱码一区二区三区| 成人av在线播放网址|