📄 disk_emu.c
字号:
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, ¬if_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 + -