2 * USB support based on Linux kernel source
4 * 2003-06-21 Georg Acher (georg@acher.org)
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
16 * 6) Remove code bloat
20 #include "../usb_wrapper.h"
24 static struct pci_dev
*pci_probe_dev
;
25 extern int (*thread_handler
)(void*);
26 extern void* thread_parm
;
28 struct my_irqs reg_irqs
[MAX_IRQS
];
34 struct timer_list
*main_timer_list
[MAX_TIMERS
];
35 struct dummy_process act_cur
={0};
36 struct dummy_process
*my_current
;
38 int (*thread_handler
)(void*);
42 static struct device_driver
*m_drivers
[MAX_DRVS
];
45 /*------------------------------------------------------------------------*/
47 * Helper functions for top-level system
49 /*------------------------------------------------------------------------*/
50 void init_wrapper(struct pci_dev
*probe_dev
)
53 for(n
=0;n
<MAX_TIMERS
;n
++)
55 main_timer_list
[n
]=NULL
;
61 pci_probe_dev
=probe_dev
;
63 for(n
=0;n
<MAX_IRQS
;n
++)
65 reg_irqs
[n
].handler
=NULL
;
70 for(n
=0;n
<MAX_DRVS
;n
++)
73 /*------------------------------------------------------------------------*/
74 void handle_irqs(int irq
)
77 // printk("handle irqs\n");
78 DPRINT1("Handle Irqs\n");
79 for(n
=0;n
<MAX_IRQS
;n
++)
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
);
85 /*------------------------------------------------------------------------*/
86 void inc_jiffies(int n
)
90 /*------------------------------------------------------------------------*/
91 void do_all_timers(void)
94 for(n
=0;n
<MAX_TIMERS
;n
++)
96 if (main_timer_list
[n
] &&
97 main_timer_list
[n
]->function
&& main_timer_list
[n
]->expires
)
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;
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
);
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
)
117 //thread_handler=handler;
119 //return 42; // PID :-)
121 ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL
);
123 PsCreateSystemThread(&hThread
,
128 (PKSTART_ROUTINE
)handler
,
131 return (int)hThread
; // FIXME: Correct?
135 int my_kill_proc(int pid
, int signal
, int unk
)
139 // TODO: Implement actual process killing
141 hThread
= (HANDLE
)pid
;
147 /*------------------------------------------------------------------------*/
149 * As simple as possible, but as complete as necessary ...
151 /*------------------------------------------------------------------------*/
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
)
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
);
164 if (dev
->driver
->probe
)
165 return dev
->driver
->probe(dev
);
169 for(n
=0;n
<drvs_num
;n
++)
171 if (m_drivers
[n
]->probe
)
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
);
177 if (m_drivers
[n
]->probe(dev
) == 0)
189 /*------------------------------------------------------------------------*/
190 int my_driver_register(struct device_driver
*driver
)
193 if (drvs_num
<MAX_DRVS
)
195 // printk("driver_register %i: %p %p",drvs_num,driver,driver->probe);
196 DPRINT1("driver_register %i: %p %p",drvs_num
,driver
,driver
->probe
);
198 m_drivers
[drvs_num
++]=driver
;
203 /*------------------------------------------------------------------------*/
204 int my_device_unregister(struct device
*dev
)
206 if (dev
->driver
&& dev
->driver
->remove
)
207 dev
->driver
->remove(dev
);
211 /*------------------------------------------------------------------------*/
212 struct device
*my_get_device(struct device
*dev
)
216 /*------------------------------------------------------------------------*/
217 void my_device_initialize(struct device
*dev
)
220 /*------------------------------------------------------------------------*/
221 void my_wake_up(PKEVENT evnt
)
225 KeSetEvent(evnt
, 0, FALSE
); // Signal event
227 /*------------------------------------------------------------------------*/
228 void my_init_waitqueue_head(PKEVENT evnt
)
230 // this is used only in core/message.c, and it isn't needed there
231 //KeInitializeEvent(evnt, NotificationEvent, TRUE); // signalled state
233 /*------------------------------------------------------------------------*/
234 /* wait until woken up (only one wait allowed!) */
235 int my_schedule_timeout(int x
)
239 // printk("schedule_timeout %i\n",x);
240 DPRINT1("schedule_timeout %i\n",x
);
256 // printk("schedule DONE!!!!!!\n");
257 DPRINT1("schedule DONE!!!!!!\n");
261 /*------------------------------------------------------------------------*/
262 void my_wait_for_completion(struct completion
*x
)
265 // printk("wait for completion\n");
266 DPRINT1("wait for completion\n");
268 while(!x
->done
&& (n
>0))
278 // printk("wait for completion done %i\n",x->done);
279 DPRINT1("wait for completion done %i\n",x
->done
);
282 /*------------------------------------------------------------------------*/
283 void my_interruptible_sleep_on(PKEVENT evnt
)
285 KeWaitForSingleObject(evnt
, Executive
, KernelMode
, FALSE
, NULL
);
286 KeClearEvent(evnt
); // reset to not-signalled
288 /*------------------------------------------------------------------------*/
289 // Helper for pci_module_init
290 /*------------------------------------------------------------------------*/
291 int my_pci_module_init(struct pci_driver
*x
)
293 struct pci_dev
*dev
=pci_probe_dev
;
294 const struct pci_device_id
*id
=NULL
;
297 DPRINT1("PCI device not set!\n");
303 /*------------------------------------------------------------------------*/
304 struct pci_dev
*my_pci_find_slot(int a
,int b
)
308 /*------------------------------------------------------------------------*/
309 int my_pci_write_config_word(struct pci_dev
*dev
, int where
, u16 val
)
311 //dev->bus, dev->devfn, where, val
312 OHCI_DEVICE_EXTENSION
*dev_ext
= (OHCI_DEVICE_EXTENSION
*)dev
->dev_ext
;
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
));
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
)
323 if (num_irqs
<MAX_IRQS
)
325 reg_irqs
[num_irqs
].handler
=handler
;
326 reg_irqs
[num_irqs
].irq
=irq
;
327 reg_irqs
[num_irqs
].data
=data
;
333 /*------------------------------------------------------------------------*/
334 int my_free_irq(int irq
, void* p
)
339 /*------------------------------------------------------------------------*/
341 /*------------------------------------------------------------------------*/
342 kmem_cache_t
*my_kmem_cache_create(const char *tag
, size_t alloc_size
,
343 size_t offset
, unsigned long flags
,
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
352 Lookaside
= ExAllocatePool(NonPagedPool
, sizeof(NPAGED_LOOKASIDE_LIST
));
354 ExInitializeNPagedLookasideList(
363 return (kmem_cache_t
*)Lookaside
;
365 /*------------------------------------------------------------------------*/
366 BOOLEAN
my_kmem_cache_destroy(kmem_cache_t
*co
)
368 ExDeleteNPagedLookasideList((PNPAGED_LOOKASIDE_LIST
)co
);
373 /*------------------------------------------------------------------------*/
374 void *my_kmem_cache_alloc(kmem_cache_t
*co
, int flags
)
376 return ExAllocateFromNPagedLookasideList((PNPAGED_LOOKASIDE_LIST
)co
);
378 /*------------------------------------------------------------------------*/
379 void my_kmem_cache_free(kmem_cache_t
*co
, void *ptr
)
381 ExFreeToNPagedLookasideList((PNPAGED_LOOKASIDE_LIST
)co
, ptr
);
383 /*------------------------------------------------------------------------*/
385 /*------------------------------------------------------------------------*/
386 void *my_dma_pool_alloc(struct dma_pool
*pool
, int gfp_flags
, dma_addr_t
*dma_handle
)
388 // HalAllocCommonBuffer
389 // But ideally IoGetDmaAdapter