2f1950a6630ae17395ec8d817968ad27c2e723d6
[tpg/acess2.git] / Modules / USB / 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 <common.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         Uint16  base;\r
37         \r
38         ENTER("");\r
39         \r
40         // Enumerate PCI Bus, getting a maximum of `MAX_CONTROLLERS` devices\r
41         while( (id = PCI_GetDeviceByClass(0x0C03, 0xFFFF, id)) >= 0 && i < MAX_CONTROLLERS )\r
42         {\r
43                 gUHCI_Controllers[i].PciId = id;\r
44                 // Assign a port range (BAR4, Reserve 32 ports)\r
45                 base = PCI_AssignPort( id, 4, 0x20 );\r
46                 gUHCI_Controllers[i].IOBase = base;\r
47                 \r
48                 LOG("Controller PCI #%i: IO Base = 0x%x", id, base);\r
49                 \r
50                 // Initialise Host\r
51                 ret = UHCI_Int_InitHost(&gUHCI_Controllers[i]);\r
52                 // Detect an error\r
53                 if(ret != 0) {\r
54                         LEAVE('i', ret);\r
55                         return ret;\r
56                 }\r
57                 \r
58                 i ++;\r
59         }\r
60         if(i == MAX_CONTROLLERS) {\r
61                 Warning("[UHCI ] Over "EXPAND_STR(MAX_CONTROLLERS)" UHCI controllers detected, ignoring rest");\r
62         }\r
63         LEAVE('i', i);\r
64         return i;\r
65 }\r
66 \r
67 /**\r
68  * \fn void UHCI_Cleanup()\r
69  * \brief Called just before module is unloaded\r
70  */\r
71 void UHCI_Cleanup()\r
72 {\r
73 }
74 \r
75 /**\r
76  * \brief Sends a packet to a device endpoint\r
77  */\r
78 int UHCI_SendPacket(int ControllerId, int Device, int Endpoint, void *Data, int Length)\r
79 {\r
80         return 0;\r
81 }\r
82 \r
83 // === INTERNAL FUNCTIONS ===\r
84 /**\r
85  * \fn int UHCI_Int_InitHost(tUCHI_Controller *Host)\r
86  * \brief Initialises a UHCI host controller\r
87  * \param Host  Pointer - Host to initialise\r
88  */\r
89 int UHCI_Int_InitHost(tUHCI_Controller *Host)\r
90 {\r
91         ENTER("pHost", Host);\r
92         \r
93         // Allocate Frame List\r
94         Host->FrameList = (void *) MM_AllocDMA(1, 32, &Host->PhysFrameList);    // 1 Page, 32-bit\r
95         if( !Host->FrameList ) {\r
96                 Warning("[UHCI ] Unable to allocate frame list, aborting");\r
97                 LEAVE('i', -1);\r
98                 return -1;\r
99         }\r
100         LOG("Allocated frame list 0x%x (0x%x)", Host->FrameList, Host->PhysFrameList);\r
101         memsetd( Host->FrameList, 1, 1024 );    // Clear List (Disabling all entries)\r
102         \r
103         //! \todo Properly fill frame list\r
104         \r
105         // Set frame length to 1 ms\r
106         outb( Host->IOBase + SOFMOD, 64 );\r
107         \r
108         // Set Frame List Address\r
109         outd( Host->IOBase + FLBASEADD, Host->PhysFrameList );\r
110         \r
111         // Set Frame Number\r
112         outw( Host->IOBase + FRNUM, 0 );\r
113         \r
114         // Enable Interrupts\r
115         //PCI_WriteWord( Host->PciId, 0xC0, 0x2000 );\r
116         \r
117         LEAVE('i', 0);\r
118         return 0;\r
119 }\r

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