diff --git a/reactos/drivers/usb/nt4compat/usbdriver/compdrv.c b/reactos/drivers/usb/nt4compat/usbdriver/compdrv.c index d978d6a402e..6ca86d1ba4a 100644 --- a/reactos/drivers/usb/nt4compat/usbdriver/compdrv.c +++ b/reactos/drivers/usb/nt4compat/usbdriver/compdrv.c @@ -370,7 +370,7 @@ compdev_select_driver(PUSB_DEV_MANAGER dev_mgr, DEV_HANDLE dev_handle) TRAP(); } - // let's scan the interfacs for those we recognize + // let's scan the interfaces for those we recognize pconfig_desc = (PUSB_CONFIGURATION_DESC) buf; if (pconfig_desc->wTotalLength > 512) { @@ -387,6 +387,9 @@ compdev_select_driver(PUSB_DEV_MANAGER dev_mgr, DEV_HANDLE dev_handle) return; } + usb_dbg_print(DBGLVL_MAXIMUM, ("compdev_select_driver(): got %d interfaces\n", + (LONG)pconfig_desc->bNumInterfaces)); + for(i = 0; i < (LONG) pconfig_desc->bNumInterfaces; i++) { for(j = 0, credit = 0, pcand = NULL; j < DEVMGR_MAX_DRIVERS; j++) @@ -407,6 +410,7 @@ compdev_select_driver(PUSB_DEV_MANAGER dev_mgr, DEV_HANDLE dev_handle) param.dev_mgr = dev_mgr; param.pdriver = pcand; param.dev_handle = 0; + param.if_desc = pif_desc; pcand->disp_tbl.dev_connect(¶m, usb_make_handle(dev_id, i, 0)); } } diff --git a/reactos/drivers/usb/nt4compat/usbdriver/devmgr.c b/reactos/drivers/usb/nt4compat/usbdriver/devmgr.c index 3e33097417c..d99dbddfe30 100644 --- a/reactos/drivers/usb/nt4compat/usbdriver/devmgr.c +++ b/reactos/drivers/usb/nt4compat/usbdriver/devmgr.c @@ -158,6 +158,12 @@ dev_mgr_driver_entry_init(PUSB_DEV_MANAGER dev_mgr, PUSB_DRIVER pdrvr) pdrvr[GEN_IF_DRIVER_IDX].driver_init = gendrv_if_driver_init; pdrvr[GEN_IF_DRIVER_IDX].driver_destroy = gendrv_if_driver_destroy; + + pdrvr[MOUSE_DRIVER_IDX].driver_init = mouse_driver_init; + pdrvr[MOUSE_DRIVER_IDX].driver_destroy = mouse_driver_destroy; + + //pdrvr[KEYBOARD_DRIVER_IDX].driver_init = gendrv_if_driver_init; + //pdrvr[KEYBOARD_DRIVER_IDX].driver_destroy = gendrv_if_driver_destroy; } BOOLEAN diff --git a/reactos/drivers/usb/nt4compat/usbdriver/devmgr.h b/reactos/drivers/usb/nt4compat/usbdriver/devmgr.h index 625cb587c4b..91b4c1d4273 100644 --- a/reactos/drivers/usb/nt4compat/usbdriver/devmgr.h +++ b/reactos/drivers/usb/nt4compat/usbdriver/devmgr.h @@ -6,6 +6,7 @@ typedef struct _CONNECT_DATA DEV_HANDLE dev_handle; struct _USB_DRIVER *pdriver; struct _USB_DEV_MANAGER *dev_mgr; + PUSB_INTERFACE_DESC if_desc; } CONNECT_DATA, *PCONNECT_DATA; @@ -49,13 +50,15 @@ typedef struct _USB_DRIVER_DESCRIPTION } USB_DRIVER_DESCRIPTION,*PUSB_DRIVER_DESCRIPTION; -#define DEVMGR_MAX_DRIVERS 6 +#define DEVMGR_MAX_DRIVERS 7//8 #define RH_DRIVER_IDX 0 #define HUB_DRIVER_IDX 1 #define UMSS_DRIVER_IDX 2 #define COMP_DRIVER_IDX 3 #define GEN_DRIVER_IDX 4 #define GEN_IF_DRIVER_IDX 5 +#define MOUSE_DRIVER_IDX 6 +#define KEYBOARD_DRIVER_IDX 7//temp disabled typedef struct _USB_DRIVER { diff --git a/reactos/drivers/usb/nt4compat/usbdriver/mouse.c b/reactos/drivers/usb/nt4compat/usbdriver/mouse.c new file mode 100644 index 00000000000..6e79298c6d4 --- /dev/null +++ b/reactos/drivers/usb/nt4compat/usbdriver/mouse.c @@ -0,0 +1,365 @@ +/* + * PROJECT: ReactOS USB Drivers + * COPYRIGHT: GPL - See COPYING in the top level directory + * FILE: mouse.c + * PURPOSE: Generic USB mouse driver + * PROGRAMMERS: Aleksey Bragin (aleksey@reactos.org) + */ + +#include "usbdriver.h" +#include "ntddmou.h" + +BOOLEAN mouse_connect(PCONNECT_DATA dev_mgr, DEV_HANDLE dev_handle); +BOOLEAN mouse_disconnect(PUSB_DEV_MANAGER dev_mgr, DEV_HANDLE dev_handle); +BOOLEAN mouse_stop(PUSB_DEV_MANAGER dev_mgr, DEV_HANDLE dev_handle); + +VOID mouse_irq(PURB purb, PVOID pcontext); +VOID mouse_set_cfg_completion(PURB purb, PVOID pcontext); + + +BOOLEAN +mouse_driver_init(PUSB_DEV_MANAGER dev_mgr, PUSB_DRIVER pdriver) +{ + PMOUSE_DRVR_EXTENSION pdrvr_ext; + + if (dev_mgr == NULL || pdriver == NULL) + return FALSE; + + //init driver structure, no PNP table functions + pdriver->driver_desc.flags = USB_DRIVER_FLAG_IF_CAPABLE; + pdriver->driver_desc.vendor_id = 0xffff; // USB Vendor ID + pdriver->driver_desc.product_id = 0xffff; // USB Product ID. + pdriver->driver_desc.release_num = 0x100; // Release Number of Device + + pdriver->driver_desc.config_val = 1; // Configuration Value + pdriver->driver_desc.if_num = 1; // Interface Number + pdriver->driver_desc.if_class = USB_CLASS_HID; // Interface Class + pdriver->driver_desc.if_sub_class = 1; // Interface SubClass + pdriver->driver_desc.if_protocol = 2; // Interface Protocol + + pdriver->driver_desc.driver_name = "USB Mouse driver"; // Driver name for Name Registry + pdriver->driver_desc.dev_class = USB_CLASS_HID; + pdriver->driver_desc.dev_sub_class = 1; // Device Subclass + pdriver->driver_desc.dev_protocol = 2; // Protocol Info. + + pdriver->driver_ext = usb_alloc_mem(NonPagedPool, sizeof(MOUSE_DRVR_EXTENSION)); + pdriver->driver_ext_size = sizeof(MOUSE_DRVR_EXTENSION); + + RtlZeroMemory(pdriver->driver_ext, sizeof(MOUSE_DRVR_EXTENSION)); + pdrvr_ext = (PMOUSE_DRVR_EXTENSION) pdriver->driver_ext; + pdrvr_ext->dev_mgr = dev_mgr; + + pdriver->disp_tbl.version = 1; + pdriver->disp_tbl.dev_connect = mouse_connect; + pdriver->disp_tbl.dev_disconnect = mouse_disconnect; + pdriver->disp_tbl.dev_stop = mouse_stop; + pdriver->disp_tbl.dev_reserved = NULL; + + usb_dbg_print(DBGLVL_MAXIMUM, ("mouse_driver_init(): mouse driver is initialized\n")); + return TRUE; +} + +BOOLEAN +mouse_driver_destroy(PUSB_DEV_MANAGER dev_mgr, PUSB_DRIVER pdriver) +{ + //PMOUSE_DRVR_EXTENSION pdrvr_ext; + if (dev_mgr == NULL || pdriver == NULL) + return FALSE; + + //pdrvr_ext = (PUMSS_DRVR_EXTENSION) pdriver->driver_ext; + //umss_delete_port_device(pdrvr_ext->port_dev_obj); + //pdrvr_ext->port_dev_obj = NULL; + + //ASSERT(IsListEmpty(&pdrvr_ext->dev_list) == TRUE); + usb_free_mem(pdriver->driver_ext); + pdriver->driver_ext = NULL; + pdriver->driver_ext_size = 0; + usb_dbg_print(DBGLVL_MAXIMUM, ("mouse_driver_destroy(): mouse driver is destroyed\n")); + return TRUE; +} + +BOOLEAN +mouse_connect(PCONNECT_DATA param, DEV_HANDLE dev_handle) +{ + PURB purb; + NTSTATUS status; + PUSB_DEV_MANAGER dev_mgr; + PUSB_DRIVER pdrvr; + PUSB_DEV pdev; + PMOUSE_DRVR_EXTENSION pdev_ext; +// LONG i; + PUSB_ENDPOINT_DESC pendp_desc = NULL; + ULONG MaxPacketSize; + + usb_dbg_print(DBGLVL_MAXIMUM, ("mouse_connect(): entering...\n")); + + dev_mgr = param->dev_mgr; + pdrvr = param->pdriver; + pdev_ext = (PMOUSE_DRVR_EXTENSION)pdrvr->driver_ext; + + // Lock USB Device + status = usb_query_and_lock_dev(dev_mgr, dev_handle, &pdev); + if (status != STATUS_SUCCESS) + { + //usb_free_mem(desc_buf); + usb_dbg_print(DBGLVL_MEDIUM, ("mouse_connect(): unable to query&lock device, status=0x%x\n", status)); + return FALSE; + } + + // Endpoint-finding code + if (param->if_desc) + { + // Get a pointer to the config packet from compdev + PUCHAR Buffer = (PUCHAR)param->if_desc; + ULONG Offset = 0; + BOOLEAN FoundEndpoint = FALSE; + + // Find our the only needed endpoint descriptor + while (Offset < 512) + { + pendp_desc = (PUSB_ENDPOINT_DESC)&Buffer[Offset]; + usb_dbg_print(DBGLVL_MAXIMUM, ("mouse_connect(): DescType=0x%x, Attrs=0x%x, Len=%d\n", + pendp_desc->bDescriptorType, pendp_desc->bmAttributes, pendp_desc->bLength)); + + if (pendp_desc->bDescriptorType == USB_DT_ENDPOINT && + pendp_desc->bLength == sizeof(USB_ENDPOINT_DESC)) + { + // Found it + FoundEndpoint = TRUE; + break; + } + + Offset += pendp_desc->bLength; + } + + if (!FoundEndpoint) + return FALSE; + + // FIXME: Check if it's INT endpoint + // (pendp_desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT) + + // endpoint must be IN + if ((pendp_desc->bEndpointAddress & USB_DIR_IN) == 0) + return FALSE; + } + + + // Endpoint descriptor substitution code + { + ULONG if_idx, endp_idx; + PUSB_ENDPOINT pendp; + + //FoundEndpoint = FALSE; + for(if_idx = 0; if_idx < MAX_INTERFACES_PER_CONFIG /*pdev->usb_config->if_count*/; if_idx++) + { + for(endp_idx = 0; endp_idx < MAX_ENDPS_PER_IF /*pdev->usb_config->interf[if_idx].endp_count*/; endp_idx++) + { + pendp = &pdev->usb_config->interf[if_idx].endp[endp_idx]; + + if (pendp->pusb_endp_desc != NULL) + { + //HACKHACK: for some reason this usb driver chooses different and completely wrong + // endpoint. Since I don't have time to research this, I just find the + // endpoint descriptor myself and copy it + memcpy(pendp->pusb_endp_desc, pendp_desc, pendp_desc->bLength); + + usb_dbg_print(DBGLVL_MAXIMUM, ("mouse_connect(): [%i][%i] DescType=0x%x, Attrs=0x%x, Len=%d\n",if_idx, endp_idx, + pendp->pusb_endp_desc->bDescriptorType, pendp->pusb_endp_desc->bmAttributes, pendp->pusb_endp_desc->bLength)); + } + } + } + } + + // Unlock USB Device + usb_unlock_dev(pdev); + + // Send URB + purb = usb_alloc_mem(NonPagedPool, sizeof(URB)); + if (purb == NULL) + return FALSE; + RtlZeroMemory(purb, sizeof(URB)); + + MaxPacketSize = pendp_desc->wMaxPacketSize; + if (MaxPacketSize > 8) + MaxPacketSize = 8; + + // Build a URB for our interrupt transfer + UsbBuildInterruptOrBulkTransferRequest(purb, + usb_make_handle((dev_handle >> 16), 0, 0), + (PUCHAR)&pdev_ext->mouse_data, + MaxPacketSize, //use max packet size + mouse_irq, + pdev_ext, + 0); + + // Call USB driver stack + status = usb_submit_urb(pdev_ext->dev_mgr, purb); + if (status != STATUS_PENDING) + { + usb_free_mem(purb); + purb = NULL; + } + + return TRUE; +} + +// pcontext == device extension +VOID +mouse_set_cfg_completion(PURB purb, PVOID pcontext) +{ + PMOUSE_DRVR_EXTENSION pdev_ext = (PMOUSE_DRVR_EXTENSION)pcontext; + DEV_HANDLE endp_handle; + NTSTATUS status; + + if (purb->status != STATUS_SUCCESS) + { + usb_free_mem(purb); + return; + } + + endp_handle = purb->endp_handle; + + //usb_free_mem(purb); + //purb = NULL; + + usb_dbg_print(DBGLVL_MAXIMUM, ("mouse_set_cfg_completion() endpoint handle=0x%x\n", endp_handle)); + + // Build a URB for our interrupt transfer + UsbBuildInterruptOrBulkTransferRequest(purb, + endp_handle, + /*usb_make_handle((pdev_ext->dev_handle >> 16), pdev_ext->if_idx, + pdev_ext->int_endp_idx),*/ + (PUCHAR)&pdev_ext->mouse_data, + 4, // FIXME: use max packet size! + mouse_irq, + pdev_ext, + 0); + + // Call USB driver stack + status = usb_submit_urb(pdev_ext->dev_mgr, purb); + if (status != STATUS_PENDING) + { + usb_free_mem(purb); + purb = NULL; + } +} + + +VOID +mouse_irq(PURB purb, PVOID pcontext) +{ + MOUSE_INPUT_DATA MouseInputData; + //ULONG InputDataConsumed; + NTSTATUS status; + PMOUSE_DRVR_EXTENSION pdev_ext = (PMOUSE_DRVR_EXTENSION)pcontext; + signed char *data = pdev_ext->mouse_data; + usb_dbg_print(DBGLVL_MAXIMUM, ("mouse_irq(): called\n")); + + ASSERT(purb); + + if (purb->status != STATUS_SUCCESS) + { + usb_dbg_print(DBGLVL_MAXIMUM, ("mouse_irq(): purb->status 0x%08X\n", purb->status)); + //return; + } + + usb_dbg_print(DBGLVL_MAXIMUM, ("Mouse input: x %d, y %d, w %d, btn: 0x%02x\n", data[1], data[2], data[3], data[0])); + + // Fill mouse input data structure + MouseInputData.Flags = MOUSE_MOVE_RELATIVE; + MouseInputData.LastX = data[1]; + MouseInputData.LastY = data[2]; + + MouseInputData.ButtonFlags = 0; + MouseInputData.ButtonData = 0; + + if ((data[0] & 0x01) && ((pdev_ext->btn_old & 0x01) != (data[0] & 0x01))) + MouseInputData.ButtonFlags |= MOUSE_LEFT_BUTTON_DOWN; + else if (!(data[0] & 0x01) && ((pdev_ext->btn_old & 0x01) != (data[0] & 0x01))) + MouseInputData.ButtonFlags |= MOUSE_LEFT_BUTTON_UP; + + if ((data[0] & 0x02) && ((pdev_ext->btn_old & 0x02) != (data[0] & 0x02))) + MouseInputData.ButtonFlags |= MOUSE_RIGHT_BUTTON_DOWN; + else if (!(data[0] & 0x02) && ((pdev_ext->btn_old & 0x02) != (data[0] & 0x02))) + MouseInputData.ButtonFlags |= MOUSE_RIGHT_BUTTON_UP; + + if ((data[0] & 0x04) && ((pdev_ext->btn_old & 0x04) != (data[0] & 0x04))) + MouseInputData.ButtonFlags |= MOUSE_MIDDLE_BUTTON_DOWN; + else if (!(data[0] & 0x04) && ((pdev_ext->btn_old & 0x04) != (data[0] & 0x04))) + MouseInputData.ButtonFlags |= MOUSE_MIDDLE_BUTTON_UP; + + if ((data[0] & 0x08) && ((pdev_ext->btn_old & 0x08) != (data[0] & 0x08))) + MouseInputData.ButtonFlags |= MOUSE_BUTTON_4_DOWN; + else if (!(data[0] & 0x08) && ((pdev_ext->btn_old & 0x08) != (data[0] & 0x08))) + MouseInputData.ButtonFlags |= MOUSE_BUTTON_4_UP; + + if ((data[0] & 0x10) && ((pdev_ext->btn_old & 0x10) != (data[0] & 0x10))) + MouseInputData.ButtonFlags |= MOUSE_BUTTON_5_DOWN; + else if (!(data[0] & 0x10) && ((pdev_ext->btn_old & 0x10) != (data[0] & 0x10))) + MouseInputData.ButtonFlags |= MOUSE_BUTTON_5_UP; + + if (data[3]) + { + MouseInputData.ButtonFlags |= MOUSE_WHEEL; + MouseInputData.ButtonData = data[3]; + } + + // Commit the input data somewhere... + /*if (UsbPortInterface.MouseConnectData->ClassService) + { + KIRQL OldIrql; + + KeRaiseIrql(DISPATCH_LEVEL, &OldIrql); + (*(PSERVICE_CALLBACK_ROUTINE)UsbPortInterface.MouseConnectData->ClassService)( + UsbPortInterface.MouseConnectData->ClassDeviceObject, + &MouseInputData, + (&MouseInputData)+1, + &InputDataConsumed); + KeLowerIrql(OldIrql); + }*/ + + // Save old button data + pdev_ext->btn_old = data[0]; + + // resubmit the urb + status = usb_submit_urb(pdev_ext->dev_mgr, purb); +} + +BOOLEAN +mouse_stop(PUSB_DEV_MANAGER dev_mgr, DEV_HANDLE dev_handle) +{ + UNREFERENCED_PARAMETER(dev_handle); + UNREFERENCED_PARAMETER(dev_mgr); + return TRUE; +} + +BOOLEAN +mouse_disconnect(PUSB_DEV_MANAGER dev_mgr, DEV_HANDLE dev_handle) +{ + PDEVICE_OBJECT dev_obj; + NTSTATUS status; + PUSB_DEV pdev; + PUSB_DRIVER pdrvr; + + if (dev_mgr == NULL || dev_handle == 0) + return FALSE; + + pdev = NULL; + //special use of the lock dev, simply use this routine to get the dev + status = usb_query_and_lock_dev(dev_mgr, dev_handle, &pdev); + if (pdev == NULL) + { + return FALSE; + } + if (status == STATUS_SUCCESS) + { + // must be a bug + TRAP(); + usb_unlock_dev(pdev); + } + pdrvr = pdev->dev_driver; + dev_obj = pdev->dev_obj; + pdev = NULL; + + return TRUE;//umss_delete_device(dev_mgr, pdrvr, dev_obj, FALSE); +} diff --git a/reactos/drivers/usb/nt4compat/usbdriver/mouse.h b/reactos/drivers/usb/nt4compat/usbdriver/mouse.h new file mode 100644 index 00000000000..6162b9b8b8f --- /dev/null +++ b/reactos/drivers/usb/nt4compat/usbdriver/mouse.h @@ -0,0 +1,23 @@ +#ifndef __MOUSE_H__ +#define __MOUSE_H__ + +typedef struct _MOUSE_DRVR_EXTENSION +{ + //INTERRUPT_DATA_BLOCK idb; + PUSB_INTERFACE_DESC pif_desc; + UCHAR if_idx, out_endp_idx, in_endp_idx, int_endp_idx; + PUSB_ENDPOINT_DESC pout_endp_desc, pin_endp_desc, pint_endp_desc; + + PUSB_DEV_MANAGER dev_mgr; + signed char mouse_data[8]; + UCHAR btn_old; +} MOUSE_DRVR_EXTENSION, *PMOUSE_DRVR_EXTENSION; + + +BOOLEAN +mouse_driver_init(PUSB_DEV_MANAGER dev_mgr, PUSB_DRIVER pdriver); + +BOOLEAN +mouse_driver_destroy(PUSB_DEV_MANAGER dev_mgr, PUSB_DRIVER pdriver); + +#endif diff --git a/reactos/drivers/usb/nt4compat/usbdriver/uhci.c b/reactos/drivers/usb/nt4compat/usbdriver/uhci.c index bf9a559c849..f54c61fac9b 100644 --- a/reactos/drivers/usb/nt4compat/usbdriver/uhci.c +++ b/reactos/drivers/usb/nt4compat/usbdriver/uhci.c @@ -1241,6 +1241,8 @@ uhci_process_pending_endp(PUHCI_DEV uhci) } // if can_submit is STATUS_SUCCESS, the purb is inserted into the schedule + uhci_dbg_print(DBGLVL_MAXIMUM, ("uhci_process_pending_endp(): endp_type=0x%x\n", + endp_type(pendp))); switch (endp_type(pendp)) { case USB_ENDPOINT_XFER_BULK: diff --git a/reactos/drivers/usb/nt4compat/usbdriver/usb.c b/reactos/drivers/usb/nt4compat/usbdriver/usb.c index e7eb2edb599..73859497e65 100644 --- a/reactos/drivers/usb/nt4compat/usbdriver/usb.c +++ b/reactos/drivers/usb/nt4compat/usbdriver/usb.c @@ -781,7 +781,6 @@ LBL_OUT: return status; } - void usb_config_dev_completion(PURB purb, PVOID context) { diff --git a/reactos/drivers/usb/nt4compat/usbdriver/usb.h b/reactos/drivers/usb/nt4compat/usbdriver/usb.h index 8a622ca3d3a..aaa9a76b750 100644 --- a/reactos/drivers/usb/nt4compat/usbdriver/usb.h +++ b/reactos/drivers/usb/nt4compat/usbdriver/usb.h @@ -955,6 +955,15 @@ ULONG endp_ref, PURB purb ); +void usb_fill_int_urb(PURB urb, + struct _USB_DEV *dev, + ULONG pipe, + PVOID transfer_buffer, + LONG buffer_length, + PURBCOMPLETION complete, + PVOID context, + int interval); + LONG usb_calc_bus_time( LONG low_speed, diff --git a/reactos/drivers/usb/nt4compat/usbdriver/usbdriver.h b/reactos/drivers/usb/nt4compat/usbdriver/usbdriver.h index a6c26a36927..29c6d6b144b 100644 --- a/reactos/drivers/usb/nt4compat/usbdriver/usbdriver.h +++ b/reactos/drivers/usb/nt4compat/usbdriver/usbdriver.h @@ -26,4 +26,5 @@ #include "devmgr.h" #include "hub.h" #include "umss.h" +#include "mouse.h" #include "uhciver.h" diff --git a/reactos/drivers/usb/nt4compat/usbdriver/usbdriver.rbuild b/reactos/drivers/usb/nt4compat/usbdriver/usbdriver.rbuild index 04796ba9a89..f15c7bcf89c 100644 --- a/reactos/drivers/usb/nt4compat/usbdriver/usbdriver.rbuild +++ b/reactos/drivers/usb/nt4compat/usbdriver/usbdriver.rbuild @@ -18,6 +18,7 @@ compdrv.c etd.c gendrv.c + mouse.c usbdriver.rc usbdriver.h