|   
yuanchengjun 
新手上路
 
 
 
  
  
积分 8 
发帖 3 
注册 2007-3-22 
状态 离线
 | 
『楼 主』:
 求 DOS USB 编程 帮助 !
 
使用 LLM 解释/回答一下
  
求DOS USB设备 驱动源码,或者例子,或者教程,…… 
不用完整的驱动,例子就可以,比如:一次收发数据包过程。 
Looking for DOS USB device driver source code, or examples, or tutorials,... No need for a complete driver, examples are okay, such as: a process of sending and receiving data packets once. 
    
 
  
 |   
 |  
  2007-4-17 04:57 | 
  
 |  
 |   
yuanchengjun 
新手上路
 
 
 
  
  
积分 8 
发帖 3 
注册 2007-3-22 
状态 离线
 | 
『第 2 楼』:
 自己顶一下
 
使用 LLM 解释/回答一下
  
DOS、C语言不会USB,估计要用汇编。 
 
大侠不吝赐教! 
DOS, C language don't know USB, probably need to use assembly. 
Great expert, please give unsparing advice! 
    
 
  
 |   
 |  
  2007-4-17 04:59 | 
  
 |  
 |   
heling 
新手上路
 
 
 
  
  
积分 18 
发帖 9 
注册 2007-6-2 
状态 离线
 | 
 |  
  2007-6-7 13:02 | 
  
 |  
 |   
kinglin 
初级用户
 
  
 
  
  
积分 62 
发帖 28 
注册 2007-7-3 
状态 离线
 | 
 |  
  2007-7-3 14:33 | 
  
 |  
 |   
windowsvesta 
初级用户
 
  
 
  
 
积分 138 
发帖 67 
注册 2007-7-4 来自 云南 
状态 离线
 | 
 |  
  2007-7-4 11:04 | 
  
 |  
 |   
johnsonlam 
银牌会员
 
      阿林
  
 
积分 1410 
发帖 497 
注册 2004-6-28 来自 九龍,香港 
状态 离线
 | 
 |  
  2007-7-4 12:59 | 
  
 |  
 |   
wzsunlight 
初级用户
 
  
 
  
  
积分 107 
发帖 52 
注册 2007-3-10 
状态 离线
 | 
 |  
  2007-9-11 20:15 | 
  
 |  
 |   
dsysps 
初级用户
 
  
 
  
  
积分 98 
发帖 34 
注册 2006-11-3 
状态 离线
 | 
『第 8 楼』:
 
 
使用 LLM 解释/回答一下
  
我也想知道,正在努力。现在EHCI的基本配置过程理解了 
//通过PCI配置空间检测EHCI 
BYTE SearchEHCI(void) 
{ 
	union REGS	regs; 
	int	bus, dev, func; 
	//WORD Did,Vid; 
	WORD ClassCod,SubClass; 
	for(bus = 0; bus <= PDI_BUS_MAX; ++bus) 
	{ 
		for(dev = 0; dev <= PDI_DEVICE_MAX; ++dev) 
		{ 
			for(func = 0; func <= PDI_FUNCTION_MAX; ++func) 
			{ 
				UsbHostPciAddr = MK_PDI(bus, dev, func);/* 计算地址 */ 
				/* 获取厂商ID */ 
				regs.x.ax = 0xB109; // READ CONFIGURATION WORD 
				regs.x.bx = UsbHostPciAddr; 
				regs.x.di = 0; // Vendor ID 
				regs.x.cx = 0xFFFF; // 非法的Vendor ID 
				int86(0x1A, ®s, ®s); 
 
				/* 判断设备是否存在。FFFFh是非法厂商ID */ 
				if (regs.x.cx != 0xFFFF) 
				{ 
					/* Class Code */ 
					regs.x.ax = 0xB109; // READ CONFIGURATION WORD 
					regs.x.bx = UsbHostPciAddr; 
					regs.x.di = 0xA; // Class 
					int86(0x1A, ®s, ®s); 
					ClassCod=regs.x.cx; 
					if(ClassCod==0x0c03) //usb host 
					{ 
						regs.x.ax = 0xB109; // READ CONFIGURATION WORD 
						regs.x.bx = UsbHostPciAddr; 
						regs.x.di = 8; //SubClass 
						int86(0x1A, ®s, ®s); 
						SubClass=regs.x.cx; 
						if((SubClass&0xff00)==0x2000) 
							return USB_EHCI_CONTROLLER; 
					} 
				} 
			} 
		} 
	} 
	return USB_NULL_CONTROLLER; 
} 
///*设置基地址为0X000D0000*/ 
void CfgBaseAddr(void) 
{ 
	union REGS	regs; 
	regs.x.ax = 0xB10c; //WRITE CONFIGURATION WORD 
	regs.x.bx = UsbHostPciAddr; 
	regs.x.di = 0X10; 
	regs.x.cx = 0; 
	int86(0x1A, ®s, ®s); 
	regs.x.ax = 0xB10c; // WRITE CONFIGURATION WORD 
	regs.x.bx = UsbHostPciAddr; 
	regs.x.di = 0X12; 
	regs.x.cx = 0X000D; 
	int86(0x1A, ®s, ®s); 
} 
......... 
I also want to know, and I'm working hard. Now I understand the basic configuration process of EHCI 
//Detect EHCI through PCI configuration space 
BYTE SearchEHCI(void) 
{ 
	union REGS	regs; 
	int	bus, dev, func; 
	//WORD Did,Vid; 
	WORD ClassCod,SubClass; 
	for(bus = 0; bus <= PDI_BUS_MAX; ++bus) 
	{ 
		for(dev = 0; dev <= PDI_DEVICE_MAX; ++dev) 
		{ 
			for(func = 0; func <= PDI_FUNCTION_MAX; ++func) 
			{ 
				UsbHostPciAddr = MK_PDI(bus, dev, func);/* Calculate address */ 
				/* Get vendor ID */ 
				regs.x.ax = 0xB109; // READ CONFIGURATION WORD 
				regs.x.bx = UsbHostPciAddr; 
				regs.x.di = 0; // Vendor ID 
				regs.x.cx = 0xFFFF; // Invalid vendor ID 
				int86(0x1A, ®s, ®s); 
 
				/* Determine if the device exists. FFFFh is an invalid vendor ID */ 
				if (regs.x.cx != 0xFFFF) 
				{ 
					/* Class Code */ 
					regs.x.ax = 0xB109; // READ CONFIGURATION WORD 
					regs.x.bx = UsbHostPciAddr; 
					regs.x.di = 0xA; // Class 
					int86(0x1A, ®s, ®s); 
					ClassCod=regs.x.cx; 
					if(ClassCod==0x0c03) //usb host 
					{ 
						regs.x.ax = 0xB109; // READ CONFIGURATION WORD 
						regs.x.bx = UsbHostPciAddr; 
						regs.x.di = 8; //SubClass 
						int86(0x1A, ®s, ®s); 
						SubClass=regs.x.cx; 
						if((SubClass&0xff00)==0x2000) 
							return USB_EHCI_CONTROLLER; 
					} 
				} 
			} 
		} 
	} 
	return USB_NULL_CONTROLLER; 
} 
///*Set base address to 0X000D0000*/ 
void CfgBaseAddr(void) 
{ 
	union REGS	regs; 
	regs.x.ax = 0xB10c; //WRITE CONFIGURATION WORD 
	regs.x.bx = UsbHostPciAddr; 
	regs.x.di = 0X10; 
	regs.x.cx = 0; 
	int86(0x1A, ®s, ®s); 
	regs.x.ax = 0xB10c; // WRITE CONFIGURATION WORD 
	regs.x.bx = UsbHostPciAddr; 
	regs.x.di = 0X12; 
	regs.x.cx = 0X000D; 
	int86(0x1A, ®s, ®s); 
} 
......... 
    
 
  
 |   
 |  
  2007-10-23 17:15 | 
  
 |  
 |   
