From d531c3bb2162a743ddfcf0ea9210b9253486bf02 Mon Sep 17 00:00:00 2001 From: Aleksey Bragin Date: Fri, 25 Feb 2005 15:05:51 +0000 Subject: [PATCH] Updated linux wrapper to contain more funcs (to allow UHCI in the future), also wait added into hub thread, so it *should* take much fewer cpu time then it was taking before (though I haven't tested it at all - will do later). Added dependency tracking to makefiles. svn path=/trunk/; revision=13741 --- reactos/drivers/usb/cromwell/core/hcd.h | 51 ++++++++++++ reactos/drivers/usb/cromwell/core/hub.c | 8 +- reactos/drivers/usb/cromwell/core/makefile | 4 + reactos/drivers/usb/cromwell/core/message.c | 3 + reactos/drivers/usb/cromwell/host/makefile | 4 + .../usb/cromwell/linux/linux_wrapper.h | 80 +++++++++++++++++-- reactos/drivers/usb/cromwell/linux/pci_ids.h | 3 + .../drivers/usb/cromwell/sys/linuxwrapper.c | 71 +++++++++++++++- reactos/drivers/usb/cromwell/usb_wrapper.h | 1 + 9 files changed, 216 insertions(+), 9 deletions(-) diff --git a/reactos/drivers/usb/cromwell/core/hcd.h b/reactos/drivers/usb/cromwell/core/hcd.h index 15eae1d8949..266324d5d15 100644 --- a/reactos/drivers/usb/cromwell/core/hcd.h +++ b/reactos/drivers/usb/cromwell/core/hcd.h @@ -161,6 +161,56 @@ struct usb_operations { struct pt_regs; +// new struct from 2.6 +struct hc_driver { + const char *description; /* "ehci-hcd" etc */ + + /* irq handler */ + irqreturn_t (*irq) (struct usb_hcd *hcd, struct pt_regs *regs); + + int flags; +#define HCD_MEMORY 0x0001 /* HC regs use memory (else I/O) */ +#define HCD_USB11 0x0010 /* USB 1.1 */ +#define HCD_USB2 0x0020 /* USB 2.0 */ + + /* called to init HCD and root hub */ + int (*reset) (struct usb_hcd *hcd); + int (*start) (struct usb_hcd *hcd); + + /* called after all devices were suspended */ + int (*suspend) (struct usb_hcd *hcd, u32 state); + + /* called before any devices get resumed */ + int (*resume) (struct usb_hcd *hcd); + + /* cleanly make HCD stop writing memory and doing I/O */ + void (*stop) (struct usb_hcd *hcd); + + /* return current frame number */ + int (*get_frame_number) (struct usb_hcd *hcd); + + /* memory lifecycle */ + struct usb_hcd *(*hcd_alloc) (void); + void (*hcd_free) (struct usb_hcd *hcd); + + /* manage i/o requests, device state */ + int (*urb_enqueue) (struct usb_hcd *hcd, struct urb *urb, + int mem_flags); + int (*urb_dequeue) (struct usb_hcd *hcd, struct urb *urb); + + /* hw synch, freeing endpoint resources that urb_dequeue can't */ + void (*endpoint_disable)(struct usb_hcd *hcd, + struct hcd_dev *dev, int bEndpointAddress); + + /* root hub support */ + int (*hub_status_data) (struct usb_hcd *hcd, char *buf); + int (*hub_control) (struct usb_hcd *hcd, + u16 typeReq, u16 wValue, u16 wIndex, + char *buf, u16 wLength); +}; + +// old version, "just in case" +#if 0 struct hc_driver { const char *description; /* "ehci-hcd" etc */ @@ -206,6 +256,7 @@ struct hc_driver { u16 typeReq, u16 wValue, u16 wIndex, char *buf, u16 wLength); }; +#endif extern void STDCALL usb_hcd_giveback_urb (struct usb_hcd *hcd, struct urb *urb, struct pt_regs *regs); extern void STDCALL usb_bus_init (struct usb_bus *bus); diff --git a/reactos/drivers/usb/cromwell/core/hub.c b/reactos/drivers/usb/cromwell/core/hub.c index b60aa8d9de6..1b7e8207f1f 100644 --- a/reactos/drivers/usb/cromwell/core/hub.c +++ b/reactos/drivers/usb/cromwell/core/hub.c @@ -1151,9 +1151,9 @@ static int hub_thread(void *__hub) //FIXME: Correct this //wait_event_interruptible(khubd_wait, !list_empty(&hub_event_list)); // interruptable_sleep_on analog - below - /*while (!list_empty(&hub_event_list)) { + while (!list_empty(&hub_event_list)) { interruptible_sleep_on(&khubd_wait); - }*/ + } if (current->flags & PF_FREEZE) refrigerator(PF_IOTHREAD); @@ -1190,6 +1190,10 @@ int usb_hub_init(void) { pid_t pid; + // ReactOS-specific + // Create Event object, initialize other sync events + KeInitializeEvent(&khubd_wait, NotificationEvent, TRUE); // signalled state + if (usb_register(&hub_driver) < 0) { err("Unable to register USB hub driver"); return -1; diff --git a/reactos/drivers/usb/cromwell/core/makefile b/reactos/drivers/usb/cromwell/core/makefile index 27d2ff92be6..5301aa379f9 100644 --- a/reactos/drivers/usb/cromwell/core/makefile +++ b/reactos/drivers/usb/cromwell/core/makefile @@ -16,3 +16,7 @@ TARGET_OBJECTS = \ include $(PATH_TO_TOP)/rules.mak include $(TOOLS_PATH)/helper.mk + +# Automatic dependency tracking +DEP_OBJECTS := $(TARGET_OBJECTS) +include $(PATH_TO_TOP)/tools/depend.mk diff --git a/reactos/drivers/usb/cromwell/core/message.c b/reactos/drivers/usb/cromwell/core/message.c index b43a52dc4e6..749c76b8029 100644 --- a/reactos/drivers/usb/cromwell/core/message.c +++ b/reactos/drivers/usb/cromwell/core/message.c @@ -15,6 +15,9 @@ #include "hcd.h" /* for usbcore internals */ +// ReactOS specific: No WAITQUEUEs here +#define wake_up(a) do {} while(0) + struct usb_api_data { wait_queue_head_t wqh; int done; diff --git a/reactos/drivers/usb/cromwell/host/makefile b/reactos/drivers/usb/cromwell/host/makefile index fa4c7e652ec..e2e02edacfc 100644 --- a/reactos/drivers/usb/cromwell/host/makefile +++ b/reactos/drivers/usb/cromwell/host/makefile @@ -14,3 +14,7 @@ TARGET_OBJECTS = \ include $(PATH_TO_TOP)/rules.mak include $(TOOLS_PATH)/helper.mk + +# Automatic dependency tracking +DEP_OBJECTS := $(TARGET_OBJECTS) +include $(PATH_TO_TOP)/tools/depend.mk diff --git a/reactos/drivers/usb/cromwell/linux/linux_wrapper.h b/reactos/drivers/usb/cromwell/linux/linux_wrapper.h index 89308c722aa..3de8596de67 100644 --- a/reactos/drivers/usb/cromwell/linux/linux_wrapper.h +++ b/reactos/drivers/usb/cromwell/linux/linux_wrapper.h @@ -12,6 +12,9 @@ * * All structs and prototypes are based on kernel source 2.5.72 * + * Modified by Aleksey Bragin (aleksey@reactos.com) for ReactOS needs + * + * * #include */ @@ -145,6 +148,14 @@ struct completion { wait_queue_head_t wait; }; +// windows lookaside list head +typedef void* kmem_cache_t; + +struct dma_pool +{ + int dummy; +}; + /* from mod_devicetable.h */ struct usb_device_id { @@ -286,6 +297,8 @@ struct usbdevfs_hub_portinfo #define MODULE_DESCRIPTION(a) #define MODULE_LICENSE(a) #define MODULE_DEVICE_TABLE(type,name) void* module_table_##name=&name +#define MODULE_PARM(a,b) +#define MODULE_PARM_DESC(a,b) #define __devinit #define __exit @@ -313,6 +326,10 @@ struct usbdevfs_hub_portinfo #define unlikely(x) (x) #define prefetch(x) 1 +#define inw(x) READ_PORT_USHORT((PUSHORT)(x)) +#define outw(x,p) WRITE_PORT_USHORT((PUSHORT)(p),(x)) +#define outl(x,p) WRITE_PORT_ULONG((PUSHORT)(p),(x)) + /* The kernel macro for list_for_each_entry makes nonsense (have no clue * why, this is just the same definition...) */ @@ -372,7 +389,7 @@ struct usbdevfs_hub_portinfo #define down_read(a) do {} while(0) #define up_read(a) do {} while(0) -#define DECLARE_WAIT_QUEUE_HEAD(x) int x +#define DECLARE_WAIT_QUEUE_HEAD(x) KEVENT x #define DECLARE_COMPLETION(x) struct completion x @@ -383,6 +400,8 @@ struct usbdevfs_hub_portinfo /* PCI */ +#define to_pci_dev(n) container_of(n, struct pci_dev, dev) + #define pci_pool_create(a,b,c,d,e) (void*)1 #define pci_pool_alloc(a,b,c) my_pci_pool_alloc(a,b,c) @@ -427,6 +446,16 @@ int my_pci_module_init(struct pci_driver *x); #define bus_register(a) do {} while(0) #define bus_unregister(a) do {} while(0) +/* DMA */ +//#define dma_pool_alloc(a,b,c) my_dma_pool_alloc((a),(b),(c)) +#define dma_pool_alloc(a,b,c) pci_pool_alloc(a,b,c) +#define dma_pool_create(a,b,c,d,e) pci_pool_create(a,b,c,d,e) +#define dma_pool_free(a,b,c) pci_pool_free(a,b,c) +#define dma_pool_destroy(a) pci_pool_destroy(a) + +#define dma_alloc_coherent(a,b,c,d) NULL +#define dma_free_coherent(a,b,c,d) do {} while(0) + #define dma_map_single(a,b,c,d) ((u32)(b)&0xfffffff) #define dma_unmap_single(a,b,c,d) do {} while(0) #define pci_unmap_single(a,b,c,d) do {} while(0) @@ -451,11 +480,15 @@ int my_pci_module_init(struct pci_driver *x); #define PCI_ROM_RESOURCE 0 #define IORESOURCE_IO 1 -#define DECLARE_WAITQUEUE(a,b) wait_queue_head_t a=0 -#define init_waitqueue_head(a) do {} while(0) +#define DECLARE_WAITQUEUE(a,b) KEVENT a=0 +#define init_waitqueue_head(a) my_init_waitqueue_head(a) #define add_wait_queue(a,b) do {} while(0) #define remove_wait_queue(a,b) do {} while(0) +void my_init_waitqueue_head(PKEVENT a); +VOID KeMemoryBarrier(VOID); + +#define mb() KeMemoryBarrier() #define wmb() __asm__ __volatile__ ("": : :"memory") #define rmb() __asm__ __volatile__ ("lock; addl $0,0(%%esp)": : :"memory") @@ -478,7 +511,7 @@ void my_wait_for_completion(struct completion*); #define wait_event_interruptible(x,y) do {} while(0) #define interruptible_sleep_on(a) my_interruptible_sleep_on(a) -void my_interruptible_sleep_on(int a); +void my_interruptible_sleep_on(PKEVENT evnt); #define flush_scheduled_work() do {} while(0) #define refrigerator(x) do {} while(0) @@ -492,6 +525,25 @@ int my_kill_proc(int pid, int signal, int unk); #define yield() do {} while(0) #define cpu_relax() do {} while(0) +#define WARN_ON(a) do {} while(0) + +/*------------------------------------------------------------------------*/ +/* Lookaside lists funcs */ +/*------------------------------------------------------------------------*/ +#define kmem_cache_create(a,b,c,d,e,f) my_kmem_cache_create((a),(b),(c),(d),(e),(f)) +#define kmem_cache_destroy(a) my_kmem_cache_destroy((a)) +#define kmem_cache_alloc(co, flags) my_kmem_cache_alloc((co), (flags)) +#define kmem_cache_free(co, ptr) my_kmem_cache_free((co), (ptr)) + +kmem_cache_t *my_kmem_cache_create(const char *tag, size_t alloc_size, + size_t offset, unsigned long flags, + void *ctor, + void *dtor); + +void my_kmem_cache_destroy(kmem_cache_t *co); +void *my_kmem_cache_alloc(kmem_cache_t *co, int flags); +void my_kmem_cache_free(kmem_cache_t *co, void *ptr); + /*------------------------------------------------------------------------*/ /* Kernel macros */ /*------------------------------------------------------------------------*/ @@ -559,6 +611,21 @@ int my_kill_proc(int pid, int signal, int unk); #define PCI_DEVFN(a,b) 0 #define PCI_SLOT(a) 0 +/** + * PCI_DEVICE_CLASS - macro used to describe a specific pci device class + * @dev_class: the class, subclass, prog-if triple for this device + * @dev_class_mask: the class mask for this device + * + * This macro is used to create a struct pci_device_id that matches a + * specific PCI class. The vendor, device, subvendor, and subdevice + * fields will be set to PCI_ANY_ID. + */ +#define PCI_DEVICE_CLASS(dev_class,dev_class_mask) \ + .class = (dev_class), .class_mask = (dev_class_mask), \ + .vendor = PCI_ANY_ID, .device = PCI_ANY_ID, \ + .subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID + + /*------------------------------------------------------------------------*/ /* Stuff from kernel */ /*------------------------------------------------------------------------*/ @@ -647,6 +714,9 @@ static void __inline__ mod_timer(struct timer_list* t, int ex) add_timer(t); } +#define time_after_eq(a,b) \ + (((long)(a) - (long)(b) >= 0)) + /*------------------------------------------------------------------------*/ /* Device driver and process related stuff */ /*------------------------------------------------------------------------*/ @@ -678,7 +748,7 @@ int my_device_unregister(struct device *dev); int my_schedule_timeout(int x); #define wake_up(x) my_wake_up(x) -void my_wake_up(void*); +void my_wake_up(PKEVENT); // cannot be mapped via macro due to collision with urb->complete static void __inline__ complete(struct completion *p) diff --git a/reactos/drivers/usb/cromwell/linux/pci_ids.h b/reactos/drivers/usb/cromwell/linux/pci_ids.h index 538413658e9..77a15698745 100644 --- a/reactos/drivers/usb/cromwell/linux/pci_ids.h +++ b/reactos/drivers/usb/cromwell/linux/pci_ids.h @@ -5,7 +5,10 @@ #define PCI_DEVICE_ID_NS_87560_LIO 0x000e #define PCI_VENDOR_ID_AMD 0x1022 #define PCI_VENDOR_ID_OPTI 0x1045 +#define PCI_VENDOR_ID_VIA 0x1106 +#define PCI_VENDOR_ID_INTEL 0x8086 #define PCI_CLASS_SERIAL_USB (PCI_CLASS_SERIAL_BUS_CTLR << 8 + PCI_SUBCLASS_SB_USB) #endif + diff --git a/reactos/drivers/usb/cromwell/sys/linuxwrapper.c b/reactos/drivers/usb/cromwell/sys/linuxwrapper.c index e1170e9c828..39791eaf2d2 100644 --- a/reactos/drivers/usb/cromwell/sys/linuxwrapper.c +++ b/reactos/drivers/usb/cromwell/sys/linuxwrapper.c @@ -134,6 +134,8 @@ int my_kill_proc(int pid, int signal, int unk) { HANDLE hThread; + // TODO: Implement actual process killing + hThread = (HANDLE)pid; ZwClose(hThread); @@ -208,9 +210,17 @@ void my_device_initialize(struct device *dev) { } /*------------------------------------------------------------------------*/ -void my_wake_up(void* p) +void my_wake_up(PKEVENT evnt) { need_wakeup=1; + + KeSetEvent(evnt, 0, FALSE); // Signal event +} +/*------------------------------------------------------------------------*/ +void my_init_waitqueue_head(PKEVENT evnt) +{ + // this is used only in core/message.c, and it isn't needed there + //KeInitializeEvent(evnt, NotificationEvent, TRUE); // signalled state } /*------------------------------------------------------------------------*/ /* wait until woken up (only one wait allowed!) */ @@ -254,6 +264,12 @@ void my_wait_for_completion(struct completion *x) // printk("wait for completion done %i\n",x->done); } /*------------------------------------------------------------------------*/ +void my_interruptible_sleep_on(PKEVENT evnt) +{ + KeWaitForSingleObject(evnt, Executive, KernelMode, FALSE, NULL); + KeClearEvent(evnt); // reset to not-signalled +} +/*------------------------------------------------------------------------*/ // Helper for pci_module_init /*------------------------------------------------------------------------*/ int my_pci_module_init(struct pci_driver *x) @@ -294,4 +310,55 @@ int my_free_irq(int irq, void* p) /* No free... */ return 0; } -/*------------------------------------------------------------------------*/ \ No newline at end of file +/*------------------------------------------------------------------------*/ +// Lookaside funcs +/*------------------------------------------------------------------------*/ +kmem_cache_t *my_kmem_cache_create(const char *tag, size_t alloc_size, + size_t offset, unsigned long flags, + void *ctor, + void *dtor) +{ + //TODO: Take in account ctor and dtor - callbacks for alloc/free, flags and offset + //FIXME: We assume this cache is always NPaged + PNPAGED_LOOKASIDE_LIST Lookaside; + ULONG Tag=0x11223344; //FIXME: Make this from tag + + Lookaside = ExAllocatePool(NonPagedPool, sizeof(NPAGED_LOOKASIDE_LIST)); + + ExInitializeNPagedLookasideList( + Lookaside, + NULL, + NULL, + 0, + alloc_size, + Tag, + 0); + + return (kmem_cache_t *)Lookaside; +} +/*------------------------------------------------------------------------*/ +void my_kmem_cache_destroy(kmem_cache_t *co) +{ + ExDeleteNPagedLookasideList((PNPAGED_LOOKASIDE_LIST)co); + + ExFreePool(co); +} +/*------------------------------------------------------------------------*/ +void *my_kmem_cache_alloc(kmem_cache_t *co, int flags) +{ + return ExAllocateFromNPagedLookasideList((PNPAGED_LOOKASIDE_LIST)co); +} +/*------------------------------------------------------------------------*/ +void my_kmem_cache_free(kmem_cache_t *co, void *ptr) +{ + ExFreeToNPagedLookasideList((PNPAGED_LOOKASIDE_LIST)co, ptr); +} +/*------------------------------------------------------------------------*/ +// DMA, not used now +/*------------------------------------------------------------------------*/ +void *my_dma_pool_alloc(struct dma_pool *pool, int gfp_flags, dma_addr_t *dma_handle) +{ + // HalAllocCommonBuffer + // But ideally IoGetDmaAdapter + return NULL; +} diff --git a/reactos/drivers/usb/cromwell/usb_wrapper.h b/reactos/drivers/usb/cromwell/usb_wrapper.h index 47e0d9bbb83..4b810cad0cb 100644 --- a/reactos/drivers/usb/cromwell/usb_wrapper.h +++ b/reactos/drivers/usb/cromwell/usb_wrapper.h @@ -12,3 +12,4 @@ void wait_ms(int mils); #define CONFIG_PCI #include "linux/usb.h" +#include "linux/pci_ids.h" \ No newline at end of file