Modules/UDI - Minor tweaks
[tpg/acess2.git] / KernelLand / Modules / Interfaces / UDI / trans / bus_pci.c
1 /*
2  * Acess2 UDI Layer
3  * - By John Hodge (thePowersGang)
4  *
5  * trans/bus_pci.c
6  * - PCI Bus Driver
7  */
8 #include <udi.h>
9 #include <udi_physio.h>
10 #include <udi_pci.h>
11 #include <acess.h>
12 #include <drv_pci.h>    // acess
13
14 // === MACROS ===
15 /* Copied from http://projectudi.cvs.sourceforge.net/viewvc/projectudi/udiref/driver/udi_dpt/udi_dpt.h */
16 #define DPT_SET_ATTR_BOOLEAN(attr, name, val)   \
17                 udi_strcpy((attr)->attr_name, (name)); \
18                 (attr)->attr_type = UDI_ATTR_BOOLEAN; \
19                 (attr)->attr_length = sizeof(udi_boolean_t); \
20                 UDI_ATTR32_SET((attr)->attr_value, (val))
21
22 #define DPT_SET_ATTR32(attr, name, val) \
23                 udi_strcpy((attr)->attr_name, (name)); \
24                 (attr)->attr_type = UDI_ATTR_UBIT32; \
25                 (attr)->attr_length = sizeof(udi_ubit32_t); \
26                 UDI_ATTR32_SET((attr)->attr_value, (val))
27
28 #define DPT_SET_ATTR_ARRAY8(attr, name, val, len) \
29                 udi_strcpy((attr)->attr_name, (name)); \
30                 (attr)->attr_type = UDI_ATTR_ARRAY8; \
31                 (attr)->attr_length = (len); \
32                 udi_memcpy((attr)->attr_value, (val), (len))
33
34 #define DPT_SET_ATTR_STRING(attr, name, val, len) \
35                 udi_strcpy((attr)->attr_name, (name)); \
36                 (attr)->attr_type = UDI_ATTR_STRING; \
37                 (attr)->attr_length = (len); \
38                 udi_strncpy_rtrim((char *)(attr)->attr_value, (val), (len))
39
40
41 // === TYPES ===
42 typedef struct
43 {
44         udi_init_context_t      init_context;
45         
46         tPCIDev cur_iter;
47 } pci_rdata_t;
48
49 // === PROTOTYPES ===
50 void    pci_usage_ind(udi_usage_cb_t *cb, udi_ubit8_t resource_level);
51 void    pci_enumerate_req(udi_enumerate_cb_t *cb, udi_ubit8_t enumeration_level);
52 void    pci_devmgmt_req(udi_mgmt_cb_t *cb, udi_ubit8_t mgmt_op, udi_ubit8_t parent_ID);
53 void    pci_final_cleanup_req(udi_mgmt_cb_t *cb);
54
55 void    pci_bridge_ch_event_ind(udi_channel_event_cb_t *cb);
56 void    pci_unbind_req(udi_bus_bind_cb_t *cb);
57 void    pci_bind_req_op(udi_bus_bind_cb_t *cb);
58 void    pci_intr_attach_req(udi_intr_attach_cb_t *cb);
59 void    pci_intr_detach_req(udi_intr_detach_cb_t *cb);
60
61
62 // === CODE ===
63 void pci_usage_ind(udi_usage_cb_t *cb, udi_ubit8_t resource_level)
64 {
65         pci_rdata_t     *rdata = UDI_GCB(cb)->context;
66         
67         switch(cb->meta_idx)
68         {
69         case 1: // mgmt
70                 break;
71         }
72
73         switch(resource_level)
74         {
75         case UDI_RESOURCES_CRITICAL:
76         case UDI_RESOURCES_LOW:
77         case UDI_RESOURCES_NORMAL:
78         case UDI_RESOURCES_PLENTIFUL:
79                 break;
80         }
81
82         // TODO: Initialise rdata
83         rdata->cur_iter = -1;
84
85         udi_usage_res(cb);
86 }
87 void pci_enumerate_req(udi_enumerate_cb_t *cb, udi_ubit8_t enumeration_level)
88 {
89         pci_rdata_t     *rdata = UDI_GCB(cb)->context;
90         switch(enumeration_level)
91         {
92         case UDI_ENUMERATE_START:
93         case UDI_ENUMERATE_START_RESCAN:
94                 rdata->cur_iter = -1;
95         case UDI_ENUMERATE_NEXT:
96                 // TODO: Filters
97                 if( (rdata->cur_iter = PCI_GetDeviceByClass(0,0, rdata->cur_iter)) == -1 )
98                 {
99                         udi_enumerate_ack(cb, UDI_ENUMERATE_DONE, 0);
100                 }
101                 else
102                 {
103                         udi_instance_attr_list_t *attr_list = cb->attr_list;
104                         Uint16  ven, dev;
105                         Uint32  class;
106                         PCI_GetDeviceInfo(rdata->cur_iter, &ven, &dev, &class);
107                         Uint8   revision;
108                         PCI_GetDeviceVersion(rdata->cur_iter, &revision);
109                         Uint16  sven, sdev;
110                         PCI_GetDeviceSubsys(rdata->cur_iter, &sven, &sdev);
111
112                         udi_strcpy(attr_list->attr_name, "identifier");
113                         attr_list->attr_length = snprintf(attr_list->attr_value,
114                                 "%04x%04x%02x%04x%04x",
115                                 ven, dev, revision, sven, sdev);
116                         attr_list ++;
117                         DPT_SET_ATTR_STRING(attr_list, "bus_type", "pci", 3);
118                         attr_list ++;
119                         DPT_SET_ATTR32(attr_list, "pci_vendor_id", ven);
120                         attr_list ++;
121                         DPT_SET_ATTR32(attr_list, "pci_device_id", dev);
122                         attr_list ++;
123
124                         cb->attr_valid_length = attr_list - cb->attr_list;
125                         cb->child_ID = rdata->cur_iter;
126                         udi_enumerate_ack(cb, UDI_ENUMERATE_OK, 1);
127                 }
128                 break;
129         }
130 }
131 void pci_devmgmt_req(udi_mgmt_cb_t *cb, udi_ubit8_t mgmt_op, udi_ubit8_t parent_ID)
132 {
133         UNIMPLEMENTED();
134 }
135 void pci_final_cleanup_req(udi_mgmt_cb_t *cb)
136 {
137         UNIMPLEMENTED();
138 }
139
140 void pci_bridge_ch_event_ind(udi_channel_event_cb_t *cb)
141 {
142         UNIMPLEMENTED();
143 }
144 void pci_bind_req(udi_bus_bind_cb_t *cb)
145 {
146         // TODO: "Lock" PCI device
147
148         // TODO: DMA constraints
149         udi_bus_bind_ack(cb, 0, UDI_DMA_LITTLE_ENDIAN, UDI_OK);
150 }
151 void pci_unbind_req(udi_bus_bind_cb_t *cb)
152 {
153         UNIMPLEMENTED();
154 }
155 void pci_intr_attach_req(udi_intr_attach_cb_t *cb)
156 {
157         UNIMPLEMENTED();
158 }
159 void pci_intr_detach_req(udi_intr_detach_cb_t *cb)
160 {
161         UNIMPLEMENTED();
162 }
163
164 // === UDI Functions ===
165 udi_mgmt_ops_t  pci_mgmt_ops = {
166         pci_usage_ind,
167         pci_enumerate_req,
168         pci_devmgmt_req,
169         pci_final_cleanup_req
170 };
171 udi_ubit8_t     pci_mgmt_op_flags[4] = {0,0,0,0};
172 udi_bus_bridge_ops_t    pci_bridge_ops = {
173         pci_bridge_ch_event_ind,
174         pci_bind_req,
175         pci_unbind_req,
176         pci_intr_attach_req,
177         pci_intr_detach_req
178 };
179 udi_ubit8_t     pci_bridge_op_flags[5] = {0,0,0,0,0};
180 udi_primary_init_t      pci_pri_init = {
181         .mgmt_ops = &pci_mgmt_ops,
182         .mgmt_op_flags = pci_mgmt_op_flags,
183         .mgmt_scratch_requirement = 0,
184         .enumeration_attr_list_length = 4,
185         .rdata_size = sizeof(pci_rdata_t),
186         .child_data_size = 0,
187         .per_parent_paths = 0
188 };
189 udi_ops_init_t  pci_ops_list[] = {
190         {
191                 1, 1, UDI_BUS_BRIDGE_OPS_NUM,
192                 0,
193                 (udi_ops_vector_t*)&pci_bridge_ops,
194                 pci_bridge_op_flags
195         },
196         {0}
197 };
198 udi_init_t      pci_init = {
199         .primary_init_info = &pci_pri_init,
200         .ops_init_list = pci_ops_list
201 };
202 const char      pci_udiprops[] =
203         "properties_version 0x101\0"
204         "message 1 Acess2 Kernel\0"
205         "message 2 John Hodge ([email protected])\0"
206         "message 3 Acess2 PCI Bus\0"
207         "supplier 1\0"
208         "contact 2\0"
209         "name 3\0"
210         "module acess_pci\0"
211         "shortname acesspci\0"
212         "requires udi 0x101\0"
213         "provides udi_bridge 0x101\0"
214         "meta 1 udi_bridge\0"
215         "enumerates 4 0 100 1 bus_name string pci\0"
216         "region 0\0"
217         "child_bind_ops 1 0 1\0"
218         "";
219 size_t  pci_udiprops_size = sizeof(pci_udiprops);

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