📄 usbhost.c
字号:
q=buf4;
for(i=0;i<sizeof(buf4);i++)
*p++ = *q++;
*p++ = 10;
*p++ = 13;
UART_SendData(buf, sizeof(buf));
g_OHCIAttach = 0;
OHCI_DeviceAttach_Init = FALSE;
HighSpeed_Owner = TRUE;
}
}
DWordWrite(&ohci_regs->portstatus1, RH_PS_CSC);
}
}
}
}
Exit_INTB_ISR:
DWordWrite(&ohci_regs->intrstatus, ints);
Exit_INTA_ISR:
outp(INT_EOI,INTA_TYPE); // ;;write to EOI
}
void _interrupt OHCI_Isr()
{
u32 ints, rhs, rhpt1s;
static char buf[32];
char buf3[28]={"Full Speed device attach..."};
char buf4[28]={"Full Speed device detach..."};
char *p, *q;
int i;
uint32 pci_int_status;
ints=inport(INT_INSERV); //read in-service register
p=buf;
q=buf3;
for(i=0;i<sizeof(buf3);i++)
*p++ = *q++;
*p++ = 10;
*p++ = 13;
//OHCI ++++++++++++++++++ For ALI +++++++++++++++++++++++++++++++++++++++++++++++++++
//Check Interrupt Status
ints = DWordRead(&ohci_regs->intrstatus);
if (ints == ~(u32)0)
goto Exit_INTB_ISR;
if (ints & OHCI_INTR_UE) {
//In application, need to modify the unrecoverable Error
}
//Write back DoneHead
if (ints & OHCI_INTR_WDH) {
DWordWrite(&ohci_regs->intrdisable, OHCI_INTR_WDH);
DH_Status = dl_done_list();
DWordWrite(&ohci_regs->intrenable, OHCI_INTR_WDH);
}
//Scheduling Overrun
if (ints & OHCI_INTR_SO) {
DWordWrite(&ohci_regs->intrstatus, OHCI_INTR_SO);
}
//Start of frame
if (ints & OHCI_INTR_SF) {
DWordWrite(&ohci_regs->intrstatus, OHCI_INTR_SF);
}
//Frame number overflow
if (ints & OHCI_INTR_FNO) {
DWordWrite(&ohci_regs->intrstatus, OHCI_INTR_FNO);
}
//Root hub status change, Port status change
if (ints & OHCI_INTR_RHSC) {
//Root hub status change
if((rhs = DWordRead(&ohci_regs->status)) != 0) {
rhs = rhs;
}
//Port status change, just handle port 1
else if((rhpt1s = DWordRead(&ohci_regs->portstatus1)) != 0) {
if(rhpt1s & RH_PS_PRSC) { //Port reset status change
DWordWrite(&ohci_regs->portstatus1, RH_PS_PRSC);
if(rhpt1s & RH_PS_PESC)
DWordWrite(&ohci_regs->portstatus1, RH_PS_PESC);
if(rhpt1s & RH_PS_CSC)
DWordWrite(&ohci_regs->portstatus1, RH_PS_CSC);
rhpt1s = DWordRead(&ohci_regs->portstatus1);
if((rhpt1s & RH_PS_CCS) == RH_PS_CCS){ //Check is connect
g_OHCIAttach = 1;
}
}
if(rhpt1s & RH_PS_CSC){ //Port connect status change
if(rhpt1s & RH_PS_CCS) {
DWordWrite(&ohci_regs->portstatus1, RH_PS_PES); //Port1 Status, set port enable
UART_SendData(buf, sizeof(buf));
g_OHCIAttach = 1;
}
else if(rhpt1s & RH_PS_PESC) {
DWordWrite(&ohci_regs->portstatus1, RH_PS_PESC);
if((rhpt1s & RH_PS_CCS) == RH_PS_CCS){
UART_SendData(buf, sizeof(buf));
g_OHCIAttach = 1;
}
else{
p=buf;
q=buf4;
for(i=0;i<sizeof(buf4);i++)
*p++ = *q++;
*p++ = 10;
*p++ = 13;
UART_SendData(buf, sizeof(buf));
g_OHCIAttach = 0;
OHCI_DeviceAttach_Init = FALSE;
HighSpeed_Owner = TRUE;
}
}
DWordWrite(&ohci_regs->portstatus1, RH_PS_CSC);
}
}
}
Exit_INTB_ISR:
DWordWrite(&ohci_regs->intrstatus, ints);
// Sten PCI NIC Interrupt --------------------------------
pci_int_status = InPortD(dec_info.io_base+CR5_ADDR);
OutPortD(dec_info.io_base+CR5_ADDR, pci_int_status);
if ((uint16)pci_int_status & 0x0001) pci_tx_handler((DEC_STRU far *)&dec_info);
if ((uint16)pci_int_status & 0x0040) pci_rx_handler((DEC_STRU far *)&dec_info);
//--------------------------------------------------------
outp(INT_EOI,INTB_TYPE); // ;;write to EOI
}
void _interrupt UartIsr()
{
u16 status, temp;
static char buf[30];
char buf1[26]={"Doing Control transfer..."};
char buf2[26]={"Doing SCSI Command......."};
char buf3[26]={"Doing Bulk Loop.........."};
char *p, *q;
int i;
status=inport(INT_INSERV); //read in-service register
//Check Interrupt Status
status = inport(PCBBase+LSR);
if(status & 0x01)
{
temp = inport(PCBBase+RBR);
if(temp !=13)
{
outport(PCBBase+THR, temp);
UartBuf[UartCnt] = temp;
UartCnt++;
}
else
{
outport(PCBBase+THR, 10);
outport(PCBBase+THR, 13);
if(UartBuf[0] == 's')
{
if(UartBuf[1] == '1')
DoTest_Mode(1);
if(UartBuf[1] == '2')
DoTest_Mode(2);
if(UartBuf[1] == '3')
DoTest_Mode(3);
if(UartBuf[1] == '4')
DoTest_Mode(4);
if(UartBuf[1] == '5')
DoTest_Mode(5);
}
else if(UartBuf[0] == 'e')
EndTest_Mode();
else if(UartBuf[0] == 'c')
{
if(UartBuf[1] == 's' && UartBuf[2] == 't')
{
p=buf;
q=buf1;
for(i=0;i<sizeof(buf1);i++)
*p++ = *q++;
*p++ = 10;
*p++ = 13;
UART_SendData(buf, sizeof(buf));
ControlCnt = 0;
ControlStart = TRUE;
}
else if(UartBuf[1] == 's' && UartBuf[2] == 'p')
if(ControlStart == TRUE)
{
ControlStart = FALSE;
SendDesc2UART();
}
}
else if(UartBuf[0] == 'b')
{
if(UartBuf[1] == 's' && UartBuf[2] == 's' && UartBuf[3] == 't'){
if((dev_des->idVendor != 0x1463) && (dev_des->idProduct != 0x05CB)) //Normal bulk SCSI command
q=buf2;
else
q=buf3;
p=buf;
for(i=0;i<sizeof(buf2);i++)
*p++ = *q++;
*p++ = 10;
*p++ = 13;
UART_SendData(buf, sizeof(buf));
SCSICnt = 0;
SCSIStart = TRUE;
}
else if(UartBuf[1] == 's' && UartBuf[2] == 's' && UartBuf[3] == 'p'){
if(SCSIStart == TRUE){
SCSIStart = FALSE;
SendSCSI2UART();
}
}
}
for(i=0;i<10;i++)
UartBuf[i] = 0;
UartCnt = 0;
}
}
//Exit_UART1_ISR:
temp = temp;
outp(INT_EOI,UART1_TYPE); // ;;write to EOI
}
void Init_PCINic(DEC_STRU far * mac_info)
{
char far *buf_ptr, far *dec_memory_ptr;
DEC_DESCRIPTOR far *dec_desc_ptr;
/* Allocate DEC information structure */
dec_memory_ptr = (char far *)malloc(0x400 + BUF_SIZE * DESC_COUNT + 16);
dec_memory_ptr = (char far *) (((unsigned long)dec_memory_ptr + 0xf) & ~0xf);
/* Init PCI NIC */
dec_desc_ptr = (DEC_DESCRIPTOR far *) dec_memory_ptr;
buf_ptr = (char far *) (dec_memory_ptr + 0x400);
init_dec_desc(mac_info, dec_desc_ptr, buf_ptr);
/* Activate PCI NIC */
DEC_Regs_Init(mac_info);
return;
}
/* Linear address to physical address */
uint32 linear_to_real(uint32 linear_addr)
{
uint32 real_addr;
real_addr = (linear_addr & 0xffff0000L) >> 8;
real_addr += (linear_addr & 0x0000ffffL);
return real_addr;
}
void init_dec_desc(DEC_STRU far *dec_ipr, DEC_DESCRIPTOR far *desc_ptr, char far *buf_ptr)
{
uint32 r_desc_addr, r_buf_addr, r_buf_addr_t;
char far * buf_tmp;
int i;
dec_ipr->tx_insert_ptr = desc_ptr;
dec_ipr->tx_remove_ptr = desc_ptr;
dec_ipr->rx_insert_ptr = (desc_ptr + DESC_COUNT);
dec_ipr->rx_remove_ptr = dec_ipr->rx_insert_ptr;
r_desc_addr = linear_to_real((uint32)desc_ptr);
r_buf_addr = linear_to_real((uint32)buf_ptr);
/* Init TX descriptor: Don't allocate TX buffer */
dec_ipr->txd_raddr = r_desc_addr;
r_buf_addr_t = r_buf_addr;
buf_tmp = buf_ptr;
for (i = 0; i < DESC_COUNT; i++) {
desc_ptr->status = 0;
desc_ptr->len = 0;
desc_ptr->own = 0;
desc_ptr->ctrl = 0xE100;
desc_ptr->buf_ptr = r_buf_addr;
desc_ptr->vbuf_ptr = buf_ptr;
desc_ptr->ndesc_ptr = r_desc_addr + DEC_DESC_SIZE;
desc_ptr->vndesc_ptr = desc_ptr + 1;
r_desc_addr += DEC_DESC_SIZE;
r_buf_addr += BUF_SIZE;
buf_ptr = (buf_ptr + BUF_SIZE);
desc_ptr = desc_ptr + 1;
}
(desc_ptr - 1)->ndesc_ptr = dec_ipr->txd_raddr;
(desc_ptr - 1)->vndesc_ptr = dec_ipr->tx_insert_ptr;
/* Init RX descriptor: Allocate RX buffer */
r_buf_addr = r_buf_addr_t;
buf_ptr = buf_tmp;
dec_ipr->rxd_raddr = r_desc_addr;
for (i = 0; i < DESC_COUNT; i++) {
desc_ptr->len = 0x0620;
desc_ptr->own = 0x8000;
desc_ptr->ctrl = 0xE100;
desc_ptr->buf_ptr = r_buf_addr;
desc_ptr->ndesc_ptr = r_desc_addr + DEC_DESC_SIZE;
desc_ptr->vbuf_ptr = buf_ptr;
desc_ptr->vndesc_ptr = (desc_ptr + 1);
desc_ptr->status = 0x0000;
r_desc_addr += DEC_DESC_SIZE;
r_buf_addr += BUF_SIZE;
desc_ptr += 1;
buf_ptr = (buf_ptr + BUF_SIZE);
}
(desc_ptr - 1)->ndesc_ptr = dec_ipr->rxd_raddr;
(desc_ptr - 1)->vndesc_ptr = dec_ipr->rx_insert_ptr;
}
void DEC_Regs_Init(DEC_STRU far * dec_ipr)
{
uint32 temp;
int io_base = dec_ipr->io_base;
OutPortD(io_base, 0x1);
while(inport(io_base)&0x1);
//Init CR6 (Operation Control)
temp = (uint32)dec_ipr->cr6_datah << 16;
temp += (uint32)((dec_ipr->cr6_datal)&(~0x2002)); //bit1:RXE, bit13:TXE
OutPortD((io_base+CR6_ADDR), temp);
//Clear CR5
temp = InPortD(io_base+CR5_ADDR);
OutPortD((io_base+CR5_ADDR), temp);
/*Init TX/RX descriptor*/
OutPortD(io_base + CR4_ADDR, dec_ipr->txd_raddr);
OutPortD(io_base + CR3_ADDR, dec_ipr->rxd_raddr);
/*Init CR0*/
OutPortD(io_base, ((uint32)dec_ipr->cr0_datah<<16)+dec_ipr->cr0_datal);
/*Init CR7 (Interrupt Mask)*/
OutPortD(io_base + CR7_ADDR,(unsigned long)0x00010041);
/*Init CR6 (Operation Control)*/
temp = (uint32)dec_ipr->cr6_datah << 16;
temp += (uint32)(dec_ipr->cr6_datal | (0x2002 | (DUPLEX_MODE*0x200))); //bit1:RXE, bit13:TXE
OutPortD((io_base+CR6_ADDR), temp);
/*Clear CR5*/
temp = InPortD(io_base+CR5_ADDR);
OutPortD((io_base+CR5_ADDR), temp);
}
void OutPortD(uint16 addr, uint32 data)
{
asm{pushf};
asm{cli};
outport(0xff00, addr);
outport(0xff02, 0x0);
outport(0xff04, (uint16)(data&0x0000ffffL));
outport(0xff06, (uint16)((data&0xffff0000L)>>16));
asm{popf};
}
uint32 InPortD(uint16 addr)
{
uint16 temp;
uint32 data;
asm{pushf};
asm{cli};
outport(0xff00, addr);
outport(0xff02, 0x0);
temp = inport(0xff04);
data = (uint32)inport(0xff06) << 16;
data += (uint32)temp;
asm{popf};
return data;
}
/* PCI TX interrupt handler */
void pci_tx_handler(DEC_STRU far * dec_ipr)
{
int io_base = dec_ipr->io_base;
DEC_DESCRIPTOR far *txd_ptr = dec_ipr->tx_remove_ptr;
DEC_DESCRIPTOR far *rxd_ptr = dec_ipr->rx_insert_ptr;
while(dec_ipr->TxFreeDesc < DESC_COUNT) {
//if (txd_ptr->status & 0x8000) break;
if (txd_ptr->own & 0x8000) break;
//dec_ipr->TxSuccCounter++;
/* Re-use RX desciptor */
rxd_ptr->own = 0x8000;
//rxd_ptr->status = 0;
outport(io_base + CR2_ADDR, txd_ptr->own); /* Trigger MAC increase RX descriptor count */
dec_ipr->TxFreeDesc++;
dec_ipr->RxFreeDesc++;
rxd_ptr = rxd_ptr->vndesc_ptr;
txd_ptr = txd_ptr->vndesc_ptr;
}
dec_ipr->tx_remove_ptr = txd_ptr;
dec_ipr->rx_insert_ptr = rxd_ptr;
}
/* MAC RX interrupt handler */
void pci_rx_handler(DEC_STRU far * dec_ipr)
{
int io_base = dec_ipr->io_base;
DEC_DESCRIPTOR far *rxd_ptr = dec_ipr->rx_remove_ptr;
DEC_DESCRIPTOR far *txd_ptr = dec_ipr->tx_insert_ptr;
while(dec_ipr->RxFreeDesc) {
if (rxd_ptr->own & 0x8000) break;
/*Packet Received*/
if(rxd_ptr->status&0x8000)
dec_ipr->RxErrL ++;
/* Another MAC send */
//txd_ptr->buf_ptr = rxd_ptr->buf_ptr;
if(rxd_ptr->own<=64)
rxd_ptr->own = 64;
else if(rxd_ptr->own>=1518)
rxd_ptr->own = 1518;
//txd_ptr->len = 0x3c;//(rxd_ptr->own&0x3fff) - 4; /* Skip 4 byte CRC */
txd_ptr->len = rxd_ptr->own - 4;
txd_ptr->own = 0x8000;
outport(io_base + CR1_ADDR, txd_ptr->len);
dec_ipr->RxFreeDesc--;
dec_ipr->TxFreeDesc--;
/* Next descriptor */
rxd_ptr = rxd_ptr->vndesc_ptr;
txd_ptr = txd_ptr->vndesc_ptr;
}
dec_ipr->rx_remove_ptr = rxd_ptr;
dec_ipr->tx_insert_ptr = txd_ptr;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -