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

📄 disk_emu.c

📁 philips公司ISP1362 USB OTG控制芯片的驱动
💻 C
📖 第 1 页 / 共 2 页
字号:
			disk_emu_tx_residue = data_len;

//			printf("block_addr = %lu, data_len = %d\n", block_addr, data_len);

			lseek(fd_disk, block_addr*BLOCK_SIZE, SEEK_SET);


			disk_emu_state = DISK_EMU_DATA_IN;
//			printf("state = DISK_EMU_DATA_IN\n");

			data_len = ((disk_emu_tx_residue > RX_BUFFER_SIZE) ?
									RX_BUFFER_SIZE : disk_emu_tx_residue);
			data_len = read(fd_msdev, rcvd_data, data_len);
//			printf("read nbytes = %x\n", data_len);
			if(data_len) disk_emu_write(data_len);

			break;

		case CMD_REQUEST_SENSE:
			
			/* Send the sense data */
			res_len = REQUEST_SENSE_DATA_SIZE;
			res_len = write(fd_msdev,request_sense_data, res_len);
			disk_emu_tx_residue -= res_len;

			disk_emu_prepare_sense_data(SENSE_KEY_NO_SENSE, 0x00, 0x00);

			disk_emu_state = DISK_EMU_STATUS;
			disk_emu_status(MSCD_CMD_RES_SUCCESS);

			break;


		case CMD_INQUIRY:

			disk_emu_tx_residue = cmd[4];

			res_len = (cmd[4] < INQUIRY_DATA_SIZE) ?  cmd[4] : INQUIRY_DATA_SIZE;

			if((cmd[1] & INQUIRY_EVPD) || cmd[2] ) {
				/* If EVPD flags are set or Page code is not zero we are not 
				 * supporting it */

				disk_emu_prepare_sense_data(SENSE_KEY_ILLEGAL_REQUEST, ASC_INV_FIELD_IN_CDB, 
								0x00);
				disk_emu_state = DISK_EMU_STATUS;
				disk_emu_status(MSCD_CMD_RES_FAILED);

			} else {

				disk_emu_tx_residue -= write(fd_msdev,inquiry_data, res_len);
				disk_emu_prepare_sense_data(SENSE_KEY_NO_SENSE, 0x00, 0x00);
				disk_emu_state = DISK_EMU_STATUS;
				disk_emu_status(MSCD_CMD_RES_SUCCESS);
			}

			break;

		case CMD_TEST_UNIT_READY:
			if(fd_disk) {
				disk_emu_prepare_sense_data(SENSE_KEY_NO_SENSE, 0x00, 0x00);
				disk_emu_state = DISK_EMU_STATUS;
				disk_emu_status(MSCD_CMD_RES_SUCCESS);
			} else {
				disk_emu_prepare_sense_data(SENSE_KEY_NOT_READY, 0x00, 0x00);
				disk_emu_state = DISK_EMU_STATUS;
				disk_emu_status(MSCD_CMD_RES_FAILED);
			}
			break;
		case CMD_START_STOP_UNIT:
			if(cmd[4]&0x01) {
				/* Start the UNIT */
				if(fd_disk < 0) fd_disk = open(MSDISK_FILE, O_RDWR);
			} else {
				/* stop the unit */
				if(fd_disk) close(fd_disk);
				fd_disk = -1;
			}
		case CMD_FORMAT_UNIT:
		case CMD_SEND_DIAGNOSTIC:
		case CMD_VERIFY10:

			disk_emu_prepare_sense_data(SENSE_KEY_NO_SENSE, 0x00, 0x00);
			disk_emu_state = DISK_EMU_STATUS;
			disk_emu_status(MSCD_CMD_RES_SUCCESS);

			break;

		case CMD_MEDIUM_REMOVAL:

			prevent = cmd[4] & 0x01;

			if(prevent && disk_emu_info.prevent) {
				/* problem */

				disk_emu_prepare_sense_data(SENSE_KEY_UNIT_ATTENTION, ASC_MEDIUM_CHANGE, 									0x00);

				disk_emu_state = DISK_EMU_STATUS;
				disk_emu_status(MSCD_CMD_RES_FAILED);

			} else {
				disk_emu_info.prevent = (cmd[4] & 0x01);

				lseek(fd_disk, LOGICAL_BLOCKS*BLOCK_SIZE, SEEK_SET);
				write(fd_disk, (unsigned char*)(&disk_emu_info), sizeof(disk_emu_info_t));
				
				disk_emu_prepare_sense_data(SENSE_KEY_NO_SENSE, 0x00, 0x00);
				disk_emu_state = DISK_EMU_STATUS;
				disk_emu_status(MSCD_CMD_RES_SUCCESS);

			}

			break;

		case CMD_READ_CAPACITY:

			if(!((cmd[8])& READ_CAPACITY_RMI)) {
				
				res_len = READ_CAPACITY_DATA_SIZE;
				disk_emu_tx_residue -= write(fd_msdev,read_capacity_data, res_len);
				disk_emu_prepare_sense_data(SENSE_KEY_NO_SENSE, 0x00, 0x00);

				disk_emu_state = DISK_EMU_STATUS;
				disk_emu_status(MSCD_CMD_RES_SUCCESS);

			} else {

				res_len = -1;
				disk_emu_prepare_sense_data(	SENSE_KEY_ILLEGAL_REQUEST, 
									ASC_INV_FIELD_IN_CDB, 
									0x00);
			}

			break;
		
		case CMD_MODE_SENSE:
			
			res_len = MODE_SENSE_DATA_SIZE;
			if(cmd[4] && cmd[4] < res_len) res_len = cmd[4];

			disk_emu_tx_residue -= write(fd_msdev,mode_sense_data, res_len);
			disk_emu_prepare_sense_data(SENSE_KEY_NO_SENSE, 0x00, 0x00);

			disk_emu_state = DISK_EMU_STATUS;
			disk_emu_status(MSCD_CMD_RES_SUCCESS);


			break;


		case CMD_RESERVE:
		case CMD_RELEASE:

			if(cmd[1] & RESERVE_EXTENT) {
				disk_emu_prepare_sense_data(SENSE_KEY_ILLEGAL_REQUEST, 
								ASC_INV_FIELD_IN_CDB, 0x00);
				disk_emu_state = DISK_EMU_STATUS;
				disk_emu_status(MSCD_CMD_RES_FAILED);
			} 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);
			}
			break;


		default:


			disk_emu_prepare_sense_data(SENSE_KEY_ILLEGAL_REQUEST, ASC_INV_FIELD_IN_CDB, 
								0x00);
			disk_emu_state = DISK_EMU_STATUS;
		
			sleep(1);
			disk_emu_status(MSCD_CMD_RES_FAILED);
			break;

	}

	return;
}

