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

📄 disk_emu.c

📁 philips公司ISP1362 USB OTG控制芯片的驱动
💻 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 + -