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

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