/*
 * Send command response to the mass storage device
 */
void disk_emu_status(unsigned char	status) 
{
	mscd_cmd_res_t	cmd_res;

	cmd_res.status = status;
	cmd_res.residue = disk_emu_tx_residue;
	ioctl(fd_msdev, MSCD_IOC_SET_CMD_RES, &cmd_res);
	disk_emu_state = DISK_EMU_IDLE;
}


/* 
 * Signal handler
 * This processes the signals received from the mass storage device
 */
void disk_emu_sighandler(int signo) {
	unsigned int status, nbytes;
	mscd_notif_t	 notif_sts;
	int ret;

	/* 
     * Get the Signal/notification from the device 
     */
    ret = ioctl(fd_msdev, MSCD_IOC_GET_NOTIF, &notif_sts);
	status = notif_sts.notif;


//	printf("Singnal received %x \n",status);
	switch (status) {

		case MSCD_CMD:
//			printf("MSCD_DATA_RCVD\n");
			if(disk_emu_state == DISK_EMU_IDLE) {

				ret = ioctl(fd_msdev, MSCD_IOC_GET_COMMAND, rcvd_data);
				disk_emu_command();

			} else if(disk_emu_state == DISK_EMU_DATA_IN) {
				nbytes = read(fd_msdev,rcvd_data, disk_emu_tx_residue);

//				printf("received bytes %d\n", nbytes);
				disk_emu_write(nbytes);
		}

		break;

	case MSCD_RESET:
//		printf("MSCD_RESET\n");
		/* This is reset mass storage device, reset the FSM */
		disk_emu_info.prevent = 0;
		lseek(fd_disk, LOGICAL_BLOCKS*BLOCK_SIZE, SEEK_SET);
		nbytes = write(fd_disk, (unsigned char*)(&disk_emu_info), sizeof(disk_emu_info_t));

		disk_emu_state = DISK_EMU_IDLE;

		break;

	default :
		break;
	}

    return;
}

int main(int argc, char **argv)
{
    int ret;
    struct sigaction action;
	int	nbytes;

	/* Open the mass storage device file */
    fd_msdev=open(MS_DEV_FILE_NAME, O_RDWR);

	if(fd_msdev < 0) {
		printf("Error in opening file: %s\n",MS_DEV_FILE_NAME);
	 	exit(0);
	}

	/* Open the mass storage disk emulation file */
	fd_disk = open(MSDISK_FILE, O_RDWR);

	if(fd_disk < 0) {
		printf("disk emulation file is not found %s\n",MSDISK_FILE);
		close(fd_msdev);
		exit(0);
	}

	/* Initalize the status from the mass storage emulation file */

	lseek(fd_disk, LOGICAL_BLOCKS*BLOCK_SIZE, SEEK_SET);
	nbytes = read(fd_disk, (unsigned char*)(&disk_emu_info),sizeof(disk_emu_info_t));

	if(nbytes != sizeof(disk_emu_info_t)) {
		printf("Init file reading failed\n");
		close(fd_disk);
		close(fd_msdev);
		exit(0);
	}

	close(fd_disk);		/* Close the file temporarly */
	fd_disk = -1;

	/* 
     * Set signal action to receive asynchronous notifications from the
     * mass storage device file 
     */
    memset(&action, 0, sizeof(action));
    action.sa_handler = disk_emu_sighandler;
    sigemptyset(&action.sa_mask);
    action.sa_flags = 0;

    sigaction(SIGIO, &action, NULL);

    ret= fcntl(fd_msdev, F_SETOWN, getpid());

    ret=fcntl(fd_msdev,F_GETFL);

    fcntl(fd_msdev, F_SETFL, fcntl(STDIN_FILENO, F_GETFL) | FASYNC);

	/* 
     * Wait for ever and process the things in signal handler
     */
	while(1) {
		/* Now the functionality of this depends on the singnal handler */
        sleep(400); 
    }

	if(fd_disk > 0) close(fd_disk);
	close(fd_msdev);
}

⌨️ 快捷键说明

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