phtsai63 
新手上路
 
 
 
  
  
积分 6 
发帖 3 
注册 2007-10-24 
状态 离线
 | 
『第 9 楼』:
 
 
使用 LLM 解释/回答一下
  
Dos USB 用 Basic 寫的, 而且只 support OHCI and UHCI. 
希望樓上的能造福大眾. 
Dos USB is written in Basic and only supports OHCI and UHCI. Hope the above can benefit the public. 
    
 
  
 |   
 |  
  2007-10-24 11:13 | 
  
 |  
 |   
winson4829 
初级用户
 
  
 
  
  
积分 58 
发帖 17 
注册 2008-3-2 
状态 离线
 | 
『第 10 楼』:
 
 
使用 LLM 解释/回答一下
  
開發環境使用 DJGPP + FreeDOS + DPMI + DOSUSB 的驅動程式 ( http://www.dosusb.net)
 
請參考  http://www.dosusb.net 內的論壇內容, 不同的 USB CHIP 不保證一定成功, 
 
但我的環境下列我寫的 SOURCE CODE 是 OK 的
 檔案名稱 : W6USBCOM.h
 
#ifndef TW6USBCOM_H 
#define TW6USBCOM_H 
 
#ifndef BYTE 
    #define BYTE    unsigned char 
#endif 
 
#ifndef WORD 
    #define WORD    unsigned short int 
#endif 
 
#ifdef __cplusplus 
   extern "C" { 
#endif 
 
void 	W6USBComReset(void); 
WORD    W6USBComDataIn(void); 
int     W6USBComDataOut(char *szData, int nCount); 
int     W6USBComGetCoding(void); 
int     W6USBComSetCoding(void); 
int     W6USBComSetState(void); 
 
#ifdef __cplusplus 
   } 
#endif 
 
#endif 
 
檔案名稱 : W6USBCOM.C
 
// -------------------------------------------------------------------- 
// 1. 需在 autoexec.bat 下啟動 USBDOS.COM 
// 2. 設計文件請參考 USBDOS 的 Home Page 或 USBDOS\SAMPLES 
// 3. USBDOS.COM 內定 InterruptVector = 0x65 
// 4. USBDOS.COM /D 可啟動偵錯模式 (USBDOS.LOG) 
// 5. urb.status bit 定義如下 : 
// Bit 0: Reserved,  
// Bit 1: Bitstuff error  
// Bit 2: CRC/Timeout  
// Bit 3: NAK 
// Bit 4: Babble detected  
// Bit 5: Data Buffer error  
// Bit 6: Stalled 
// Bit 7: Active 
// Ex.	88 hex means a NAK received, since the active bit is set the data 
//      packet can be retried, 44 hex means a CRC/Timeout error which caused a stall. 
//      The device may need a reset. 
//      The OHCI controller returns different completion codes than the UHCI 
//      controller. To simplify driver development, the DOSUSB driver translates the 
//      OHCI completion codes to UHCI status codes. However, in the dosusb.log file 
//      the OHCI codes are specified. 
//      OHCI completion code 1 is translated to 44h, 2 to 42h, 3 to 44h, 4 to 40h, 
//      5,6 and 7 to 44h, 8 to 50h, 9 to 00h, 12 to 20h, 13 to A0h and 14 to 88h. 
// -------------------------------------------------------------------- 
 
#include <stdlib.h> 
#include <stdio.h> 
#include <conio.h> 
#include <signal.h> 
 
#include "USBCom.h" 
 
#define __PACKED__	__attribute__ ((packed)) 
 
#define C4USBInterruptVector	0x65 
 
int gnDevAdd		=1; 
int gnInEndpoint	=3; 
int gnOutEndpoint	=2; 
 
typedef struct 
{ 
	BYTE  transaction_token __PACKED__ ; 
	BYTE  chain_end_flag  	__PACKED__ ; 
	BYTE  dev_add 			__PACKED__ ; 
	BYTE  end_point 		__PACKED__ ; 
	BYTE  error_code 		__PACKED__ ; 
	BYTE  status 			__PACKED__ ; 
	WORD  transaction_flags __PACKED__ ; 
	WORD  buffer_off 		__PACKED__ ;   
	WORD  buffer_seg 		__PACKED__ ;   
	WORD  buffer_length 	__PACKED__ ;   
	WORD  actual_length 	__PACKED__ ;   
	WORD  setup_buffer_off 	__PACKED__ ;  
	WORD  setup_buffer_seg 	__PACKED__ ;  
	WORD  start_frame 		__PACKED__ ;   
	WORD  nr_of_packets 	__PACKED__ ;   
	BYTE  int_interval 		__PACKED__ ;   
	BYTE  error_count 		__PACKED__ ;   
	WORD  timeout 			__PACKED__ ;   
	WORD  next_urb_off 		__PACKED__ ;   
	WORD  next_urb_seg 		__PACKED__ ;   
} TURBType; 
 
typedef struct 
{ 
	BYTE bmRequestType	__PACKED__;  
	BYTE bRequest		__PACKED__;  
	WORD wValue			__PACKED__;  
	WORD wIndex			__PACKED__;  
	WORD wLength		__PACKED__;  
}  TDeviceRequest; 
 
char	gszUSBDataIn; 
 
//************************************************************************************************* 
int main(int argc, char *argv) 
{ 
    #ifndef ALLEGRO_MINGW32 
	    int     i, n, k; 
	    int     nInEndpoint; 
	    char	szData; 
 
		if(!__djgpp_nearptr_enable())  
		{ 
			printf("!__djgpp_nearptr_enable()"); 
			return(0); 
		}		 
	     
	    if(W6USBComSetCoding()!=0) 	return(0); 
	    if(W6USBComGetCoding()!=0) 	return(0); 
	    if(W6USBComSetState()!=0) 	return(0); 
 
	    printf("Simple TTY-Terminal at 38.400 baud - press ESC to exit\n"); 
 
	    nInEndpoint   	= gnInEndpoint; 
	    gnInEndpoint  	= 1; 
	    if( (n= W6USBComDataIn())>0 ) 
	    { 
		    printf("Line status in hex: \n"); 
		    for(i=0;i<2;i++) 
		    { 
		        printf("%.2X ",gszUSBDataIn); 
		    } 
	    }	     
	    gnInEndpoint=nInEndpoint; 
 
	    for(k=0;k<30;k++) 
	    { 
	        // 接收內容 
	        if((n=W6USBComDataIn())>0) 
	        { 
	            printf("urb.actual_length = %d\n", n); 
	            for(i=0;i<n;i++) printf("%c", gszUSBDataIn); 
	            printf("\n"); 
	        } 
 
			szData = 'A'; 
			szData = 0x00; 
	        W6USBComDataOut(szData,1);          // 送出 'A' 
	        delay(1000); 
	    } 
	#else 
		return(0); 
    #endif 
} 
 
 
// ************************************************************************************************* 
WORD W6USBComDataIn() 
{ 
    #ifndef ALLEGRO_MINGW32 
		__dpmi_regs  	regs; 
		TURBType		urb; 
	         
	    // set up in request 
	    urb.transaction_token	=0x69; 
	    urb.chain_end_flag		=0; 
	    urb.dev_add				=gnDevAdd; 
	    urb.end_point			=gnInEndpoint; 
	    urb.error_code			=0; 
	    urb.status				=0; 
	    urb.transaction_flags	=0; 
	    urb.buffer_seg			=(__tb+64) >> 4;			// __tb 定義在 go32.h 為一個1024K內實體記錄位址 
	    urb.buffer_off			=(__tb+64) &  0x0F; 
	    urb.buffer_length		=64; 
	    urb.actual_length		=64; 
	    urb.setup_buffer_off	=0; 
	    urb.setup_buffer_seg	=0; 
	    urb.start_frame			=0; 
	    urb.nr_of_packets		=0; 
	    urb.int_interval		=0; 
	    urb.error_count			=0; 
	    urb.timeout				=0; 
	    urb.next_urb_off		=0; 
	    urb.next_urb_seg		=0; 
 
		// 將 urb 填入 __tb 
		dosmemput((char *)&urb, sizeof(urb), __tb); 
 
	    // registor : Flags = 0: AX = 1: BX = 2: CX = 3: DX = 4: SI = 5: DI = 6 BP = 7: DS = 8: ES = 9 
	    regs.x.ds = __tb >> 4; 
	    regs.x.dx = __tb &  0x0F; 
	    __dpmi_int (C4USBInterruptVector, ®s);           // call DosUHCI 
 
		// 將 __tb 回傳的資料填到 urb 
	    dosmemget (__tb, sizeof(urb), (char *)&urb);   
 
		// invalid device address? 
		if (urb.error_code==1) 	return(0); 
 
		// transaction error? 
		if(urb.status > 1)		return(0);		 
 
		// 將 __tb 回傳的資料填到 gszUSBDataIn 
		if(urb.actual_length>0) dosmemget (__tb+64, urb.actual_length, gszUSBDataIn);  
 
		return(urb.actual_length); 
	#else 
		return(0); 
    #endif 
} 
 
// 0 : success 
// 1 : Invalid device address 
// 2 : transaction error? 
int W6USBComDataOut(char *szData, int nCount) 
{ 
    #ifndef ALLEGRO_MINGW32 
		__dpmi_regs 	regs; 
		TURBType		urb; 
		char			szTmp; 
 
		// 把 szData 的資料指定到 __tb+64 位置 
		if(nCount==0) nCount=strlen(szData); 
		if(nCount==0) return(0); 
 
 
		dosmemput(szData, nCount, __tb+64); 
		 
		// outputs data in buffer 
		// set up out request 
		urb.transaction_token	=0xE1; 
		urb.chain_end_flag		=0; 
		urb.dev_add				=gnDevAdd; 
		urb.end_point			=gnOutEndpoint; 
		urb.error_code			=0; 
		urb.status				=0; 
		urb.transaction_flags	=0; 
	    urb.buffer_seg			=(__tb+64) >> 4;			// __tb 定義在 go32.h 為一個1024K內實體記錄位址 
	    urb.buffer_off			=(__tb+64) &  0x0F; 
		urb.buffer_length		=nCount; 
		urb.actual_length		=64; 
		urb.setup_buffer_off	=0; 
		urb.setup_buffer_seg	=0; 
		urb.start_frame			=0; 
		urb.nr_of_packets		=0; 
		urb.int_interval		=0; 
		urb.error_count			=0; 
		urb.timeout				=0; 
		urb.next_urb_off		=0; 
		urb.next_urb_seg		=0; 
 
		// 將 urb 填入 __tb 
		dosmemput((char *)&urb, sizeof(urb), __tb); 
 
	    // registor : Flags = 0: AX = 1: BX = 2: CX = 3: DX = 4: SI = 5: DI = 6 BP = 7: DS = 8: ES = 9 
	    regs.x.ds = __tb >> 4; 
	    regs.x.dx = __tb &  0x0F; 
	    __dpmi_int (C4USBInterruptVector, ®s);           // call DosUHCI 
 
		// 將 __tb 回傳的資料填到 urb 
	    dosmemget (__tb, sizeof(urb), (char *)&urb);   
 
		// invalid device address? 
		if (urb.error_code==1) 	return(urb.error_code); 
 
		// transaction error? 
		if(urb.status > 1)		return(urb.status); 
 
	    return(0); 
	#else 
		return(0); 
    #endif 
} 
 
// 0 : success 
// 1 : Invalid device address 
// 2 : transaction error? 
int W6USBComGetCoding() 
{ 
    #ifndef ALLEGRO_MINGW32 
		__dpmi_regs  	regs; 
		TDeviceRequest	device_request; 
		TURBType		urb; 
 
		device_request.bmRequestType=0xA1; 
		device_request.bRequest		=0x21; 
		device_request.wValue		=0x00; 
		device_request.wIndex		=0; 
		device_request.wLength		=0x7; 
 
		// 把 device_request 的資料指定到 __tb+128 位置 
		dosmemput((char *)&device_request, sizeof(device_request), __tb+128); 
 
		// set up get Line Coding request 
		urb.transaction_token	=0x2D; 
		urb.chain_end_flag		=0; 
		urb.dev_add				=gnDevAdd; 
		urb.end_point			=0; 
		urb.error_code			=0; 
		urb.status				=0; 
		urb.transaction_flags	=0; 
	    urb.buffer_seg			=(__tb+64) >> 4;			// __tb 定義在 go32.h 為一個1024K內實體記錄位址 
	    urb.buffer_off			=(__tb+64) &  0x0F; 
		urb.buffer_length		=18; 
		urb.actual_length		=64; 
		urb.setup_buffer_seg	=(__tb+128) >> 4;			// device_request segment 
		urb.setup_buffer_off	=(__tb+128) &  0x0F;		// device_request offset 
		urb.start_frame			=0; 
		urb.nr_of_packets		=0; 
		urb.int_interval		=0; 
		urb.error_count			=0; 
		urb.timeout				=0; 
		urb.next_urb_seg		=0; 
		urb.next_urb_off		=0; 
 
		// 將 urb 填入 __tb 
		dosmemput((char *)&urb, sizeof(urb), __tb);	 
 
	    // registor : Flags = 0: AX = 1: BX = 2: CX = 3: DX = 4: SI = 5: DI = 6 BP = 7: DS = 8: ES = 9 
	    regs.x.ds = __tb >> 4; 
	    regs.x.dx = __tb &  0x0F; 
	    __dpmi_int (C4USBInterruptVector, ®s);           // call DosUHCI 
 
		// 將 __tb 回傳的資料填到 urb 
	    dosmemget (__tb, sizeof(urb), (char *)&urb);   
		 
		// invalid device address? 
		if (urb.error_code==1) 	return(urb.error_code); 
 
		// transaction error? 
		if(urb.status > 1)		return(urb.status); 
 
	    return(0); 
	#else 
		return(0); 
    #endif 
 
} 
 
// 0 : success 
// 1 : Invalid device address 
// 2 : transaction error? 
int W6USBComSetCoding() 
{ 
    #ifndef ALLEGRO_MINGW32 
		__dpmi_regs  	regs; 
	    int 			nInEndpoint; 
	    int 			nOutEndpoint; 
	    char			szData; 
	    int				nDataLen; 
		TDeviceRequest  device_request; 
		TURBType		urb;     
	         
		device_request.bmRequestType=0x21; 
		device_request.bRequest	=0x20; 
		device_request.wValue	=0x00; 
		device_request.wIndex	=0; 
		device_request.wLength	=0x7; 
 
		// 把 device_request 的資料指定到 __tb+128 位置 
		dosmemput((char *)&device_request, sizeof(device_request), __tb+128); 
 
		// set up get Line Coding request 
		urb.transaction_token	=0x2D; 
		urb.chain_end_flag		=0; 
		urb.dev_add				=gnDevAdd; 
		urb.end_point			=0; 
		urb.error_code			=0; 
		urb.status				=0; 
		urb.transaction_flags	=0; 
		urb.buffer_seg			=0; //varseg(buffer) 
		urb.buffer_off			=0; //varptr(buffer) 
		urb.buffer_length		=0; 
		urb.actual_length		=0; 
		urb.setup_buffer_seg	=(__tb+128) >> 4;			// device_request segment 
		urb.setup_buffer_off	=(__tb+128) &  0x0F;		// device_request offset 
		urb.start_frame			=0; 
		urb.nr_of_packets		=0; 
		urb.int_interval		=0; 
		urb.error_count			=0; 
		urb.timeout				=0; 
		urb.next_urb_seg		=0; 
		urb.next_urb_off		=0; 
 
		// 將 urb 填入 __tb 
		dosmemput((char *)&urb, sizeof(urb), __tb); 
		 
		// registor : Flags = 0: AX = 1: BX = 2: CX = 3: DX = 4: SI = 5: DI = 6 BP = 7: DS = 8: ES = 9 
	    regs.x.ds = __tb >> 4; 
	    regs.x.dx = __tb &  0x0F; 
		__dpmi_int (C4USBInterruptVector, ®s);           // call DosUHCI 
 
		// 將 __tb 回傳的資料填到 urb 
	    dosmemget (__tb, sizeof(urb), (char *)&urb);   
 
		// invalid device address? 
		if (urb.error_code==1) 	return(urb.error_code); 
 
		// transaction error? 
		if(urb.status > 1)		return(urb.status); 
 
		// now send line coding structure - 38400 baud 8-N-1 
		nInEndpoint = gnInEndpoint; 
		nOutEndpoint= gnOutEndpoint; 
		// 0x1C200	=115200 
		// 0xE100	=57600 
		// 0x9600	=38400 
		// 0x4B00	=19200 
		// 0x2580	=9600 
		// 0x12C0	=4800 
		// 0x0960	=2400 
		// 0x04B0	=1200 
		// --> chr$(0x00)+chr$(0x96) = 0x9600 (little endian) = 38400 baud 
		// --> chr$(8) = 8bit 
		szData 		= 0x00; 
		szData 		= 0x96; 
		szData 		= 0x00; 
		szData 		= 0x00; 
		szData 		= 0x00; 
		szData 		= 0x00; 
		szData 		= 0x08; 
		nDataLen		= 7; 
 
		gnOutEndpoint 	= 0; 
		W6USBComDataOut(szData, nDataLen); 
 
		gnInEndpoint	= 0; 
		W6USBComDataIn(); 
 
		gnInEndpoint    = nInEndpoint; 
		gnOutEndpoint   = nOutEndpoint; 
 
		return(0); 
	#else 
		return(0); 
    #endif 
} 
 
// 0 : success 
// 1 : Invalid device address 
// 2 : transaction error? 
int W6USBComSetState() 
{ 
    #ifndef ALLEGRO_MINGW32 
        __dpmi_regs  	regs; 
		TDeviceRequest  device_request; 
		TURBType		urb; 
     
		device_request.bmRequestType=0x21; 
		device_request.bRequest		=0x22; 
		device_request.wValue		=0x03; 
		device_request.wIndex		=0; 
		device_request.wLength		=0x00 
 
		// 把 device_request 的資料指定到 __tb+128 位置 
		dosmemput((char *)&device_request, sizeof(device_request), __tb+128); 
 
		// set up request 
		urb.transaction_token	=0x2D; 
		urb.chain_end_flag		=0; 
		urb.dev_add				=gnDevAdd; 
		urb.end_point			=0; 
		urb.error_code			=0; 
		urb.status				=0; 
		urb.transaction_flags	=0; 
		urb.buffer_seg			=(__tb+64) >> 4; 
		urb.buffer_off			=(__tb+64) &  0x0F; 
		urb.buffer_length		=0; 
		urb.actual_length		=0; 
		urb.setup_buffer_seg	=(__tb+128) >> 4;			// device_request segment 
		urb.setup_buffer_off	=(__tb+128) &  0x0F;		// device_request offset 
		urb.start_frame			=0; 
		urb.nr_of_packets		=0; 
		urb.int_interval		=0; 
		urb.error_count			=0; 
		urb.timeout				=0; 
		urb.next_urb_seg		=0; 
		urb.next_urb_off		=0; 
 
		// 將 urb 填入 __tb 
		dosmemput((char *)&urb, sizeof(urb), __tb); 
	 
		// registor : Flags = 0: AX = 1: BX = 2: CX = 3: DX = 4: SI = 5: DI = 6 BP = 7: DS = 8: ES = 9 
    	regs.x.ds = __tb >> 4; 
	    regs.x.dx = __tb &  0x0F; 
		__dpmi_int (C4USBInterruptVector, ®s);           // call DosUHCI 
 
		// 將 __tb 回傳的資料填到 urb 
    	dosmemget (__tb, sizeof(urb), (char *)&urb);   
 
		// invalid device address? 
		if (urb.error_code==1) 	return(urb.error_code); 
 
		// transaction error? 
		if(urb.status > 1)		return(urb.status); 
 
		// success 
		return(0); 
	#else 
		return(0); 
    #endif 
 
} 
 
void W6USBComReset() 
{ 
    #ifndef ALLEGRO_MINGW32 
        __dpmi_regs  	regs; 
		TURBType		urb; 
     
		// set up request 
		urb.transaction_token	=0xFF;						// 0xFF 為 Reset token (參考 USBDOS.htm) 
		urb.chain_end_flag		=0; 
		urb.dev_add				=gnDevAdd;					// 0 : 表全部 
		urb.end_point			=0; 
		urb.error_code			=0; 
		urb.status				=0; 
		urb.transaction_flags	=0; 
		urb.buffer_seg			=0; 
		urb.buffer_off			=0; 
		urb.buffer_length		=0; 
		urb.actual_length		=0; 
		urb.setup_buffer_seg	=0;		 
		urb.setup_buffer_off	=0;		 
		urb.start_frame			=0; 
		urb.nr_of_packets		=0; 
		urb.int_interval		=0; 
		urb.error_count			=0; 
		urb.timeout				=0; 
		urb.next_urb_seg		=0; 
		urb.next_urb_off		=0; 
 
		// 將 urb 填入 __tb 
		dosmemput((char *)&urb, sizeof(urb), __tb); 
		 
		// registor : Flags = 0: AX = 1: BX = 2: CX = 3: DX = 4: SI = 5: DI = 6 BP = 7: DS = 8: ES = 9 
		regs.x.ax = 1;										// 1 : Reset command (USBDOS.HTM) 
    	regs.x.ds = __tb >> 4; 
	    regs.x.dx = __tb &  0x0F; 
		__dpmi_int (C4USBInterruptVector, ®s);           // call DosUHCI 
    #endif 
} 
 
 
int W6USBComDeviceDescriptor() 
{ 
    #ifndef ALLEGRO_MINGW32 
        __dpmi_regs  	regs; 
		TDeviceRequest  device_request; 
		TURBType		urb; 
     
		device_request.bmRequestType	= 0x80; 
		device_request.bRequest 		= 6; 
		device_request.wValue 			= 0x100; 
		device_request.wIndex 			= 0; 
		device_request.wLength 			= 8; 
 
		// 把 device_request 的資料指定到 __tb+128 位置 
		dosmemput((char *)&device_request, sizeof(device_request), __tb+128); 
 
		// set up request 
		urb.transaction_token	=0x2D; 
		urb.chain_end_flag		=0; 
		urb.dev_add				=gnDevAdd; 
		urb.end_point			=0; 
		urb.error_code			=0; 
		urb.status				=0; 
		urb.transaction_flags	=0; 
		urb.buffer_seg			=(__tb+64) >> 4; 
		urb.buffer_off			=(__tb+64) &  0x0F; 
		urb.buffer_length		=8; 
		urb.actual_length		=8; 
		urb.setup_buffer_seg	=(__tb+128) >> 4;			// device_request segment 
		urb.setup_buffer_off	=(__tb+128) &  0x0F;		// device_request offset 
		urb.start_frame			=0; 
		urb.nr_of_packets		=0; 
		urb.int_interval		=0; 
		urb.error_count			=0; 
		urb.timeout				=0; 
		urb.next_urb_seg		=0; 
		urb.next_urb_off		=0; 
 
		// 將 urb 填入 __tb 
		dosmemput((char *)&urb, sizeof(urb), __tb); 
	 
		// registor : Flags = 0: AX = 1: BX = 2: CX = 3: DX = 4: SI = 5: DI = 6 BP = 7: DS = 8: ES = 9 
    	regs.x.ds = __tb >> 4; 
	    regs.x.dx = __tb &  0x0F; 
		__dpmi_int (C4USBInterruptVector, ®s);           // call DosUHCI 
 
		// 將 __tb 回傳的資料填到 urb 
    	dosmemget (__tb, sizeof(urb), (char *)&urb);   
 
		// invalid device address? 
		if (urb.error_code==1) 	return(urb.error_code); 
 
		// transaction error? 
		if(urb.status > 1)		return(urb.status); 
 
		// 將 __tb 回傳的資料填到 gszUSBDataIn 
		if(urb.actual_length>0) dosmemget (__tb+64, urb.actual_length, gszUSBDataIn);  
 
		// 會回應 8 個 BYTES 
		printf("\n\nDevice Descriptor:"); 
		printf("\nLength:                %d",			gszUSBDataIn); 
		printf("\nDescriptor type:       %d",			gszUSBDataIn); 
		printf("\nUSB specification nr.: %02X%02X hex",	gszUSBDataIn,gszUSBDataIn); 
		printf("\nClass code:            %d",			gszUSBDataIn); 
		printf("\nSubclass code:         %d",			gszUSBDataIn); 
		printf("\nProtocol code:         %d",			gszUSBDataIn); 
		printf("\nMax Packet size:       %d\n",			gszUSBDataIn); 
	 
		// success 
		return(0); 
	#else 
		return(0); 
    #endif 
} 
  
Development environment uses DJGPP + FreeDOS + DPMI + DOSUSB driver ( http://www.dosusb.net)
 
Please refer to the forum content in  http://www.dosusb.net. Different USB CHIPs are not guaranteed to be successful, 
 
But in my environment, the SOURCE CODE I wrote is OK
 File name: W6USBCOM.h
 
#ifndef TW6USBCOM_H 
#define TW6USBCOM_H 
 
#ifndef BYTE 
    #define BYTE    unsigned char 
#endif 
 
#ifndef WORD 
    #define WORD    unsigned short int 
#endif 
 
#ifdef __cplusplus 
   extern "C" { 
#endif 
 
void 	W6USBComReset(void); 
WORD    W6USBComDataIn(void); 
int     W6USBComDataOut(char *szData, int nCount); 
int     W6USBComGetCoding(void); 
int     W6USBComSetCoding(void); 
int     W6USBComSetState(void); 
 
#ifdef __cplusplus 
   } 
#endif 
 
#endif 
 
File name: W6USBCOM.C
 
// -------------------------------------------------------------------- 
// 1. USBDOS.COM needs to be started in autoexec.bat 
// 2. For design files, please refer to the Home Page of USBDOS or USBDOS\SAMPLES 
// 3. USBDOS.COM has the default InterruptVector = 0x65 
// 4. USBDOS.COM /D can start the debug mode (USBDOS.LOG) 
// 5. Definition of urb.status bit is as follows: 
// Bit 0: Reserved,  
// Bit 1: Bitstuff error  
// Bit 2: CRC/Timeout  
// Bit 3: NAK 
// Bit 4: Babble detected  
// Bit 5: Data Buffer error  
// Bit 6: Stalled 
// Bit 7: Active 
// Ex.	88 hex means a NAK received, since the active bit is set the data 
//      packet can be retried, 44 hex means a CRC/Timeout error which caused a stall. 
//      The device may need a reset. 
//      The OHCI controller returns different completion codes than the UHCI 
//      controller. To simplify driver development, the DOSUSB driver translates the 
//      OHCI completion codes to UHCI status codes. However, in the dosusb.log file 
//      the OHCI codes are specified. 
//      OHCI completion code 1 is translated to 44h, 2 to 42h, 3 to 44h, 4 to 40h, 
//      5,6 and 7 to 44h, 8 to 50h, 9 to 00h, 12 to 20h, 13 to A0h and 14 to 88h. 
// -------------------------------------------------------------------- 
 
#include <stdlib.h> 
#include <stdio.h> 
#include <conio.h> 
#include <signal.h> 
 
#include "USBCom.h" 
 
#define __PACKED__	__attribute__ ((packed)) 
 
#define C4USBInterruptVector	0x65 
 
int gnDevAdd		=1; 
int gnInEndpoint	=3; 
int gnOutEndpoint	=2; 
 
typedef struct 
{ 
	BYTE  transaction_token __PACKED__ ; 
	BYTE  chain_end_flag  	__PACKED__ ; 
	BYTE  dev_add 			__PACKED__ ; 
	BYTE  end_point 		__PACKED__ ; 
	BYTE  error_code 		__PACKED__ ; 
	BYTE  status 			__PACKED__ ; 
	WORD  transaction_flags __PACKED__ ; 
	WORD  buffer_off 		__PACKED__ ;   
	WORD  buffer_seg 		__PACKED__ ;   
	WORD  buffer_length 	__PACKED__ ;   
	WORD  actual_length 	__PACKED__ ;   
	WORD  setup_buffer_off 	__PACKED__ ;  
	WORD  setup_buffer_seg 	__PACKED__ ;  
	WORD  start_frame 		__PACKED__ ;   
	WORD  nr_of_packets 	__PACKED__ ;   
	BYTE  int_interval 		__PACKED__ ;   
	BYTE  error_count 		__PACKED__ ;   
	WORD  timeout 			__PACKED__ ;   
	WORD  next_urb_off 		__PACKED__ ;   
	WORD  next_urb_seg 		__PACKED__ ;   
} TURBType; 
 
typedef struct 
{ 
	BYTE bmRequestType	__PACKED__;  
	BYTE bRequest		__PACKED__;  
	WORD wValue			__PACKED__;  
	WORD wIndex			__PACKED__;  
	WORD wLength		__PACKED__;  
}  TDeviceRequest; 
 
char	gszUSBDataIn; 
 
//************************************************************************************************* 
int main(int argc, char *argv) 
{ 
    #ifndef ALLEGRO_MINGW32 
	    int     i, n, k; 
	    int     nInEndpoint; 
	    char	szData; 
 
		if(!__djgpp_nearptr_enable())  
		{ 
			printf("!__djgpp_nearptr_enable()"); 
			return(0); 
		}		 
	     
	    if(W6USBComSetCoding()!=0) 	return(0); 
	    if(W6USBComGetCoding()!=0) 	return(0); 
	    if(W6USBComSetState()!=0) 	return(0); 
 
	    printf("Simple TTY-Terminal at 38.400 baud - press ESC to exit\n"); 
 
	    nInEndpoint   	= gnInEndpoint; 
	    gnInEndpoint  	= 1; 
	    if( (n= W6USBComDataIn())>0 ) 
	    { 
		    printf("Line status in hex: \n"); 
		    for(i=0;i<2;i++) 
		    { 
		        printf("%.2X ",gszUSBDataIn); 
		    } 
	    }	     
	    gnInEndpoint=nInEndpoint; 
 
	    for(k=0;k<30;k++) 
	    { 
	        // Receive content 
	        if((n=W6USBComDataIn())>0) 
	        { 
	            printf("urb.actual_length = %d\n", n); 
	            for(i=0;i<n;i++) printf("%c", gszUSBDataIn); 
	            printf("\n"); 
	        } 
 
			szData = 'A'; 
			szData = 0x00; 
	        W6USBComDataOut(szData,1);          // Send 'A' 
	        delay(1000); 
	    } 
	#else 
		return(0); 
    #endif 
} 
 
 
// ************************************************************************************************* 
WORD W6USBComDataIn() 
{ 
    #ifndef ALLEGRO_MINGW32 
		__dpmi_regs  	regs; 
		TURBType		urb; 
	         
	    // set up in request 
	    urb.transaction_token	=0x69; 
	    urb.chain_end_flag		=0; 
	    urb.dev_add				=gnDevAdd; 
	    urb.end_point			=gnInEndpoint; 
	    urb.error_code			=0; 
	    urb.status				=0; 
	    urb.transaction_flags	=0; 
	    urb.buffer_seg			=(__tb+64) >> 4;			// __tb is defined in go32.h as a physical address record within 1024K 
	    urb.buffer_off			=(__tb+64) &  0x0F; 
	    urb.buffer_length		=64; 
	    urb.actual_length		=64; 
	    urb.setup_buffer_off	=0; 
	    urb.setup_buffer_seg	=0; 
	    urb.start_frame			=0; 
	    urb.nr_of_packets		=0; 
	    urb.int_interval		=0; 
	    urb.error_count			=0; 
	    urb.timeout				=0; 
	    urb.next_urb_off		=0; 
	    urb.next_urb_seg		=0; 
 
		// Fill urb into __tb 
		dosmemput((char *)&urb, sizeof(urb), __tb); 
 
	    // Register : Flags = 0: AX = 1: BX = 2: CX = 3: DX = 4: SI = 5: DI = 6 BP = 7: DS = 8: ES = 9 
	    regs.x.ds = __tb >> 4; 
	    regs.x.dx = __tb &  0x0F; 
	    __dpmi_int (C4USBInterruptVector, ®s);           // call DosUHCI 
 
		// Fill the data returned by __tb into urb 
	    dosmemget (__tb, sizeof(urb), (char *)&urb);   
 
		// invalid device address? 
		if (urb.error_code==1) 	return(0); 
 
		// transaction error? 
		if(urb.status > 1)		return(0);		 
 
		// Fill the data returned by __tb into gszUSBDataIn 
		if(urb.actual_length>0) dosmemget (__tb+64, urb.actual_length, gszUSBDataIn);  
 
		return(urb.actual_length); 
	#else 
		return(0); 
    #endif 
} 
 
// 0 : success 
// 1 : Invalid device address 
// 2 : transaction error? 
int W6USBComDataOut(char *szData, int nCount) 
{ 
    #ifndef ALLEGRO_MINGW32 
		__dpmi_regs 	regs; 
		TURBType		urb; 
		char			szTmp; 
 
		// Specify the data of szData to the __tb+64 position 
		if(nCount==0) nCount=strlen(szData); 
		if(nCount==0) return(0); 
 
 
		dosmemput(szData, nCount, __tb+64); 
		 
		// outputs data in buffer 
		// set up out request 
		urb.transaction_token	=0xE1; 
		urb.chain_end_flag		=0; 
		urb.dev_add				=gnDevAdd; 
		urb.end_point			=gnOutEndpoint; 
		urb.error_code			=0; 
		urb.status				=0; 
		urb.transaction_flags	=0; 
	    urb.buffer_seg			=(__tb+64) >> 4;			// __tb is defined in go32.h as a physical address record within 1024K 
	    urb.buffer_off			=(__tb+64) &  0x0F; 
		urb.buffer_length		=nCount; 
		urb.actual_length		=64; 
		urb.setup_buffer_off	=0; 
		urb.setup_buffer_seg	=0; 
		urb.start_frame			=0; 
		urb.nr_of_packets		=0; 
		urb.int_interval		=0; 
		urb.error_count			=0; 
		urb.timeout				=0; 
		urb.next_urb_off		=0; 
		urb.next_urb_seg		=0; 
 
		// Fill urb into __tb 
		dosmemput((char *)&urb, sizeof(urb), __tb); 
 
	    // Register : Flags = 0: AX = 1: BX = 2: CX = 3: DX = 4: SI = 5: DI = 6 BP = 7: DS = 8: ES = 9 
	    regs.x.ds = __tb >> 4; 
	    regs.x.dx = __tb &  0x0F; 
	    __dpmi_int (C4USBInterruptVector, ®s);           // call DosUHCI 
 
		// Fill the data returned by __tb into urb 
	    dosmemget (__tb, sizeof(urb), (char *)&urb);   
 
		// invalid device address? 
		if (urb.error_code==1) 	return(urb.error_code); 
 
		// transaction error? 
		if(urb.status > 1)		return(urb.status); 
 
	    return(0); 
	#else 
		return(0); 
    #endif 
} 
 
// 0 : success 
// 1 : Invalid device address 
// 2 : transaction error? 
int W6USBComGetCoding() 
{ 
    #ifndef ALLEGRO_MINGW32 
		__dpmi_regs  	regs; 
		TDeviceRequest	device_request; 
		TURBType		urb; 
 
		device_request.bmRequestType=0xA1; 
		device_request.bRequest		=0x21; 
		device_request.wValue		=0x00; 
		device_request.wIndex		=0; 
		device_request.wLength		=0x7; 
 
		// Specify the data of device_request to the __tb+128 position 
		dosmemput((char *)&device_request, sizeof(device_request), __tb+128); 
 
		// set up get Line Coding request 
		urb.transaction_token	=0x2D; 
		urb.chain_end_flag		=0; 
		urb.dev_add				=gnDevAdd; 
		urb.end_point			=0; 
		urb.error_code			=0; 
		urb.status				=0; 
		urb.transaction_flags	=0; 
	    urb.buffer_seg			=(__tb+64) >> 4;			// __tb is defined in go32.h as a physical address record within 1024K 
	    urb.buffer_off			=(__tb+64) &  0x0F; 
		urb.buffer_length		=18; 
		urb.actual_length		=64; 
		urb.setup_buffer_seg	=(__tb+128) >> 4;			// device_request segment 
		urb.setup_buffer_off	=(__tb+128) &  0x0F;		// device_request offset 
		urb.start_frame			=0; 
		urb.nr_of_packets		=0; 
		urb.int_interval		=0; 
		urb.error_count			=0; 
		urb.timeout				=0; 
		urb.next_urb_seg		=0; 
		urb.next_urb_off		=0; 
 
		// Fill urb into __tb 
		dosmemput((char *)&urb, sizeof(urb), __tb);	 
 
	    // Register : Flags = 0: AX = 1: BX = 2: CX = 3: DX = 4: SI = 5: DI = 6 BP = 7: DS = 8: ES = 9 
	    regs.x.ds = __tb >> 4; 
	    regs.x.dx = __tb &  0x0F; 
	    __dpmi_int (C4USBInterruptVector, ®s);           // call DosUHCI 
 
		// Fill the data returned by __tb into urb 
	    dosmemget (__tb, sizeof(urb), (char *)&urb);   
		 
		// invalid device address? 
		if (urb.error_code==1) 	return(urb.error_code); 
 
		// transaction error? 
		if(urb.status > 1)		return(urb.status); 
 
	    return(0); 
	#else 
		return(0); 
    #endif 
 
} 
 
// 0 : success 
// 1 : Invalid device address 
// 2 : transaction error? 
int W6USBComSetCoding() 
{ 
    #ifndef ALLEGRO_MINGW32 
		__dpmi_regs  	regs; 
	    int 			nInEndpoint; 
	    int 			nOutEndpoint; 
	    char			szData; 
	    int				nDataLen; 
		TDeviceRequest  device_request; 
		TURBType		urb;     
	         
		device_request.bmRequestType=0x21; 
		device_request.bRequest	=0x20; 
		device_request.wValue	=0x00; 
		device_request.wIndex	=0; 
		device_request.wLength	=0x7; 
 
		// Specify the data of device_request to the __tb+128 position 
		dosmemput((char *)&device_request, sizeof(device_request), __tb+128); 
 
		// set up get Line Coding request 
		urb.transaction_token	=0x2D; 
		urb.chain_end_flag		=0; 
		urb.dev_add				=gnDevAdd; 
		urb.end_point			=0; 
		urb.error_code			=0; 
		urb.status				=0; 
		urb.transaction_flags	=0; 
		urb.buffer_seg			=0; //varseg(buffer) 
		urb.buffer_off			=0; //varptr(buffer) 
		urb.buffer_length		=0; 
		urb.actual_length		=0; 
		urb.setup_buffer_seg	=(__tb+128) >> 4;			// device_request segment 
		urb.setup_buffer_off	=(__tb+128) &  0x0F;		// device_request offset 
		urb.start_frame			=0; 
		urb.nr_of_packets		=0; 
		urb.int_interval		=0; 
		urb.error_count			=0; 
		urb.timeout				=0; 
		urb.next_urb_seg		=0; 
		urb.next_urb_off		=0; 
 
		// Fill urb into __tb 
		dosmemput((char *)&urb, sizeof(urb), __tb); 
		 
		// Register : Flags = 0: AX = 1: BX = 2: CX = 3: DX = 4: SI = 5: DI = 6 BP = 7: DS = 8: ES = 9 
	    regs.x.ds = __tb >> 4; 
	    regs.x.dx = __tb &  0x0F; 
		__dpmi_int (C4USBInterruptVector, ®s);           // call DosUHCI 
 
		// Fill the data returned by __tb into urb 
	    dosmemget (__tb, sizeof(urb), (char *)&urb);   
 
		// invalid device address? 
		if (urb.error_code==1) 	return(urb.error_code); 
 
		// transaction error? 
		if(urb.status > 1)		return(urb.status); 
 
		// now send line coding structure - 38400 baud 8-N-1 
		nInEndpoint = gnInEndpoint; 
		nOutEndpoint= gnOutEndpoint; 
		// 0x1C200	=115200 
		// 0xE100	=57600 
		// 0x9600	=38400 
		// 0x4B00	=19200 
		// 0x2580	=9600 
		// 0x12C0	=4800 
		// 0x0960	=2400 
		// 0x04B0	=1200 
		// --> chr$(0x00)+chr$(0x96) = 0x9600 (little endian) = 38400 baud 
		// --> chr$(8) = 8bit 
		szData 		= 0x00; 
		szData 		= 0x96; 
		szData 		= 0x00; 
		szData 		= 0x00; 
		szData 		= 0x00; 
		szData 		= 0x00; 
		szData 		= 0x08; 
		nDataLen		= 7; 
 
		gnOutEndpoint 	= 0; 
		W6USBComDataOut(szData, nDataLen); 
 
		gnInEndpoint	= 0; 
		W6USBComDataIn(); 
 
		gnInEndpoint    = nInEndpoint; 
		gnOutEndpoint   = nOutEndpoint; 
 
		return(0); 
	#else 
		return(0); 
    #endif 
} 
 
// 0 : success 
// 1 : Invalid device address 
// 2 : transaction error? 
int W6USBComSetState() 
{ 
    #ifndef ALLEGRO_MINGW32 
        __dpmi_regs  	regs; 
		TDeviceRequest  device_request; 
		TURBType		urb; 
     
		device_request.bmRequestType=0x21; 
		device_request.bRequest		=0x22; 
		device_request.wValue		=0x03; 
		device_request.wIndex		=0; 
		device_request.wLength		=0x00 
 
		// Specify the data of device_request to the __tb+128 position 
		dosmemput((char *)&device_request, sizeof(device_request), __tb+128); 
 
		// set up request 
		urb.transaction_token	=0x2D; 
		urb.chain_end_flag		=0; 
		urb.dev_add				=gnDevAdd; 
		urb.end_point			=0; 
		urb.error_code			=0; 
		urb.status				=0; 
		urb.transaction_flags	=0; 
		urb.buffer_seg			=(__tb+64) >> 4; 
		urb.buffer_off			=(__tb+64) &  0x0F; 
		urb.buffer_length		=0; 
		urb.actual_length		=0; 
		urb.setup_buffer_seg	=(__tb+128) >> 4;			// device_request segment 
		urb.setup_buffer_off	=(__tb+128) &  0x0F;		// device_request offset 
		urb.start_frame			=0; 
		urb.nr_of_packets		=0; 
		urb.int_interval		=0; 
		urb.error_count			=0; 
		urb.timeout				=0; 
		urb.next_urb_seg		=0; 
		urb.next_urb_off		=0; 
 
		// Fill urb into __tb 
		dosmemput((char *)&urb, sizeof(urb), __tb); 
	 
		// Register : Flags = 0: AX = 1: BX = 2: CX = 3: DX = 4: SI = 5: DI = 6 BP = 7: DS = 8: ES = 9 
    	regs.x.ds = __tb >> 4; 
	    regs.x.dx = __tb &  0x0F; 
		__dpmi_int (C4USBInterruptVector, ®s);           // call DosUHCI 
 
		// Fill the data returned by __tb into urb 
    	dosmemget (__tb, sizeof(urb), (char *)&urb);   
 
		// invalid device address? 
		if (urb.error_code==1) 	return(urb.error_code); 
 
		// transaction error? 
		if(urb.status > 1)		return(urb.status); 
 
		// success 
		return(0); 
	#else 
		return(0); 
    #endif 
 
} 
 
void W6USBComReset() 
{ 
    #ifndef ALLEGRO_MINGW32 
        __dpmi_regs  	regs; 
		TURBType		urb; 
     
		// set up request 
		urb.transaction_token	=0xFF;						// 0xFF is Reset token (refer to USBDOS.htm) 
		urb.chain_end_flag		=0; 
		urb.dev_add				=gnDevAdd;					// 0 : means all 
		urb.end_point			=0; 
		urb.error_code			=0; 
		urb.status				=0; 
		urb.transaction_flags	=0; 
		urb.buffer_seg			=0; 
		urb.buffer_off			=0; 
		urb.buffer_length		=0; 
		urb.actual_length		=0; 
		urb.setup_buffer_seg	=0;		 
		urb.setup_buffer_off	=0;		 
		urb.start_frame			=0; 
		urb.nr_of_packets		=0; 
		urb.int_interval		=0; 
		urb.error_count			=0; 
		urb.timeout				=0; 
		urb.next_urb_seg		=0; 
		urb.next_urb_off		=0; 
 
		// Fill urb into __tb 
		dosmemput((char *)&urb, sizeof(urb), __tb); 
		 
		// Register : Flags = 0: AX = 1: BX = 2: CX = 3: DX = 4: SI = 5: DI = 6 BP = 7: DS = 8: ES = 9 
		regs.x.ax = 1;										// 1 : Reset command (USBDOS.HTM) 
    	regs.x.ds = __tb >> 4; 
	    regs.x.dx = __tb &  0x0F; 
		__dpmi_int (C4USBInterruptVector, ®s);           // call DosUHCI 
    #endif 
} 
 
 
int W6USBComDeviceDescriptor() 
{ 
    #ifndef ALLEGRO_MINGW32 
        __dpmi_regs  	regs; 
		TDeviceRequest  device_request; 
		TURBType		urb; 
     
		device_request.bmRequestType	= 0x80; 
		device_request.bRequest 		= 6; 
		device_request.wValue 			= 0x100; 
		device_request.wIndex 			= 0; 
		device_request.wLength 			= 8; 
 
		// Specify the data of device_request to the __tb+128 position 
		dosmemput((char *)&device_request, sizeof(device_request), __tb+128); 
 
		// set up request 
		urb.transaction_token	=0x2D; 
		urb.chain_end_flag		=0; 
		urb.dev_add				=gnDevAdd; 
		urb.end_point			=0; 
		urb.error_code			=0; 
		urb.status				=0; 
		urb.transaction_flags	=0; 
		urb.buffer_seg			=(__tb+64) >> 4; 
		urb.buffer_off			=(__tb+64) &  0x0F; 
		urb.buffer_length		=8; 
		urb.actual_length		=8; 
		urb.setup_buffer_seg	=(__tb+128) >> 4;			// device_request segment 
		urb.setup_buffer_off	=(__tb+128) &  0x0F;		// device_request offset 
		urb.start_frame			=0; 
		urb.nr_of_packets		=0; 
		urb.int_interval		=0; 
		urb.error_count			=0; 
		urb.timeout				=0; 
		urb.next_urb_seg		=0; 
		urb.next_urb_off		=0; 
 
		// Fill urb into __tb 
		dosmemput((char *)&urb, sizeof(urb), __tb); 
	 
		// Register : Flags = 0: AX = 1: BX = 2: CX = 3: DX = 4: SI = 5: DI = 6 BP = 7: DS = 8: ES = 9 
    	regs.x.ds = __tb >> 4; 
	    regs.x.dx = __tb &  0x0F; 
		__dpmi_int (C4USBInterruptVector, ®s);           // call DosUHCI 
 
		// Fill the data returned by __tb into urb 
    	dosmemget (__tb, sizeof(urb), (char *)&urb);   
 
		// invalid device address? 
		if (urb.error_code==1) 	return(urb.error_code); 
 
		// transaction error? 
		if(urb.status > 1)		return(urb.status); 
 
		// Fill the data returned by __tb into gszUSBDataIn 
		if(urb.actual_length>0) dosmemget (__tb+64, urb.actual_length, gszUSBDataIn);  
 
		// will respond 8 BYTES 
		printf("\n\nDevice Descriptor:"); 
		printf("\nLength:                %d",			gszUSBDataIn); 
		printf("\nDescriptor type:       %d",			gszUSBDataIn); 
		printf("\nUSB specification nr.: %02X%02X hex",	gszUSBDataIn,gszUSBDataIn); 
		printf("\nClass code:            %d",			gszUSBDataIn); 
		printf("\nSubclass code:         %d",			gszUSBDataIn); 
		printf("\nProtocol code:         %d",			gszUSBDataIn); 
		printf("\nMax Packet size:       %d\n",			gszUSBDataIn); 
	 
		// success 
		return(0); 
	#else 
		return(0); 
    #endif 
} 
  
    
 
  
 |   
 |  
  2008-3-6 14:34 | 
  
 |  
 |   
happe 
新手上路
 
 
 
  
  
积分 12 
发帖 6 
注册 2008-3-11 
状态 离线
 | 
『第 11 楼』:
 
 
使用 LLM 解释/回答一下
  
还在学习 这里的东西太多了... 
DOS USB 编程是怎么回事? 
看了还是不明白 
Still learning. There are so many things here... 
What is DOS USB programming about? 
Still don't understand after looking. 
    
 
  
  |  
                  
  
                    立珊计算机技术 |   
 |  
  2008-3-11 05:01 | 
  
 |  
  |