aa29dc000dcd6f26140bde2a13fca6370140eaa7
[reactos.git] / reactos / drivers / usb / cromwell / sys / linuxwrapper.c
1 /*
2 * USB support based on Linux kernel source
3 *
4 * 2003-06-21 Georg Acher (georg@acher.org)
5 *
6 * Concept:
7 *
8 * 1) Forget all device interrupts, scheduling, semaphores, threads etc.
9 * 1a) Forget all DMA and PCI helper functions
10 * 2) Forget usbdevfs, procfs and ioctls
11 * 3) Emulate OHCI interrupts and root hub timer by polling
12 * 4) Emulate hub kernel thread by polling
13 * 5) Emulate synchronous USB-messages (usb_*_msg) with busy waiting
14 *
15 * To be done:
16 * 6) Remove code bloat
17 *
18 */
19
20 #include "../usb_wrapper.h"
21
22 /* internal state */
23
24 static struct pci_dev *pci_probe_dev;
25 extern int (*thread_handler)(void*);
26 extern void* thread_parm;
27
28 struct my_irqs reg_irqs[MAX_IRQS];
29 int num_irqs;
30 int need_wakeup;
31
32 int my_jiffies;
33
34 struct timer_list *main_timer_list[MAX_TIMERS];
35 struct dummy_process act_cur={0};
36 struct dummy_process *my_current;
37
38 int (*thread_handler)(void*);
39 void* thread_parm;
40
41 #define MAX_DRVS 8
42 static struct device_driver *m_drivers[MAX_DRVS];
43 static int drvs_num;
44
45 /*------------------------------------------------------------------------*/
46 /*
47 * Helper functions for top-level system
48 */
49 /*------------------------------------------------------------------------*/
50 void init_wrapper(struct pci_dev *probe_dev)
51 {
52 int n;
53 for(n=0;n<MAX_TIMERS;n++)
54 {
55 main_timer_list[n]=NULL;
56 }
57
58 my_jiffies=0;
59 num_irqs=0;
60 my_current=&act_cur;
61 pci_probe_dev=probe_dev;
62
63 for(n=0;n<MAX_IRQS;n++)
64 {
65 reg_irqs[n].handler=NULL;
66 reg_irqs[n].irq=-1;
67 }
68 drvs_num=0;
69 need_wakeup=0;
70 for(n=0;n<MAX_DRVS;n++)
71 m_drivers[n]=NULL;
72 }
73 /*------------------------------------------------------------------------*/
74 void handle_irqs(int irq)
75 {
76 int n;
77 // printk("handle irqs\n");
78 DPRINT1("Handle Irqs\n");
79 for(n=0;n<MAX_IRQS;n++)
80 {
81 if (reg_irqs[n].handler && (irq==reg_irqs[n].irq || irq==-1))
82 reg_irqs[n].handler(reg_irqs[n].irq,reg_irqs[n].data,NULL);
83 }
84 }
85 /*------------------------------------------------------------------------*/
86 void inc_jiffies(int n)
87 {
88 my_jiffies+=n;
89 }
90 /*------------------------------------------------------------------------*/
91 void do_all_timers(void)
92 {
93 int n;
94 for(n=0;n<MAX_TIMERS;n++)
95 {
96 if (main_timer_list[n] &&
97 main_timer_list[n]->function && main_timer_list[n]->expires)
98 {
99 void (*function)(unsigned long)=main_timer_list[n]->function;
100 unsigned long data=main_timer_list[n]->data;
101 main_timer_list[n]->expires=0;
102
103 main_timer_list[n]=NULL; // remove timer
104 // printk("do timer %i fn %p\n",n,function);
105 DPRINT1("do timer %i fn %p\n",n,function);
106
107 function(data);
108 }
109 }
110 }
111 /*------------------------------------------------------------------------*/
112 // Purpose: Remember thread procedure and data in global var
113 // ReactOS Purpose: Create real kernel thread
114 int my_kernel_thread(int STDCALL (*handler)(void*), void* parm, int flags)
115 {
116 HANDLE hThread;
117 //thread_handler=handler;
118 //thread_parm=parm;
119 //return 42; // PID :-)
120
121 ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);
122
123 PsCreateSystemThread(&hThread,
124 THREAD_ALL_ACCESS,
125 NULL,
126 NULL,
127 NULL,
128 (PKSTART_ROUTINE)handler,
129 parm);
130
131 return (int)hThread; // FIXME: Correct?
132 }
133
134 // Kill the process
135 int my_kill_proc(int pid, int signal, int unk)
136 {
137 HANDLE hThread;
138
139 // TODO: Implement actual process killing
140
141 hThread = (HANDLE)pid;
142 ZwClose(hThread);
143
144 return 0;
145 }
146
147 /*------------------------------------------------------------------------*/
148 /* Device management
149 * As simple as possible, but as complete as necessary ...
150 */
151 /*------------------------------------------------------------------------*/
152
153
154 /* calls probe function for hotplug (which does device matching), this is the
155 only link between usbcore and the registered device drivers! */
156 int my_device_add(struct device *dev)
157 {
158 int n,found=0;
159 // printk("drv_num %i %p %p\n",drvs_num,m_drivers[0]->probe,m_drivers[1]->probe);
160 DPRINT1("drv_num %i %p %p\n",drvs_num,m_drivers[0]->probe,m_drivers[1]->probe);
161
162 if (dev->driver)
163 {
164 if (dev->driver->probe)
165 return dev->driver->probe(dev);
166 }
167 else
168 {
169 for(n=0;n<drvs_num;n++)
170 {
171 if (m_drivers[n]->probe)
172 {
173 dev->driver=m_drivers[n];
174 // printk("probe%i %p ",n,m_drivers[n]->probe);
175 DPRINT1("probe%i %p ",n,m_drivers[n]->probe);
176
177 if (m_drivers[n]->probe(dev) == 0)
178 {
179 // return 0;
180 found=1;
181 }
182 }
183 }
184 if (found) return 0;
185 }
186 dev->driver=NULL;
187 return -ENODEV;
188 }
189 /*------------------------------------------------------------------------*/
190 int my_driver_register(struct device_driver *driver)
191 {
192
193 if (drvs_num<MAX_DRVS)
194 {
195 // printk("driver_register %i: %p %p",drvs_num,driver,driver->probe);
196 DPRINT1("driver_register %i: %p %p",drvs_num,driver,driver->probe);
197
198 m_drivers[drvs_num++]=driver;
199 return 0;
200 }
201 return -1;
202 }
203 /*------------------------------------------------------------------------*/
204 int my_device_unregister(struct device *dev)
205 {
206 if (dev->driver && dev->driver->remove)
207 dev->driver->remove(dev);
208 return 0;
209
210 }
211 /*------------------------------------------------------------------------*/
212 struct device *my_get_device(struct device *dev)
213 {
214 return NULL;
215 }
216 /*------------------------------------------------------------------------*/
217 void my_device_initialize(struct device *dev)
218 {
219 }
220 /*------------------------------------------------------------------------*/
221 void my_wake_up(PKEVENT evnt)
222 {
223 need_wakeup=1;
224
225 KeSetEvent(evnt, 0, FALSE); // Signal event
226 }
227 /*------------------------------------------------------------------------*/
228 void my_init_waitqueue_head(PKEVENT evnt)
229 {
230 // this is used only in core/message.c, and it isn't needed there
231 //KeInitializeEvent(evnt, NotificationEvent, TRUE); // signalled state
232 }
233 /*------------------------------------------------------------------------*/
234 /* wait until woken up (only one wait allowed!) */
235 int my_schedule_timeout(int x)
236 {
237 int wait=1;
238 x+=10; // safety
239 // printk("schedule_timeout %i\n",x);
240 DPRINT1("schedule_timeout %i\n",x);
241
242 while(x>0)
243 {
244 do_all_timers();
245 #ifndef HAVE_IRQS
246 handle_irqs(-1);
247
248 #endif
249 if (need_wakeup)
250 break;
251 wait_ms(wait);
252 inc_jiffies(wait);
253 x-=wait;
254 }
255 need_wakeup=0;
256 // printk("schedule DONE!!!!!!\n");
257 DPRINT1("schedule DONE!!!!!!\n");
258
259 return x;
260 }
261 /*------------------------------------------------------------------------*/
262 void my_wait_for_completion(struct completion *x)
263 {
264 int n=100;
265 // printk("wait for completion\n");
266 DPRINT1("wait for completion\n");
267
268 while(!x->done && (n>0))
269 {
270 do_all_timers();
271 #ifndef HAVE_IRQS
272 handle_irqs(-1);
273
274 #endif
275 wait_ms(10);
276 n--;
277 }
278 // printk("wait for completion done %i\n",x->done);
279 DPRINT1("wait for completion done %i\n",x->done);
280
281 }
282 /*------------------------------------------------------------------------*/
283 void my_interruptible_sleep_on(PKEVENT evnt)
284 {
285 KeWaitForSingleObject(evnt, Executive, KernelMode, FALSE, NULL);
286 KeClearEvent(evnt); // reset to not-signalled
287 }
288 /*------------------------------------------------------------------------*/
289 // Helper for pci_module_init
290 /*------------------------------------------------------------------------*/
291 int my_pci_module_init(struct pci_driver *x)
292 {
293 struct pci_dev *dev=pci_probe_dev;
294 const struct pci_device_id *id=NULL;
295 if (!pci_probe_dev)
296 {
297 DPRINT1("PCI device not set!\n");
298 return 0;
299 }
300 x->probe(dev, id);
301 return 0;
302 }
303 /*------------------------------------------------------------------------*/
304 struct pci_dev *my_pci_find_slot(int a,int b)
305 {
306 return NULL;
307 }
308 /*------------------------------------------------------------------------*/
309 int my_pci_write_config_word(struct pci_dev *dev, int where, u16 val)
310 {
311 //dev->bus, dev->devfn, where, val
312 OHCI_DEVICE_EXTENSION *dev_ext = (OHCI_DEVICE_EXTENSION *)dev->dev_ext;
313
314 //FIXME: Is returning this value correct?
315 //FIXME: Mixing pci_dev and win structs isn't a good thing at all
316 return HalSetBusDataByOffset(PCIConfiguration, dev->bus->number, dev_ext->SystemIoSlotNumber, &val, where, sizeof(val));
317 }
318 /*------------------------------------------------------------------------*/
319 int my_request_irq(unsigned int irq,
320 int (*handler)(int,void *, struct pt_regs *),
321 unsigned long mode, const char *desc, void *data)
322 {
323 if (num_irqs<MAX_IRQS)
324 {
325 reg_irqs[num_irqs].handler=handler;
326 reg_irqs[num_irqs].irq=irq;
327 reg_irqs[num_irqs].data=data;
328 num_irqs++;
329 return 0;
330 }
331 return 1;
332 }
333 /*------------------------------------------------------------------------*/
334 int my_free_irq(int irq, void* p)
335 {
336 /* No free... */
337 return 0;
338 }
339 /*------------------------------------------------------------------------*/
340 // Lookaside funcs
341 /*------------------------------------------------------------------------*/
342 kmem_cache_t *my_kmem_cache_create(const char *tag, size_t alloc_size,
343 size_t offset, unsigned long flags,
344 void *ctor,
345 void *dtor)
346 {
347 //TODO: Take in account ctor and dtor - callbacks for alloc/free, flags and offset
348 //FIXME: We assume this cache is always NPaged
349 PNPAGED_LOOKASIDE_LIST Lookaside;
350 ULONG Tag=0x11223344; //FIXME: Make this from tag
351
352 Lookaside = ExAllocatePool(NonPagedPool, sizeof(NPAGED_LOOKASIDE_LIST));
353
354 ExInitializeNPagedLookasideList(
355 Lookaside,
356 NULL,
357 NULL,
358 0,
359 alloc_size,
360 Tag,
361 0);
362
363 return (kmem_cache_t *)Lookaside;
364 }
365 /*------------------------------------------------------------------------*/
366 BOOLEAN my_kmem_cache_destroy(kmem_cache_t *co)
367 {
368 ExDeleteNPagedLookasideList((PNPAGED_LOOKASIDE_LIST)co);
369
370 ExFreePool(co);
371 return FALSE;
372 }
373 /*------------------------------------------------------------------------*/
374 void *my_kmem_cache_alloc(kmem_cache_t *co, int flags)
375 {
376 return ExAllocateFromNPagedLookasideList((PNPAGED_LOOKASIDE_LIST)co);
377 }
378 /*------------------------------------------------------------------------*/
379 void my_kmem_cache_free(kmem_cache_t *co, void *ptr)
380 {
381 ExFreeToNPagedLookasideList((PNPAGED_LOOKASIDE_LIST)co, ptr);
382 }
383 /*------------------------------------------------------------------------*/
384 // DMA, not used now
385 /*------------------------------------------------------------------------*/
386 void *my_dma_pool_alloc(struct dma_pool *pool, int gfp_flags, dma_addr_t *dma_handle)
387 {
388 // HalAllocCommonBuffer
389 // But ideally IoGetDmaAdapter
390 return NULL;
391 }