📄 reader.cc
字号:
/*******************************************************************
* scsicmd.cc -- Test some scsi command for usb mass storage
* using the SPC-3 and SBC-2
* using the bulk only protocol.
* using the DosUsb driver.
*******************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <dos.h>
#include <dpmi.h>
#include <sys/farptr.h>
#include <sys/segments.h>
#include <sys/movedata.h>
#include "public.h"
#include "x86int.h"
#include "dosmem.h"
#include "usb.h"
#include "bulk.h"
#include "scsi.h"
DOS_MEM urb(URB_LENGTH);
DOS_MEM device_request(SETUP_REQUEST_LENGTH);
DOS_MEM cbw(CBW_LENGTH);
DOS_MEM buffer(BUFFER_LENGTH);
int i, j;
WORD wLen;
//BYTE bPacketSize;
//char sManufacturer[32], sProduct[32], sSerialNumber[32];
BYTE devAddr, inEndpoint, outEndpoint;
BYTE bTemp, *pByte;
DWORD dwTag, dwTemp;
X86_REGS inregs;
// ==========================================
/**********************************
* Clear URB
**********************************/
void initURB(void) {
int i;
for (i = 0; i < URB_LENGTH; i++)
urb.SetBYTE(0, i);
}
/**************************************************
* Control Transaction -- Send a request to device
*
* You have to fill device_request before calling
* this function.
* Data returned from device will store in buffer.
***************************************************/
void bulkCmdProc(int bufLen, int actualLen) {
initURB();
urb.SetBYTE(0x2d, URB_TRANSACTION_TOKEN); // control
urb.SetBYTE(devAddr, URB_DEV_ADD);
urb.SetWORD(buffer.GetSegment(), URB_BUFFER_SEG);
urb.SetWORD(buffer.GetOffset(), URB_BUFFER_OFF);
urb.SetWORD(bufLen, URB_BUFFER_LENGTH);
urb.SetWORD(actualLen, URB_ACTUAL_LENGTH);
urb.SetWORD(device_request.GetSegment(), URB_SETUP_BUFFER_SEG);
urb.SetWORD(device_request.GetOffset(), URB_SETUP_BUFFER_OFF);
for (j = 0; j < buffer.GetLength(); j++) buffer.SetBYTE(1, j);
inregs.x.ds = urb.GetSegment();
inregs.x.dx = urb.GetOffset();
x86_int(0x65, &inregs); // call DosUsb
}
/*****************************************************
* Reset command
*
* See USB mass storage class -- Bulk-Inly Transport
*****************************************************/
void bulkReset(void) {
device_request.SetBYTE(BULK_GET_MAX_LUN, SR_REQUEST_TYPE);
device_request.SetBYTE(REQ_BULK_RESET, SR_REQUEST);
device_request.SetWORD(0, SR_VALUE);
device_request.SetWORD(0, SR_INDEX); // interface number
device_request.SetWORD(0, SR_LENGTH);
bulkCmdProc(0, 8);
return;
}
/*****************************************************
* Get max. Logical Unit Number
*
* See USB mass storage class -- Bulk-Inly Transport
* Return max. LUN
*****************************************************/
int bulkMaxLun(void) {
device_request.SetBYTE(BULK_GET_MAX_LUN, SR_REQUEST_TYPE);
device_request.SetBYTE(REQ_BULK_GET_MAX_LUN, SR_REQUEST);
device_request.SetWORD(0, SR_VALUE);
device_request.SetWORD(0, SR_INDEX); // interface number
device_request.SetWORD(1, SR_LENGTH);
bulkCmdProc(1, 8);
return buffer.GetBYTE(0);
}
// ======================================
/*****************************************************
* Clear CBW(Command Block Wrapper)
*
* See USB mass storage class -- Bulk-Inly Transport
*****************************************************/
void initCBW(void) {
int i;
for (i = 0; i < CBW_LENGTH; i++)
cbw.SetBYTE(0, i);
}
/****************************************************
* OUT Transaction -- Send a SCSI command to device
****************************************************/
void scsiCmdProc(void) {
initURB();
urb.SetBYTE(0xe1, URB_TRANSACTION_TOKEN); // out
urb.SetBYTE(devAddr, URB_DEV_ADD);
urb.SetBYTE(outEndpoint, URB_END_POINT);
urb.SetWORD(cbw.GetSegment(), URB_BUFFER_SEG);
urb.SetWORD(cbw.GetOffset(), URB_BUFFER_OFF);
urb.SetWORD(31, URB_BUFFER_LENGTH);
urb.SetWORD(31, URB_ACTUAL_LENGTH);
inregs.x.ds = urb.GetSegment();
inregs.x.dx = urb.GetOffset();
x86_int(0x65, &inregs); // call DosUsb
}
/******************************************
* SCSI Command -- INQUIRY
*
* See SCSI Primary Commands - 3(SPC-3)
******************************************/
void scsiInquiry(void) {
initCBW();
cbw.SetDWORD(0x43425355, CBW_SIGNATURE);
cbw.SetDWORD(++dwTag, CBW_TAG);
cbw.SetDWORD(0x24, CBW_DATA_TRANSFER_LENGTH);
cbw.SetBYTE(0x80, CBW_FLAGS);
cbw.SetBYTE(0, CBW_LUN);
cbw.SetBYTE(6, CBW_CB_LENGTH);
cbw.SetBYTE(SCSI_INQUIRY, CBW_CDB);
cbw.SetDWORD(0x24, CBW_CDB + 4);
scsiCmdProc();
}
/******************************************
* SCSI Command -- READ(10)
*
* See SCSI Block Commands - 2(SBC-2)
******************************************/
void scsiRead10(DWORD dwLba) {
pByte = (BYTE *)&dwLba;
initCBW();
cbw.SetDWORD(0x43425355, CBW_SIGNATURE);
cbw.SetDWORD(++dwTag, CBW_TAG);
cbw.SetDWORD(512, CBW_DATA_TRANSFER_LENGTH); // 512 bytes
cbw.SetBYTE(0x80, CBW_FLAGS); // Data in
cbw.SetBYTE(10, CBW_CB_LENGTH);
cbw.SetBYTE(SCSI_READ10, CBW_CDB); // operation code
cbw.SetBYTE(pByte[3], CBW_CDB + 2); // LBA
cbw.SetBYTE(pByte[2], CBW_CDB + 3);
cbw.SetBYTE(pByte[1], CBW_CDB + 4);
cbw.SetBYTE(pByte[0], CBW_CDB + 5);
cbw.SetBYTE(1, CBW_CDB + 8); // transfer length
scsiCmdProc();
}
/******************************************
* SCSI Command -- READ CAPACITY (10)
*
* See SCSI Block Commands - 2(SBC-2)
******************************************/
void scsiReadCapacity10(void) {
initCBW();
cbw.SetDWORD(0x43425355, CBW_SIGNATURE);
cbw.SetDWORD(++dwTag, CBW_TAG);
cbw.SetDWORD(8, CBW_DATA_TRANSFER_LENGTH); // 8 bytes
cbw.SetBYTE(0x80, CBW_FLAGS); // data in
cbw.SetBYTE(0, CBW_LUN);
cbw.SetBYTE(10, CBW_CB_LENGTH);
cbw.SetBYTE(SCSI_READ_CAPACITY10, CBW_CDB); // OPERATION CODE
scsiCmdProc();
}
/******************************************
* SCSI Command -- REQUEST SENSE
*
* See SCSI Primary Commands - 3(SPC-3)
******************************************/
void scsiRequestSense(void) {
initCBW();
cbw.SetDWORD(0x43425355, CBW_SIGNATURE);
cbw.SetDWORD(++dwTag, CBW_TAG);
cbw.SetDWORD(0x12, CBW_DATA_TRANSFER_LENGTH); // 8 bytes
cbw.SetBYTE(0x80, CBW_FLAGS); // data in
cbw.SetBYTE(0, CBW_LUN);
cbw.SetBYTE(12, CBW_CB_LENGTH);
cbw.SetBYTE(SCSI_REQUEST_SENSE, CBW_CDB); // OPERATION CODE
cbw.SetBYTE(0x12, CBW_CDB + 4); // OPERATION CODE
scsiCmdProc();
}
/******************************************
* SCSI Command -- TEST UNIT READY
*
* See SCSI Primary Commands - 3(SPC-3)
******************************************/
void scsiTestUnitReady(void) {
initCBW();
cbw.SetDWORD(0x43425355, CBW_SIGNATURE);
cbw.SetDWORD(++dwTag, CBW_TAG);
cbw.SetDWORD(0, CBW_DATA_TRANSFER_LENGTH); // 8 bytes
cbw.SetBYTE(0x80, CBW_FLAGS); // data in
cbw.SetBYTE(0, CBW_LUN);
cbw.SetBYTE(6, CBW_CB_LENGTH);
cbw.SetBYTE(SCSI_TEST_UNIT_READY, CBW_CDB); // OPERATION CODE
scsiCmdProc();
}
// ========================================
/*****************************************************
* IN Transaction -- Get data returned from device
* after SCSI command
*****************************************************/
void getData(void) {
initURB();
for (j = 0; j < buffer.GetLength(); j++) buffer.SetBYTE(0, j);
urb.SetBYTE(0x69, URB_TRANSACTION_TOKEN); // in
urb.SetBYTE(devAddr, URB_DEV_ADD);
urb.SetBYTE(inEndpoint, URB_END_POINT);
urb.SetWORD(buffer.GetSegment(), URB_BUFFER_SEG);
urb.SetWORD(buffer.GetOffset(), URB_BUFFER_OFF);
urb.SetWORD(64, URB_BUFFER_LENGTH);
urb.SetWORD(64, URB_ACTUAL_LENGTH);
inregs.x.ds = urb.GetSegment();
inregs.x.dx = urb.GetOffset();
x86_int(0x65, &inregs); // call DosUsb
}
/**************************************************
* Show the meaning of status after calling DOSUSB
**************************************************/
void showStatus(BYTE bStatus) {
printf("Completion code:");
switch (bStatus) {
case 0:
printf("No Error");
break;
case 0x44:
printf("CRC/Data Toggle Mismatch/Device Not Responding/PID Check Failure/Inexpected PID");
break;
case 0x42:
printf("Bit Stuffing");
break;
case 0x40:
printf("Stall");
break;
case 0x50:
printf("Data Overrun");
break;
case 0x20:
printf("Buffer Overrun");
break;
case 0xa0:
printf("Buffer Underrun");
break;
case 0x88:
printf("Not Accessed");
break;
default:
printf("Unknown status: 0X02x", bStatus);
break;
}
}
/*****************************************************
* Get and Show CSW(Command Status Wrapper)
*
* See USB mass storage class -- Bulk-Inly Transport
*****************************************************/
void getCSW(void) {
getData();
printf("\nActual length: %d", urb.GetWORD(URB_ACTUAL_LENGTH));
printf("\nGet CSW: Error Code: %d ", urb.GetBYTE(URB_ERROR_CODE));
showStatus(urb.GetBYTE(URB_STATUS));
printf("\nSignature: 0X%08x Tag: 0X%08x",
buffer.GetDWORD(0), buffer.GetDWORD(4));
printf("\nCSWDataResidue: 0X%08x CSWStatus: 0X%02x",
buffer.GetDWORD(8), buffer.GetDWORD(12));
}
/*****************************************************
* Show data returned from device after SCSI INQUIRY
*****************************************************/
void showInquiryResult(void) {
j = urb.GetBYTE(URB_ACTUAL_LENGTH);
bTemp = buffer.GetBYTE(0);
printf("\nInquiry: URB_Actual_Length = %d\n", j);
printf("\nPeripheral Qualifier: %d Peripheral device type: %d",
(bTemp & 0xe0) >> 5, (bTemp & 0x1f));
printf("\nRemovable medium bit: %d Version: 0X%02x",
(buffer.GetBYTE(1)==0?0:1), buffer.GetBYTE(2));
//(buffer.GetBYTE(1) >> 7), buffer.GetBYTE(2));
bTemp = buffer.GetBYTE(3);
printf("\nNormal ACA supported: %d Hierarchical support bit: %d",
((bTemp & 0x20) >> 5), ((bTemp & 0x10) >> 4));
printf("\nResponse Data Format: %d", bTemp & 0x0f);
printf("\nAdditional Length: %d", buffer.GetBYTE(4));
bTemp = buffer.GetBYTE(5);
printf("\nSCC supported: %d Access Control Coordinator: %d",
(bTemp & 0x80) >> 7, (bTemp & 0x40) >> 6);
printf("\nTarget port group support: %d", (bTemp & 0x30) >> 4);
printf("\nThirty-Party Copy: %d PROTECT: %d\n",
(bTemp & 0x08) >> 3, (bTemp & 0x01));
for (i = 8; i < j; i++) {
if (buffer.GetBYTE(i) != 0) {
putch(buffer.GetBYTE(i));
}
}
}
/**********************************************
* Show data of sector in HEX
**********************************************/
void showData(void) {
printf("\nActual Length of Data: %d\n", urb.GetWORD(URB_ACTUAL_LENGTH));
if (urb.GetWORD(URB_ACTUAL_LENGTH) > 0)
for (j = 0; j < 64; j++) {
printf("%02x ", (UBYTE)buffer.GetBYTE(j));
}
}
// main program
int main() {
devAddr = 1; // device address according to Device Descriptor
inEndpoint = 2;
outEndpoint = 1;
dwTag = 0;
bulkReset();
// ******************************************
printf("\n\n***1st setp: Get max. LUN***");
i = bulkMaxLun();
if (urb.GetBYTE(URB_ERROR_CODE) == 1) {
printf("\n\nInvalid Device Address.\n");
exit(1);
}
if (urb.GetBYTE(URB_STATUS) > 1) {
printf("\n\nDevice does not response.\n");
exit(1);
}
printf("\nActual Length: %d", urb.GetWORD(URB_ACTUAL_LENGTH));
printf("\nLogical Unit: %d", i + 1);
printf("\nPress any key to continue......");
getch();
// *************************************************
printf("\n\n***2nd setp: SCSI INQUIRY command***");
scsiInquiry();
printf("\nError Code: %d ", urb.GetBYTE(URB_ERROR_CODE));
showStatus(urb.GetBYTE(URB_STATUS));
// get INQUIRY result
getData();
printf("\nGet Inquiry Result: Error Code: %d ", urb.GetBYTE(URB_ERROR_CODE));
showStatus(urb.GetBYTE(URB_STATUS));
showInquiryResult();
getCSW();
printf("\nPress any key to continue......");
getch();
// **********************************************
printf("\n\n***3th step: SCSI request sense***");
scsiRequestSense();
printf("\nError Code: %d ", urb.GetBYTE(URB_ERROR_CODE));
showStatus(urb.GetBYTE(URB_STATUS));
getData();
wLen = urb.GetWORD(URB_ACTUAL_LENGTH);
printf("\nActual length: %d", wLen);
printf("\nValid: %d Response Code: 0X%02x",
((buffer.GetBYTE(0) & 0x80) == 0?0:1), (buffer.GetBYTE(0) &0x7f));
printf("\nSense Key: 0x%02x Addition Sense length: %d",
(buffer.GetBYTE(2) & 0x0f), buffer.GetBYTE(7));
getCSW();
printf("\nPress any key to continue......");
getch();
// *************************************************
printf("\n\n***4th step: SCSI Test unit ready***");
scsiTestUnitReady();
printf("\nError Code: %d ", urb.GetBYTE(URB_ERROR_CODE));
showStatus(urb.GetBYTE(URB_STATUS));
getCSW();
printf("\nPress any key to continue......");
getch();
// *******************************************
printf("\n\n***5th step: get capacity***");
scsiReadCapacity10();
printf("\nError Code: %d ", urb.GetBYTE(URB_ERROR_CODE));
showStatus(urb.GetBYTE(URB_STATUS));
getData();
printf("\nActual length: %d", urb.GetWORD(URB_ACTUAL_LENGTH));
pByte = (BYTE *)&dwTemp;
*pByte = buffer.GetBYTE(3);
*(pByte + 1) = buffer.GetBYTE(2);
*(pByte + 2) = buffer.GetBYTE(1);
*(pByte + 3) = buffer.GetBYTE(0);
printf("\nLBA: 0X%08x", dwTemp);
pByte = (BYTE *)&dwTemp;
*pByte = buffer.GetBYTE(7);
*(pByte + 1) = buffer.GetBYTE(6);
*(pByte + 2) = buffer.GetBYTE(5);
*(pByte + 3) = buffer.GetBYTE(4);
printf(" Capacity: 0X%08x", dwTemp);
getCSW();
printf("\nPress any key to continue......");
getch();
// *********************************************
printf("\n\n***6th step: SCSI READ(10) command***");
scsiRead10(0);
printf("\nError Code: %d ", urb.GetBYTE(URB_ERROR_CODE));
showStatus(urb.GetBYTE(URB_STATUS));
for (j = 0; j < buffer.GetLength(); j++) buffer.SetBYTE(0, j);
i = 0;
while (i < 8) {
getData();
if (urb.GetBYTE(URB_STATUS) == 0) {
i++;
showData();
printf("\nPress any to continue...");
getch();
} else if ((UBYTE)urb.GetBYTE(URB_STATUS) != 0X88) {
break;
}
}
getCSW();
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -