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

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