⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 disk_emu.c

📁 linux下的usb开发
💻 C
📖 第 1 页 / 共 2 页
字号:
/************************************************************* * Philips Mass Storage disk emulation * * (c) 2002 Koninklijke Philips Electronics N.V., All rights reserved *  * This  source code and any compilation or derivative thereof is the * proprietary information of Koninklijke Philips Electronics N.V. * and is confidential in nature. * Under no circumstances is this software to be exposed to or placed * under an Open Source License of any type without the expressed * written permission of Koninklijke Philips Electronics N.V. * * File Name:	disk_emu.c * * History:	 * *	Version	Date		Author		Comments * ------------------------------------------------- * 	1.0		09/23/02	SYARRA		Initial Creation * *************************************************************/#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <signal.h>#include <fcntl.h>#include <sys/ioctl.h>#include "msbridge.h"#include "disk_emu.h"#define		RX_BUFFER_SIZE		0x20000#define		TX_BUFFER_SIZE		0x20000/*------------------------------------------------* *          Global variable definitions           * *------------------------------------------------*/int fd_msdev;					/* Mass storage device file */int fd_disk;					/* Disk emulation file */unsigned char	disk_emu_state = DISK_EMU_IDLE;	/* Disk emulation state */unsigned long	disk_emu_tx_residue;	/* Transfer residue */disk_emu_info_t	disk_emu_info;			/* Status *//* Transfer and receiver buffers */unsigned char rcvd_data[RX_BUFFER_SIZE];unsigned char disk_data[TX_BUFFER_SIZE];unsigned long	tx_residue = 0;unsigned char	inquiry_data[INQUIRY_DATA_SIZE] = { 	0x00, 0x80, 0x02, 0x00, 0x33, 0x00, 0x00, 0x00,	'P', 'h', 'i', 'l', 'i', 'p', 's', ' ',	'O', 'T', 'G', ' ', 'M', 'a', 's', 's', 	' ', 'S', 't', 'o', 'r', 'a', 'g', 'e',	'1', '.', '0', '0'};unsigned char	read_capacity_data[READ_CAPACITY_DATA_SIZE] = {	((LAST_LBA >>24) & 0xFF), 	/* block address */	((LAST_LBA >>16) & 0xFF),	((LAST_LBA >>8) & 0xFF),	(LAST_LBA & 0xFF),	((BLOCK_SIZE >> 24) & 0xFF), /* each block size (4 bytes) */	((BLOCK_SIZE >> 16) & 0xFF),	((BLOCK_SIZE >> 8) & 0xFF),	(BLOCK_SIZE & 0xFF)};unsigned char	mode_sense_data[MODE_SENSE_DATA_SIZE] = {	0x0B,	/* Length of this sense data */	0x00,	/* medium type */	0x00,	/* Device specific parameters */	0x08, 	/* block descriptor length */	0x00,	/* density code */	((LAST_LBA >>16) & 0xFF),	/* Last Block address */	((LAST_LBA >>8) & 0xFF),	(LAST_LBA & 0xFF),	0x00,	/* Reserved */	((BLOCK_SIZE >> 16) & 0xFF), /* Block Size */	((BLOCK_SIZE >> 8) & 0xFF),	(BLOCK_SIZE & 0xFF)};unsigned char	request_sense_data[REQUEST_SENSE_DATA_SIZE] = {			0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 			0x00, 0x00 };/*-----------------------------------------------------* *          Local function declerations                * *-----------------------------------------------------*/static	void disk_emu_prepare_sense_data(unsigned char sense_key, 								unsigned char asc, 								unsigned char ascq);static	void disk_emu_command(void);static	void disk_emu_sighandler(int signo);static	void disk_emu_status(unsigned char	status);static	int	disk_emu_read(unsigned long	data_len);static	int	disk_emu_write(unsigned long	data_len);static	void disk_emu_print_cmd(unsigned char *cmd);/*-----------------------------------------------------* *          Local function definitions                 * *-----------------------------------------------------*/void disk_emu_print_cmd(unsigned char *cmd) {	char	cmd_name[30];		switch(cmd[0]) {		case CMD_TEST_UNIT_READY:			strcpy(cmd_name,"TEST_UNIT_READY    ");			break;		case CMD_REQUEST_SENSE:			strcpy(cmd_name,"REQUEST_SENSE      ");			break;		case CMD_FORMAT_UNIT:			strcpy(cmd_name,"CMD_FORMAT_UNIT");			break;		case CMD_INQUIRY:			strcpy(cmd_name,"INQUIRY            ");			break;		case CMD_RESERVE:			strcpy(cmd_name,"RESERVE            ");			break;		case CMD_RELEASE:			strcpy(cmd_name,"RELEASE            ");			break;		case CMD_MODE_SENSE:			strcpy(cmd_name,"MODE_SENSE         ");			break;		case CMD_START_STOP_UNIT:			strcpy(cmd_name,"START_STOP_UNIT    ");			break;		case CMD_SEND_DIAGNOSTIC:			strcpy(cmd_name,"SEND_DIAGNOSTIC    ");			break;		case CMD_MEDIUM_REMOVAL:			strcpy(cmd_name,"MEDIUM_REMOVAL     ");			break;		case CMD_READ_CAPACITY:			strcpy(cmd_name,"READ_CAPACITY      ");			break;		case CMD_READ10:			strcpy(cmd_name,"READ10             ");			break;		case CMD_WRITE10:			strcpy(cmd_name,"WRITE10            ");			break;		case CMD_VERIFY10:			strcpy(cmd_name,"VERIFY10           ");			break;		default:			strcpy(cmd_name,"UNKNOWN COMMAND    ");			break;	}//	printf("%s received len = %d\n",cmd_name, cmd[14]);}void disk_emu_prepare_sense_data(unsigned char sense_key, 						unsigned char asc, 						unsigned char ascq) {	request_sense_data[2] = sense_key;	request_sense_data[12] = asc;	request_sense_data[13] = ascq;}int	disk_emu_read(unsigned long	data_len){	unsigned long	res_len, nbytes;	unsigned char	*data_ptr;	/* Read from the emulation disk */	res_len = read(fd_disk, disk_data, data_len);	if(res_len <=0) {		disk_emu_prepare_sense_data(	SENSE_KEY_MEDIUM_ERROR, 							ASC_ADDR_NOT_FOUND_4_ID_FLD, 							0x00);		disk_emu_state = DISK_EMU_STATUS;		disk_emu_status(MSCD_CMD_RES_FAILED);		return 0;	}	/* Write to the mass storage device */	data_ptr = disk_data;	while(res_len) {		nbytes = write(fd_msdev,data_ptr, res_len);		data_ptr += nbytes;		res_len -= nbytes;		disk_emu_tx_residue -= nbytes;	}	if(disk_emu_tx_residue) {		data_len = ((disk_emu_tx_residue > TX_BUFFER_SIZE) ?						TX_BUFFER_SIZE : disk_emu_tx_residue);		disk_emu_read(data_len);	} else {		disk_emu_prepare_sense_data(	SENSE_KEY_NO_SENSE, 0x00, 0x00);		disk_emu_state = DISK_EMU_STATUS;		disk_emu_status(MSCD_CMD_RES_SUCCESS);	}	return 0;	}/* End of disk_emu_read */int	disk_emu_write(unsigned long data_len){	unsigned long	res_len;	/*      * This call will be a blocked one until we receive the	 * data from the host     */	disk_emu_tx_residue -= data_len;	/* Write to the emuation disk */	res_len = write(fd_disk, rcvd_data, data_len);	if(res_len <=0 ) {		disk_emu_prepare_sense_data(	SENSE_KEY_MEDIUM_ERROR, 					ASC_ADDR_NOT_FOUND_4_ID_FLD, 					0x00);	}	if(data_len != res_len) {//		printf("read write error\n");	}	if(!disk_emu_tx_residue) {		disk_emu_state = DISK_EMU_STATUS;		disk_emu_prepare_sense_data(	SENSE_KEY_NO_SENSE, 0x00,0x00);		disk_emu_status(MSCD_CMD_RES_SUCCESS);	} else {		data_len = ((disk_emu_tx_residue > RX_BUFFER_SIZE) ?								RX_BUFFER_SIZE : disk_emu_tx_residue);		if(data_len) disk_emu_write(data_len);	}	return 0;}/* End of disk_emu_write */void disk_emu_command(void) {	unsigned char	*cmd = rcvd_data;	unsigned char	cmd_type = cmd[0];	unsigned int	data_len = 0;	unsigned long 	block_addr;	unsigned char	prevent;	long	res_len = 0;	disk_emu_print_cmd(cmd);	disk_emu_state = DISK_EMU_CMD;//	printf("state = DISK_EMU_CMD\n");	switch(cmd_type) {				case CMD_READ10:			block_addr = ((cmd[2] << 24) | (cmd[3] << 16) | (cmd[4] <<8) | cmd[5] );			data_len = ((cmd[7] << 8) | cmd[8]) *BLOCK_SIZE;			disk_emu_tx_residue = data_len;			if(fd_disk < 0) fd_disk = open(MSDISK_FILE, O_RDWR);			if(disk_emu_tx_residue && (fd_disk != 1)) {				/* Need to do more checking */				lseek(fd_disk, block_addr*BLOCK_SIZE, SEEK_SET);				/* Some thing to be read from the disk emulation */				data_len = ((disk_emu_tx_residue > TX_BUFFER_SIZE) ?								TX_BUFFER_SIZE : disk_emu_tx_residue);				disk_emu_state = DISK_EMU_DATA_OUT;//				printf("state = DISK_EMU_DATA_OUT\n");				disk_emu_read(data_len);			} else {//				printf("read call failed \n");				disk_emu_state = DISK_EMU_STATUS;				disk_emu_status(MSCD_CMD_RES_FAILED);			}			break;		case CMD_WRITE10:			block_addr = ((cmd[2] << 24) | (cmd[3] << 16) | (cmd[4] <<8) | cmd[5] );			data_len = ((cmd[7] << 8) | cmd[8]) *BLOCK_SIZE;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -