📄 scsi.c
字号:
INT8U *u8ModeSenseData; u8ModeSenseData = (INT8U*)malloc(DATA_LENGTH_MODE_SENSE); Mass_stor_us->srb = (struct scsi_cmnd *)malloc(sizeof(struct scsi_cmnd )); for(u8j =0; u8j< ScsiCmd_Fail_Retry ;u8j++) { memset(Mass_stor_us->srb, 0, sizeof(struct scsi_cmnd )); // Build SCSI command. vSCSICmd_MODE_SENSE(Mass_stor_us, Mass_stor_us->srb,0x3F, u8ModeSenseData); // call mass storage function to send CBW // and get Mode Sense Data. Return CSW to check status. Host20_MSCD_usb_stor_control_thread(Mass_stor_us); if(Mass_stor_us->srb->result == SAM_STAT_GOOD) { // save all Mode Sense(page code=0x3F) data // Now we only use u8ModeSenseData[2], this byte save device // write protection information Mass_stor_us->Mass_stor_device[u8Drive].bWriteProtect = (u8ModeSenseData[2]==0x80)? TRUE:FALSE; free(u8ModeSenseData); if(Mass_stor_us->srb != NULL) free(Mass_stor_us->srb); return TRUE; } } free(u8ModeSenseData); if(Mass_stor_us->srb != NULL) free(Mass_stor_us->srb); return FALSE;}//***************************************************************************************// Function Name:bSCSI_READ_CAPACITY// Description:To get the CAPACITY// Input:// Output:// Status:S//***************************************************************************************///////////////////////////////////////////////////////////////////////////////// bSCSI_READ_CAPACITY()// Description:// 1. scsi READ_CAPACITY command.// input: none// output: TRUE or FALSE (BOOLEAN)///////////////////////////////////////////////////////////////////////////////BOOLEAN bSCSI_READ_CAPACITY(void){ INT8U u8j; INT8U *u8ReadCapacityData; for(u8j =0; u8j< ScsiCmd_Fail_Retry ;u8j++) { u8ReadCapacityData = (INT8U*)malloc(DATA_LENGTH_READ_CAPACITY); Mass_stor_us->srb = (struct scsi_cmnd *)malloc(sizeof(struct scsi_cmnd )); memset(Mass_stor_us->srb, 0, sizeof(struct scsi_cmnd )); // Build SCSI command. vSCSICmd_READ_CAPACITY(Mass_stor_us, Mass_stor_us->srb, u8ReadCapacityData); // call mass storage function to send CBW // and get CAPACITY Data. Return CSW to check status. Host20_MSCD_usb_stor_control_thread(Mass_stor_us); if(Mass_stor_us->srb->result == SAM_STAT_GOOD) { // save all CAPACITY data Mass_stor_us->Mass_stor_device[u8Drive].u32BlockTotalNum = ((INT32U)u8ReadCapacityData[0] << 24) | ((INT32U)u8ReadCapacityData[1] << 16) | ((INT32U)u8ReadCapacityData[2] << 8) | ((INT32U)u8ReadCapacityData[3] ) ; Mass_stor_us->Mass_stor_device[u8Drive].u32BlockSize = ((INT32U)u8ReadCapacityData[4] << 24) | ((INT32U)u8ReadCapacityData[5] << 16) | ((INT32U)u8ReadCapacityData[6] << 8) | ((INT32U)u8ReadCapacityData[7] ) ; if ( Mass_stor_us->Mass_stor_device[u8Drive].u32BlockSize > 1024) { printf("Block size over 1024, is %X\n",Mass_stor_us->Mass_stor_device[u8Drive].u32BlockSize); while(1); } SCSI_DbgPrint("SCSI CAPACITY : SCSI Device total block <0x%x%x>\n", (INT16U)(Mass_stor_us->Mass_stor_device[u8Drive].u32BlockTotalNum >> 16), (INT16U)Mass_stor_us->Mass_stor_device[u8Drive].u32BlockTotalNum); SCSI_DbgPrint("SCSI CAPACITY : SCSI Product block size <0x%x bytes>\n",(INT16U)Mass_stor_us->Mass_stor_device[u8Drive].u32BlockSize); free(u8ReadCapacityData); if(Mass_stor_us->srb != NULL) free(Mass_stor_us->srb); return TRUE; } else { free(u8ReadCapacityData); if(Mass_stor_us->srb != NULL) free(Mass_stor_us->srb); } } return FALSE;}//***************************************************************************************// Function Name:bSCSI_TEST_UNIT_READY// Description: To know that "device is ready ?"// Input:// Output:// Status://***************************************************************************************///////////////////////////////////////////////////////////////////////////////// bSCSI_TEST_UNIT_READY()// Description:// 1. scsi TEST_UNIT_READY command.// input: none// output: TRUE or FALSE (BOOLEAN)///////////////////////////////////////////////////////////////////////////////BOOLEAN bSCSI_TEST_UNIT_READY(void){ INT8U u8j; for(u8j =0; u8j< ScsiCmd_Fail_Retry ;u8j++) { Mass_stor_us->srb = (struct scsi_cmnd *)malloc(sizeof(struct scsi_cmnd )); memset(Mass_stor_us->srb, 0, sizeof(struct scsi_cmnd )); // Build SCSI command. vSCSICmd_TEST_UNIT_READY(Mass_stor_us, Mass_stor_us->srb); // call mass storage function to send CBW // and get CAPACITY Data. Return CSW to check status. Host20_MSCD_usb_stor_control_thread(Mass_stor_us); if(Mass_stor_us->srb->result == SAM_STAT_GOOD) { Mass_stor_us->Mass_stor_device[u8Drive].bDeviceReady = TRUE; SCSI_DbgPrint("SCSI TEST UNIT READY (Lun=%d): Succeed\n",u8Drive); if(Mass_stor_us->srb != NULL) free(Mass_stor_us->srb); return TRUE; } else { if(Mass_stor_us->srb != NULL) free(Mass_stor_us->srb); }//Bruce #if 0 //Bruce if(iCardSuddenlyRemove == TRUE)//Bruce {//Bruce fLib_RemoveFileSystem((u8Drive+'A'));//Bruce Mass_stor_us->Mass_stor_device[u8Drive].bDeviceReady = FALSE;//Bruce iCardSuddenlyRemove = FALSE;//Bruce SCSI_DbgPrint("**Media already be removed.%s","\n");//Bruce }//Bruce if(iCardReplace == TRUE)//Bruce {//Bruce SCSI_DbgPrint("**Media has been replaced.%s","\n");//Bruce fLib_RemoveFileSystem((u8Drive+'A'));//Bruce //Bruce Drive = 'A'+u8Drive; //Bruce fLib_InsertFileSystem(Drive, &(Mass_stor_us->Mass_stor_device[u8Drive].FileSys));//Bruce fLib_InitFATFileSystemRoutines(&(Mass_stor_us->Mass_stor_device[u8Drive].FileSys), //Bruce &(Mass_stor_us->Mass_stor_device[u8Drive]), //Bruce (INIT_CARD)bSCSI_Initial, //Bruce (READ_SECTOR)bSCSI_READ_10, //Bruce (WRITE_SECTOR)bSCSI_Write_10, //Bruce (ERASE_SECTOR)bSCSI_ERASE);//Bruce // Get FAT, John add//Bruce SplitDrivePath(&Drive, &DriveName, Path);//Bruce GetFileSystem(DriveName);//Bruce iCardReplace = FALSE;//Bruce }//Bruce #endif } SCSI_DbgPrint("SCSI TEST UNIT READY : Failed%s","\n"); return FALSE;}//***************************************************************************************// Function Name:bSCSI_Initial// Description:// Input:// Output:// Status:P-OK//***************************************************************************************BOOLEAN bSCSI_Initial(struct LUN_Device* LunDevice){ //INT8U i=0; //iCardSuddenlyRemove = FALSE; //iCardReplace = FALSE; if(!bSCSI_TEST_UNIT_READY()) { SCSI_DbgPrint("Scsi Device not ready (Lun=%d).\n",u8Drive); return FALSE; } bSCSI_INQUIRY(); if(!bSCSI_READ_CAPACITY()) { SCSI_DbgPrint("Read CAPACITY failed.%s","\n"); return FALSE; } if(!bSCSI_TEST_UNIT_READY()) { SCSI_DbgPrint("Scsi Device not ready (Lun=%d).\n",u8Drive); return FALSE; } return TRUE; }//***************************************************************************************// Function Name:bUSBDisk_FileSystem_Initial// Description:// Input:// Output:// Status:P-OK//***************************************************************************************BOOLEAN bUSBDisk_FileSystem_Initial(void){ UINT32 DriveName; INT8 Path[MAX_DIRECTORY_PATH_SIZE]; INT8U Drive,i,DriveTmp[2];// fLib_InitFileSystem(); /* register a file system to file system control */ for(i=0; i<=Mass_stor_us->max_lun; i++) { if(!Mass_stor_us->Mass_stor_device[i].bDeviceReady) { Mass_stor_us->Mass_stor_device[i].u8LunNum = i; u8Drive = i; Drive = 'A'+i;//'C'+ fLib_InsertFileSystem(Drive, &(Mass_stor_us->Mass_stor_device[i].FileSys)); fLib_InitFATFileSystemRoutines(&(Mass_stor_us->Mass_stor_device[i].FileSys), &(Mass_stor_us->Mass_stor_device[i]), (INIT_CARD)bSCSI_Initial, (READ_SECTOR)bSCSI_READ_10, (WRITE_SECTOR)bSCSI_Write_10, (ERASE_SECTOR)bSCSI_ERASE); // Get FAT, John add SplitDrivePath((INT8*)&Drive, &DriveName, Path); GetFileSystem(DriveName); // Show Drive status.. DriveTmp[0] = Drive; DriveTmp[1] = 0; if(Mass_stor_us->Mass_stor_device[i].bDeviceReady == TRUE) { printf("Drive '%01s' ready to wrok..\n",DriveTmp); } else { printf("Drive '%01s' already registered, but can't work now..\n",DriveTmp); } } } u8Drive = Mass_stor_us->max_lun; return TRUE;}//***************************************************************************************// Function Name:// Description:// Input:// Output:// Status://***************************************************************************************void vUSBDisk_FileSystem_Remove(void){ INT8U Drive ,i; for(i=0; i<=Mass_stor_us->max_lun; i++) { Drive = 'A'+i; fLib_RemoveFileSystem(Drive); }}//***************************************************************************************// Function Name:// Description:// Input:// Output:// Status://***************************************************************************************BOOLEAN bSCSI_ERASE( struct LUN_Device* LunDevice, INT32U u32BlockAddr, INT32U u32BlockNum, INT32U u32SectorSize){ return TRUE;}//***************************************************************************************// Function Name:// Description:// Input:// Output:// Status://***************************************************************************************BOOLEAN bSCSI_READ_10( struct LUN_Device* LunDevice, INT32U u32BlockAddr, INT32U u32BlockNum, INT32U u32SectorSize, INT8U *u8Buffer){#if 1 INT32U u32DataLeft = (Mass_stor_us->Mass_stor_device[LunDevice->u8LunNum].u32BlockSize)*u32BlockNum; INT32U u32TransBlockTmp, u32TransSizeTmp,u32BlockOfSet = 0, u32TransOfSet = 0; Mass_stor_us->srb = (struct scsi_cmnd *)malloc(sizeof(struct scsi_cmnd )); memset(Mass_stor_us->srb, 0, sizeof(struct scsi_cmnd )); while(u32DataLeft > 0) { if(u32DataLeft > Scsi_Max_Transfer_Len) { u32TransBlockTmp = Scsi_Max_Transfer_Len / Mass_stor_us->Mass_stor_device[LunDevice->u8LunNum].u32BlockSize; u32TransSizeTmp = u32TransBlockTmp * Mass_stor_us->Mass_stor_device[LunDevice->u8LunNum].u32BlockSize; u32DataLeft -= u32TransSizeTmp; } else { u32TransBlockTmp = u32DataLeft/Mass_stor_us->Mass_stor_device[LunDevice->u8LunNum].u32BlockSize; u32TransSizeTmp = u32DataLeft; u32DataLeft = 0; } // Build SCSI command. vSCSICmd_READ_10(Mass_stor_us, Mass_stor_us->srb, LunDevice->u8LunNum, u32BlockAddr + u32BlockOfSet, (INT16U)u32TransBlockTmp, u8Buffer + u32TransOfSet); // call mass storage function to send scsi command Host20_MSCD_usb_stor_control_thread(Mass_stor_us); if(Mass_stor_us->srb->result != SAM_STAT_GOOD) { SCSI_DbgPrint("Scsi READ_10 command failed.%s","\n"); if(Mass_stor_us->srb != NULL) free(Mass_stor_us->srb); return FALSE; } u32BlockOfSet += u32TransBlockTmp; u32TransOfSet += u32TransSizeTmp; } if(Mass_stor_us->srb != NULL) free(Mass_stor_us->srb); printf("#"); return TRUE;#else Mass_stor_us->srb = (struct scsi_cmnd *)malloc(sizeof(struct scsi_cmnd )); memset(Mass_stor_us->srb, 0, sizeof(struct scsi_cmnd )); // Build SCSI command. vSCSICmd_READ_10(Mass_stor_us, Mass_stor_us->srb, LunDevice->u8LunNum, u32BlockAddr, (INT16U)u32BlockNum, u8Buffer); // call mass storage function to send scsi command Host20_MSCD_usb_stor_control_thread(Mass_stor_us); if(Mass_stor_us->srb->result != SAM_STAT_GOOD) { SCSI_DbgPrint("Scsi READ_10 command failed.%s","\n"); if(Mass_stor_us->srb != NULL) free(Mass_stor_us->srb); return FALSE; } if(Mass_stor_us->srb != NULL) free(Mass_stor_us->srb); printf("#"); return TRUE;#endif }//***************************************************************************************// Function Name:// Description:// Input:// Output:// Status://***************************************************************************************BOOLEAN bSCSI_Write_10( struct LUN_Device* LunDevice, INT32U u32BlockAddr, INT32U u32BlockNum, INT32U u32SectorSize, INT8U *u8Buffer){#if 1 INT32U u32DataLeft = (Mass_stor_us->Mass_stor_device[LunDevice->u8LunNum].u32BlockSize)*u32BlockNum; INT32U u32TransBlockTmp, u32TransSizeTmp,u32BlockOfSet = 0, u32TransOfSet = 0; if(!Mass_stor_us->Mass_stor_device[u8Drive].bWriteProtect) { Mass_stor_us->srb = (struct scsi_cmnd *)malloc(sizeof(struct scsi_cmnd )); memset(Mass_stor_us->srb, 0, sizeof(struct scsi_cmnd )); while(u32DataLeft > 0) { if(u32DataLeft > Scsi_Max_Transfer_Len) { u32TransBlockTmp = Scsi_Max_Transfer_Len / Mass_stor_us->Mass_stor_device[LunDevice->u8LunNum].u32BlockSize; u32TransSizeTmp = u32TransBlockTmp * Mass_stor_us->Mass_stor_device[LunDevice->u8LunNum].u32BlockSize; u32DataLeft -= u32TransSizeTmp; } else { u32TransBlockTmp = u32DataLeft/Mass_stor_us->Mass_stor_device[LunDevice->u8LunNum].u32BlockSize; u32TransSizeTmp = u32DataLeft; u32DataLeft = 0; } // Build SCSI command. vSCSICmd_WRITE_10(Mass_stor_us, Mass_stor_us->srb, LunDevice->u8LunNum, u32BlockAddr + u32BlockOfSet, (INT16U)u32TransBlockTmp, u8Buffer + u32TransOfSet); // call mass storage function to send scsi command Host20_MSCD_usb_stor_control_thread(Mass_stor_us); if(Mass_stor_us->srb->result != SAM_STAT_GOOD) { SCSI_DbgPrint("Scsi WRITE_10 command failed.%s","\n"); if(Mass_stor_us->srb != NULL) free(Mass_stor_us->srb); return FALSE; } u32BlockOfSet += u32TransBlockTmp; u32TransOfSet += u32TransSizeTmp; } if(Mass_stor_us->srb != NULL) free(Mass_stor_us->srb); printf("*"); return TRUE; } else { printf("This device is write protect now\n"); return FALSE; }#else if(!Mass_stor_us->Mass_stor_device[u8Drive].bWriteProtect) { Mass_stor_us->srb = (struct scsi_cmnd *)malloc(sizeof(struct scsi_cmnd )); memset(Mass_stor_us->srb, 0, sizeof(struct scsi_cmnd )); // Build SCSI command. vSCSICmd_WRITE_10(Mass_stor_us, Mass_stor_us->srb, LunDevice->u8LunNum, u32BlockAddr, (INT16U)u32BlockNum, u8Buffer); // call mass storage function to send scsi command Host20_MSCD_usb_stor_control_thread(Mass_stor_us); if(Mass_stor_us->srb->result != SAM_STAT_GOOD) { SCSI_DbgPrint("Scsi WRITE_10 command failed.%s","\n"); if(Mass_stor_us->srb != NULL) free(Mass_stor_us->srb); return FALSE; } if(Mass_stor_us->srb != NULL) free(Mass_stor_us->srb); printf("*"); return TRUE; } else { printf("This device is write protect now\n"); return FALSE; }#endif }//***************************************************************************************// Function Name:vScsi_SendCmd_Done// Description:// Input:// Output:// Status://***************************************************************************************static void vScsi_SendCmd_Done(struct scsi_cmnd *srb){ SCSI_DbgPrint("Send SCSI command (0x%x) Done (LUN=%d), result = 0x%x\n", srb->cmnd[0],u8Drive, srb->result);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -