Rev 1430 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 1430 | Rev 1600 | ||
---|---|---|---|
1 | #include "types.h" |
1 | #include |
- | 2 | #include |
|
2 | #include "link.h" |
3 | #include |
3 | 4 | ||
4 | #include |
5 | //#include |
5 | #include |
6 | //#include |
6 | #include |
7 | //#include |
7 | - | ||
8 | #include "pci.h" |
8 | |
9 | 9 | ||
10 | #include "syscall.h" |
10 | #include |
11 | #include "usb.h" |
11 | #include "usb.h" |
12 | 12 | ||
13 | 13 | ||
14 | int __stdcall srv_usb(ioctl_t *io); |
14 | int __stdcall srv_usb(ioctl_t *io); |
15 | 15 | ||
16 | Bool init_hc(hc_t *hc); |
16 | bool init_hc(hc_t *hc); |
17 | 17 | ||
18 | static slab_t qh_slab; |
18 | static slab_t qh_slab; |
19 | static slab_t td_slab; |
19 | static slab_t td_slab; |
20 | 20 | ||
21 | static link_t hc_list; |
21 | LIST_HEAD( hc_list ); |
22 | static link_t newdev_list; |
22 | LIST_HEAD( newdev_list ); |
23 | static link_t rq_list; |
23 | LIST_HEAD( rq_list ); |
24 | 24 | ||
25 | u32_t __stdcall drvEntry(int action) |
25 | u32_t drvEntry(int action, char *cmdline) |
26 | { |
26 | { |
27 | u32_t retval; |
27 | u32_t retval; |
28 | hc_t *hc; |
28 | hc_t *hc; |
29 | udev_t *dev; |
29 | udev_t *dev; |
30 | 30 | ||
31 | int i; |
31 | int i; |
32 | 32 | ||
33 | if(action != 1) |
33 | if(action != 1) |
34 | return 0; |
34 | return 0; |
35 | 35 | ||
36 | if(!dbg_open("/rd/1/drivers/usb.log")) |
36 | if(!dbg_open("/rd/1/drivers/usb.log")) |
37 | { |
37 | { |
38 | printf("Can't open /rd/1/drivers/usb.log\nExit\n"); |
38 | printf("Can't open /rd/1/drivers/usb.log\nExit\n"); |
39 | return 0; |
39 | return 0; |
40 | } |
40 | } |
41 | 41 | ||
42 | list_initialize(&hc_list); |
42 | if( !FindUSBControllers() ) { |
43 | list_initialize(&newdev_list); |
- | |
44 | list_initialize(&rq_list); |
- | |
45 | - | ||
46 | if( !FindPciDevice() ) { |
- | |
47 | dbgprintf("no uhci devices found\n"); |
43 | dbgprintf("no uhci devices found\n"); |
48 | return 0; |
44 | return 0; |
49 | }; |
45 | }; |
50 | 46 | ||
51 | qh_slab.available = 256; |
47 | qh_slab.available = 256; |
52 | qh_slab.start = KernelAlloc(4096); |
48 | qh_slab.start = KernelAlloc(4096); |
53 | qh_slab.nextavail = (addr_t)qh_slab.start; |
49 | qh_slab.nextavail = (addr_t)qh_slab.start; |
54 | qh_slab.dma = GetPgAddr(qh_slab.start); |
50 | qh_slab.dma = GetPgAddr(qh_slab.start); |
55 | 51 | ||
56 | qh_t *p; |
52 | qh_t *p; |
57 | addr_t dma; |
53 | addr_t dma; |
58 | 54 | ||
59 | for (i = 0, p = (qh_t*)qh_slab.start, dma = qh_slab.dma; |
55 | for (i = 0, p = (qh_t*)qh_slab.start, dma = qh_slab.dma; |
60 | i < 256; i++, p++, dma+= sizeof(qh_t)) |
56 | i < 256; i++, p++, dma+= sizeof(qh_t)) |
61 | { |
57 | { |
62 | p->qlink = (addr_t)(p+1); |
58 | p->qlink = (addr_t)(p+1); |
63 | p->qelem = 1; |
59 | p->qelem = 1; |
64 | p->dma = dma; |
60 | p->dma = dma; |
65 | p->r1 = 0; |
61 | p->r1 = 0; |
66 | }; |
62 | }; |
67 | 63 | ||
68 | td_slab.available = 128; |
64 | td_slab.available = 128; |
69 | td_slab.start = KernelAlloc(4096); |
65 | td_slab.start = KernelAlloc(4096); |
70 | td_slab.nextavail = (addr_t)td_slab.start; |
66 | td_slab.nextavail = (addr_t)td_slab.start; |
71 | td_slab.dma = GetPgAddr(td_slab.start); |
67 | td_slab.dma = GetPgAddr(td_slab.start); |
72 | 68 | ||
73 | td_t *td; |
69 | td_t *td; |
74 | for (i = 0, td = (td_t*)td_slab.start, dma = td_slab.dma; |
70 | for (i = 0, td = (td_t*)td_slab.start, dma = td_slab.dma; |
75 | i < 128; i++, td++, dma+= sizeof(td_t)) |
71 | i < 128; i++, td++, dma+= sizeof(td_t)) |
76 | { |
72 | { |
77 | td->link = (addr_t)(td+1); |
73 | td->link = (addr_t)(td+1); |
78 | td->status = 0; |
74 | td->status = 0; |
79 | td->token = 0; |
75 | td->token = 0; |
80 | td->buffer = 0; |
76 | td->buffer = 0; |
81 | td->dma = dma; |
77 | td->dma = dma; |
82 | }; |
78 | }; |
83 | 79 | ||
84 | 80 | ||
85 | hc = (hc_t*)hc_list.next; |
81 | hc = (hc_t*)hc_list.next; |
86 | 82 | ||
87 | while( &hc->link != &hc_list) |
83 | while( &hc->list != &hc_list) |
88 | { |
84 | { |
89 | init_hc(hc); |
85 | init_hc(hc); |
90 | hc = (hc_t*)hc->link.next; |
86 | hc = (hc_t*)hc->list.next; |
91 | } |
87 | } |
92 | 88 | ||
93 | dbgprintf("\n"); |
89 | dbgprintf("\n"); |
94 | 90 | ||
95 | dev = (udev_t*)newdev_list.next; |
91 | dev = (udev_t*)newdev_list.next; |
96 | while( &dev->link != &newdev_list) |
92 | while( &dev->list != &newdev_list) |
97 | { |
93 | { |
98 | udev_t *tmp = dev; |
94 | udev_t *tmp = dev; |
99 | dev = (udev_t*)dev->link.next; |
95 | dev = (udev_t*)dev->list.next; |
100 | 96 | ||
101 | if(tmp->id != 0) |
97 | if(tmp->id != 0) |
102 | init_device(tmp); |
98 | init_device(tmp); |
103 | } |
99 | } |
104 | 100 | ||
105 | while(1) |
101 | while(1) |
106 | { |
102 | { |
107 | udev_t *dev; |
103 | udev_t *dev; |
108 | request_t *rq; |
104 | request_t *rq; |
109 | 105 | ||
110 | rq = (request_t*)rq_list.next; |
106 | rq = (request_t*)rq_list.next; |
111 | while( &rq->link != &rq_list) |
107 | while( &rq->list != &rq_list) |
112 | { |
108 | { |
113 | qh_t *qh; |
109 | qh_t *qh; |
114 | td_t *td; |
110 | td_t *td; |
115 | 111 | ||
116 | td = rq->td_head; |
112 | td = rq->td_head; |
117 | dev = rq->dev; |
113 | dev = rq->dev; |
118 | qh = dev->host->qh1; |
114 | qh = dev->host->qh1; |
119 | 115 | ||
120 | qh->qelem = td->dma; |
116 | qh->qelem = td->dma; |
121 | 117 | ||
122 | __asm__ __volatile__ ("":::"memory"); |
118 | __asm__ __volatile__ ("":::"memory"); |
123 | rq = (request_t*)rq->link.next; |
119 | rq = (request_t*)rq->list.next; |
124 | }; |
120 | }; |
125 | 121 | ||
126 | delay(10/10); |
122 | delay(10/10); |
127 | 123 | ||
128 | rq = (request_t*)rq_list.next; |
124 | rq = (request_t*)rq_list.next; |
129 | while( &rq->link != &rq_list) |
125 | while( &rq->list != &rq_list) |
130 | { |
126 | { |
131 | request_t *tmp; |
127 | request_t *tmp; |
132 | td_t *td; |
128 | td_t *td; |
133 | 129 | ||
134 | tmp = rq; |
130 | tmp = rq; |
135 | rq = (request_t*)rq->link.next; |
131 | rq = (request_t*)rq->list.next; |
136 | 132 | ||
137 | td = tmp->td_head; |
133 | td = tmp->td_head; |
138 | 134 | ||
139 | if( td->status & TD_CTRL_ACTIVE) |
135 | if( td->status & TD_CTRL_ACTIVE) |
140 | continue; |
136 | continue; |
141 | 137 | ||
142 | tmp->handler(tmp->dev, tmp); |
138 | tmp->handler(tmp->dev, tmp); |
143 | }; |
139 | }; |
144 | }; |
140 | }; |
145 | 141 | ||
146 | retval = RegService("USB", srv_usb); |
142 | retval = RegService("USB", srv_usb); |
147 | dbgprintf("reg service USB as: %x\n", retval); |
143 | dbgprintf("reg service USB as: %x\n", retval); |
148 | 144 | ||
149 | return retval; |
145 | return retval; |
150 | }; |
146 | }; |
151 | 147 | ||
152 | 148 | ||
153 | #define API_VERSION 0x01000100 |
149 | #define API_VERSION 0x01000100 |
154 | 150 | ||
155 | #define SRV_GETVERSION 0 |
151 | #define SRV_GETVERSION 0 |
156 | 152 | ||
157 | 153 | ||
158 | int __stdcall srv_usb(ioctl_t *io) |
154 | int __stdcall srv_usb(ioctl_t *io) |
159 | { |
155 | { |
160 | u32_t *inp; |
156 | u32_t *inp; |
161 | u32_t *outp; |
157 | u32_t *outp; |
162 | 158 | ||
163 | inp = io->input; |
159 | inp = io->input; |
164 | outp = io->output; |
160 | outp = io->output; |
165 | 161 | ||
166 | switch(io->io_code) |
162 | switch(io->io_code) |
167 | { |
163 | { |
168 | case SRV_GETVERSION: |
164 | case SRV_GETVERSION: |
169 | if(io->out_size==4) |
165 | if(io->out_size==4) |
170 | { |
166 | { |
171 | *outp = API_VERSION; |
167 | *outp = API_VERSION; |
172 | return 0; |
168 | return 0; |
173 | } |
169 | } |
174 | break; |
170 | break; |
175 | 171 | ||
176 | 172 | ||
177 | default: |
173 | default: |
178 | return ERR_PARAM; |
174 | return ERR_PARAM; |
179 | }; |
175 | }; |
180 | return ERR_PARAM; |
176 | return ERR_PARAM; |
181 | } |
177 | } |
182 | 178 | ||
183 | 179 | ||
184 | static qh_t* alloc_qh() |
180 | static qh_t* alloc_qh() |
185 | { |
181 | { |
186 | if( qh_slab.available ) |
182 | if( qh_slab.available ) |
187 | { |
183 | { |
188 | qh_t *qh; |
184 | qh_t *qh; |
189 | 185 | ||
190 | qh_slab.available--; |
186 | qh_slab.available--; |
191 | qh = (qh_t*)qh_slab.nextavail; |
187 | qh = (qh_t*)qh_slab.nextavail; |
192 | qh_slab.nextavail = qh->qlink; |
188 | qh_slab.nextavail = qh->qlink; |
193 | return qh; |
189 | return qh; |
194 | } |
190 | } |
195 | return NULL; |
191 | return NULL; |
196 | }; |
192 | }; |
197 | 193 | ||
198 | static void free_qh(qh_t *qh) |
194 | static void free_qh(qh_t *qh) |
199 | { |
195 | { |
200 | qh->qlink = qh_slab.nextavail; |
196 | qh->qlink = qh_slab.nextavail; |
201 | qh_slab.nextavail = (addr_t)qh; |
197 | qh_slab.nextavail = (addr_t)qh; |
202 | qh_slab.available++; |
198 | qh_slab.available++; |
203 | }; |
199 | }; |
204 | 200 | ||
205 | static td_t* alloc_td() |
201 | static td_t* alloc_td() |
206 | { |
202 | { |
207 | if( td_slab.available ) |
203 | if( td_slab.available ) |
208 | { |
204 | { |
209 | td_t *td; |
205 | td_t *td; |
210 | 206 | ||
211 | td_slab.available--; |
207 | td_slab.available--; |
212 | td = (td_t*)td_slab.nextavail; |
208 | td = (td_t*)td_slab.nextavail; |
213 | td_slab.nextavail = td->link; |
209 | td_slab.nextavail = td->link; |
214 | return td; |
210 | return td; |
215 | } |
211 | } |
216 | return NULL; |
212 | return NULL; |
217 | }; |
213 | }; |
218 | 214 | ||
219 | static void free_td(td_t *td) |
215 | static void free_td(td_t *td) |
220 | { |
216 | { |
221 | td->link = td_slab.nextavail; |
217 | td->link = td_slab.nextavail; |
222 | td_slab.nextavail = (addr_t)td; |
218 | td_slab.nextavail = (addr_t)td; |
223 | td_slab.available++; |
219 | td_slab.available++; |
224 | }; |
220 | }; |
225 | 221 | ||
226 | #include "pci.inc" |
222 | #include "pci.inc" |
227 | #include "detect.inc" |
223 | #include "detect.inc" |
228 | #include "hcd.inc" |
224 | #include "hcd.inc" |
229 | #include "hid.inc">> |
225 | #include "hid.inc">> |