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

📄 disk_emu.c

📁 linux下的usb开发
💻 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 + -