Some major reworking. Re-enable the old way of building up the framelist pointers. MAke some parts more verbose for testing. Fix the stray td to actually something useful.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@13993 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -192,6 +192,27 @@ UHCI::UHCI( pci_info *info , Stack *stack )
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
According tot the *BSD usb sources, there needs to be a stray transfer
|
||||||
|
descriptor in order to get some chipset to work nicely (PIIX or something
|
||||||
|
like that).
|
||||||
|
*/
|
||||||
|
uhci_td *straytd;
|
||||||
|
if ( m_stack->AllocateChunk( (void **)&(straytd) , &phy , 32 ) != B_OK )
|
||||||
|
{
|
||||||
|
dprintf( "USB UHCI::UHCI() Failed to allocate a stray transfer descriptor\n" );
|
||||||
|
delete_area( m_framearea );
|
||||||
|
m_initok = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
straytd->link_phy = TD_TERMINATE;
|
||||||
|
straytd->this_phy = reinterpret_cast<addr_t>(phy);
|
||||||
|
straytd->link_log = 0;
|
||||||
|
straytd->buffer_log = 0;
|
||||||
|
straytd->status = 0;
|
||||||
|
straytd->token = TD_TOKEN_NULL | 0x7f << TD_TOKEN_DEVADDR_SHIFT | 0x69;
|
||||||
|
straytd->buffer_phy = 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Set up the virtual structure. I stole this idea from the linux usb stack,
|
Set up the virtual structure. I stole this idea from the linux usb stack,
|
||||||
the idea is that for every interrupt interval there is a queue head. These
|
the idea is that for every interrupt interval there is a queue head. These
|
||||||
@@ -224,7 +245,8 @@ UHCI::UHCI( pci_info *info , Stack *stack )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Make sure the qh_terminate terminates
|
// Make sure the qh_terminate terminates
|
||||||
m_qh_virtual[11]->link_phy = QH_TERMINATE;
|
m_qh_virtual[11]->link_phy = straytd->this_phy;
|
||||||
|
m_qh_virtual[11]->link_log = straytd;
|
||||||
|
|
||||||
//Insert the queues in the frame list. The linux developers mentioned
|
//Insert the queues in the frame list. The linux developers mentioned
|
||||||
// in a comment that they used some magic to distribute the elements all
|
// in a comment that they used some magic to distribute the elements all
|
||||||
@@ -232,7 +254,7 @@ UHCI::UHCI( pci_info *info , Stack *stack )
|
|||||||
// (or do I know how I should do that), instead, I just take the frame
|
// (or do I know how I should do that), instead, I just take the frame
|
||||||
// number and determine where it should begin
|
// number and determine where it should begin
|
||||||
|
|
||||||
/* //NOTE, in c++ this is butt-ugly. We have a addr_t *array (because with
|
//NOTE, in c++ this is butt-ugly. We have a addr_t *array (because with
|
||||||
//an addr_t *array we can apply pointer arithmetic), uhci_qh *pointers
|
//an addr_t *array we can apply pointer arithmetic), uhci_qh *pointers
|
||||||
//that need to be put through the logical | to make sure the pointer is
|
//that need to be put through the logical | to make sure the pointer is
|
||||||
//invalid for the hc. The result of that needs to be converted into a
|
//invalid for the hc. The result of that needs to be converted into a
|
||||||
@@ -241,29 +263,25 @@ UHCI::UHCI( pci_info *info , Stack *stack )
|
|||||||
{
|
{
|
||||||
int frame = i+1;
|
int frame = i+1;
|
||||||
if ( ( frame % 256 ) == 0 )
|
if ( ( frame % 256 ) == 0 )
|
||||||
m_framelist[i] = reinterpret_cast<addr_t*>( reinterpret_cast<addr_t>(m_qh_interrupt_256) | FRAMELIST_NEXT_IS_QH );
|
m_framelist[i] = m_qh_interrupt_256->this_phy | FRAMELIST_NEXT_IS_QH;
|
||||||
else if ( ( frame % 128 ) == 0 )
|
else if ( ( frame % 128 ) == 0 )
|
||||||
m_framelist[i] = reinterpret_cast<addr_t*>( reinterpret_cast<addr_t>(m_qh_interrupt_128) | FRAMELIST_NEXT_IS_QH );
|
m_framelist[i] = m_qh_interrupt_128->this_phy | FRAMELIST_NEXT_IS_QH;
|
||||||
else if ( ( frame % 64 ) == 0 )
|
else if ( ( frame % 64 ) == 0 )
|
||||||
m_framelist[i] = reinterpret_cast<addr_t*>( reinterpret_cast<addr_t>(m_qh_interrupt_64) | FRAMELIST_NEXT_IS_QH );
|
m_framelist[i] = m_qh_interrupt_64->this_phy | FRAMELIST_NEXT_IS_QH;
|
||||||
else if ( ( frame % 32 ) == 0 )
|
else if ( ( frame % 32 ) == 0 )
|
||||||
m_framelist[i] = reinterpret_cast<addr_t*>( reinterpret_cast<addr_t>(m_qh_interrupt_32) | FRAMELIST_NEXT_IS_QH );
|
m_framelist[i] = m_qh_interrupt_32->this_phy | FRAMELIST_NEXT_IS_QH;
|
||||||
else if ( ( frame % 16 ) == 0 )
|
else if ( ( frame % 16 ) == 0 )
|
||||||
m_framelist[i] = reinterpret_cast<addr_t*>( reinterpret_cast<addr_t>(m_qh_interrupt_16) | FRAMELIST_NEXT_IS_QH );
|
m_framelist[i] = m_qh_interrupt_16->this_phy | FRAMELIST_NEXT_IS_QH;
|
||||||
else if ( ( frame % 8 ) == 0 )
|
else if ( ( frame % 8 ) == 0 )
|
||||||
m_framelist[i] = reinterpret_cast<addr_t*>( reinterpret_cast<addr_t>(m_qh_interrupt_8) | FRAMELIST_NEXT_IS_QH );
|
m_framelist[i] = m_qh_interrupt_8->this_phy | FRAMELIST_NEXT_IS_QH;
|
||||||
else if ( ( frame % 4 ) == 0 )
|
else if ( ( frame % 4 ) == 0 )
|
||||||
m_framelist[i] = reinterpret_cast<addr_t*>( reinterpret_cast<addr_t>(m_qh_interrupt_4) | FRAMELIST_NEXT_IS_QH );
|
m_framelist[i] = m_qh_interrupt_4->this_phy | FRAMELIST_NEXT_IS_QH;
|
||||||
else if ( ( frame % 2 ) == 0 )
|
else if ( ( frame % 2 ) == 0 )
|
||||||
m_framelist[i] = reinterpret_cast<addr_t*>( reinterpret_cast<addr_t>(m_qh_interrupt_2) | FRAMELIST_NEXT_IS_QH );
|
m_framelist[i] = m_qh_interrupt_2->this_phy | FRAMELIST_NEXT_IS_QH;
|
||||||
else
|
else
|
||||||
m_framelist[i] = reinterpret_cast<addr_t*>( reinterpret_cast<addr_t>(m_qh_interrupt_1) | FRAMELIST_NEXT_IS_QH );
|
m_framelist[i] = m_qh_interrupt_1->this_phy | FRAMELIST_NEXT_IS_QH;
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
for ( int i = 0 ; i < 1024 ; i++ )
|
|
||||||
m_framelist[i] = reinterpret_cast<addr_t*>( reinterpret_cast<addr_t>(m_qh_control) | FRAMELIST_NEXT_IS_QH );
|
|
||||||
|
|
||||||
//Set base pointer
|
//Set base pointer
|
||||||
UHCI::pci_module->write_io_32( m_reg_base + UHCI_FRBASEADD , (int32)(m_framelist_phy) );
|
UHCI::pci_module->write_io_32( m_reg_base + UHCI_FRBASEADD , (int32)(m_framelist_phy) );
|
||||||
UHCI::pci_module->write_io_16( m_reg_base + UHCI_FRNUM , 0 );
|
UHCI::pci_module->write_io_16( m_reg_base + UHCI_FRNUM , 0 );
|
||||||
@@ -286,10 +304,13 @@ status_t UHCI::Start()
|
|||||||
UHCI::pci_module->write_io_16( m_reg_base + UHCI_USBCMD , UHCI_USBCMD_RS );
|
UHCI::pci_module->write_io_16( m_reg_base + UHCI_USBCMD , UHCI_USBCMD_RS );
|
||||||
|
|
||||||
bool running = false;
|
bool running = false;
|
||||||
|
uint16 status = 0;
|
||||||
for ( int i = 0 ; i <= 10 ; i++ )
|
for ( int i = 0 ; i <= 10 ; i++ )
|
||||||
{
|
{
|
||||||
if ( ( UHCI::pci_module->read_io_16( m_reg_base + UHCI_USBSTS ) & UHCI_USBSTS_HCHALT ) == 0 )
|
status = UHCI::pci_module->read_io_16( m_reg_base + UHCI_USBSTS );
|
||||||
snooze( 1 );
|
dprintf( "UHCI::Start() current loop %u, status %u\n" , i , status );
|
||||||
|
if ( status & UHCI_USBSTS_HCHALT )
|
||||||
|
snooze( 1000 );
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
running = true;
|
running = true;
|
||||||
@@ -303,7 +324,7 @@ status_t UHCI::Start()
|
|||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
TRACE( "UHCI::Start() Controller is started. USBSTS: %u\n" , UHCI::pci_module->read_io_16( m_reg_base + UHCI_USBSTS ) );
|
TRACE( "UHCI::Start() Controller is started. USBSTS: %u curframe: %u \n" , UHCI::pci_module->read_io_16( m_reg_base + UHCI_USBSTS ) , UHCI::pci_module->read_io_16( m_reg_base + UHCI_FRNUM ) );
|
||||||
return BusManager::Start();
|
return BusManager::Start();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -324,14 +345,14 @@ status_t UHCI::SubmitTransfer( Transfer *t )
|
|||||||
void UHCI::GlobalReset()
|
void UHCI::GlobalReset()
|
||||||
{
|
{
|
||||||
UHCI::pci_module->write_io_16( m_reg_base + UHCI_USBCMD , UHCI_USBCMD_GRESET );
|
UHCI::pci_module->write_io_16( m_reg_base + UHCI_USBCMD , UHCI_USBCMD_GRESET );
|
||||||
spin( 100000 );
|
snooze( 100000 );
|
||||||
UHCI::pci_module->write_io_16( m_reg_base + UHCI_USBCMD , 0 );
|
UHCI::pci_module->write_io_16( m_reg_base + UHCI_USBCMD , 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
status_t UHCI::Reset()
|
status_t UHCI::Reset()
|
||||||
{
|
{
|
||||||
UHCI::pci_module->write_io_16( m_reg_base + UHCI_USBCMD , UHCI_USBCMD_HCRESET );
|
UHCI::pci_module->write_io_16( m_reg_base + UHCI_USBCMD , UHCI_USBCMD_HCRESET );
|
||||||
spin( 100000 );
|
snooze( 100000 );
|
||||||
if ( UHCI::pci_module->read_io_16( m_reg_base + UHCI_USBCMD ) & UHCI_USBCMD_HCRESET )
|
if ( UHCI::pci_module->read_io_16( m_reg_base + UHCI_USBCMD ) & UHCI_USBCMD_HCRESET )
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
return B_OK;
|
return B_OK;
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ private:
|
|||||||
|
|
||||||
//Frame list memory
|
//Frame list memory
|
||||||
area_id m_framearea;
|
area_id m_framearea;
|
||||||
addr_t *m_framelist[1024]; //The frame list struct
|
addr_t m_framelist[1024]; //The frame list struct
|
||||||
addr_t m_framelist_phy; //The physical pointer to the frame list
|
addr_t m_framelist_phy; //The physical pointer to the frame list
|
||||||
|
|
||||||
// Virtual frame
|
// Virtual frame
|
||||||
|
|||||||
@@ -113,6 +113,7 @@ typedef struct
|
|||||||
#define TD_STATUS_ACTIVE ( 1 << 23 )
|
#define TD_STATUS_ACTIVE ( 1 << 23 )
|
||||||
#define TD_TOKEN_DATA1 ( 1 << 19 )
|
#define TD_TOKEN_DATA1 ( 1 << 19 )
|
||||||
#define TD_TOKEN_NULL (0x7FF << 21 )
|
#define TD_TOKEN_NULL (0x7FF << 21 )
|
||||||
|
#define TD_TOKEN_DEVADDR_SHIFT 8
|
||||||
#define TD_DEPTH_FIRST 0x4
|
#define TD_DEPTH_FIRST 0x4
|
||||||
#define TD_TERMINATE 0x1
|
#define TD_TERMINATE 0x1
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user