git.ucc.asn.au
/
tpg
/
acess2.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
Modules/UHCI - Added logging and ASSERTs to find bugs
[tpg/acess2.git]
/
KernelLand
/
Modules
/
USB
/
UHCI
/
uhci.c
diff --git
a/KernelLand/Modules/USB/UHCI/uhci.c
b/KernelLand/Modules/USB/UHCI/uhci.c
index
61b71ca
..
98a4b09
100644
(file)
--- a/
KernelLand/Modules/USB/UHCI/uhci.c
+++ b/
KernelLand/Modules/USB/UHCI/uhci.c
@@
-36,9
+36,9
@@
void UHCI_int_AppendTD(tUHCI_Controller *Cont, tUHCI_QH *QH, tUHCI_TD *TD);
tUHCI_TD *UHCI_int_CreateTD(tUHCI_Controller *Cont, int Addr, Uint8 Type, int bTgl, tUSBHostCb Cb, void *CbData, void *Buf, size_t Length);
// --- API
void *UHCI_InitInterrupt(void *Ptr, int Endpt, int bOutbound, int Period, tUSBHostCb Cb, void *CbData, void *Buf, size_t Len);
tUHCI_TD *UHCI_int_CreateTD(tUHCI_Controller *Cont, int Addr, Uint8 Type, int bTgl, tUSBHostCb Cb, void *CbData, void *Buf, size_t Length);
// --- API
void *UHCI_InitInterrupt(void *Ptr, int Endpt, int bOutbound, int Period, tUSBHostCb Cb, void *CbData, void *Buf, size_t Len);
-void *UHCI_InitIsoch(void *Ptr, int Endpt);
-void *UHCI_InitControl(void *Ptr, int Endpt);
-void *UHCI_InitBulk(void *Ptr, int Endpt);
+void *UHCI_InitIsoch(void *Ptr, int Endpt
, size_t MaxPacketSize
);
+void *UHCI_InitControl(void *Ptr, int Endpt
, size_t MaxPacketSize
);
+void *UHCI_InitBulk(void *Ptr, int Endpt
, size_t MaxPacketSize
);
void UHCI_RemoveEndpoint(void *Ptr, void *EndptHandle);
void *UHCI_SendIsoch(void *Ptr, void *Dest, tUSBHostCb Cb, void *CbData, int Dir, void *Data, size_t Length, int When);
void *UHCI_SendControl(void *Ptr, void *Dest, tUSBHostCb Cb, void *CbData,
void UHCI_RemoveEndpoint(void *Ptr, void *EndptHandle);
void *UHCI_SendIsoch(void *Ptr, void *Dest, tUSBHostCb Cb, void *CbData, int Dir, void *Data, size_t Length, int When);
void *UHCI_SendControl(void *Ptr, void *Dest, tUSBHostCb Cb, void *CbData,
@@
-93,7
+93,14
@@
int UHCI_Initialise(char **Arguments)
int ret;
ENTER("");
int ret;
ENTER("");
-
+
+ if( Arguments && *Arguments && strcmp(*Arguments, "0") == 0 )
+ {
+ LOG("Disabled by argument");
+ LEAVE('i', MODULE_ERR_NOTNEEDED);
+ return MODULE_ERR_NOTNEEDED;
+ }
+
// Initialise with no maximum value
Semaphore_Init( &gUHCI_InterruptSempahore, 0, 0, "UHCI", "Interrupt Queue");
// Initialise with no maximum value
Semaphore_Init( &gUHCI_InterruptSempahore, 0, 0, "UHCI", "Interrupt Queue");
@@
-107,14
+114,15
@@
int UHCI_Initialise(char **Arguments)
tPAddr tmp;
gaUHCI_TDPool = (void *) MM_AllocDMA(1, 32, &tmp);
memset(gaUHCI_TDPool, 0, PAGE_SIZE);
tPAddr tmp;
gaUHCI_TDPool = (void *) MM_AllocDMA(1, 32, &tmp);
memset(gaUHCI_TDPool, 0, PAGE_SIZE);
+ LOG("gaUHCI_TDPool = %p (%P)", gaUHCI_TDPool, tmp);
}
// Enumerate PCI Bus, getting a maximum of `MAX_CONTROLLERS` devices
}
// Enumerate PCI Bus, getting a maximum of `MAX_CONTROLLERS` devices
+ // Class:SubClass:Protocol = 0xC (Serial) : 0x3 (USB) : 0x00 (UHCI)
while( (id = PCI_GetDeviceByClass(0x0C0300, 0xFFFFFF, id)) >= 0 && i < MAX_CONTROLLERS )
{
tUHCI_Controller *cinfo = &gUHCI_Controllers[i];
Uint32 base_addr;
while( (id = PCI_GetDeviceByClass(0x0C0300, 0xFFFFFF, id)) >= 0 && i < MAX_CONTROLLERS )
{
tUHCI_Controller *cinfo = &gUHCI_Controllers[i];
Uint32 base_addr;
- // NOTE: Check "protocol" from PCI?
cinfo->PciId = id;
base_addr = PCI_GetBAR(id, 4);
cinfo->PciId = id;
base_addr = PCI_GetBAR(id, 4);
@@
-184,6
+192,7
@@
int UHCI_int_InitHost(tUHCI_Controller *Host)
LEAVE('i', -1);
return -1;
}
LEAVE('i', -1);
return -1;
}
+ LOG("->FrameList = %p (%P)", Host->FrameList, Host->PhysFrameList);
Host->TDQHPage = (void *) MM_AllocDMA(1, 32, &Host->PhysTDQHPage);
if( !Host->TDQHPage ) {
Host->TDQHPage = (void *) MM_AllocDMA(1, 32, &Host->PhysTDQHPage);
if( !Host->TDQHPage ) {
@@
-192,6
+201,7
@@
int UHCI_int_InitHost(tUHCI_Controller *Host)
LEAVE('i', -1);
return -1;
}
LEAVE('i', -1);
return -1;
}
+ LOG("->TDQHPage = %p (%P)", Host->TDQHPage, Host->PhysTDQHPage);
// Fill frame list
// - The numbers 0...31, but bit reversed (16 (0b1000) = 1 (0b00001)
// Fill frame list
// - The numbers 0...31, but bit reversed (16 (0b1000) = 1 (0b00001)
@@
-199,6
+209,7
@@
int UHCI_int_InitHost(tUHCI_Controller *Host)
0,16,8,24,4,20,12,28,2,18,10,26,6,22,14,30,
1,17,9,25,5,21,13,29,3,19,11,27,7,23,15,31
};
0,16,8,24,4,20,12,28,2,18,10,26,6,22,14,30,
1,17,9,25,5,21,13,29,3,19,11,27,7,23,15,31
};
+ // Fill all slots (but every 4th will be changed below
for( int i = 0; i < 1024; i ++ ) {
Uint32 addr = MM_GetPhysAddr( &Host->TDQHPage->ControlQH );
Host->FrameList[i] = addr | 2;
for( int i = 0; i < 1024; i ++ ) {
Uint32 addr = MM_GetPhysAddr( &Host->TDQHPage->ControlQH );
Host->FrameList[i] = addr | 2;
@@
-214,7
+225,7
@@
int UHCI_int_InitHost(tUHCI_Controller *Host)
Host->FrameList[768 + i*4] = addr | 2;
}
Host->FrameList[768 + i*4] = addr | 2;
}
- // Build up interrupt binary tree
+ // Build up interrupt binary tree
{
tUHCI_QH *dest = Host->TDQHPage->InterruptQHs;
Uint32 destphys = Host->PhysTDQHPage;
{
tUHCI_QH *dest = Host->TDQHPage->InterruptQHs;
Uint32 destphys = Host->PhysTDQHPage;
@@
-222,7
+233,9
@@
int UHCI_int_InitHost(tUHCI_Controller *Host)
// Set up next pointer to index to i/2 in the next step
for( int _count = 64; _count > 1; _count /= 2 )
{
// Set up next pointer to index to i/2 in the next step
for( int _count = 64; _count > 1; _count /= 2 )
{
+ LOG("count=%i, dest=%p, destphys=%P", _count, dest, destphys);
for( int i = 0; i < _count; i ++ ) {
for( int i = 0; i < _count; i ++ ) {
+ LOG(" %i-%i: %P==%P", _count, i, MM_GetPhysAddr(dest+i), destphys+i*sizeof(tUHCI_QH));
dest[i].Next = destphys + (_count + i/2) * sizeof(tUHCI_QH) + 2;
dest[i].Child = 1;
}
dest[i].Next = destphys + (_count + i/2) * sizeof(tUHCI_QH) + 2;
dest[i].Child = 1;
}
@@
-257,6
+270,7
@@
int UHCI_int_InitHost(tUHCI_Controller *Host)
PCI_ConfigWrite( Host->PciId, 0xC0, 2, 0x2000 );
// Enable processing
PCI_ConfigWrite( Host->PciId, 0xC0, 2, 0x2000 );
// Enable processing
+ LOG("Processing enabling");
_OutWord( Host, USBCMD, 0x0001 );
LEAVE('i', 0);
_OutWord( Host, USBCMD, 0x0001 );
LEAVE('i', 0);
@@
-301,16
+315,18
@@
void UHCI_int_AppendTD(tUHCI_Controller *Cont, tUHCI_QH *QH, tUHCI_TD *TD)
TD->Control |= (TD->Token >> 21) & 0x7FF;
// Stop controller
TD->Control |= (TD->Token >> 21) & 0x7FF;
// Stop controller
+ tPAddr tdaddr = MM_GetPhysAddr( TD );
+ ASSERT(tdaddr);
_OutWord( Cont, USBCMD, 0x0000 );
// Add
TD->Link = 1;
if( QH->Child & 1 ) {
_OutWord( Cont, USBCMD, 0x0000 );
// Add
TD->Link = 1;
if( QH->Child & 1 ) {
- QH->Child =
MM_GetPhysAddr( TD )
;
+ QH->Child =
tdaddr
;
}
else {
// Depth first
}
else {
// Depth first
- QH->_LastItem->Link =
MM_GetPhysAddr( TD )
| 4;
+ QH->_LastItem->Link =
tdaddr
| 4;
}
QH->_LastItem = TD;
}
QH->_LastItem = TD;
@@
-512,22
+528,54
@@
void *UHCI_InitInterrupt(void *Ptr, int Endpt, int bOutbound,
return td;
}
return td;
}
-void *UHCI_
InitControl(void *Ptr, int Endpt
)
+void *UHCI_
int_InitEndpt(tUHCI_Controller *Cont, int Type, int Endpt, size_t MaxPacketSize
)
{
{
- // TODO: Bitmap of tgl values
- return (void*)(Endpt+1);
+ if( Endpt >= 256*16 )
+ return NULL;
+
+ if( MaxPacketSize > MAX_PACKET_SIZE) {
+ Log_Warning("UHCI", "MaxPacketSize for %x greater than controller max (%i > %i)",
+ Endpt, MaxPacketSize, MAX_PACKET_SIZE);
+ return NULL;
+ }
+
+ if( Cont->DevInfo[Endpt / 16] == NULL ) {
+ Cont->DevInfo[Endpt / 16] = calloc( 1, sizeof(*Cont->DevInfo[0]) );
+ }
+ tUHCI_EndpointInfo *epi = &Cont->DevInfo[Endpt/16]->EndpointInfo[Endpt%16];
+ if( epi->Type ) {
+ // oops, in use
+ Log_Warning("UHCI", "Endpoint %x reused?", Endpt);
+ return NULL;
+ }
+
+ epi->MaxPacketSize = MaxPacketSize;
+ epi->Type = Type;
+ epi->Tgl = 0;
+
+ return (void*)(tVAddr)(Endpt+1);
+
}
}
-void *UHCI_Init
Bulk(void *Ptr, int Endpt
)
+void *UHCI_Init
Control(void *Ptr, int Endpt, size_t MaxPacketSize
)
{
{
- // TODO: Bitmap of tgl values
- return (void*)(Endpt+1);
+ return UHCI_int_InitEndpt(Ptr, 1, Endpt, MaxPacketSize);
+}
+
+void *UHCI_InitBulk(void *Ptr, int Endpt, size_t MaxPacketSize)
+{
+ return UHCI_int_InitEndpt(Ptr, 2, Endpt, MaxPacketSize);
}
void UHCI_RemoveEndpoint(void *Ptr, void *Handle)
{
}
void UHCI_RemoveEndpoint(void *Ptr, void *Handle)
{
- if( (int)Handle < 0x7FF ) {
-
+ tUHCI_Controller *Cont = Ptr;
+ if( Handle == NULL )
+ return ;
+
+ if( (tVAddr)Handle <= 256*16 ) {
+ int addr = (tVAddr)Handle;
+ Cont->DevInfo[addr/16]->EndpointInfo[addr%16].Type = 0;
}
else {
// TODO: Stop interrupt transaction
}
else {
// TODO: Stop interrupt transaction
@@
-542,13
+590,14
@@
void *UHCI_SendControl(void *Ptr, void *Endpt, tUSBHostCb Cb, void *CbData,
void *InData, size_t InLength
)
{
void *InData, size_t InLength
)
{
- ENTER("pPtr pEndpt
i
bOutbound", Ptr, Endpt, bOutbound);
+ ENTER("pPtr pEndpt bOutbound", Ptr, Endpt, bOutbound);
tUHCI_Controller *Cont = Ptr;
tUHCI_QH *qh = &Cont->TDQHPage->ControlQH;
tUHCI_TD *td;
tUHCI_Controller *Cont = Ptr;
tUHCI_QH *qh = &Cont->TDQHPage->ControlQH;
tUHCI_TD *td;
- int Dest = (int)Endpt-1;
- int Tgl = 0;
+ tUHCI_EndpointInfo *epi;
+ int dest, tgl;
+ size_t mps;
if( Endpt == NULL ) {
Log_Error("UHCI", "Passed a NULL Endpoint handle");
if( Endpt == NULL ) {
Log_Error("UHCI", "Passed a NULL Endpoint handle");
@@
-561,10
+610,12
@@
void *UHCI_SendControl(void *Ptr, void *Endpt, tUSBHostCb Cb, void *CbData,
LEAVE('n');
return NULL;
}
LEAVE('n');
return NULL;
}
- // if( Cont->Devs[Dest/16] == NULL ) LEAVE_RET('n', NULL);
- // if( Cont->Devs[Dest/16].EndPt[Dest%16].Type != 1 ) LEAVE_RET('n', NULL);
- // MAX_PACKET_SIZE = Cont->Devs[Dest/16].EndPt[Dest%16].MPS;
- // Tgl = Cont->Devs[Dest/16].EndPt[Dest%16].Tgl;
+ dest = (tVAddr)Endpt - 1;
+ if( Cont->DevInfo[dest/16] == NULL ) LEAVE_RET('n', NULL);
+ epi = &Cont->DevInfo[dest/16]->EndpointInfo[dest%16];
+ if( epi->Type != 1 ) LEAVE_RET('n', NULL);
+ mps = epi->MaxPacketSize;
+ tgl = epi->Tgl;
// TODO: Build up list and then append to QH in one operation
// TODO: Build up list and then append to QH in one operation
@@
-582,33
+633,41
@@
void *UHCI_SendControl(void *Ptr, void *Endpt, tUSBHostCb Cb, void *CbData,
}
// Sanity check data lengths
}
// Sanity check data lengths
- if( SetupLength >
MAX_PACKET_SIZE )
LEAVE_RET('n', NULL);
- if( status_len >
MAX_PACKET_SIZE )
LEAVE_RET('n', NULL);
+ if( SetupLength >
mps )
LEAVE_RET('n', NULL);
+ if( status_len >
mps )
LEAVE_RET('n', NULL);
// Create and append SETUP packet
// Create and append SETUP packet
- td = UHCI_int_CreateTD(Cont,
Dest, PID_SETUP, T
gl, NULL, NULL, (void*)SetupData, SetupLength);
+ td = UHCI_int_CreateTD(Cont,
dest, PID_SETUP, t
gl, NULL, NULL, (void*)SetupData, SetupLength);
UHCI_int_AppendTD(Cont, qh, td);
UHCI_int_AppendTD(Cont, qh, td);
-
Tgl = !T
gl;
+
tgl = !t
gl;
- //
D
ata packets
+ //
Send d
ata packets
while( data_len > 0 )
{
while( data_len > 0 )
{
- size_t len = MIN(data_len,
MAX_PACKET_SIZE
);
- td = UHCI_int_CreateTD(Cont,
Dest, data_pid, T
gl, NULL, NULL, data_ptr, len);
+ size_t len = MIN(data_len,
mps
);
+ td = UHCI_int_CreateTD(Cont,
dest, data_pid, t
gl, NULL, NULL, data_ptr, len);
UHCI_int_AppendTD(Cont, qh, td);
UHCI_int_AppendTD(Cont, qh, td);
-
Tgl = !T
gl;
+
tgl = !t
gl;
data_ptr += len;
data_len -= len;
data_ptr += len;
data_len -= len;
- // TODO: Handle multi-packet
}
}
- td = UHCI_int_CreateTD(Cont, Dest, status_pid, Tgl, Cb, CbData, status_ptr, status_len);
+ // Send status
+ td = UHCI_int_CreateTD(Cont, dest, status_pid, tgl, Cb, CbData, status_ptr, status_len);
UHCI_int_AppendTD(Cont, qh, td);
UHCI_int_AppendTD(Cont, qh, td);
- Tgl = !Tgl;
-
- // Cont->Devs[Dest/16].EndPt[Dest%16].Tgl = !Tgl;
+ tgl = !tgl;
+ // Update toggle value
+ epi->Tgl = tgl;
+
+ // --- HACK!!!
+// for( int i = 0; i < 1024; i ++ )
+// {
+// LOG("- FrameList[%i] = %x", i, Cont->FrameList[i]);
+// }
+ // --- /HACK
+
LEAVE('p', td);
return td;
}
LEAVE('p', td);
return td;
}
@@
-618,35
+677,55
@@
void *UHCI_SendBulk(void *Ptr, void *Endpt, tUSBHostCb Cb, void *CbData, int bOu
tUHCI_Controller *Cont = Ptr;
tUHCI_QH *qh = &Cont->TDQHPage->BulkQH;
tUHCI_TD *td = NULL;
tUHCI_Controller *Cont = Ptr;
tUHCI_QH *qh = &Cont->TDQHPage->BulkQH;
tUHCI_TD *td = NULL;
- int Dest = (int)Endpt - 1;
- int Tgl = 0;
+ tUHCI_EndpointInfo *epi;
+ int dest, tgl;
+ size_t mps;
- ENTER("pPtr pEndpt pCb pCbData bOutbound pData iLength", Ptr,
Des
t, Cb, CbData, bOutbound, Data, Length);
+ ENTER("pPtr pEndpt pCb pCbData bOutbound pData iLength", Ptr,
Endp
t, Cb, CbData, bOutbound, Data, Length);
if( Endpt == NULL ) {
if( Endpt == NULL ) {
- Log_Error("UHCI", "
Passed a NULL E
ndpoint handle");
+ Log_Error("UHCI", "
_SendBulk passed a NULL e
ndpoint handle");
LEAVE('n');
return NULL;
}
// Sanity check Endpt
LEAVE('n');
return NULL;
}
// Sanity check Endpt
- // TODO: Validation
- // TODO: Data toggle
+ if( (tVAddr)Endpt > 256*16 ) {
+ Log_Error("UHCI", "_SendBulk passed an interrupt endpoint handle");
+ LEAVE('n');
+ return NULL;
+ }
+ dest = (tVAddr)Endpt - 1;
+ if( Cont->DevInfo[dest/16] == NULL ) {
+ Log_Error("UHCI", "_SendBulk passed an uninitialised handle");
+ LEAVE('n');
+ return NULL;
+ }
+ epi = &Cont->DevInfo[dest/16]->EndpointInfo[dest%16];
+ if( epi->Type != 2 ) {
+ Log_Error("UHCI", "_SendBulk passed an invalid endpoint type (%i!=2)", epi->Type);
+ LEAVE('n');
+ return NULL;
+ }
+ tgl = epi->Tgl;
+ mps = epi->MaxPacketSize;
Uint8 pid = (bOutbound ? PID_OUT : PID_IN);
char *pos = Data;
while( Length > 0 )
{
Uint8 pid = (bOutbound ? PID_OUT : PID_IN);
char *pos = Data;
while( Length > 0 )
{
- size_t len = MIN(
MAX_PACKET_SIZE
, Length);
+ size_t len = MIN(
mps
, Length);
- td = UHCI_int_CreateTD(Cont,
Dest, pid, T
gl, Cb, (len == Length ? CbData : NULL), pos, len);
+ td = UHCI_int_CreateTD(Cont,
dest, pid, t
gl, Cb, (len == Length ? CbData : NULL), pos, len);
UHCI_int_AppendTD(Cont, qh, td);
pos += len;
Length -= len;
UHCI_int_AppendTD(Cont, qh, td);
pos += len;
Length -= len;
-
Tgl = !T
gl;
+
tgl = !t
gl;
}
}
+
+ epi->Tgl = tgl;
LEAVE('p', td);
return td;
LEAVE('p', td);
return td;
@@
-744,7
+823,8
@@
void UHCI_int_CleanQH(tUHCI_Controller *Cont, tUHCI_QH *QH)
continue ;
}
continue ;
}
- LOG("Removed %p from QH %p", td, QH);
+ LOG("Removed %p from QH %p", td, QH);
+ ASSERT(td->Link);
if( !prev )
QH->Child = td->Link;
if( !prev )
QH->Child = td->Link;
@@
-912,26
+992,38
@@
void UHCI_InterruptHandler(int IRQ, void *Ptr)
// USB Error Interrupt
if( status & 2 )
{
// USB Error Interrupt
if( status & 2 )
{
-
+ Log_Notice("UHCI", "USB Error");
}
// Resume Detect
// - Fired if in suspend state and a USB device sends the RESUME signal
if( status & 4 )
{
}
// Resume Detect
// - Fired if in suspend state and a USB device sends the RESUME signal
if( status & 4 )
{
-
+ Log_Notice("UHCI", "Resume Detect");
}
// Host System Error
if( status & 8 )
{
}
// Host System Error
if( status & 8 )
{
-
+ Log_Notice("UHCI", "Host System Error");
}
// Host Controller Process Error
if( status & 0x10 )
{
Log_Error("UHCI", "Host controller process error on controller %p", Ptr);
}
// Host Controller Process Error
if( status & 0x10 )
{
Log_Error("UHCI", "Host controller process error on controller %p", Ptr);
+ // Spam Tree
+ //for( int i = 0; i < 1024; i += 4 ) {
+ // LOG("%4i: %x", i, Host->FrameList[i]);
+ //}
+
+ tPAddr phys = Host->TDQHPage->ControlQH.Child;
+ while( !(phys & 1) && MM_GetRefCount(phys & ~15))
+ {
+ tUHCI_TD *td = UHCI_int_GetTDFromPhys(Host, phys);
+ LOG("%08P: %08x %08x %08x", phys, td->Control, td->Token, td->BufferPointer);
+ phys = td->Link;
+ }
}
_OutWord(Host, USBSTS, status);
}
_OutWord(Host, USBSTS, status);
UCC
git Repository :: git.ucc.asn.au