fb92d545e49c928ca8097ed25812d82b0f721e6f
[tpg/acess2.git] / Modules / USB / Core / uhci.c
1 /*\r
2  * Acess 2 USB Stack\r
3  * Universal Host Controller Interface\r
4  */\r
5 #define DEBUG   1\r
6 #include <acess.h>\r
7 #include <vfs.h>\r
8 #include <drv_pci.h>\r
9 #include "usb.h"\r
10 #include "uhci.h"\r
11 \r
12 // === CONSTANTS ===\r
13 #define MAX_CONTROLLERS 4\r
14 #define NUM_TDs 1024\r
15 \r
16 // === PROTOTYPES ===\r
17  int    UHCI_Initialise();\r
18 void    UHCI_Cleanup();\r
19  int    UHCI_IOCtl(tVFS_Node *node, int id, void *data);\r
20  int    UHCI_Int_InitHost(tUHCI_Controller *Host);\r
21 \r
22 // === GLOBALS ===
23 //Uint  gaFrameList[1024];\r
24 tUHCI_TD        gaUHCI_TDPool[NUM_TDs];\r
25 tUHCI_Controller        gUHCI_Controllers[MAX_CONTROLLERS];\r
26 \r
27 // === CODE ===\r
28 /**\r
29  * \fn int UHCI_Initialise()\r
30  * \brief Called to initialise the UHCI Driver\r
31  */\r
32 int UHCI_Initialise()\r
33 {\r
34          int    i=0, id=-1;\r
35          int    ret;\r
36         \r
37         ENTER("");\r
38         \r
39         // Enumerate PCI Bus, getting a maximum of `MAX_CONTROLLERS` devices\r
40         while( (id = PCI_GetDeviceByClass(0x0C03, 0xFFFF, id)) >= 0 && i < MAX_CONTROLLERS )\r
41         {\r
42                 // NOTE: Check "protocol" from PCI?\r
43                 \r
44                 gUHCI_Controllers[i].PciId = id;\r
45                 // Assign a port range (BAR4, Reserve 32 ports)\r
46                 //base = PCI_AssignPort( id, 4, 0x20 );\r
47                 gUHCI_Controllers[i].IOBase = PCI_GetBAR4(id);\r
48                 gUHCI_Controllers[i].IRQNum = PCI_GetIRQ(id);\r
49                 \r
50                 Log("[USB  ] Controller PCI #%i: IO Base = 0x%x, IRQ %i",\r
51                         id, gUHCI_Controllers[i].IOBase, gUHCI_Controllers[i].IRQNum);\r
52                 \r
53                 // Initialise Host\r
54                 ret = UHCI_Int_InitHost(&gUHCI_Controllers[i]);\r
55                 // Detect an error\r
56                 if(ret != 0) {\r
57                         LEAVE('i', ret);\r
58                         return ret;\r
59                 }\r
60                 \r
61                 i ++;\r
62         }\r
63         if(i == MAX_CONTROLLERS) {\r
64                 Warning("[UHCI ] Over "EXPAND_STR(MAX_CONTROLLERS)" UHCI controllers detected, ignoring rest");\r
65         }\r
66         LEAVE('i', i);\r
67         return i;\r
68 }\r
69 \r
70 /**\r
71  * \fn void UHCI_Cleanup()\r
72  * \brief Called just before module is unloaded\r
73  */\r
74 void UHCI_Cleanup()\r
75 {\r
76 }
77 \r
78 /**\r
79  * \brief Sends a packet to a device endpoint\r
80  */\r
81 int UHCI_SendPacket(int ControllerId, int Length)\r
82 {\r
83         //tUHCI_TD      *td = UHCI_AllocateTD();\r
84         return 0;\r
85 }\r
86 \r
87 // === INTERNAL FUNCTIONS ===\r
88 /**\r
89  * \fn int UHCI_Int_InitHost(tUCHI_Controller *Host)\r
90  * \brief Initialises a UHCI host controller\r
91  * \param Host  Pointer - Host to initialise\r
92  */\r
93 int UHCI_Int_InitHost(tUHCI_Controller *Host)\r
94 {\r
95         ENTER("pHost", Host);\r
96         \r
97         outw( Host->IOBase + USBCMD, 4 );       // GRESET\r
98         // TODO: Wait for at least 10ms\r
99         outw( Host->IOBase + USBCMD, 0 );       // GRESET\r
100         \r
101         // Allocate Frame List\r
102         Host->FrameList = (void *) MM_AllocDMA(1, 32, &Host->PhysFrameList);    // 1 Page, 32-bit\r
103         if( !Host->FrameList ) {\r
104                 Log_Warning("UHCI", "Unable to allocate frame list, aborting");\r
105                 LEAVE('i', -1);\r
106                 return -1;\r
107         }\r
108         LOG("Allocated frame list 0x%x (0x%x)", Host->FrameList, Host->PhysFrameList);\r
109         memsetd( Host->FrameList, 1, 1024 );    // Clear List (Disabling all entries)\r
110         \r
111         //! \todo Properly fill frame list\r
112         \r
113         // Set frame length to 1 ms\r
114         outb( Host->IOBase + SOFMOD, 64 );\r
115         \r
116         // Set Frame List Address\r
117         outd( Host->IOBase + FLBASEADD, Host->PhysFrameList );\r
118         \r
119         // Set Frame Number\r
120         outw( Host->IOBase + FRNUM, 0 );\r
121         \r
122         // Enable Interrupts\r
123         //PCI_WriteWord( Host->PciId, 0xC0, 0x2000 );\r
124         \r
125         LEAVE('i', 0);\r
126         return 0;\r
127 }\r

UCC git Repository :: git.ucc.asn.au