diff --git a/reactos/drivers/usb/nt4compat/CMakeLists.txt b/reactos/drivers/usb/nt4compat/CMakeLists.txt
deleted file mode 100644
index 3075585ebec..00000000000
--- a/reactos/drivers/usb/nt4compat/CMakeLists.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-
-add_subdirectory(usbdrv)
diff --git a/reactos/drivers/usb/nt4compat/directory.rbuild b/reactos/drivers/usb/nt4compat/directory.rbuild
deleted file mode 100644
index 8f2df716086..00000000000
--- a/reactos/drivers/usb/nt4compat/directory.rbuild
+++ /dev/null
@@ -1,7 +0,0 @@
-
-
-
-
-
-
-
diff --git a/reactos/drivers/usb/nt4compat/usbdrv/CMakeLists.txt b/reactos/drivers/usb/nt4compat/usbdrv/CMakeLists.txt
deleted file mode 100644
index b44650507c1..00000000000
--- a/reactos/drivers/usb/nt4compat/usbdrv/CMakeLists.txt
+++ /dev/null
@@ -1,35 +0,0 @@
-
-add_definitions(
- -DINCLUDE_EHCI
- -D_MULTI_UHCI
- -D_MULTI_EHCI
- -D_X86)
-
-list(APPEND SOURCE
- ehci.c
- ohci.c
- uhci.c
- roothub.c
- hub.c
- td.c
- usb.c
- umss.c
- bulkonly.c
- cbi.c
- devmgr.c
- dmgrdisp.c
- compdrv.c
- etd.c
- gendrv.c
- mouse.c
- keyboard.c
- usbdriver.rc)
-
-add_library(usbdrv SHARED ${SOURCE})
-
-set_module_type(usbdrv kernelmodedriver)
-add_importlibs(usbdrv ntoskrnl hal)
-
-add_pch(usbdrv usbdriver.h)
-
-add_cd_file(TARGET usbdrv DESTINATION reactos/system32/drivers NO_CAB FOR all)
diff --git a/reactos/drivers/usb/nt4compat/usbdrv/bulkonly.c b/reactos/drivers/usb/nt4compat/usbdrv/bulkonly.c
deleted file mode 100644
index 7a0cc124689..00000000000
--- a/reactos/drivers/usb/nt4compat/usbdrv/bulkonly.c
+++ /dev/null
@@ -1,797 +0,0 @@
-/**
- * bulkonly.c - USB driver stack project for Windows NT 4.0
- *
- * Copyright (c) 2002-2004 Zhiming mypublic99@yahoo.com
- *
- * This program/include file is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program/include file is distributed in the hope that it will be
- * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
- * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program (in the main directory of the distribution, the file
- * COPYING); if not, write to the Free Software Foundation,Inc., 59 Temple
- * Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "usbdriver.h"
-#include
-
-#define OLYMPUS_CSW( pdev_EXT, staTUS ) \
-( ( ( pdev_EXT )->flags & UMSS_DEV_FLAG_OLYMPUS_DEV ) ? ( ( staTUS ) == CSW_OLYMPUS_SIGNATURE ) : FALSE )
-
-BOOLEAN umss_clear_pass_through_length(PIO_PACKET io_packet);
-
-NTSTATUS umss_bulkonly_send_sense_req(PUMSS_DEVICE_EXTENSION pdev_ext);
-
-VOID umss_bulkonly_send_cbw_completion(IN PURB purb, IN PVOID context);
-
-VOID umss_bulkonly_transfer_data(PUMSS_DEVICE_EXTENSION pdev_ext);
-
-VOID umss_sync_submit_urb_completion(PURB purb, PVOID context);
-
-NTSTATUS umss_sync_submit_urb(PUMSS_DEVICE_EXTENSION pdev_ext, PURB purb);
-
-VOID umss_bulkonly_get_status(PUMSS_DEVICE_EXTENSION pdev_ext);
-
-VOID umss_bulkonly_transfer_data_complete(PURB purb, PVOID reference);
-
-VOID umss_bulkonly_reset_pipe_and_get_status(IN PVOID reference);
-
-VOID umss_bulkonly_reset_recovery(IN PVOID reference);
-
-VOID umss_bulkonly_get_status_complete(IN PURB purb, IN PVOID context);
-
-/*++
-Routine Description:
-
- Handler for all I/O requests using bulk-only protocol.
-
- Arguments:
-
- DeviceExtension - Device extension for our FDO.
-
-Return Value:
-
- NONE
-
---*/
-NTSTATUS
-umss_bulkonly_startio(IN PUMSS_DEVICE_EXTENSION pdev_ext, IN PIO_PACKET io_packet)
-{
- PCOMMAND_BLOCK_WRAPPER cbw;
- NTSTATUS status;
-
- if (pdev_ext == NULL || io_packet == NULL || io_packet->pirp == NULL)
- return STATUS_INVALID_PARAMETER;
-
- pdev_ext->retry = TRUE;
- RtlCopyMemory(&pdev_ext->io_packet, io_packet, sizeof(pdev_ext->io_packet));
-
- // Setup the command block wrapper for this request
- cbw = &pdev_ext->cbw;
- cbw->dCBWSignature = CBW_SIGNATURE;
- cbw->dCBWTag = 0;
- cbw->dCBWDataTransferLength = io_packet->data_length;
- cbw->bmCBWFlags = (io_packet->flags & USB_DIR_IN) ? 0x80 : 0;
- cbw->bCBWLun = io_packet->lun;
- cbw->bCBWLength = io_packet->cdb_length;
- RtlCopyMemory(cbw->CBWCB, io_packet->cdb, sizeof(cbw->CBWCB));
-
- RtlZeroMemory(&pdev_ext->csw, sizeof(pdev_ext->csw));
- // Send the command block wrapper to the device.
- // Calls UMSS_BulkOnlySendCBWComplete when transfer completes.
- status = umss_bulk_transfer(pdev_ext,
- USB_DIR_OUT,
- cbw, sizeof(COMMAND_BLOCK_WRAPPER), umss_bulkonly_send_cbw_completion);
-
- return status;
-}
-
-
-NTSTATUS
-umss_bulk_transfer(IN PUMSS_DEVICE_EXTENSION pdev_ext,
- IN UCHAR trans_dir, IN PVOID buf, IN ULONG buf_length, IN PURBCOMPLETION completion)
-{
- PURB purb;
- NTSTATUS status;
- DEV_HANDLE endp_handle;
-
- if (pdev_ext == NULL || buf == NULL || completion == NULL)
- return STATUS_INVALID_PARAMETER;
-
- if (buf_length > (ULONG) MAX_BULK_TRANSFER_LENGTH)
- return STATUS_INVALID_PARAMETER;
-
- purb = usb_alloc_mem(NonPagedPool, sizeof(URB));
-
- if (purb == NULL)
- return STATUS_NO_MEMORY;
-
- if (trans_dir == USB_DIR_OUT)
- {
- endp_handle = usb_make_handle((pdev_ext->dev_handle >> 16), pdev_ext->if_idx, pdev_ext->out_endp_idx);
- }
- else
- {
- endp_handle = usb_make_handle((pdev_ext->dev_handle >> 16), pdev_ext->if_idx, pdev_ext->in_endp_idx);
- }
-
- UsbBuildInterruptOrBulkTransferRequest(purb, endp_handle, buf, buf_length, completion, pdev_ext, 0);
- dev_mgr_register_irp(pdev_ext->dev_mgr, pdev_ext->io_packet.pirp, purb);
- status = usb_submit_urb(pdev_ext->dev_mgr, purb);
- if (status == STATUS_PENDING)
- {
- return status;
- }
-
- dev_mgr_remove_irp(pdev_ext->dev_mgr, pdev_ext->io_packet.pirp);
- if (purb)
- {
- usb_free_mem(purb);
- purb = NULL;
- }
- return status;
-}
-
-VOID
-umss_bulkonly_send_cbw_completion(IN PURB purb, IN PVOID context)
-{
- NTSTATUS status;
- PUMSS_DEVICE_EXTENSION pdev_ext;
-
- pdev_ext = (PUMSS_DEVICE_EXTENSION) context;
-
- status = purb->status;
- dev_mgr_remove_irp(pdev_ext->dev_mgr, pdev_ext->io_packet.pirp);
-
- if ((pdev_ext->io_packet.flags & IOP_FLAG_STAGE_MASK) == IOP_FLAG_STAGE_SENSE)
- {
- usb_free_mem(purb->data_buffer);
- purb->data_buffer = NULL;
- purb->data_length = 0;
- }
-
- if (status != STATUS_SUCCESS)
- {
- if (usb_halted(status))
- {
- //Schedule a work-item to do a reset recovery
- if (!umss_schedule_workitem
- ((PVOID) pdev_ext, umss_bulkonly_reset_recovery, pdev_ext->dev_mgr, pdev_ext->dev_handle))
- {
- umss_complete_request(pdev_ext, STATUS_IO_DEVICE_ERROR);
- }
- }
- else
- {
- // Device failed CBW without stalling, so complete with error
- umss_complete_request(pdev_ext, status);
- }
- }
- else
- {
- // CBW was accepted by device, so start data phase of I/O operation
- umss_bulkonly_transfer_data(pdev_ext);
- }
-
- usb_free_mem(purb);
-
- purb = NULL;
- return;
-}
-
-//can only be called at passive level
-NTSTATUS
-umss_sync_submit_urb(PUMSS_DEVICE_EXTENSION pdev_ext, PURB purb)
-{
- NTSTATUS status;
-
- if (pdev_ext == NULL || purb == NULL)
- return STATUS_INVALID_PARAMETER;
-
- purb->completion = umss_sync_submit_urb_completion;
- purb->context = (PVOID) pdev_ext;
-
- dev_mgr_register_irp(pdev_ext->dev_mgr, pdev_ext->io_packet.pirp, purb);
- status = usb_submit_urb(pdev_ext->dev_mgr, purb);
- if (status == STATUS_PENDING)
- {
- KeWaitForSingleObject(&pdev_ext->sync_event, Executive, KernelMode, TRUE, NULL);
- status = purb->status;
- }
- else
- dev_mgr_remove_irp(pdev_ext->dev_mgr, pdev_ext->io_packet.pirp);
-
- return status;
-}
-
-VOID
-umss_sync_submit_urb_completion(PURB purb, PVOID context)
-{
- PUMSS_DEVICE_EXTENSION pdev_ext;
-
- if (purb == NULL || context == NULL)
- return;
-
- pdev_ext = (PUMSS_DEVICE_EXTENSION) context;
- dev_mgr_remove_irp(pdev_ext->dev_mgr, pdev_ext->io_packet.pirp);
- KeSetEvent(&pdev_ext->sync_event, 0, FALSE);
- return;
-}
-
-/*++
-Routine Description:
-
- Worker function used to execute a reset recovery after a stall.
-
- Arguments:
-
- Reference - Our device extension.
-
-Return Value:
-
- NONE
-
---*/
-VOID
-umss_bulkonly_reset_recovery(IN PVOID reference)
-{
- PUMSS_DEVICE_EXTENSION pdev_ext;
- URB urb;
- NTSTATUS status;
- DEV_HANDLE endp_handle;
-
- pdev_ext = (PUMSS_DEVICE_EXTENSION) reference;
- usb_dbg_print(DBGLVL_MAXIMUM, ("umss_bulkonly_reset_recovery(): entering...\n"));
- // Steps for reset recovery:
- // 1. Send device a mass storage reset command on the default endpoint.
- // 2. Reset the bulk-in endpoint.
- // 3. Reset the bulk-out endpoint.
- // 4. Complete the original I/O request with error.
-
-
- // Build the mass storage reset command
- UsbBuildVendorRequest(&urb, pdev_ext->dev_handle | 0xffff, //default pipe
- NULL, //no extra data
- 0, //no size
- 0x21, //class, interface
- BULK_ONLY_MASS_STORAGE_RESET,
- 0,
- pdev_ext->pif_desc->bInterfaceNumber,
- NULL, //completion
- NULL, //context
- 0); //reference
-
- // Send mass storage reset command to device
- status = umss_sync_submit_urb(pdev_ext, &urb);
-
- if (status != STATUS_SUCCESS)
- {
- usb_dbg_print(DBGLVL_MINIMUM, ("umss_bulkonly_reset_recovery(): Reset Recovery failed!\n"));
- }
- else
- {
- //Reset Bulk-in endpoint
- endp_handle = usb_make_handle((pdev_ext->dev_handle >> 16), pdev_ext->if_idx, pdev_ext->in_endp_idx);
- status = umss_reset_pipe(pdev_ext, endp_handle);
-
- if (!NT_SUCCESS(status))
- {
- usb_dbg_print(DBGLVL_MINIMUM,
- ("umss_bulkonly_reset_recovery(): Unable to clear Bulk-in endpoint\n"));
- }
-
- //Reset Bulk-out endpoint
- endp_handle = usb_make_handle((pdev_ext->dev_handle >> 16), pdev_ext->if_idx, pdev_ext->out_endp_idx);
- status = umss_reset_pipe(pdev_ext, endp_handle);
-
- if (!NT_SUCCESS(status))
- {
- usb_dbg_print(DBGLVL_MINIMUM,
- ("umss_bulkonly_reset_recovery(): Unable to clear Bulk-out endpoint\n"));
- }
- }
- umss_complete_request(pdev_ext, status);
-}
-
-/*++
-Routine Description:
-
- Schedules a bulk data transfer to/from the device.
-
- Arguments:
-
- DeviceExtension - Our FDO's device extension.
-
-Return Value:
-
- NONE
-
---*/
-VOID
-umss_bulkonly_transfer_data(PUMSS_DEVICE_EXTENSION pdev_ext)
-{
- PVOID data_buf;
- ULONG data_buf_length;
- NTSTATUS status;
- UCHAR trans_dir = USB_DIR_IN; // FIXME: Initialize this properly!
-
- // Steps for data phase
- // 1. Get data buffer fragment (either SGD list, flat buffer, or none).
- // 2. Schedule data transfer if neccessary.
- // 3. Repeat 1-2 until all data transferred, or endpoint stalls.
- // 4. Move to status phase.
-
- // Get next data buffer element, if any
- data_buf = umss_get_buffer(pdev_ext, &data_buf_length);
-
- if (NULL == data_buf)
- {
- //No data to transfer, so move to status phase
- umss_bulkonly_get_status(pdev_ext);
- }
- else
- {
- // Schedule the data transfer.
- // Calls umss_bulkonly_transfer_data_complete when transfer completes.
-
- if ((pdev_ext->io_packet.flags & IOP_FLAG_STAGE_MASK) == IOP_FLAG_STAGE_NORMAL)
- trans_dir = (UCHAR) ((pdev_ext->cbw.bmCBWFlags & USB_DIR_IN) ? USB_DIR_IN : USB_DIR_OUT);
- else if ((pdev_ext->io_packet.flags & IOP_FLAG_STAGE_MASK) == IOP_FLAG_STAGE_SENSE)
- trans_dir = USB_DIR_IN;
-
- if ((status = umss_bulk_transfer(pdev_ext,
- trans_dir,
- data_buf,
- data_buf_length,
- umss_bulkonly_transfer_data_complete)) != STATUS_PENDING)
- {
- umss_complete_request(pdev_ext, status);
- }
- }
- return;
-}
-
-/*++
-Routine Description:
- Completion handler for bulk data transfer requests.
---*/
-VOID
-umss_bulkonly_transfer_data_complete(PURB purb, PVOID reference)
-{
- NTSTATUS status;
- PUMSS_DEVICE_EXTENSION pdev_ext;
- pdev_ext = (PUMSS_DEVICE_EXTENSION) reference;
-
- status = purb->status;
-
- dev_mgr_remove_irp(pdev_ext->dev_mgr, pdev_ext->io_packet.pirp);
-
- if (status != STATUS_SUCCESS)
- {
- //
- // clear the data length if this is a scsi pass through request
- //
- umss_clear_pass_through_length(&pdev_ext->io_packet);
-
- // Device failed data phase
- // Check if we need to clear stalled pipe
- if (usb_halted(status))
- {
- PULONG buf;
- buf = usb_alloc_mem(NonPagedPool, 32);
- if (!buf) return;
-
- buf[0] = (ULONG) pdev_ext;
- buf[1] = (ULONG) purb->endp_handle;
-
- usb_dbg_print(DBGLVL_MINIMUM, ("umss_transfer_data_complete(): transfer data error!\n"));
- if (!umss_schedule_workitem
- ((PVOID) buf, umss_bulkonly_reset_pipe_and_get_status, pdev_ext->dev_mgr,
- pdev_ext->dev_handle))
- {
- usb_free_mem(buf), buf = NULL;
- usb_dbg_print(DBGLVL_MINIMUM,
- ("umss_transfer_data_complete(): Failed to allocate work-item to reset pipe!\n"));
- TRAP();
- umss_complete_request(pdev_ext, status);
- }
- }
- else
- {
- //finish our request
- umss_complete_request(pdev_ext, status);
- }
- }
- else
- {
- // Start next part of data phase
- //umss_bulkonly_transfer_data( pdev_ext );
- umss_bulkonly_get_status(pdev_ext);
- //umss_complete_request( pdev_ext, status );
- }
-
- usb_free_mem(purb);
- purb = NULL;
-
- return; // STATUS_MORE_PROCESSING_REQUIRED;
-}
-
-
-VOID
-umss_bulkonly_reset_pipe_and_get_status(IN PVOID reference)
-{
- PUMSS_DEVICE_EXTENSION pdev_ext;
- DEV_HANDLE endp_handle;
- NTSTATUS status;
-
- usb_dbg_print(DBGLVL_MINIMUM, ("umss_bulkonly_reset_pipe_and_get_status(): entering...\n"));
-
- pdev_ext = (PUMSS_DEVICE_EXTENSION) (((PULONG) reference)[0]);
- endp_handle = (DEV_HANDLE) ((PULONG) reference)[1];
- usb_free_mem(reference);
- reference = NULL;
-
- // Reset the endpoint
- if ((status = umss_reset_pipe(pdev_ext, endp_handle)) != STATUS_SUCCESS)
- {
- usb_dbg_print(DBGLVL_MINIMUM, ("umss_bulkonly_reset_pipe_and_get_status(): reset pipe failed\n"));
- umss_complete_request(pdev_ext, status);
- return;
- }
- // Data phase is finished since the endpoint stalled, so go to status phase
- usb_dbg_print(DBGLVL_MINIMUM,
- ("umss_bulkonly_reset_pipe_and_get_status(): reset pipe succeeds, continue to get status\n"));
- umss_bulkonly_get_status(pdev_ext);
-}
-
-VOID
-umss_bulkonly_get_status(PUMSS_DEVICE_EXTENSION pdev_ext)
-{
- NTSTATUS status;
- // Schedule bulk transfer to get command status wrapper from device
- status = umss_bulk_transfer(pdev_ext,
- USB_DIR_IN,
- &(pdev_ext->csw),
- sizeof(COMMAND_STATUS_WRAPPER), umss_bulkonly_get_status_complete);
- if (status != STATUS_PENDING)
- {
- umss_complete_request(pdev_ext, status);
- }
-}
-
-/*++
-Routine Description:
-
- Completion handler for bulk data transfer request.
-
- Arguments:
-
- DeviceObject - Previous device object.
- Irp - Irp used for sending command.
- Reference - Our FDO.
-
-Return Value:
-
- Driver-originated IRPs always return STATUS_MORE_PROCESSING_REQUIRED.
-
---*/
-VOID
-umss_bulkonly_get_status_complete(IN PURB purb, IN PVOID context)
-{
- NTSTATUS status;
- PUMSS_DEVICE_EXTENSION pdev_ext;
- PCOMMAND_STATUS_WRAPPER csw;
-
- pdev_ext = (PUMSS_DEVICE_EXTENSION) context;
- status = purb->status;
-
- dev_mgr_remove_irp(pdev_ext->dev_mgr, pdev_ext->io_packet.pirp);
-
- csw = &(pdev_ext->csw);
- if (status == STATUS_SUCCESS &&
- ((csw->dCSWSignature == CSW_SIGNATURE) || OLYMPUS_CSW(pdev_ext, csw->dCSWSignature)))
- {
- if (csw->bCSWStatus == CSW_STATUS_PASSED)
- {
- // Received valid CSW with good status
-
- if ((pdev_ext->io_packet.flags & IOP_FLAG_STAGE_MASK) == IOP_FLAG_STAGE_NORMAL &&
- (pdev_ext->io_packet.flags & IOP_FLAG_REQ_SENSE) && pdev_ext->io_packet.sense_data != NULL)
- UMSS_FORGE_GOOD_SENSE(pdev_ext->io_packet.sense_data)
- umss_complete_request(pdev_ext, STATUS_SUCCESS);
- }
- else if (csw->bCSWStatus == CSW_STATUS_FAILED)
- {
- // start a request sense if necessary
- if ((pdev_ext->io_packet.flags & IOP_FLAG_REQ_SENSE) &&
- (pdev_ext->io_packet.flags & IOP_FLAG_STAGE_MASK) == IOP_FLAG_STAGE_NORMAL)
- {
- if (umss_bulkonly_send_sense_req(pdev_ext) != STATUS_PENDING)
- {
- // don't know how to handle.
- umss_complete_request(pdev_ext, STATUS_IO_DEVICE_ERROR);
- }
- else
- {
- // fall through to free the urb
- }
- }
- else
- {
- // error occurred, reset device
- if (!umss_schedule_workitem
- ((PVOID) pdev_ext, umss_bulkonly_reset_recovery, pdev_ext->dev_mgr, pdev_ext->dev_handle))
- {
- umss_complete_request(pdev_ext, STATUS_IO_DEVICE_ERROR);
- }
- }
- }
- else
- {
- // error occurred, reset device
- if (!umss_schedule_workitem
- ((PVOID) pdev_ext, umss_bulkonly_reset_recovery, pdev_ext->dev_mgr, pdev_ext->dev_handle))
- {
- umss_complete_request(pdev_ext, STATUS_IO_DEVICE_ERROR);
- }
- }
- }
- else if ((status != STATUS_SUCCESS) && (usb_halted(status)) && (pdev_ext->retry))
- {
- // Device stalled CSW transfer, retry once before failing
- PULONG buf;
- pdev_ext->retry = FALSE;
-
- buf = usb_alloc_mem(NonPagedPool, 32);
- if (!buf) return;
-
- buf[0] = (ULONG) pdev_ext;
- buf[1] = (ULONG) purb->endp_handle;
-
- if (!umss_schedule_workitem
- ((PVOID) buf, umss_bulkonly_reset_pipe_and_get_status, pdev_ext->dev_mgr, pdev_ext->dev_handle))
- {
- usb_free_mem(buf), buf = NULL;
- usb_dbg_print(DBGLVL_MINIMUM,
- ("umss_bulkonly_get_status_complete(): Failed to allocate work-item to reset pipe!\n"));
- TRAP();
- umss_complete_request(pdev_ext, status);
- }
- }
- else if (status != STATUS_CANCELLED)
- {
- // An error has occured. Reset the device.
- if (!umss_schedule_workitem
- ((PVOID) pdev_ext, umss_bulkonly_reset_recovery, pdev_ext->dev_mgr, pdev_ext->dev_handle))
- {
- usb_dbg_print(DBGLVL_MINIMUM,
- ("umss_bulkonly_get_status_complete(): Failed to schedule work-item to reset pipe!\n"));
- TRAP();
- umss_complete_request(pdev_ext, status);
- }
- }
- else
- {
- // the request is canceled
- usb_dbg_print(DBGLVL_MINIMUM, ("umss_bulkonly_get_status_complete(): the request is canceled\n"));
- umss_complete_request(pdev_ext, STATUS_CANCELLED);
- }
-
- usb_free_mem(purb);
- purb = NULL;
-
- return;
-}
-
-/*++
-Routine Description:
-
- Queries Bulk-Only device for maximum LUN number
-
- Arguments:
-
- DeviceExtension - Our device extension.
-
-Return Value:
-
- Maximum LUN number for device, or 0 if error occurred.
-
---*/
-CHAR
-umss_bulkonly_get_maxlun(IN PUMSS_DEVICE_EXTENSION pdev_ext)
-{
- PURB purb = NULL;
- UCHAR max_lun;
- NTSTATUS status;
-
- purb = usb_alloc_mem(NonPagedPool, sizeof(URB));
-
- if (!purb)
- {
- usb_dbg_print(DBGLVL_MINIMUM,
- ("umss_bulkonly_get_maxlun(): Failed to allocate URB, setting max LUN to 0\n"));
- max_lun = 0;
- }
- else
- {
- // Build the get max lun command
- UsbBuildVendorRequest(purb, (pdev_ext->dev_handle | 0xffff), &max_lun, sizeof(max_lun), 0xb1, //class, interface, in
- BULK_ONLY_GET_MAX_LUN, 0, pdev_ext->pif_desc->bInterfaceNumber, NULL, NULL, 0);
-
- // Send get max lun command to device
- status = umss_sync_submit_urb(pdev_ext, purb);
-
- if (status != STATUS_PENDING)
- {
- usb_dbg_print(DBGLVL_MINIMUM,
- ("umss_bulkonly_get_maxlun(): Get Max LUN command failed, setting max LUN to 0!\n"));
- max_lun = 0;
- }
- }
-
- if (purb)
- usb_free_mem(purb);
-
- usb_dbg_print(DBGLVL_MINIMUM, ("umss_bulkonly_get_maxlun(): Max LUN = %x\n", max_lun));
-
- return max_lun;
-}
-
-PVOID
-umss_get_buffer(PUMSS_DEVICE_EXTENSION pdev_ext, ULONG * buf_length)
-{
- PVOID buffer;
-
- if ((pdev_ext->io_packet.flags & IOP_FLAG_STAGE_MASK) == IOP_FLAG_STAGE_NORMAL)
- {
- buffer = (PVOID) pdev_ext->io_packet.data_buffer;
- *buf_length = pdev_ext->io_packet.data_length;
- }
- else if ((pdev_ext->io_packet.flags & IOP_FLAG_STAGE_MASK) == IOP_FLAG_STAGE_SENSE)
- {
- buffer = (PVOID) pdev_ext->io_packet.sense_data;
- *buf_length = pdev_ext->io_packet.sense_data_length;
- }
- else
- {
- buffer = NULL;
- *buf_length = 0;
- }
-
- return buffer;
-}
-
-BOOLEAN
-umss_bulkonly_build_sense_cdb(PUMSS_DEVICE_EXTENSION pdev_ext, PCOMMAND_BLOCK_WRAPPER cbw)
-{
- UCHAR sub_class;
- PUCHAR cdb;
-
- if (pdev_ext == NULL || cbw == NULL)
- return FALSE;
-
- cdb = cbw->CBWCB;
- RtlZeroMemory(cdb, MAX_CDB_LENGTH);
- sub_class = pdev_ext->pif_desc->bInterfaceSubClass;
-
- cdb[0] = SFF_REQUEST_SENSEE;
- cdb[1] = pdev_ext->io_packet.lun << 5;
- cdb[4] = 18;
-
- switch (sub_class)
- {
- case UMSS_SUBCLASS_SFF8070I:
- case UMSS_SUBCLASS_UFI:
- {
- cbw->bCBWLength = 12;
- break;
- }
- case UMSS_SUBCLASS_RBC:
- case UMSS_SUBCLASS_SCSI_TCS:
- {
- cbw->bCBWLength = 6;
- break;
- }
- default:
- return FALSE;
- }
- return TRUE;
-}
-
-NTSTATUS
-umss_bulkonly_send_sense_req(PUMSS_DEVICE_EXTENSION pdev_ext)
-{
- PCOMMAND_BLOCK_WRAPPER cbw;
- NTSTATUS status;
-
- if (pdev_ext == NULL || pdev_ext->io_packet.sense_data == NULL
- || pdev_ext->io_packet.sense_data_length < 18)
- return STATUS_INVALID_PARAMETER;
-
- pdev_ext->retry = TRUE;
-
- cbw = usb_alloc_mem(NonPagedPool, sizeof(COMMAND_BLOCK_WRAPPER));
- if (!cbw) return STATUS_NO_MEMORY;
-
- RtlZeroMemory(cbw, sizeof(COMMAND_BLOCK_WRAPPER));
- pdev_ext->io_packet.flags &= ~IOP_FLAG_STAGE_MASK;
- pdev_ext->io_packet.flags |= IOP_FLAG_STAGE_SENSE;
-
- cbw->dCBWSignature = CBW_SIGNATURE;
- cbw->dCBWTag = 0;
- cbw->dCBWDataTransferLength = pdev_ext->io_packet.sense_data_length;
- cbw->bmCBWFlags = USB_DIR_IN;
- cbw->bCBWLun = 0;
-
- if (umss_bulkonly_build_sense_cdb(pdev_ext, cbw) == FALSE)
- {
- usb_free_mem(cbw);
- cbw = NULL;
- return STATUS_UNSUCCESSFUL;
- }
-
- status = umss_bulk_transfer(pdev_ext,
- USB_DIR_OUT,
- cbw, sizeof(COMMAND_BLOCK_WRAPPER), umss_bulkonly_send_cbw_completion);
-
- if (status != STATUS_PENDING)
- {
- usb_free_mem(cbw);
- cbw = NULL;
- }
- return status;
-}
-
-BOOLEAN
-umss_clear_pass_through_length(PIO_PACKET io_packet)
-{
- //
- // clear the respective data length to meet request of scsi pass through requirement.
- //
-
- BOOLEAN sense_stage;
- ULONG ctrl_code;
- PIO_STACK_LOCATION cur_stack;
- PSCSI_PASS_THROUGH pass_through;
- PSCSI_PASS_THROUGH_DIRECT pass_through_direct;
-
- if (io_packet == NULL)
- return FALSE;
-
- if ((io_packet->flags & IOP_FLAG_SCSI_CTRL_TRANSFER) == 0)
- return FALSE;
-
- sense_stage = FALSE;
- if (io_packet->flags & IOP_FLAG_STAGE_SENSE)
- sense_stage = TRUE;
-
- cur_stack = IoGetCurrentIrpStackLocation(io_packet->pirp);
- ctrl_code = cur_stack->Parameters.DeviceIoControl.IoControlCode;
- if (ctrl_code == IOCTL_SCSI_PASS_THROUGH_DIRECT)
- {
- pass_through_direct = io_packet->pirp->AssociatedIrp.SystemBuffer;
- if (sense_stage)
- pass_through_direct->SenseInfoLength = 0;
- else
- pass_through_direct->DataTransferLength = 0;
- }
- else if (ctrl_code == IOCTL_SCSI_PASS_THROUGH)
- {
- pass_through = io_packet->pirp->AssociatedIrp.SystemBuffer;
- if (sense_stage)
- pass_through->SenseInfoLength = 0;
- else
- pass_through->DataTransferLength = 0;
- }
- else
- return FALSE;
-
- return TRUE;
-}
diff --git a/reactos/drivers/usb/nt4compat/usbdrv/cbi.c b/reactos/drivers/usb/nt4compat/usbdrv/cbi.c
deleted file mode 100644
index f90383cd3da..00000000000
--- a/reactos/drivers/usb/nt4compat/usbdrv/cbi.c
+++ /dev/null
@@ -1,302 +0,0 @@
-/**
- * cbi.c - USB driver stack project for Windows NT 4.0
- *
- * Copyright (c) 2002-2004 Zhiming mypublic99@yahoo.com
- *
- * This program/include file is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program/include file is distributed in the hope that it will be
- * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
- * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program (in the main directory of the distribution, the file
- * COPYING); if not, write to the Free Software Foundation,Inc., 59 Temple
- * Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "usbdriver.h"
-
-VOID umss_cbi_send_adsc_complete(PURB purb, PVOID context);
-VOID umss_cbi_transfer_data(PUMSS_DEVICE_EXTENSION pdev_ext);
-VOID umss_cbi_get_status(PUMSS_DEVICE_EXTENSION pdev_ext);
-VOID umss_cbi_transfer_data_complete(PURB purb, PVOID context);
-VOID umss_cbi_get_status_complete(PURB purb, PVOID context);
-
-NTSTATUS
-umss_class_specific_request(IN PUMSS_DEVICE_EXTENSION pdev_ext,
- IN UCHAR request,
- IN UCHAR dir,
- IN PVOID buffer,
- IN ULONG buffer_length,
- IN PURBCOMPLETION completion)
-{
- PURB purb;
- NTSTATUS status;
-
- UNREFERENCED_PARAMETER(dir);
-
- purb = usb_alloc_mem(NonPagedPool, sizeof(URB));
- if (!purb) return STATUS_NO_MEMORY;
-
- // Build URB for the ADSC command
- UsbBuildVendorRequest(purb,
- pdev_ext->dev_handle | 0xffff,
- buffer,
- buffer_length,
- 0x21, request, 0, pdev_ext->pif_desc->bInterfaceNumber, completion, pdev_ext, 0);
-
- status = usb_submit_urb(pdev_ext->dev_mgr, purb);
- if (status != STATUS_PENDING)
- {
- usb_free_mem(purb);
- purb = NULL;
- return status;
- }
- dev_mgr_register_irp(pdev_ext->dev_mgr, pdev_ext->io_packet.pirp, purb);
- return status;
-}
-
-NTSTATUS
-umss_cbi_startio(IN PUMSS_DEVICE_EXTENSION pdev_ext, IN PIO_PACKET io_packet)
-{
- NTSTATUS status;
-
- status = STATUS_NOT_SUPPORTED;
- return status;
-
- RtlCopyMemory(&pdev_ext->io_packet, io_packet, sizeof(pdev_ext->io_packet));
-
- // Send the ADSC request to the device
- // Calls UMSS_CbiSendADSCComplete when transfer completes
- status = umss_class_specific_request(pdev_ext,
- ACCEPT_DEVICE_SPECIFIC_COMMAND,
- USB_DIR_OUT,
- io_packet->cdb, io_packet->cdb_length, umss_cbi_send_adsc_complete);
-
- return status;
-}
-
-
-
-VOID
-umss_cbi_send_adsc_complete(PURB purb, PVOID context)
-{
- NTSTATUS status;
- PUMSS_DEVICE_EXTENSION pdev_ext;
- PIO_PACKET io_packet;
-
- pdev_ext = (PUMSS_DEVICE_EXTENSION) context;
- io_packet = &pdev_ext->io_packet;
-
- status = purb->status;
-
- dev_mgr_remove_irp(pdev_ext->dev_mgr, pdev_ext->io_packet.pirp);
-
- if (!usb_success(status))
- {
- usb_dbg_print(DBGLVL_MINIMUM, ("umss_cbi_send_adsc_complete(): Command Block Failure!!!\n"));
-
- // BUGBUG - Should reset device here?
- // Device failed Command Block, complete with error
- umss_complete_request(pdev_ext, STATUS_IO_DEVICE_ERROR);
-
- }
- else if (io_packet->data_length)
- {
-
- usb_dbg_print(DBGLVL_HIGH, ("umss_cbi_send_adsc_complete(): Queuing Data Transfer DPC\n"));
- umss_cbi_transfer_data(pdev_ext);
-
- }
- else if (pdev_ext->pif_desc->bInterfaceProtocol == PROTOCOL_CBI)
- {
- // Device supports interrupt pipe, so get status
- umss_cbi_get_status(pdev_ext);
- }
- else
- {
- // Device does not report status, so complete request
- umss_complete_request(pdev_ext, STATUS_SUCCESS);
- }
-
- usb_free_mem(purb);
- purb = NULL;
-}
-
-
-
-VOID
-umss_cbi_reset_pipe(IN PVOID reference)
-{
- PUMSS_DEVICE_EXTENSION pdev_ext;
- pdev_ext = (PUMSS_DEVICE_EXTENSION) reference;
-
- // Reset the appropriate pipe, based on data direction
- umss_reset_pipe(pdev_ext,
- (pdev_ext->io_packet.flags & USB_DIR_IN) ?
- usb_make_handle((pdev_ext->dev_handle >> 16), pdev_ext->if_idx, pdev_ext->in_endp_idx) :
- usb_make_handle((pdev_ext->dev_handle >> 16), pdev_ext->if_idx, pdev_ext->out_endp_idx));
-
- // Device stalled endpoint, so complete I/O operation with error.
- // BUGBUG is this correct? Check spec...
- umss_complete_request(pdev_ext, USB_STATUS_STALL_PID);
-}
-
-VOID
-umss_cbi_transfer_data(PUMSS_DEVICE_EXTENSION pdev_ext)
-{
- PVOID buffer = NULL;
- ULONG buffer_length;
-
- // Get next data buffer element, if any.
- buffer = umss_get_buffer(pdev_ext, &buffer_length);
- if (NULL == buffer)
- {
- //Done with data phase, so move to status phase if (supported)
-
- if (pdev_ext->pif_desc->bInterfaceProtocol == PROTOCOL_CBI)
- {
- // Device supports interrupt pipe, so get status
- umss_cbi_get_status(pdev_ext);
- }
- else
- {
- // No interrupt pipe, so just complete the request
- umss_complete_request(pdev_ext, STATUS_SUCCESS);
- }
- }
- else
- {
- // Transfer next element of the data phase
- umss_bulk_transfer(pdev_ext,
- (UCHAR) ((pdev_ext->io_packet.flags & USB_DIR_IN) ? USB_DIR_IN : USB_DIR_OUT),
- buffer, buffer_length, umss_cbi_transfer_data_complete);
- }
-}
-
-
-VOID
-umss_cbi_transfer_data_complete(PURB purb, PVOID context)
-{
- NTSTATUS status;
- PUMSS_DEVICE_EXTENSION pdev_ext;
-
- pdev_ext = (PUMSS_DEVICE_EXTENSION) context;
- status = purb->status;
-
- usb_free_mem(purb);
- purb = NULL;
-
- if (!usb_success(status))
- {
- // Device failed Data Transfer
- // Check if we need to clear stalled pipe
- if (usb_halted(status))
- {
- // Reset pipe can only be done at passive level, so we need
- // to schedule a work item to do it.
- if (!umss_schedule_workitem
- ((PVOID) pdev_ext, umss_cbi_reset_pipe, pdev_ext->dev_mgr, pdev_ext->dev_handle))
- {
- usb_dbg_print(DBGLVL_MINIMUM,
- ("umss_cbi_transfer_data_complete(): Failed to allocate work-item to reset pipe!\n"));
- TRAP();
- umss_complete_request(pdev_ext, STATUS_IO_DEVICE_ERROR);
- }
- }
- else
- {
- umss_complete_request(pdev_ext, STATUS_IO_DEVICE_ERROR);
- }
- return;
- }
- // Transfer succeeded
- // umss_cbi_transfer_data( pdev_ext );
- umss_complete_request(pdev_ext, STATUS_SUCCESS);
- return;
-}
-
-
-VOID
-umss_cbi_get_status(PUMSS_DEVICE_EXTENSION pdev_ext)
-{
- PURB purb;
- NTSTATUS status;
-
- purb = usb_alloc_mem(NonPagedPool, sizeof(URB));
- if (purb == NULL)
- return;
-
- // Build a URB for our interrupt transfer
- UsbBuildInterruptOrBulkTransferRequest(purb,
- usb_make_handle((pdev_ext->dev_handle >> 16), pdev_ext->if_idx,
- pdev_ext->int_endp_idx), (PUCHAR) & pdev_ext->idb,
- sizeof(INTERRUPT_DATA_BLOCK), umss_cbi_get_status_complete,
- 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;
- }
- dev_mgr_register_irp(pdev_ext->dev_mgr, pdev_ext->io_packet.pirp, purb);
- return;
-}
-
-
-VOID
-umss_cbi_get_status_complete(PURB purb, PVOID context)
-{
- NTSTATUS status;
- PUMSS_DEVICE_EXTENSION pdev_ext;
- PINTERRUPT_DATA_BLOCK idb;
-
- pdev_ext = (PUMSS_DEVICE_EXTENSION) context;
-
- status = purb->status;
- dev_mgr_remove_irp(pdev_ext->dev_mgr, pdev_ext->io_packet.pirp);
-
- usb_free_mem(purb);
- purb = NULL;
-
- if (!usb_success(status))
- {
- // Device failed Data Transfer
- // Check if we need to clear stalled pipe
- if (usb_halted(status))
- {
- if (!umss_schedule_workitem
- ((PVOID) pdev_ext, umss_cbi_reset_pipe, pdev_ext->dev_mgr, pdev_ext->dev_handle))
- {
- usb_dbg_print(DBGLVL_MINIMUM,
- ("umss_cbi_get_status_complete(): Failed to allocate work-item to reset pipe!\n"));
- TRAP();
- umss_complete_request(pdev_ext, STATUS_IO_DEVICE_ERROR);
- return;
- }
- }
- umss_complete_request(pdev_ext, STATUS_IO_DEVICE_ERROR);
- return;
- }
-
- // Interrupt transfer succeeded
- idb = &(pdev_ext->idb);
-
- // Check for an error in the status block
- if ((0 != idb->bType) || (0 != (idb->bValue & 0x3)))
- {
- umss_complete_request(pdev_ext, STATUS_IO_DEVICE_ERROR);
- }
- else
- {
- umss_complete_request(pdev_ext, STATUS_SUCCESS);
- }
-}
diff --git a/reactos/drivers/usb/nt4compat/usbdrv/compdrv.c b/reactos/drivers/usb/nt4compat/usbdrv/compdrv.c
deleted file mode 100644
index 8760a4f6fe3..00000000000
--- a/reactos/drivers/usb/nt4compat/usbdrv/compdrv.c
+++ /dev/null
@@ -1,511 +0,0 @@
-/**
- * compdrv.c - USB driver stack project for Windows NT 4.0
- *
- * Copyright (c) 2002-2004 Zhiming mypublic99@yahoo.com
- *
- * This program/include file is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program/include file is distributed in the hope that it will be
- * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
- * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program (in the main directory of the distribution, the file
- * COPYING); if not, write to the Free Software Foundation,Inc., 59 Temple
- * Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-//this driver is part of the dev manager responsible to manage if device
-#include "usbdriver.h"
-
-VOID compdev_set_cfg_completion(PURB purb, PVOID context);
-VOID compdev_select_driver(PUSB_DEV_MANAGER dev_mgr, DEV_HANDLE dev_handle);
-BOOLEAN compdev_connect(PDEV_CONNECT_DATA param, DEV_HANDLE dev_handle);
-BOOLEAN compdev_stop(PUSB_DEV_MANAGER dev_mgr, DEV_HANDLE dev_handle);
-BOOLEAN compdev_disconnect(PUSB_DEV_MANAGER dev_mgr, DEV_HANDLE dev_handle);
-
-BOOLEAN
-compdev_driver_init(PUSB_DEV_MANAGER dev_mgr, PUSB_DRIVER pdriver)
-{
- if (dev_mgr == NULL || pdriver == NULL)
- return FALSE;
-
- pdriver->driver_desc.flags = USB_DRIVER_FLAG_DEV_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 = 0; // Configuration Value
- pdriver->driver_desc.if_num = 0; // Interface Number
- pdriver->driver_desc.if_class = 0; // Interface Class
- pdriver->driver_desc.if_sub_class = 0; // Interface SubClass
- pdriver->driver_desc.if_protocol = 0; // Interface Protocol
-
- pdriver->driver_desc.driver_name = "USB composit dev driver"; // Driver name for Name Registry
- pdriver->driver_desc.dev_class = USB_CLASS_PER_INTERFACE;
- pdriver->driver_desc.dev_sub_class = 0; // Device Subclass
- pdriver->driver_desc.dev_protocol = 0; // Protocol Info.
-
- //we have no extra data sturcture currently
- pdriver->driver_ext = NULL;
- pdriver->driver_ext_size = 0;
-
- pdriver->disp_tbl.version = 1;
- pdriver->disp_tbl.dev_connect = compdev_connect;
- pdriver->disp_tbl.dev_disconnect = compdev_disconnect;
- pdriver->disp_tbl.dev_stop = compdev_stop;
- pdriver->disp_tbl.dev_reserved = NULL;
-
- return TRUE;
-}
-
-BOOLEAN
-compdev_driver_destroy(PUSB_DEV_MANAGER dev_mgr, PUSB_DRIVER pdriver)
-{
- UNREFERENCED_PARAMETER(dev_mgr);
- UNREFERENCED_PARAMETER(pdriver);
- return TRUE;
-}
-
-BOOLEAN
-compdev_connect(PDEV_CONNECT_DATA param, DEV_HANDLE dev_handle)
-{
- PURB purb;
- PUSB_CTRL_SETUP_PACKET psetup;
- NTSTATUS status;
- PUCHAR buf;
- LONG credit, i, j;
- PUSB_CONFIGURATION_DESC pconfig_desc;
- PUSB_INTERFACE_DESC pif_desc;
- PUSB_DEV_MANAGER dev_mgr;
-
- if (param == NULL || dev_handle == 0)
- return FALSE;
-
- dev_mgr = param->dev_mgr;
-
- // let's set the configuration
- purb = usb_alloc_mem(NonPagedPool, sizeof(URB));
- if (purb == NULL)
- return FALSE;
-
- buf = usb_alloc_mem(NonPagedPool, 512);
- if (buf == NULL)
- {
- usb_dbg_print(DBGLVL_MAXIMUM, ("compdev_connect(): can not alloc buf\n"));
- usb_free_mem(purb);
- return FALSE;
- }
-
- // before we set the configuration, let's search to find if there
- // exist interfaces we supported
- psetup = (PUSB_CTRL_SETUP_PACKET) (purb)->setup_packet;
- urb_init((purb));
- purb->endp_handle = dev_handle | 0xffff;
- purb->data_buffer = buf;
- purb->data_length = 512;
- purb->completion = NULL; // this is an immediate request, no completion required
- purb->context = NULL;
- purb->reference = 0;
- psetup->bmRequestType = 0x80;
- psetup->bRequest = USB_REQ_GET_DESCRIPTOR;
- psetup->wValue = USB_DT_CONFIG << 8;
- psetup->wIndex = 0;
- psetup->wLength = 512;
-
- status = usb_submit_urb(dev_mgr, purb);
- if (status == STATUS_PENDING)
- {
- TRAP();
- usb_free_mem(buf);
- usb_free_mem(purb);
- return FALSE;
- }
-
- // let's scan the interfacs for those we recognize
- pconfig_desc = (PUSB_CONFIGURATION_DESC) buf;
- if (pconfig_desc->wTotalLength > 512)
- {
- usb_free_mem(buf);
- usb_free_mem(purb);
- usb_dbg_print(DBGLVL_MAXIMUM, ("compdev_connect(): error, bad configuration desc\n"));
- return FALSE;
- }
-
- pif_desc = (PUSB_INTERFACE_DESC) & pconfig_desc[1];
- for(i = 0, credit = 0; i < (LONG) pconfig_desc->bNumInterfaces; i++)
- {
- for(j = 0; j < DEVMGR_MAX_DRIVERS; j++)
- {
- credit = dev_mgr_score_driver_for_if(dev_mgr, &dev_mgr->driver_list[j], pif_desc);
- if (credit)
- break;
- }
- if (credit)
- break;
-
- if (usb_skip_if_and_altif((PUCHAR *) & pif_desc))
- break;
- }
-
- i = pconfig_desc->bConfigurationValue;
- usb_free_mem(buf);
- buf = NULL;
- if (credit == 0)
- {
- usb_free_mem(purb);
- usb_dbg_print(DBGLVL_MAXIMUM, ("compdev_connect(): oops..., no supported interface found\n"));
- return FALSE;
- }
-
- //set the configuration
- urb_init(purb);
- purb->endp_handle = dev_handle | 0xffff;
- purb->data_buffer = NULL;
- purb->data_length = 0;
- purb->completion = compdev_set_cfg_completion;
- purb->context = dev_mgr;
- purb->reference = (ULONG) param->pdriver;
- psetup->bmRequestType = 0;
- psetup->bRequest = USB_REQ_SET_CONFIGURATION;
- psetup->wValue = (USHORT) i;
- psetup->wIndex = 0;
- psetup->wLength = 0;
-
- usb_dbg_print(DBGLVL_MAXIMUM, ("compdev_connect(): start config the device, cfgval=%d\n", i));
- status = usb_submit_urb(dev_mgr, purb);
-
- if (status != STATUS_PENDING)
- {
- usb_free_mem(purb);
-
- if (status == STATUS_SUCCESS)
- return TRUE;
-
- return FALSE;
- }
-
- return TRUE;
-}
-
-VOID
-compdev_event_select_if_driver(PUSB_DEV pdev, ULONG event, ULONG context, ULONG param)
-{
- PUSB_DEV_MANAGER dev_mgr;
- DEV_HANDLE dev_handle;
-
- UNREFERENCED_PARAMETER(param);
- UNREFERENCED_PARAMETER(context);
- UNREFERENCED_PARAMETER(event);
-
- if (pdev == NULL)
- return;
-
- //
- // RtlZeroMemory( &cd, sizeof( cd ) );
- //
- dev_mgr = dev_mgr_from_dev(pdev);
- dev_handle = usb_make_handle(pdev->dev_id, 0, 0);
- compdev_select_driver(dev_mgr, dev_handle);
- return;
-}
-
-BOOLEAN
-compdev_post_event_select_driver(PUSB_DEV_MANAGER dev_mgr, DEV_HANDLE dev_handle)
-{
- PUSB_EVENT pevent;
- BOOLEAN bret;
- PUSB_DEV pdev;
- USE_BASIC_NON_PENDING_IRQL;
-
- if (dev_mgr == NULL || dev_handle == 0)
- return FALSE;
-
- if (usb_query_and_lock_dev(dev_mgr, dev_handle, &pdev) != STATUS_SUCCESS)
- return FALSE;
-
- KeAcquireSpinLockAtDpcLevel(&dev_mgr->event_list_lock);
- lock_dev(pdev, TRUE);
-
- if (dev_state(pdev) == USB_DEV_STATE_ZOMB)
- {
- bret = FALSE;
- goto LBL_OUT;
- }
-
- pevent = alloc_event(&dev_mgr->event_pool, 1);
- if (pevent == NULL)
- {
- bret = FALSE;
- goto LBL_OUT;
- }
- pevent->flags = USB_EVENT_FLAG_ACTIVE;
- pevent->event = USB_EVENT_DEFAULT;
- pevent->pdev = pdev;
- pevent->context = 0;
- pevent->param = 0;
- pevent->pnext = 0; //vertical queue for serialized operation
- pevent->process_event = compdev_event_select_if_driver;
- pevent->process_queue = event_list_default_process_queue;
-
- InsertTailList(&dev_mgr->event_list, &pevent->event_link);
- KeSetEvent(&dev_mgr->wake_up_event, 0, FALSE); // wake up the dev_mgr_thread
- bret = TRUE;
-
- LBL_OUT:
-
- unlock_dev(pdev, TRUE);
- KeReleaseSpinLockFromDpcLevel(&dev_mgr->event_list_lock);
- usb_unlock_dev(pdev);
- return bret;
-}
-
-VOID
-compdev_set_cfg_completion(PURB purb, PVOID context)
-{
- DEV_HANDLE dev_handle;
- PUSB_DEV_MANAGER dev_mgr;
- PUSB_DRIVER pdriver;
- NTSTATUS status;
- PUSB_DEV pdev;
- USE_BASIC_NON_PENDING_IRQL;
-
- if (purb == NULL || context == NULL)
- return;
-
- dev_handle = purb->endp_handle & ~0xffff;
- dev_mgr = (PUSB_DEV_MANAGER) context;
- pdriver = (PUSB_DRIVER) purb->reference;
-
- if (purb->status != STATUS_SUCCESS)
- {
- usb_free_mem(purb);
- return;
- }
-
- usb_free_mem(purb);
- purb = NULL;
-
- // set the dev state
- status = usb_query_and_lock_dev(dev_mgr, dev_handle, &pdev);
- if (status != STATUS_SUCCESS)
- {
- usb_unlock_dev(pdev);
- return;
- }
- // safe to release the pdev ref since we are in urb completion
- usb_unlock_dev(pdev);
-
- lock_dev(pdev, TRUE);
- if (dev_state(pdev) >= USB_DEV_STATE_BEFORE_ZOMB)
- {
- unlock_dev(pdev, TRUE);
- return;
- }
-
- if (dev_mgr_set_driver(dev_mgr, dev_handle, pdriver, pdev) == FALSE)
- return;
-
- //transit the state to configured
- pdev->flags &= ~USB_DEV_STATE_MASK;
- pdev->flags |= USB_DEV_STATE_CONFIGURED;
- unlock_dev(pdev, TRUE);
-
- //
- // we change to use our thread for driver choosing. it will reduce
- // the race condition when different pnp event comes simultaneously
- //
- usb_dbg_print(DBGLVL_MAXIMUM, ("compdev_set_cfg_completion(): start select driver for the dev\n"));
- compdev_post_event_select_driver(dev_mgr, dev_handle);
-
- return;
-}
-
-VOID
-compdev_select_driver(PUSB_DEV_MANAGER dev_mgr, DEV_HANDLE dev_handle)
-{
- URB urb;
- LONG i, j, k, credit;
- ULONG dev_id;
- PUCHAR buf;
- NTSTATUS status;
- PUSB_DRIVER pcand, ptemp_drv;
-
- PUSB_CTRL_SETUP_PACKET psetup;
- PUSB_INTERFACE_DESC pif_desc;
- PUSB_CONFIGURATION_DESC pconfig_desc;
- PUSB_DEV pdev;
-
- usb_dbg_print(DBGLVL_MAXIMUM, ("compdev_select_driver(): entering...\n"));
-
- dev_id = dev_handle >> 16;
-
- buf = usb_alloc_mem(NonPagedPool, 512);
-
- if (buf == NULL)
- return;
-
- // now let's get the descs, one configuration
- urb_init(&urb);
- psetup = (PUSB_CTRL_SETUP_PACKET) urb.setup_packet;
- urb.endp_handle = dev_handle | 0xffff;
- urb.data_buffer = buf;
- urb.data_length = 512;
- urb.completion = NULL; // this is an immediate request, no completion required
- urb.context = NULL;
- urb.reference = 0;
- psetup->bmRequestType = 0x80;
- psetup->bRequest = USB_REQ_GET_DESCRIPTOR;
- psetup->wValue = USB_DT_CONFIG << 8;
- psetup->wIndex = 0;
- psetup->wLength = 512;
-
- status = usb_submit_urb(dev_mgr, &urb);
- if (status == STATUS_PENDING)
- {
- TRAP();
- }
-
- // let's scan the interfaces for those we recognize
- pconfig_desc = (PUSB_CONFIGURATION_DESC) buf;
- if (pconfig_desc->wTotalLength > 512)
- {
- usb_free_mem(buf);
- usb_dbg_print(DBGLVL_MAXIMUM, ("compdev_select_driver(): error, bad configuration desc\n"));
- return;
- }
- pif_desc = (PUSB_INTERFACE_DESC) & pconfig_desc[1];
-
- if (usb_query_and_lock_dev(dev_mgr, dev_handle, &pdev) != STATUS_SUCCESS)
- {
- usb_free_mem(buf);
- usb_dbg_print(DBGLVL_MAXIMUM, ("compdev_select_driver(): error, dev does not exist\n"));
- 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++)
- {
- ptemp_drv = &dev_mgr->driver_list[j];
- k = dev_mgr_score_driver_for_if(dev_mgr, ptemp_drv, pif_desc);
- if (k > credit)
- credit = k, pcand = ptemp_drv;
- }
-
- if (credit)
- {
- // ok, we find one
- DEV_CONNECT_DATA param;
-
- if (pcand->disp_tbl.dev_connect)
- {
- 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));
- }
- }
- if (usb_skip_if_and_altif((PUCHAR *) & pif_desc) == FALSE)
- {
- break;
- }
- }
- usb_unlock_dev(pdev);
-
- if (buf)
- {
- usb_free_mem(buf);
- buf = NULL;
- }
- return;
-}
-
-BOOLEAN
-compdev_stop(PUSB_DEV_MANAGER dev_mgr, DEV_HANDLE dev_handle)
-{
- PUSB_DEV pdev;
- LONG i;
- ULONG dev_id;
- PUSB_DRIVER pdrv;
- NTSTATUS status;
-
- if (dev_mgr == NULL || dev_handle == 0)
- return FALSE;
-
- pdev = NULL;
- dev_id = dev_handle >> 16;
- status = usb_query_and_lock_dev(dev_mgr, dev_handle, &pdev);
- if (pdev)
- {
- if (pdev->usb_config)
- {
- for(i = 0; i < pdev->usb_config->if_count; i++)
- {
- if ((pdrv = pdev->usb_config->interf[i].pif_drv))
- {
- pdrv->disp_tbl.dev_stop(dev_mgr, usb_make_handle(dev_id, i, 0));
- }
- }
- }
- }
- if (status == STATUS_SUCCESS)
- {
- usb_unlock_dev(pdev);
- }
- return TRUE;
-}
-
-BOOLEAN
-compdev_disconnect(PUSB_DEV_MANAGER dev_mgr, DEV_HANDLE dev_handle)
-{
- PUSB_DEV pdev;
- LONG i;
- ULONG dev_id;
- PUSB_DRIVER pdrv;
- NTSTATUS status;
-
- if (dev_mgr == NULL || dev_handle == 0)
- return FALSE;
-
- pdev = NULL;
- dev_id = dev_handle >> 16;
- status = usb_query_and_lock_dev(dev_mgr, dev_handle, &pdev);
- if (pdev)
- {
- if (pdev->usb_config)
- {
- for(i = 0; i < pdev->usb_config->if_count; i++)
- {
- if ((pdrv = pdev->usb_config->interf[i].pif_drv))
- {
- pdrv->disp_tbl.dev_disconnect(dev_mgr, usb_make_handle(dev_id, i, 0));
- }
- }
- }
- }
- if (status == STATUS_SUCCESS)
- {
- usb_unlock_dev(pdev);
- }
- return TRUE;
-}
-
-// note:
-// dev_mgr_set_driver seems to be dangeous since compdev, gendrv and hub and
-// umss use it to set the driver while there may exist race condition when the
-// dev_mgr_disconnect_dev is called. If the driver is set and the
-// disconnect_dev cut in immediately, the stop or disconnect may not function
-// well. Now hub and compdev's set dev_mgr_set_driver are ok.
-//
-// another danger comes from umss's dev irp processing. This may confuse the device
-// when the disk is being read or written, and at the same time dmgrdisp's dispatch
-// route irp request to the device a control request.
diff --git a/reactos/drivers/usb/nt4compat/usbdrv/debug.h b/reactos/drivers/usb/nt4compat/usbdrv/debug.h
deleted file mode 100644
index 49d9c16e362..00000000000
--- a/reactos/drivers/usb/nt4compat/usbdrv/debug.h
+++ /dev/null
@@ -1,71 +0,0 @@
-#ifndef _UHCIDBG_H_
-#define _UHCIDBG_H_
-
-#define DBGLVL_OFF 0 // if gDebugLevel set to this, there is NO debug output
-#define DBGLVL_MINIMUM 1 // minimum verbosity
-#define DBGLVL_DEFAULT 2 // default verbosity level if no registry override
-#define DBGLVL_MEDIUM 3 // medium verbosity
-#define DBGLVL_HIGH 4 // highest 'safe' level (without severely affecting timing )
-#define DBGLVL_MAXIMUM 5 // maximum level, may be dangerous
-#define DBGLVL_ULTRA 6 // ultra, prints hell lots of stuff from ISR/allocs/etc
-
-#ifndef DBGSTR_PREFIX
-#define DBGSTR_PREFIX "wood_uhci: "
-#endif
-
-#define DEBUG_UHCI TRUE
-#define DEBUG_HUB TRUE
-#define DEBUG_DEV_MGR TRUE
-
-#define DPRINT DbgPrint
-
-
-#define UHCI_DBGOUTSIZE 512
-
-#define hcd_dbg_print_cond( ilev, cond, _x_) \
- if( debug_level && ( ilev <= debug_level ) && ( cond )) { \
- DPRINT( DBGSTR_PREFIX ); \
- DPRINT _x_ ; \
- }
-
-#define hcd_dbg_print( ilev, _x_) hcd_dbg_print_cond( ilev, TRUE, _x_ )
-
-extern ULONG debug_level;
-
-#if DBG
-
-#define uhci_dbg_print_cond( ilev, cond, _x_ ) hcd_dbg_print_cond( ilev, cond, _x_ )
-#define uhci_dbg_print( ilev, _x_) hcd_dbg_print_cond( ilev, TRUE, _x_ )
-
-#define uhci_trap_cond( ilev, cond ) if ( debug_level && ( ilev <= debug_level ) && (cond) ) TRAP()
-#define uhci_trap( ilev ) uhci_trap_cond( ilev, TRUE )
-
-
-#define uhci_assert( cond ) ASSERT( cond )
-#define dbg_count_list( _x_ ) usb_count_list( _x_ )
-
-#define TRAP() DbgBreakPoint()
-
-#else // if not DBG
-
-// dummy definitions that go away in the retail build
-
-#define uhci_dbg_print_cond( ilev, cond, _x_ )
-#define uhci_dbg_print( ilev, _x_)
-#define uhci_trap_cont( ilev, cond )
-#define uhci_trap( ilev )
-#define uhci_assert( cond )
-#define TRAP()
-#define dbg_count_list( _x_ ) 0
-
-#endif //DBG
-
-#define usb_dbg_print( ilev, _x_ ) uhci_dbg_print( ilev, _x_ )
-#define ehci_dbg_print( ilev, _x_ ) uhci_dbg_print( ilev, _x_ )
-#define ohci_dbg_print( ilev, _x_ ) uhci_dbg_print( ilev, _x_ )
-#define ehci_dbg_print_cond( ilev, cond, _x_ ) uhci_dbg_print_cond( ilev, cond, _x_ )
-
-#define DO_NOTHING
-
-LONG usb_count_list( struct _LIST_ENTRY* list_head );
-#endif // included
diff --git a/reactos/drivers/usb/nt4compat/usbdrv/devmgr.c b/reactos/drivers/usb/nt4compat/usbdrv/devmgr.c
deleted file mode 100644
index 6b0862aebb2..00000000000
--- a/reactos/drivers/usb/nt4compat/usbdrv/devmgr.c
+++ /dev/null
@@ -1,1564 +0,0 @@
-/**
- * devmgr.c - USB driver stack project for Windows NT 4.0
- *
- * Copyright (c) 2002-2004 Zhiming mypublic99@yahoo.com
- *
- * This program/include file is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program/include file is distributed in the hope that it will be
- * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
- * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program (in the main directory of the distribution, the file
- * COPYING); if not, write to the Free Software Foundation,Inc., 59 Temple
- * Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "usbdriver.h"
-
-#define realloc_buf( pdEV, puRB ) \
-{\
- PBYTE data_buf;\
- int i;\
- data_buf = usb_alloc_mem( NonPagedPool, ( pdEV )->desc_buf_size += 1024 );\
- if (!data_buf)\
- {\
- goto LBL_OUT;\
- }\
- RtlZeroMemory( data_buf, ( pdEV )->desc_buf_size );\
- for( i = 0; i < ( LONG )( puRB )->context; i++ )\
- {\
- data_buf[ i ] = ( pdEV )->desc_buf[ i ];\
- }\
- usb_free_mem( ( pdEV )->desc_buf );\
- ( pdEV )->desc_buf = data_buf;\
- ( pdEV )->pusb_dev_desc = ( PUSB_DEVICE_DESC )( pdEV )->desc_buf;\
- ( puRB )->data_buffer = &data_buf[ ( LONG ) ( puRB )->context ];\
-}
-
-
-//----------------------------------------------------------
-
-USB_DRIVER g_driver_list[DEVMGR_MAX_DRIVERS];
-USB_DEV_MANAGER g_dev_mgr;
-
-
-//----------------------------------------------------------
-BOOLEAN
-dev_mgr_set_if_driver(PUSB_DEV_MANAGER dev_mgr,
- DEV_HANDLE if_handle,
- PUSB_DRIVER pdriver,
- PUSB_DEV pdev //if pdev != NULL, we use pdev instead if_handle, and must have dev_lock acquired.
- )
-{
- ULONG i;
- USE_BASIC_NON_PENDING_IRQL;
-
- if (dev_mgr == NULL || if_handle == 0 || pdriver == NULL)
- return FALSE;
-
- i = if_idx_from_handle(if_handle);
- if (pdev != NULL)
- {
- if (dev_state(pdev) < USB_DEV_STATE_BEFORE_ZOMB)
- {
- pdev->usb_config->interf[i].pif_drv = pdriver;
- return TRUE;
- }
- return FALSE;
- }
-
- if (usb_query_and_lock_dev(dev_mgr, if_handle, &pdev) != STATUS_SUCCESS)
- return FALSE;
-
- lock_dev(pdev, TRUE);
- if (dev_state(pdev) != USB_DEV_STATE_ZOMB)
- {
- pdev->usb_config->interf[i].pif_drv = pdriver;
- }
- unlock_dev(pdev, TRUE);
- usb_unlock_dev(pdev);
- return TRUE;
-}
-
-BOOLEAN
-dev_mgr_set_driver(PUSB_DEV_MANAGER dev_mgr,
- DEV_HANDLE dev_handle,
- PUSB_DRIVER pdriver,
- PUSB_DEV pdev //if pdev != NULL, we use pdev instead if_handle
- )
-{
- USE_BASIC_NON_PENDING_IRQL;
-
- if (dev_mgr == NULL || dev_handle == 0 || pdriver == NULL)
- return FALSE;
-
- if (pdev != NULL)
- {
- if (dev_state(pdev) < USB_DEV_STATE_BEFORE_ZOMB)
- {
- pdev->dev_driver = pdriver;
- return TRUE;
- }
- return FALSE;
- }
-
- if (usb_query_and_lock_dev(dev_mgr, dev_handle, &pdev) != STATUS_SUCCESS)
- return FALSE;
-
- lock_dev(pdev, FALSE);
- if (dev_state(pdev) < USB_DEV_STATE_BEFORE_ZOMB)
- {
- pdev->dev_driver = pdriver;
- }
- unlock_dev(pdev, FALSE);
- usb_unlock_dev(pdev);
-
- return TRUE;
-}
-
-BOOLEAN
-dev_mgr_post_event(PUSB_DEV_MANAGER dev_mgr, PUSB_EVENT event)
-{
- KIRQL old_irql;
-
- if (dev_mgr == NULL || event == NULL)
- return FALSE;
-
- KeAcquireSpinLock(&dev_mgr->event_list_lock, &old_irql);
- InsertTailList(&dev_mgr->event_list, &event->event_link);
- KeReleaseSpinLock(&dev_mgr->event_list_lock, old_irql);
-
- KeSetEvent(&dev_mgr->wake_up_event, 0, FALSE);
- return TRUE;
-}
-
-VOID
-dev_mgr_driver_entry_init(PUSB_DEV_MANAGER dev_mgr, PUSB_DRIVER pdrvr)
-{
- // Device Info
-
- RtlZeroMemory(pdrvr, sizeof(USB_DRIVER) * DEVMGR_MAX_DRIVERS);
-
- pdrvr[RH_DRIVER_IDX].driver_init = rh_driver_init; // in fact, this routine will init the rh device rather that the driver struct.
- pdrvr[RH_DRIVER_IDX].driver_destroy = rh_driver_destroy; // we do not need rh to destroy currently, since that may means fatal hardware failure
-
- pdrvr[HUB_DRIVER_IDX].driver_init = hub_driver_init; //no need, since dev_mgr is also a hub driver
- pdrvr[HUB_DRIVER_IDX].driver_destroy = hub_driver_destroy;
-
- pdrvr[UMSS_DRIVER_IDX].driver_init = umss_if_driver_init;
- pdrvr[UMSS_DRIVER_IDX].driver_destroy = umss_if_driver_destroy;
-
- pdrvr[COMP_DRIVER_IDX].driver_init = compdev_driver_init;
- pdrvr[COMP_DRIVER_IDX].driver_destroy = compdev_driver_destroy;
-
- pdrvr[GEN_DRIVER_IDX].driver_init = gendrv_driver_init;
- pdrvr[GEN_DRIVER_IDX].driver_destroy = gendrv_driver_destroy;
-
- 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 = kbd_driver_init;
- pdrvr[KEYBOARD_DRIVER_IDX].driver_destroy = kbd_driver_destroy;
-}
-
-BOOLEAN
-dev_mgr_strobe(PUSB_DEV_MANAGER dev_mgr)
-{
- PUSB_EVENT pevent;
- HANDLE thread_handle;
-
- if (dev_mgr == NULL)
- return FALSE;
- if (dev_mgr->hcd_count == 0)
- return FALSE;
-
- dev_mgr->term_flag = FALSE;
-
- if (dev_mgr->hcd_count == 0)
- return FALSE;
-
- KeInitializeSpinLock(&dev_mgr->event_list_lock);
- InitializeListHead(&dev_mgr->event_list);
- init_event_pool(&dev_mgr->event_pool);
-
- pevent = alloc_event(&dev_mgr->event_pool, 1);
- if (pevent == NULL)
- {
- destroy_event_pool(&dev_mgr->event_pool);
- return FALSE;
- }
-
- pevent->flags = USB_EVENT_FLAG_ACTIVE;
- pevent->event = USB_EVENT_INIT_DEV_MGR;
-
- pevent->process_queue = event_list_default_process_queue;
- pevent->process_event = (PROCESS_EVENT)dev_mgr_event_init;
-
- pevent->context = (ULONG) dev_mgr;
-
- KeInitializeEvent(&dev_mgr->wake_up_event, SynchronizationEvent, FALSE);
- KeInitializeEvent(&dev_mgr->drivers_inited, NotificationEvent, FALSE);
-
- InsertTailList(&dev_mgr->event_list, &pevent->event_link);
-
- if (PsCreateSystemThread(&thread_handle, 0, NULL, NULL, NULL, dev_mgr_thread, dev_mgr) != STATUS_SUCCESS)
- {
- destroy_event_pool(&dev_mgr->event_pool);
- return FALSE;
- }
-
- ObReferenceObjectByHandle(thread_handle,
- THREAD_ALL_ACCESS, NULL, KernelMode, (PVOID *) & dev_mgr->pthread, NULL);
-
- ZwClose(thread_handle);
-
- return TRUE;
-}
-
-BOOLEAN
-dev_mgr_event_init(PUSB_DEV pdev, //always null. we do not use this param
- ULONG event, ULONG context, ULONG param)
-{
- LARGE_INTEGER due_time;
- PUSB_DEV_MANAGER dev_mgr;
- LONG i;
-
- usb_dbg_print(DBGLVL_MAXIMUM, ("dev_mgr_event_init(): dev_mgr=0x%x, event=0x%x\n", context, event));
- dev_mgr = (PUSB_DEV_MANAGER) context;
- if (dev_mgr == NULL)
- return FALSE;
-
- if (event != USB_EVENT_INIT_DEV_MGR)
- return FALSE;
-
- //dev_mgr->root_hub = NULL;
- KeInitializeTimer(&dev_mgr->dev_mgr_timer);
-
- KeInitializeDpc(&dev_mgr->dev_mgr_timer_dpc, dev_mgr_timer_dpc_callback, (PVOID) dev_mgr);
-
- KeInitializeSpinLock(&dev_mgr->timer_svc_list_lock);
- InitializeListHead(&dev_mgr->timer_svc_list);
- init_timer_svc_pool(&dev_mgr->timer_svc_pool);
- dev_mgr->timer_click = 0;
-
- init_irp_list(&dev_mgr->irp_list);
-
- KeInitializeSpinLock(&dev_mgr->dev_list_lock);
- InitializeListHead(&dev_mgr->dev_list);
-
- dev_mgr->hub_count = 0;
- InitializeListHead(&dev_mgr->hub_list);
-
- dev_mgr->conn_count = 0;
- dev_mgr->driver_list = g_driver_list;
-
- dev_mgr_driver_entry_init(dev_mgr, dev_mgr->driver_list);
-
- for(i = 0; i < DEVMGR_MAX_DRIVERS; i++)
- {
- if (dev_mgr->driver_list[i].driver_init == NULL)
- continue;
-
- if (dev_mgr->driver_list[i].driver_init(dev_mgr, &dev_mgr->driver_list[i]) == FALSE)
- break;
- }
- if (i == DEVMGR_MAX_DRIVERS)
- {
- due_time.QuadPart = -(DEV_MGR_TIMER_INTERVAL_NS - 10);
-
- KeSetTimerEx(&dev_mgr->dev_mgr_timer,
- due_time, DEV_MGR_TIMER_INTERVAL_MS, &dev_mgr->dev_mgr_timer_dpc);
-
- /* Signal we're done initing */
- KeSetEvent(&dev_mgr->drivers_inited, 0, FALSE);
-
- return TRUE;
- }
-
- i--;
-
- for(; i >= 0; i--)
- {
- if (dev_mgr->driver_list[i].driver_destroy)
- dev_mgr->driver_list[i].driver_destroy(dev_mgr, &dev_mgr->driver_list[i]);
- }
-
- KeCancelTimer(&dev_mgr->dev_mgr_timer);
- KeRemoveQueueDpc(&dev_mgr->dev_mgr_timer_dpc);
- KeSetEvent(&dev_mgr->drivers_inited, 0, FALSE);
- return FALSE;
-
-}
-
-VOID
-dev_mgr_destroy(PUSB_DEV_MANAGER dev_mgr)
-{
- LONG i;
- // oops...
- KeCancelTimer(&dev_mgr->dev_mgr_timer);
- KeRemoveQueueDpc(&dev_mgr->dev_mgr_timer_dpc);
-
- for(i = DEVMGR_MAX_DRIVERS - 1; i >= 0; i--)
- dev_mgr->driver_list[i].driver_destroy(dev_mgr, &dev_mgr->driver_list[i]);
-
- destroy_irp_list(&dev_mgr->irp_list);
- destroy_timer_svc_pool(&dev_mgr->timer_svc_pool);
- destroy_event_pool(&dev_mgr->event_pool);
-
-}
-
-VOID
-NTAPI
-dev_mgr_thread(PVOID context)
-{
- PUSB_DEV_MANAGER dev_mgr;
- PUSB_EVENT pevent;
- PLIST_ENTRY pthis, pnext;
- USB_EVENT usb_event;
- LARGE_INTEGER time_out;
- NTSTATUS status;
- BOOLEAN dev_mgr_inited;
- KIRQL old_irql;
- LONG i;
-
- dev_mgr = (PUSB_DEV_MANAGER) context;
- dev_mgr_inited = FALSE;
- usb_cal_cpu_freq();
- time_out.u.LowPart = (10 * 1000 * 1000) * 100 - 1; //1 minutes
- time_out.u.HighPart = 0;
- time_out.QuadPart = -time_out.QuadPart;
-
- //usb_dbg_print( DBGLVL_MAXIMUM + 1, ( "dev_mgr_thread(): current uhci status=0x%x\n", uhci_status( dev_mgr->pdev_ext->uhci ) ) );
-
- while (dev_mgr->term_flag == FALSE)
- {
- KeAcquireSpinLock(&dev_mgr->event_list_lock, &old_irql);
- if (IsListEmpty(&dev_mgr->event_list) == TRUE)
- {
- KeReleaseSpinLock(&dev_mgr->event_list_lock, old_irql);
- status = KeWaitForSingleObject(&dev_mgr->wake_up_event, Executive, KernelMode, TRUE, &time_out);
- continue;
- }
-
- /*
- usb_dbg_print( DBGLVL_MAXIMUM, ( "dev_mgr_thread(): current element in event list is 0x%x\n", \
- dbg_count_list( &dev_mgr->event_list ) ) ); */
-
- dev_mgr_inited = TRUE; //since we have post one event, if this statement is executed, dev_mgr_event_init must be called sometime later or earlier
-
- ListFirst(&dev_mgr->event_list, pthis);
- pevent = struct_ptr(pthis, USB_EVENT, event_link);
-
- while (pevent && ((pevent->flags & USB_EVENT_FLAG_ACTIVE) == 0))
- {
- //skip inactive ones
- ListNext(&dev_mgr->event_list, &pevent->event_link, pnext);
- pevent = struct_ptr(pnext, USB_EVENT, event_link);
- }
-
- if (pevent != NULL)
- {
- if (pevent->process_queue == NULL)
- pevent->process_queue = event_list_default_process_queue;
-
- pevent->process_queue(&dev_mgr->event_list, &dev_mgr->event_pool, pevent, &usb_event);
- }
- else
- {
- //no active event
- KeReleaseSpinLock(&dev_mgr->event_list_lock, old_irql);
- status = KeWaitForSingleObject(&dev_mgr->wake_up_event, Executive, KernelMode, TRUE, &time_out // 10 minutes
- );
-
- usb_dbg_print(DBGLVL_MAXIMUM, ("dev_mgr_thread(): wake up, reason=0x%x\n", status));
- continue;
- }
-
- KeReleaseSpinLock(&dev_mgr->event_list_lock, old_irql);
-
- if (usb_event.process_event)
- {
- usb_event.process_event(usb_event.pdev, usb_event.event, usb_event.context, usb_event.param);
- }
- else
- {
- event_list_default_process_event(usb_event.pdev,
- usb_event.event, usb_event.context, usb_event.param);
- }
- }
-
- if (dev_mgr_inited)
- {
- for(i = 0; i < dev_mgr->hcd_count; i++)
- dev_mgr_disconnect_dev(dev_mgr->hcd_array[i]->hcd_get_root_hub(dev_mgr->hcd_array[i]));
- dev_mgr_destroy(dev_mgr);
- }
- PsTerminateSystemThread(0);
-}
-
-VOID
-NTAPI
-dev_mgr_timer_dpc_callback(PKDPC Dpc, PVOID context, PVOID SystemArgument1, PVOID SystemArgument2)
-{
- PUSB_DEV_MANAGER dev_mgr;
- LIST_HEAD templist;
- PLIST_ENTRY pthis, pnext;
- static ULONG ticks = 0;
-
- ticks++;
- dev_mgr = (PUSB_DEV_MANAGER) context;
- if (dev_mgr == NULL)
- return;
-
- dev_mgr->timer_click++;
- InitializeListHead(&templist);
-
- KeAcquireSpinLockAtDpcLevel(&dev_mgr->timer_svc_list_lock);
- if (IsListEmpty(&dev_mgr->timer_svc_list) == TRUE)
- {
- KeReleaseSpinLockFromDpcLevel(&dev_mgr->timer_svc_list_lock);
- return;
- }
-
- ListFirst(&dev_mgr->timer_svc_list, pthis);
- while (pthis)
- {
- ((PTIMER_SVC) pthis)->counter++;
- ListNext(&dev_mgr->timer_svc_list, pthis, pnext);
- if (((PTIMER_SVC) pthis)->counter >= ((PTIMER_SVC) pthis)->threshold)
- {
- RemoveEntryList(pthis);
- InsertTailList(&templist, pthis);
- }
- pthis = pnext;
- }
-
- KeReleaseSpinLockFromDpcLevel(&dev_mgr->timer_svc_list_lock);
-
-
- while (IsListEmpty(&templist) == FALSE)
- {
- pthis = RemoveHeadList(&templist);
- ((PTIMER_SVC) pthis)->func(((PTIMER_SVC) pthis)->pdev, (PVOID) ((PTIMER_SVC) pthis)->context);
- KeAcquireSpinLockAtDpcLevel(&dev_mgr->timer_svc_list_lock);
- free_timer_svc(&dev_mgr->timer_svc_pool, (PTIMER_SVC) pthis);
- KeReleaseSpinLockFromDpcLevel(&dev_mgr->timer_svc_list_lock);
- }
-
-}
-
-BOOLEAN
-dev_mgr_request_timer_svc(PUSB_DEV_MANAGER dev_mgr,
- PUSB_DEV pdev, ULONG context, ULONG due_time, TIMER_SVC_HANDLER handler)
-{
- PTIMER_SVC timer_svc;
- KIRQL old_irql;
-
- if (dev_mgr == NULL || pdev == NULL || due_time == 0 || handler == NULL)
- return FALSE;
-
- KeAcquireSpinLock(&dev_mgr->timer_svc_list_lock, &old_irql);
- timer_svc = alloc_timer_svc(&dev_mgr->timer_svc_pool, 1);
- if (timer_svc == NULL)
- {
- KeReleaseSpinLock(&dev_mgr->timer_svc_list_lock, old_irql);
- return FALSE;
- }
- timer_svc->pdev = pdev;
- timer_svc->threshold = due_time;
- timer_svc->func = handler;
- timer_svc->counter = 0;
-
- InsertTailList(&dev_mgr->timer_svc_list, &timer_svc->timer_svc_link);
- KeReleaseSpinLock(&dev_mgr->timer_svc_list_lock, old_irql);
- return TRUE;
-}
-
-BYTE
-dev_mgr_alloc_addr(PUSB_DEV_MANAGER dev_mgr, PHCD hcd)
-{
- // alloc a usb addr for the device within 1-128
- if (dev_mgr == NULL || hcd == NULL)
- return 0xff;
-
- return hcd->hcd_alloc_addr(hcd);
-}
-
-BOOLEAN
-dev_mgr_free_addr(PUSB_DEV_MANAGER dev_mgr, PUSB_DEV pdev, BYTE addr)
-{
- PHCD hcd;
- if (addr & 0x80)
- return FALSE;
-
- if (dev_mgr == NULL || pdev == NULL)
- return FALSE;
-
- hcd = pdev->hcd;
- if (hcd == NULL)
- return FALSE;
- hcd->hcd_free_addr(hcd, addr);
- return TRUE;
-}
-
-PUSB_DEV
-dev_mgr_alloc_device(PUSB_DEV_MANAGER dev_mgr, PHCD hcd)
-{
- BYTE addr;
- PUSB_DEV pdev;
-
- if ((addr = dev_mgr_alloc_addr(dev_mgr, hcd)) == 0xff)
- return NULL;
-
- pdev = usb_alloc_mem(NonPagedPool, sizeof(USB_DEV));
- if (pdev == NULL)
- return NULL;
-
- RtlZeroMemory(pdev, sizeof(USB_DEV));
-
- KeInitializeSpinLock(&pdev->dev_lock);
- dev_mgr->conn_count++;
-
- pdev->flags = USB_DEV_STATE_RESET; //class | cur_state | low speed
- pdev->ref_count = 0;
- pdev->dev_addr = addr;
-
- pdev->hcd = hcd;
-
- pdev->dev_id = dev_mgr->conn_count; //will be used to compose dev_handle
-
- InitializeListHead(&pdev->default_endp.urb_list);
- pdev->default_endp.pusb_if = (PUSB_INTERFACE) pdev;
- pdev->default_endp.flags = USB_ENDP_FLAG_DEFAULT_ENDP; //toggle | busy-count | stall | default-endp
-
- return pdev;
-}
-
-VOID
-dev_mgr_free_device(PUSB_DEV_MANAGER dev_mgr, PUSB_DEV pdev)
-{
- if (pdev == NULL || dev_mgr == NULL)
- return;
-
- dev_mgr_free_addr(dev_mgr, pdev, pdev->dev_addr);
- if (pdev->usb_config && pdev != pdev->hcd->hcd_get_root_hub(pdev->hcd))
- {
- //root hub has its config and desc buf allocated together,
- //so no usb_config allocated seperately
- dev_mgr_destroy_usb_config(pdev->usb_config);
- pdev->usb_config = NULL;
- }
- if (pdev->desc_buf)
- {
- usb_free_mem(pdev->desc_buf);
- pdev->desc_buf = NULL;
- }
- usb_free_mem(pdev);
- pdev = NULL;
- return;
-}
-
-//called when a disconnect is detected on the port
-VOID
-dev_mgr_disconnect_dev(PUSB_DEV pdev)
-{
- PLIST_ENTRY pthis, pnext;
- PHUB2_EXTENSION phub_ext = NULL;
- PUSB_CONFIGURATION pconfig;
- PUSB_DEV_MANAGER dev_mgr;
- PHCD hcd;
- BOOLEAN is_hub, found;
- ULONG dev_id;
- int i;
-
- USE_NON_PENDING_IRQL;
-
- if (pdev == NULL)
- return;
-
- found = FALSE;
-
- usb_dbg_print(DBGLVL_MAXIMUM, ("dev_mgr_disconnect_dev(): entering, pdev=0x%x\n", pdev));
- lock_dev(pdev, FALSE);
- pdev->flags &= ~USB_DEV_STATE_MASK;
- pdev->flags |= USB_DEV_STATE_BEFORE_ZOMB;
- dev_mgr = dev_mgr_from_dev(pdev);
- unlock_dev(pdev, FALSE);
-
- // notify dev_driver that the dev stops function before any operations
- if (pdev->dev_driver && pdev->dev_driver->disp_tbl.dev_stop)
- pdev->dev_driver->disp_tbl.dev_stop(dev_mgr, dev_handle_from_dev(pdev));
-
- //safe to use the dev pointer in this function.
- lock_dev(pdev, FALSE);
- pdev->flags &= ~USB_DEV_STATE_MASK;
- pdev->flags |= USB_DEV_STATE_ZOMB;
- hcd = pdev->hcd;
- dev_id = pdev->dev_id;
- unlock_dev(pdev, FALSE);
-
- if (dev_mgr == NULL)
- return;
-
- hcd->hcd_remove_device(hcd, pdev);
-
- //disconnect its children
- if ((pdev->flags & USB_DEV_CLASS_MASK) == USB_DEV_CLASS_HUB ||
- (pdev->flags & USB_DEV_CLASS_MASK) == USB_DEV_CLASS_ROOT_HUB)
- {
- phub_ext = hub_ext_from_dev(pdev);
- if (phub_ext)
- {
- for(i = 1; i <= phub_ext->port_count; i++)
- {
- if (phub_ext->child_dev[i])
- {
- dev_mgr_disconnect_dev(phub_ext->child_dev[i]);
- phub_ext->child_dev[i] = NULL;
- }
- }
- }
- }
-
- pconfig = pdev->usb_config;
-
- //remove event belong to the dev
- is_hub = ((pdev->flags & USB_DEV_CLASS_MASK) == USB_DEV_CLASS_HUB);
-
- if (phub_ext && is_hub)
- {
- for(i = 1; i <= phub_ext->port_count; i++)
- {
- found = hub_remove_reset_event(pdev, i, FALSE);
- if (found)
- break;
- }
- }
-
- //free event of the dev from the event list
- KeAcquireSpinLock(&dev_mgr->event_list_lock, &old_irql);
- ListFirst(&dev_mgr->event_list, pthis);
- while (pthis)
- {
- ListNext(&dev_mgr->event_list, pthis, pnext);
- if (((PUSB_EVENT) pthis)->pdev == pdev)
- {
- PLIST_ENTRY p1;
- RemoveEntryList(pthis);
- if ((((PUSB_EVENT) pthis)->flags & USB_EVENT_FLAG_QUE_TYPE) != USB_EVENT_FLAG_NOQUE)
- {
- //has a queue, re-insert the queue
- if ((p1 = (PLIST_ENTRY) ((PUSB_EVENT) pthis)->pnext))
- {
- InsertHeadList(&dev_mgr->event_list, p1);
- free_event(&dev_mgr->event_pool, struct_ptr(pthis, USB_EVENT, event_link));
- pthis = p1;
- //note: this queue will be examined again in the next loop
- //to find the matched dev in the queue
- continue;
- }
- }
- free_event(&dev_mgr->event_pool, struct_ptr(pthis, USB_EVENT, event_link));
- }
- else if (((((PUSB_EVENT) pthis)->flags & USB_EVENT_FLAG_QUE_TYPE)
- != USB_EVENT_FLAG_NOQUE) && ((PUSB_EVENT) pthis)->pnext)
- {
- //has a queue, examine the queue
- PUSB_EVENT p1, p2;
- p1 = (PUSB_EVENT) pthis;
- p2 = p1->pnext;
- while (p2)
- {
- if (p2->pdev == pdev)
- {
- p1->pnext = p2->pnext;
- p2->pnext = NULL;
- free_event(&dev_mgr->event_pool, p2);
- p2 = p1->pnext;
- }
- else
- {
- p1 = p2;
- p2 = p2->pnext;
- }
- }
- }
- pthis = pnext;
- }
- KeReleaseSpinLock(&dev_mgr->event_list_lock, old_irql);
-
- // found indicates the reset event on one of the dev's port in process
- if (found)
- hub_start_next_reset_port(dev_mgr_from_dev(pdev), FALSE);
-
- // remove timer-svc belonging to the dev
- KeAcquireSpinLock(&dev_mgr->timer_svc_list_lock, &old_irql);
- ListFirst(&dev_mgr->timer_svc_list, pthis);
- i = 0;
- while (pthis)
- {
- ListNext(&dev_mgr->timer_svc_list, pthis, pnext);
- if (((PUSB_EVENT) pthis)->pdev == pdev)
- {
- RemoveEntryList(pthis);
- free_timer_svc(&dev_mgr->timer_svc_pool, struct_ptr(pthis, TIMER_SVC, timer_svc_link));
- i++;
- }
- pthis = pnext;
- }
- KeReleaseSpinLock(&dev_mgr->timer_svc_list_lock, old_irql);
-
- // release the refcount
- if (i)
- {
- lock_dev(pdev, FALSE);
- pdev->ref_count -= i;
- unlock_dev(pdev, FALSE);
- }
-
- // wait for all the reference count be released
- for(;;)
- {
- LARGE_INTEGER interval;
-
- lock_dev(pdev, FALSE);
- if (pdev->ref_count == 0)
- {
- unlock_dev(pdev, FALSE);
- break;
- }
- unlock_dev(pdev, FALSE);
- // Wait two ms.
- interval.QuadPart = -20000;
- KeDelayExecutionThread(KernelMode, FALSE, &interval);
- }
-
- if (pdev->dev_driver && pdev->dev_driver->disp_tbl.dev_disconnect)
- pdev->dev_driver->disp_tbl.dev_disconnect(dev_mgr, dev_handle_from_dev(pdev));
-
- // we put it here to let handle valid before disconnect
- KeAcquireSpinLock(&dev_mgr->dev_list_lock, &old_irql);
- ListFirst(&dev_mgr->dev_list, pthis);
- while (pthis)
- {
- if (((PUSB_DEV) pthis) == pdev)
- {
- RemoveEntryList(pthis);
- break;
- }
- ListNext(&dev_mgr->dev_list, pthis, pnext);
- pthis = pnext;
- }
- KeReleaseSpinLock(&dev_mgr->dev_list_lock, old_irql);
-
-
- if (pdev != pdev->hcd->hcd_get_root_hub(pdev->hcd))
- {
- dev_mgr_free_device(dev_mgr, pdev);
- }
- else
- {
- //rh_destroy( pdev );
- //TRAP();
- //destroy it in dev_mgr_destroy
- }
-
- return;
-}
-
-//called in hub_set_address_completion
-BOOLEAN
-dev_mgr_start_config_dev(PUSB_DEV pdev)
-{
- PBYTE data_buf;
- PUSB_CTRL_SETUP_PACKET psetup;
- PURB purb;
- PHCD hcd;
- USE_BASIC_NON_PENDING_IRQL;
-
- hcd_dbg_print(DBGLVL_MAXIMUM, ("dev_mgr_start_config_dev: pdev=%p\n", pdev));
-
- if (pdev == NULL)
- return FALSE;
-
- lock_dev(pdev, TRUE);
- if (dev_state(pdev) == USB_DEV_STATE_ZOMB)
- {
- unlock_dev(pdev, TRUE);
- return FALSE;
- }
-
- hcd = pdev->hcd;
-
- //first, get device descriptor
- purb = usb_alloc_mem(NonPagedPool, sizeof(URB));
- data_buf = usb_alloc_mem(NonPagedPool, 512);
- if (purb == NULL || data_buf == NULL)
- {
- unlock_dev(pdev, TRUE);
- return FALSE;
- }
-
- RtlZeroMemory(purb, sizeof(URB));
- RtlZeroMemory(data_buf, 512);
-
- psetup = (PUSB_CTRL_SETUP_PACKET) purb->setup_packet;
-
- purb->data_buffer = data_buf; // user data
- purb->data_length = 8; // get partial desc
-
- pdev->desc_buf = data_buf;
- pdev->desc_buf_size = 512;
-
- purb->pdev = pdev;
- purb->pendp = &pdev->default_endp; //pipe for current transfer
-
- purb->completion = dev_mgr_get_desc_completion;
- purb->reference = 0;
-
- InitializeListHead(&purb->trasac_list);
-
- psetup->bmRequestType = 0x80;
- psetup->bRequest = USB_REQ_GET_DESCRIPTOR;
- psetup->wValue = (USB_DT_DEVICE << 8) | 0;
- psetup->wIndex = 0;
- psetup->wLength = 8; //sizeof( USB_DEVICE_DESC );
- unlock_dev(pdev, TRUE);
-
- if (hcd->hcd_submit_urb(hcd, pdev, purb->pendp, purb) != STATUS_PENDING)
- {
- usb_free_mem(purb);
- usb_free_mem(data_buf);
- return FALSE;
- }
- return TRUE;
-}
-
-VOID
-dev_mgr_get_desc_completion(PURB purb, PVOID context)
-{
- PUSB_DEV pdev;
- PUSB_CONFIGURATION_DESC pconfig_desc;
- PUSB_ENDPOINT pendp;
- PUSB_DEV_MANAGER dev_mgr;
- NTSTATUS status;
- PUSB_CTRL_SETUP_PACKET psetup;
- PHCD hcd;
-
- USE_BASIC_NON_PENDING_IRQL;
-
- if (purb == NULL)
- return;
-
- hcd_dbg_print(DBGLVL_MAXIMUM,
- ("dev_mgr_get_desc_completion: purb->reference=%d\n", purb->reference));
-
- pdev = purb->pdev;
- pendp = purb->pendp;
-
- if (pdev == NULL || pendp == NULL)
- {
- usb_free_mem(purb);
- purb = NULL;
- return;
- }
-
- lock_dev(pdev, TRUE);
- if (dev_state(pdev) == USB_DEV_STATE_ZOMB)
- {
- unlock_dev(pdev, TRUE);
- goto LBL_OUT;
- }
-
- pendp = &pdev->default_endp;
- dev_mgr = dev_mgr_from_dev(pdev);
- hcd = pdev->hcd;
- psetup = (PUSB_CTRL_SETUP_PACKET) purb->setup_packet;
-
- if (usb_error(purb->status))
- {
- unlock_dev(pdev, TRUE);
- hcd_dbg_print(DBGLVL_MAXIMUM,
- ("dev_mgr_get_desc_completion: can not get dev desc ref=0x%x, status=0x%x\n",
- purb->reference, purb->status));
- goto LBL_OUT;
- }
-
- switch (purb->reference)
- {
- case 0:
- {
- //only partial dev_desc
- //enable the dev specific default endp maxpacketsize
- pdev->pusb_dev_desc = (PUSB_DEVICE_DESC) purb->data_buffer;
-
- psetup = (PUSB_CTRL_SETUP_PACKET) purb->setup_packet;
- psetup->wLength = sizeof(USB_DEVICE_DESC);
-
- //get the complete dev_desc
- purb->reference = 1;
- purb->status = 0;
- purb->data_length = sizeof(USB_DEVICE_DESC);
-
- unlock_dev(pdev, TRUE);
-
- status = hcd->hcd_submit_urb(hcd, pdev, pendp, purb);
- if (status != STATUS_PENDING)
- {
- goto LBL_OUT;
- }
- return;
- }
- case 1:
- {
- //let's begin to get config descriptors.
- if (pdev->pusb_dev_desc->bNumConfigurations == 0)
- {
- unlock_dev(pdev, TRUE);
- goto LBL_OUT;
- }
-
- purb->data_buffer += sizeof(USB_DEVICE_DESC);
- purb->data_length = 8;
- purb->reference++;
- purb->context = (PVOID) sizeof(USB_DEVICE_DESC);
- purb->status = 0;
-
- psetup->wValue = (USB_DT_CONFIG << 8) | 0;
- psetup->wLength = 8;
- unlock_dev(pdev, TRUE);
-
- status = hcd->hcd_submit_urb(hcd, pdev, pendp, purb);
-
- if (status != STATUS_PENDING)
- {
- goto LBL_OUT;
- }
- return;
- }
- default:
- {
- LONG config_idx;
- config_idx = (purb->reference >> 1) - 1;
- if ((purb->reference & 1) == 0)
- {
- //partial config desc is obtained.
- pconfig_desc = (PUSB_CONFIGURATION_DESC) purb->data_buffer;
- if (pconfig_desc->wTotalLength >= 1024)
- {
- //treat as an error
- unlock_dev(pdev, TRUE);
- goto LBL_OUT;
-
- }
-
- if (pconfig_desc->wTotalLength > (USHORT) (pdev->desc_buf_size - (LONG) purb->context))
- {
- //rewind the 8-byte hdr
- *((PULONG) & context) -= 8;
- realloc_buf(pdev, purb);
- }
- purb->data_length = pconfig_desc->wTotalLength;
- psetup->wLength = pconfig_desc->wTotalLength;
- purb->reference++;
- unlock_dev(pdev, TRUE);
- status = hcd->hcd_submit_urb(hcd, pdev, pendp, purb);
- if (status != STATUS_PENDING)
- goto LBL_OUT;
-
- }
- else
- {
- //complete desc is returned.
- if (config_idx + 1 < pdev->pusb_dev_desc->bNumConfigurations)
- {
- //still have configurations left
- *((PULONG) & context) += psetup->wLength;
- purb->data_buffer = &pdev->desc_buf[(LONG) context];
- purb->data_length = 8;
- psetup->wLength = 8;
- psetup->wValue = (((USB_DT_CONFIG) << 8) | (config_idx + 1));
- purb->reference++;
- purb->context = context;
-
- if (((LONG) context) + 8 > pdev->desc_buf_size)
- realloc_buf(pdev, purb);
-
- purb->status = 0;
- unlock_dev(pdev, TRUE);
- status = hcd->hcd_submit_urb(hcd, pdev, pendp, purb);
- if (status != STATUS_PENDING)
- goto LBL_OUT;
- }
- else
- {
- //config descriptors have all been fetched
- unlock_dev(pdev, TRUE);
- usb_free_mem(purb);
- purb = NULL;
-
- // load driver for the device
- dev_mgr_start_select_driver(pdev);
- }
- }
- return;
- }
- }
-
-LBL_OUT:
- if (purb)
- {
- usb_free_mem(purb);
- purb = NULL;
- }
-
- lock_dev(pdev, TRUE);
- if (dev_state(pdev) != USB_DEV_STATE_ZOMB)
- {
- if (pdev->desc_buf)
- {
- usb_free_mem(pdev->desc_buf);
- pdev->desc_buf_size = 0;
- pdev->desc_buf = NULL;
- pdev->pusb_dev_desc = NULL;
- pdev->usb_config = NULL;
- }
- }
- unlock_dev(pdev, TRUE);
-
- return;
-}
-
-BOOLEAN
-dev_mgr_start_select_driver(PUSB_DEV pdev)
-{
- PUSB_DEV_MANAGER dev_mgr;
- PUSB_EVENT pevent;
- BOOLEAN bret;
-
- USE_BASIC_NON_PENDING_IRQL;
-
- if (pdev == NULL)
- return FALSE;
-
- dev_mgr = dev_mgr_from_dev(pdev);
- KeAcquireSpinLockAtDpcLevel(&dev_mgr->event_list_lock);
- lock_dev(pdev, TRUE);
-
- if (dev_state(pdev) == USB_DEV_STATE_ZOMB)
- {
- bret = FALSE;
- goto LBL_OUT;
- }
-
- pevent = alloc_event(&dev_mgr->event_pool, 1);
- if (pevent == NULL)
- {
- bret = FALSE;
- goto LBL_OUT;
- }
- pevent->flags = USB_EVENT_FLAG_ACTIVE;
- pevent->event = USB_EVENT_DEFAULT;
- pevent->pdev = pdev;
- pevent->context = 0;
- pevent->param = 0;
- pevent->pnext = 0; //vertical queue for serialized operation
- pevent->process_event = dev_mgr_event_select_driver;
- pevent->process_queue = event_list_default_process_queue;
-
- InsertTailList(&dev_mgr->event_list, &pevent->event_link);
- KeSetEvent(&dev_mgr->wake_up_event, 0, FALSE);
- bret = TRUE;
-
-LBL_OUT:
- unlock_dev(pdev, TRUE);
- KeReleaseSpinLockFromDpcLevel(&dev_mgr->event_list_lock);
- return bret;
-}
-
-BOOLEAN
-dev_mgr_connect_to_dev(PVOID Parameter)
-{
- PUSB_DEV pdev;
- DEV_HANDLE dev_handle;
- NTSTATUS status;
- PUSB_DRIVER pdriver;
- PDEV_CONNECT_DATA pcd = (PDEV_CONNECT_DATA) Parameter;
- PUSB_DEV_MANAGER dev_mgr;
- DEV_CONNECT_DATA param;
-
- if (pcd == NULL)
- return FALSE;
- dev_handle = pcd->dev_handle;
- pdriver = pcd->pdriver;
- dev_mgr = pcd->dev_mgr;
-
- param.dev_mgr = dev_mgr;
- param.pdriver = pdriver;
- param.dev_handle = 0; //not used
-
- status = usb_query_and_lock_dev(dev_mgr, dev_handle, &pdev);
- if (status != STATUS_SUCCESS)
- return FALSE;
-
- usb_dbg_print(DBGLVL_MAXIMUM, ("dev_mgr_connect_to_dev(): about to call driver's dev_connect\n"));
- status = pdriver->disp_tbl.dev_connect(¶m, dev_handle);
- usb_unlock_dev(pdev);
- return status;
-}
-
-VOID
-dev_mgr_event_select_driver(PUSB_DEV pdev, ULONG event, ULONG context, ULONG param)
-{
- PUSB_DEV_MANAGER dev_mgr;
- PUSB_DRIVER pdriver, pcand;
- LONG credit, match, i;
- DEV_HANDLE handle = 0;
- DEV_CONNECT_DATA cd;
-
- USE_BASIC_NON_PENDING_IRQL;
-
- UNREFERENCED_PARAMETER(param);
- UNREFERENCED_PARAMETER(context);
-
- usb_dbg_print(DBGLVL_MAXIMUM, ("dev_mgr_event_select_driver(): pdev=%p event=0x%x\n", pdev, event));
-
- if (pdev == NULL)
- return;
-
- lock_dev(pdev, FALSE);
- if (dev_state(pdev) == USB_DEV_STATE_ZOMB)
- {
- unlock_dev(pdev, FALSE);
- return;
- }
- dev_mgr = dev_mgr_from_dev(pdev);
-
- pcand = NULL;
- match = 0;
- for(i = HUB_DRIVER_IDX; i < DEVMGR_MAX_DRIVERS; i++)
- {
- //bypass root-hub driver with idx zero
- pdriver = (PUSB_DRIVER) & dev_mgr->driver_list[i];
-
- if (pdriver->driver_desc.flags & USB_DRIVER_FLAG_DEV_CAPABLE)
- credit = dev_mgr_score_driver_for_dev(dev_mgr, pdriver, pdev->pusb_dev_desc);
- else
- {
- continue;
- }
- if (credit > match)
- pcand = pdriver, match = credit;
-
- }
-
- if (match)
- {
- // we set class driver here
- // pdev->dev_driver = pcand;
- handle = usb_make_handle(pdev->dev_id, 0, 0);
- }
- unlock_dev(pdev, FALSE);
-
- if (match)
- {
-
- cd.dev_handle = handle;
- cd.pdriver = pcand;
- cd.dev_mgr = dev_mgr;
-
- if (dev_mgr_connect_to_dev(&cd))
- return;
-
- // ExInitializeWorkItem( pwork_item, dev_mgr_connect_to_dev, ( PVOID )pcd );
- // ExQueueWorkItem( pwork_item, DelayedWorkQueue );
- }
- cd.dev_handle = handle;
- cd.pdriver = &dev_mgr->driver_list[GEN_DRIVER_IDX];
- cd.dev_mgr = dev_mgr;
- dev_mgr_connect_to_dev(&cd);
- return;
-}
-
-BOOLEAN
-dev_mgr_build_usb_endp(PUSB_INTERFACE pif, PUSB_ENDPOINT pendp, PUSB_ENDPOINT_DESC pendp_desc)
-{
- if (pendp == NULL || pif == NULL || pendp_desc == NULL)
- return FALSE;
-
- pendp->flags = 0;
- InitializeListHead(&pendp->urb_list); //pending urb queue
- pendp->pusb_if = pif;
- pendp->pusb_endp_desc = pendp_desc;
- return TRUE;
-}
-
-BOOLEAN
-dev_mgr_build_usb_if(PUSB_CONFIGURATION pcfg, PUSB_INTERFACE pif, PUSB_INTERFACE_DESC pif_desc, BOOLEAN alt_if)
-{
- LONG i;
- PUSB_ENDPOINT_DESC pendp_desc;
- PBYTE pbuf;
-
- if (pcfg == NULL || pif == NULL || pif_desc == NULL)
- return FALSE;
-
- if (alt_if == FALSE)
- {
- pif->endp_count = pif_desc->bNumEndpoints > MAX_ENDPS_PER_IF
- ? MAX_ENDPS_PER_IF : pif_desc->bNumEndpoints;
-
- pif->pif_drv = NULL;
- pif->pusb_config = pcfg;
- pif->pusb_if_desc = pif_desc;
- pif->if_ext_size = 0;
- pif->if_ext = NULL;
-
- InitializeListHead(&pif->altif_list);
- pif->altif_count = 0;
-
- pbuf = &((PBYTE) pif_desc)[sizeof(USB_INTERFACE_DESC)];
-
- i = 0;
- while (i < pif->endp_count)
- {
- pendp_desc = (PUSB_ENDPOINT_DESC)pbuf;
-
- // check if it's an endpoint descriptor
- if (pendp_desc->bDescriptorType == USB_DT_ENDPOINT)
- {
- // add it
- dev_mgr_build_usb_endp(pif, &pif->endp[i], pendp_desc);
- i++;
- }
-
- // skip to the next one
- pbuf += pendp_desc->bLength;
- }
- }
- else
- {
- PUSB_INTERFACE paltif;
- PLIST_ENTRY pthis, pnext;
-
- pif->altif_count++;
- paltif = usb_alloc_mem(NonPagedPool, sizeof(USB_INTERFACE));
- if (!paltif) return FALSE;
-
- RtlZeroMemory(paltif, sizeof(USB_INTERFACE));
- InsertTailList(&pif->altif_list, &paltif->altif_list);
- paltif->pif_drv = NULL;
- paltif->pusb_config = pcfg;
- paltif->pusb_if_desc = pif_desc;
- paltif->if_ext_size = 0;
- paltif->if_ext = NULL;
- paltif->endp_count = pif_desc->bNumEndpoints > MAX_ENDPS_PER_IF
- ? MAX_ENDPS_PER_IF : pif_desc->bNumEndpoints;
-
- ListFirst(&pif->altif_list, pthis);
-
- while (pthis)
- {
- //synchronize the altif_count;
- PUSB_INTERFACE pthis_if;
- pthis_if = (PUSB_INTERFACE) (((PBYTE) pthis) - offsetof(USB_INTERFACE, altif_list));
- pthis_if->altif_count = pif->altif_count;
- ListNext(&pif->altif_list, pthis, pnext);
- pthis = pnext;
- }
-
- }
- return TRUE;
-}
-
-NTSTATUS
-dev_mgr_build_usb_config(PUSB_DEV pdev, PBYTE pbuf, ULONG config_val, LONG config_count)
-{
- PUSB_CONFIGURATION pcfg;
- PUSB_INTERFACE_DESC pif_desc;
- PUSB_INTERFACE pif;
- int i;
- LONG if_count;
-
- if (pdev == NULL || pbuf == NULL)
- return STATUS_INVALID_PARAMETER;
-
-
- pdev->usb_config = usb_alloc_mem(NonPagedPool, sizeof(USB_CONFIGURATION));
- pcfg = pdev->usb_config;
-
- if (pdev->usb_config == NULL)
- return STATUS_NO_MEMORY;
-
- RtlZeroMemory(pcfg, sizeof(USB_CONFIGURATION));
- pcfg->pusb_config_desc = usb_find_config_desc_by_val(pbuf, config_val, config_count);
-
- if (pcfg->pusb_config_desc == NULL)
- {
- usb_free_mem(pcfg);
- pdev->usb_config = NULL;
- return STATUS_UNSUCCESSFUL;
- }
- pcfg->if_count = pcfg->pusb_config_desc->bNumInterfaces;
- pcfg->pusb_dev = pdev;
- pif_desc = (PUSB_INTERFACE_DESC) & ((PBYTE) pcfg->pusb_config_desc)[sizeof(USB_CONFIGURATION_DESC)];
- if_count = pcfg->if_count;
-
- for(i = 0; i < if_count; i++, pif_desc++)
- {
- if (pif_desc->bAlternateSetting == 0)
- {
- dev_mgr_build_usb_if(pcfg, &pcfg->interf[i], pif_desc, FALSE);
- }
- else
- {
- pif = &pcfg->interf[i-1];
- dev_mgr_build_usb_if(pcfg, pif, pif_desc, TRUE);
- }
- }
- return STATUS_SUCCESS;
-}
-
-NTSTATUS
-dev_mgr_destroy_usb_config(PUSB_CONFIGURATION pcfg)
-{
- long i;
- PLIST_ENTRY pthis;
- PUSB_INTERFACE pif;
-
- if (pcfg == NULL)
- return FALSE;
-
- for(i = 0; i < pcfg->if_count; i++)
- {
- pif = &pcfg->interf[i];
-
- if (pif->altif_count)
- {
- ListFirst(&pif->altif_list, pthis);
- while (pthis)
- {
- PUSB_INTERFACE pthis_if;
- pthis_if = (PUSB_INTERFACE) (((PBYTE) pthis) - offsetof(USB_INTERFACE, altif_list));
- RemoveEntryList(pthis);
- usb_free_mem(pthis_if);
- if (IsListEmpty(&pif->altif_list) == TRUE)
- break;
-
- ListFirst(&pif->altif_list, pthis);
- }
- }
- }
- usb_free_mem(pcfg);
- return TRUE;
-}
-
-#define is_dev_product_match( pdriVER, pdev_DESC ) \
-( ( pdriVER )->driver_desc.vendor_id == ( pdev_DESC )->idVendor \
- && ( pdriVER )->driver_desc.product_id == ( pdev_DESC )->idProduct )
-
-LONG
-dev_mgr_score_driver_for_dev(PUSB_DEV_MANAGER dev_mgr, PUSB_DRIVER pdriver, PUSB_DEVICE_DESC pdev_desc)
-{
- LONG credit = 0;
-
- UNREFERENCED_PARAMETER(dev_mgr);
-
- //assume supports all the sub_class are supported if sub_class is zero
- if (pdriver->driver_desc.dev_class == pdev_desc->bDeviceClass)
- {
- if (pdriver->driver_desc.dev_sub_class == 0 && pdriver->driver_desc.dev_protocol == 0)
- credit = 3;
- else if (pdriver->driver_desc.dev_sub_class == pdev_desc->bDeviceSubClass)
- {
- if (pdriver->driver_desc.dev_protocol == 0)
- credit = 6;
- else if (pdriver->driver_desc.dev_protocol == pdev_desc->bDeviceProtocol)
- credit = 9;
- }
- }
-
- if (is_dev_product_match(pdriver, pdev_desc))
- credit += 20;
-
- return credit;
-}
-
-LONG
-dev_mgr_score_driver_for_if(PUSB_DEV_MANAGER dev_mgr, PUSB_DRIVER pdriver, PUSB_INTERFACE_DESC pif_desc)
-{
- LONG credit;
-
- if (pdriver == NULL
- || !(pdriver->driver_desc.flags & USB_DRIVER_FLAG_IF_CAPABLE) || pif_desc == NULL || dev_mgr == NULL)
- return 0;
-
- if (is_header_match((PBYTE) pif_desc, USB_DT_INTERFACE) == FALSE)
- {
- return 0;
- }
-
- credit = 0;
- if ((pdriver->driver_desc.if_class == pif_desc->bInterfaceClass))
- {
- if (pdriver->driver_desc.if_sub_class == 0 && pdriver->driver_desc.if_protocol == 0)
- credit = 2;
- if (pdriver->driver_desc.if_sub_class == pif_desc->bInterfaceSubClass)
- {
- if (pdriver->driver_desc.if_protocol == 0)
- credit = 4;
- if (pdriver->driver_desc.if_protocol == pif_desc->bInterfaceProtocol)
- credit = 6;
- }
- }
- else
- credit = 1;
-
- return credit;
-}
-
-#define is_equal_driver( pd1, pd2, ret ) \
-{\
- int i;\
- ret = TRUE;\
- PUSB_DRIVER pdr1, pdr2;\
- pdr1 = ( PUSB_DRIVER )( pd1 );\
- pdr2 = ( PUSB_DRIVER ) ( pd2 );\
- for( i = 0; i < 16; i++ )\
- {\
- if( pdr1->driver_name[ i ] != pdr2->driver_name[ i ] )\
- {\
- ret = FALSE;\
- break;\
- }\
- }\
-}
-
-//return value is the hcd id
-UCHAR
-dev_mgr_register_hcd(PUSB_DEV_MANAGER dev_mgr, PHCD hcd)
-{
- if (dev_mgr == NULL || hcd == NULL)
- return 0xff;
-
- if (dev_mgr->hcd_count >= MAX_HCDS)
- return 0xff;
-
- dev_mgr->hcd_array[dev_mgr->hcd_count++] = hcd;
- return dev_mgr->hcd_count - 1;
-}
-
-VOID
-dev_mgr_deregister_hcd(PUSB_DEV_MANAGER dev_mgr, UCHAR hcd_id)
-{
- UCHAR i;
-
- if (dev_mgr == NULL || hcd_id >= MAX_HCDS - 1)
- return;
-
- for (i = hcd_id; i < dev_mgr->hcd_count - 1; i++)
- dev_mgr->hcd_array[i] = dev_mgr->hcd_array[i + 1];
-
- dev_mgr->hcd_count--;
-}
-
-BOOLEAN
-dev_mgr_register_irp(PUSB_DEV_MANAGER dev_mgr, PIRP pirp, PURB purb)
-{
- if (dev_mgr == NULL)
- return FALSE;
-
- if (add_irp_to_list(&dev_mgr->irp_list, pirp, purb))
- {
- return TRUE;
- }
- TRAP();
- return FALSE;
-}
-
-//caller must guarantee that when this func is called,
-//the urb associated must exist.
-PURB
-dev_mgr_remove_irp(PUSB_DEV_MANAGER dev_mgr, PIRP pirp)
-{
- PURB purb;
- if (dev_mgr == NULL)
- return NULL;
-
- purb = remove_irp_from_list(&dev_mgr->irp_list, pirp, NULL);
- return purb;
-}
-
-VOID
-NTAPI
-dev_mgr_cancel_irp(PDEVICE_OBJECT dev_obj, PIRP pirp)
-{
- PUSB_DEV_MANAGER dev_mgr;
- PDEVEXT_HEADER pdev_ext_hdr;
-
- pdev_ext_hdr = (PDEVEXT_HEADER) dev_obj->DeviceExtension;
- dev_mgr = pdev_ext_hdr->dev_mgr;
-
- if (dev_obj->CurrentIrp == pirp)
- {
- IoReleaseCancelSpinLock(pirp->CancelIrql);
- // we did not IoStartNextPacket, leave it for the urb completion
- }
- else
- {
- KeRemoveEntryDeviceQueue(&dev_obj->DeviceQueue, &pirp->Tail.Overlay.DeviceQueueEntry);
- IoReleaseCancelSpinLock(pirp->CancelIrql);
-
- pirp->IoStatus.Information = 0;
- pirp->IoStatus.Status = STATUS_CANCELLED;
- IoCompleteRequest(pirp, IO_NO_INCREMENT);
- // the device queue is moved on, no need to call IoStartNextPacket
- return;
- }
-
- //
- // remove the irp and call the dev_mgr_cancel_irp
- // the completion will be done in urb completion
- //
- remove_irp_from_list(&dev_mgr->irp_list, pirp, dev_mgr);
- return;
-
-}
-
-// release the hcd
-VOID
-dev_mgr_release_hcd(PUSB_DEV_MANAGER dev_mgr)
-{
- LONG i;
- PHCD hcd;
- for(i = 0; i < dev_mgr->hcd_count; i++)
- {
- hcd = dev_mgr->hcd_array[i];
- hcd->hcd_release(hcd);
- dev_mgr->hcd_array[i] = 0;
- }
- dev_mgr->hcd_count = 0;
- return;
-}
-
-VOID
-dev_mgr_start_hcd(PUSB_DEV_MANAGER dev_mgr)
-{
- LONG i;
- PHCD hcd;
- for(i = 0; i < dev_mgr->hcd_count; i++)
- {
- hcd = dev_mgr->hcd_array[i];
- hcd->hcd_start(hcd);
- }
- return;
-}
diff --git a/reactos/drivers/usb/nt4compat/usbdrv/devmgr.h b/reactos/drivers/usb/nt4compat/usbdrv/devmgr.h
deleted file mode 100644
index f90c9f0974c..00000000000
--- a/reactos/drivers/usb/nt4compat/usbdrv/devmgr.h
+++ /dev/null
@@ -1,281 +0,0 @@
-#ifndef __DEVMGR_H__
-#define __DEVMGR_H__
-
-typedef struct _DEV_CONNECT_DATA
-{
- DEV_HANDLE dev_handle;
- struct _USB_DRIVER *pdriver;
- struct _USB_DEV_MANAGER *dev_mgr;
- PUSB_INTERFACE_DESC if_desc;
-
-} DEV_CONNECT_DATA, *PDEV_CONNECT_DATA;
-
-typedef BOOLEAN ( *PDEV_CONNECT_EX )( PDEV_CONNECT_DATA init_param, DEV_HANDLE dev_handle );
-typedef BOOLEAN ( *PDEV_CONNECT )( struct _USB_DEV_MANAGER *dev_mgr, DEV_HANDLE dev_handle );
-typedef BOOLEAN ( *PDRVR_INIT )( struct _USB_DEV_MANAGER *dev_mgr, struct _USB_DRIVER *pdriver );
-
-typedef struct _PNP_DISPATCH
-{
- ULONG version;
- PDEV_CONNECT_EX dev_connect;
- PDEV_CONNECT dev_reserved; //currently we do not use this entry
- PDEV_CONNECT dev_stop;
- PDEV_CONNECT dev_disconnect;
-
-}PNP_DISPATCH, *PPNP_DISPATCH;
-
-#define USB_DRIVER_FLAG_IF_CAPABLE 0x80000000
-#define USB_DRIVER_FLAG_DEV_CAPABLE 0x40000000
-
-typedef struct _USB_DRIVER_DESCRIPTION
-{
- // Device Info
- DWORD flags;
- WORD vendor_id; // USB Vendor ID
- WORD product_id; // USB Product ID.
- WORD release_num; // Release Number of Device
-
- // Interface Info
- BYTE config_val; // Configuration Value
- BYTE if_num; // Interface Number
- BYTE if_class; // Interface Class
- BYTE if_sub_class; // Interface SubClass
- BYTE if_protocol; // Interface Protocol
-
- // Driver Info
- const char *driver_name; // Driver name for Name Registry
- BYTE dev_class; // Device Class (from SampleStorageDeviceID.h)
- BYTE dev_sub_class; // Device Subclass
- BYTE dev_protocol; // Protocol Info.
-
-} USB_DRIVER_DESCRIPTION,*PUSB_DRIVER_DESCRIPTION;
-
-#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
-#define DEVMGR_MAX_DRIVERS 8
-
-typedef struct _USB_DRIVER
-{
- USB_DRIVER_DESCRIPTION driver_desc;
- PNP_DISPATCH disp_tbl;
-
- PBYTE driver_ext;
- LONG driver_ext_size;
-
- PDRVR_INIT driver_init;
- PDRVR_INIT driver_destroy;
-
-} USB_DRIVER, *PUSB_DRIVER;
-
-extern USB_DRIVER g_driver_list[ DEVMGR_MAX_DRIVERS ];
-
-#define MAX_HCDS 8
-#define dev_mgr_from_hcd( hCD ) ( ( hCD )->hcd_get_dev_mgr( hCD ) )
-#define dev_mgr_from_dev( pdEV ) ( dev_mgr_from_hcd( pdEV->hcd ) )
-
-typedef struct _USB_DEV_MANAGER
-{
- //BYTE dev_addr_map[ MAX_DEVS / 8 ]; //one bit per dev
- struct _HCD *hcd_array[ MAX_HCDS ];
- unsigned char hcd_count;
-
- KSPIN_LOCK dev_list_lock;
- LIST_HEAD dev_list;
-
- //PDEVICE_EXTENSION pdev_ext;
-
- PVOID pthread;
- BOOLEAN term_flag;
- KEVENT wake_up_event;
-
- KSPIN_LOCK event_list_lock;
- LIST_HEAD event_list;
- USB_EVENT_POOL event_pool;
-
- KEVENT drivers_inited;
- KTIMER dev_mgr_timer;
- KDPC dev_mgr_timer_dpc;
- KSPIN_LOCK timer_svc_list_lock;
- LIST_HEAD timer_svc_list;
- TIMER_SVC_POOL timer_svc_pool;
- LONG timer_click;
- IRP_LIST irp_list;
-
- PUSB_DRIVER driver_list;
- LONG hub_count;
- LIST_HEAD hub_list; //for reference only
-
- //statistics
- LONG conn_count; //will also be used to assign device id
- PDRIVER_OBJECT usb_driver_obj; //this driver object
- LONG open_count; //increment when IRP_MJ_CREATE arrives
- //and decrement when IRP_MJ_CLOSE arrives
-
-} USB_DEV_MANAGER, *PUSB_DEV_MANAGER;
-
-BOOLEAN
-dev_mgr_post_event(
-PUSB_DEV_MANAGER dev_mgr,
-PUSB_EVENT event
-);
-
-BOOLEAN
-dev_mgr_init(
-PUSB_DEV dev, //always null. we do not use this param
-ULONG event,
-ULONG dev_mgr
-);
-
-VOID
-dev_mgr_destroy(
-PUSB_DEV_MANAGER dev_mgr
-);
-
-VOID NTAPI
-dev_mgr_thread(
-PVOID dev_mgr
-);
-
-VOID NTAPI
-dev_mgr_timer_dpc_callback(
-PKDPC Dpc,
-PVOID DeferredContext,
-PVOID SystemArgument1,
-PVOID SystemArgument2
-);
-
-BOOLEAN
-dev_mgr_request_timer_svc(
-PUSB_DEV_MANAGER dev_mgr,
-PUSB_DEV pdev,
-ULONG context,
-ULONG due_time,
-TIMER_SVC_HANDLER handler
-);
-
-BYTE
-dev_mgr_alloc_addr(
-PUSB_DEV_MANAGER dev_mgr,
-PHCD hcd
-);
-
-BOOLEAN
-dev_mgr_free_addr(
-PUSB_DEV_MANAGER dev_mgr,
-PUSB_DEV pdev,
-BYTE addr
-);
-
-PUSB_DEV
-dev_mgr_alloc_device(
-PUSB_DEV_MANAGER dev_mgr,
-PHCD hcd
-);
-
-VOID
-dev_mgr_free_device(
-PUSB_DEV_MANAGER dev_mgr,
-PUSB_DEV pdev
-);
-
-VOID
-dev_mgr_disconnect_dev(
-PUSB_DEV pdev
-);
-
-BOOLEAN
-dev_mgr_strobe(
-PUSB_DEV_MANAGER dev_mgr
-);
-
-NTSTATUS
-dev_mgr_build_usb_config(
-PUSB_DEV pdev,
-PBYTE pbuf,
-ULONG config_val,
-LONG config_count
-);
-
-UCHAR
-dev_mgr_register_hcd(
-PUSB_DEV_MANAGER dev_mgr,
-PHCD hcd
-);
-
-VOID
-dev_mgr_deregister_hcd(
-PUSB_DEV_MANAGER dev_mgr,
-UCHAR hcd_id
-);
-
-NTSTATUS
-dev_mgr_dispatch(
-IN PUSB_DEV_MANAGER dev_mgr,
-IN PIRP irp
-);
-
-BOOLEAN
-dev_mgr_register_irp(
-PUSB_DEV_MANAGER dev_mgr,
-PIRP pirp,
-PURB purb
-);
-
-PURB
-dev_mgr_remove_irp(
-PUSB_DEV_MANAGER dev_mgr,
-PIRP pirp
-);
-
-LONG
-dev_mgr_score_driver_for_if(
-PUSB_DEV_MANAGER dev_mgr,
-PUSB_DRIVER pdriver,
-PUSB_INTERFACE_DESC pif_desc
-);
-
-BOOLEAN
-dev_mgr_set_driver(
-PUSB_DEV_MANAGER dev_mgr,
-DEV_HANDLE dev_handle,
-PUSB_DRIVER pdriver,
-PUSB_DEV pdev //if pdev != NULL, we use pdev instead if_handle
-);
-
-BOOLEAN
-dev_mgr_set_if_driver(
-PUSB_DEV_MANAGER dev_mgr,
-DEV_HANDLE if_handle,
-PUSB_DRIVER pdriver,
-PUSB_DEV pdev //if pdev != NULL, we use pdev instead if_handle
-);
-
-VOID
-dev_mgr_release_hcd(
-PUSB_DEV_MANAGER dev_mgr
-);
-
-VOID
-dev_mgr_start_hcd(
-PUSB_DEV_MANAGER dev_mgr
-);
-
-BOOLEAN dev_mgr_start_config_dev(PUSB_DEV pdev);
-BOOLEAN dev_mgr_event_init(PUSB_DEV dev, //always null. we do not use this param
- ULONG event,
- ULONG context,
- ULONG param);
-VOID dev_mgr_get_desc_completion(PURB purb, PVOID context);
-VOID dev_mgr_event_select_driver(PUSB_DEV pdev, ULONG event, ULONG context, ULONG param);
-LONG dev_mgr_score_driver_for_dev(PUSB_DEV_MANAGER dev_mgr, PUSB_DRIVER pdriver, PUSB_DEVICE_DESC pdev_desc);
-NTSTATUS dev_mgr_destroy_usb_config(PUSB_CONFIGURATION pcfg);
-BOOLEAN dev_mgr_start_select_driver(PUSB_DEV pdev);
-VOID NTAPI dev_mgr_cancel_irp(PDEVICE_OBJECT pdev_obj, PIRP pirp);
-
-#endif
diff --git a/reactos/drivers/usb/nt4compat/usbdrv/dmgrdisp.c b/reactos/drivers/usb/nt4compat/usbdrv/dmgrdisp.c
deleted file mode 100644
index e24b49821fe..00000000000
--- a/reactos/drivers/usb/nt4compat/usbdrv/dmgrdisp.c
+++ /dev/null
@@ -1,535 +0,0 @@
-/**
- * dmgrdisp.c - USB driver stack project for Windows NT 4.0
- *
- * Copyright (c) 2002-2004 Zhiming mypublic99@yahoo.com
- *
- * This program/include file is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program/include file is distributed in the hope that it will be
- * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
- * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program (in the main directory of the distribution, the file
- * COPYING); if not, write to the Free Software Foundation,Inc., 59 Temple
- * Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "usbdriver.h"
-
-VOID
-disp_urb_completion(PURB purb, PVOID context)
-{
- PUSB_DEV_MANAGER dev_mgr;
- ULONG ctrl_code;
- NTSTATUS status;
- PDEVEXT_HEADER dev_hdr;
-
- UNREFERENCED_PARAMETER(context);
-
- if (purb == NULL)
- return;
-
- ctrl_code = (ULONG) purb->reference;
- dev_mgr = (PUSB_DEV_MANAGER) purb->context;
-
- // at this stage, the irp can not be canceled since the urb
- // won't be found in any queue and the irp is not in any queue.
- // see line 4685 in hub.c
- // Sometimes, it may be very fast to enter this routine before
- // the dev_mgr_register_irp to be called in dispatch routine in
- // usb2.0 environment as
- // we did in usb1.1 driver. We can not simply add a loop to wait
- // for the dispatch thread to add the irp to the list, because
- // here we are at DPC level higher than the dispatch thread
- // running level. And the solution is to register the irp
- // before the urb is scheduled instead of registering it after
- // urb is scheduled.
- if (purb->pirp)
- {
- PIO_STACK_LOCATION irp_stack;
- dev_mgr_remove_irp(dev_mgr, purb->pirp);
-
- status = purb->status;
- irp_stack = IoGetCurrentIrpStackLocation(purb->pirp);
-
- if (purb->status != STATUS_SUCCESS)
- {
- purb->pirp->IoStatus.Information = 0;
- }
- else
- {
- // currently only IRP_MJ_DEVICE_CONTROL and IRP_MJ_INTERNAL_DEVICE_CONTROL
- // are allowed. And we do not need to set information
- // for IRP_MJ_INTERNAL_DEVICE_CONTROL
- if (irp_stack->MajorFunction == IRP_MJ_DEVICE_CONTROL)
- purb->pirp->IoStatus.Information = purb->data_length;
- }
- purb->pirp->IoStatus.Status = status;
- if (irp_stack)
- {
- dev_hdr = irp_stack->DeviceObject->DeviceExtension;
- if (dev_hdr->start_io)
- {
- IoStartNextPacket(irp_stack->DeviceObject, TRUE);
- }
- }
- IoCompleteRequest(purb->pirp, IO_NO_INCREMENT);
- }
- return;
-}
-
-VOID
-disp_noio_urb_completion(PURB purb, PVOID context)
-{
- PUSB_CTRL_SETUP_PACKET psetup;
- PURB purb2;
- PUSB_DEV_MANAGER dev_mgr;
- NTSTATUS status = STATUS_SUCCESS;
- PIO_STACK_LOCATION irp_stack;
- PDEVEXT_HEADER dev_hdr;
-
- if (purb == NULL)
- return;
-
- psetup = (PUSB_CTRL_SETUP_PACKET) purb->setup_packet;
-
- if ((psetup->bmRequestType == 0x2) &&
- (psetup->bRequest == USB_REQ_CLEAR_FEATURE) &&
- (psetup->wIndex == 0)) //reset pipe
- {
- purb2 = (PURB) context;
- }
- else
- {
- purb2 = purb;
- }
-
- if (purb2->pirp == NULL)
- return;
-
- dev_mgr = (PUSB_DEV_MANAGER) purb2->context;
-
- dev_mgr_remove_irp(dev_mgr, purb2->pirp);
-
- if (purb->status != STATUS_SUCCESS)
- status = STATUS_IO_DEVICE_ERROR;
-
- purb2->pirp->IoStatus.Information = 0;
- purb2->pirp->IoStatus.Status = status;
- irp_stack = IoGetCurrentIrpStackLocation(purb->pirp);
- if (irp_stack)
- {
- dev_hdr = irp_stack->DeviceObject->DeviceExtension;
- if (dev_hdr->start_io)
- {
- IoStartNextPacket(irp_stack->DeviceObject, TRUE);
- }
- }
- IoCompleteRequest(purb2->pirp, IO_NO_INCREMENT);
- return;
-}
-
-//this function is called by the hcd's
-//dispatch when they have done their job.
-NTSTATUS
-dev_mgr_dispatch(IN PUSB_DEV_MANAGER dev_mgr, IN PIRP irp)
-{
- PIO_STACK_LOCATION irp_stack;
- NTSTATUS status;
- ULONG ctrl_code;
- USE_NON_PENDING_IRQL;
-
- ASSERT(irp);
- if (dev_mgr == NULL)
- {
- EXIT_DISPATCH(STATUS_INVALID_PARAMETER, irp);
- }
-
- status = STATUS_SUCCESS;
- irp_stack = IoGetCurrentIrpStackLocation(irp);
- ctrl_code = irp_stack->Parameters.DeviceIoControl.IoControlCode;
-
- switch (irp_stack->MajorFunction)
- {
- case IRP_MJ_CREATE:
- {
- InterlockedIncrement(&dev_mgr->open_count);
- EXIT_DISPATCH(STATUS_SUCCESS, irp);
- }
- case IRP_MJ_CLOSE:
- {
- InterlockedDecrement(&dev_mgr->open_count);
- EXIT_DISPATCH(STATUS_SUCCESS, irp);
- }
- case IRP_MJ_INTERNAL_DEVICE_CONTROL:
- case IRP_MJ_DEVICE_CONTROL:
- {
- switch (ctrl_code)
- {
- case IOCTL_GET_DEV_COUNT:
- {
- LONG dev_count;
-
- irp->IoStatus.Information = 0;
- if (irp_stack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(LONG))
- {
- EXIT_DISPATCH(STATUS_INVALID_PARAMETER, irp);
- }
-
- KeAcquireSpinLock(&dev_mgr->dev_list_lock, &old_irql);
- dev_count = usb_count_list(&dev_mgr->dev_list);
- KeReleaseSpinLock(&dev_mgr->dev_list_lock, old_irql);
-
- *((PLONG) irp->AssociatedIrp.SystemBuffer) = dev_count;
- irp->IoStatus.Information = sizeof(LONG);
- EXIT_DISPATCH(STATUS_SUCCESS, irp);
- }
- case IOCTL_ENUM_DEVICES:
- {
- PLIST_ENTRY pthis, pnext;
- LONG dev_count, array_size, i, j = 0;
- PUSB_DEV pdev;
- PENUM_DEV_ARRAY peda;
-
- irp->IoStatus.Information = 0;
- if (irp_stack->Parameters.DeviceIoControl.InputBufferLength < sizeof(LONG))
- {
- EXIT_DISPATCH(STATUS_INVALID_PARAMETER, irp);
- }
- if (irp_stack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(ENUM_DEV_ARRAY))
- {
- EXIT_DISPATCH(STATUS_INVALID_PARAMETER, irp);
- }
- array_size = *((PULONG) irp->AssociatedIrp.SystemBuffer);
-
- KeAcquireSpinLock(&dev_mgr->dev_list_lock, &old_irql);
- dev_count = usb_count_list(&dev_mgr->dev_list);
- dev_count = dev_count > array_size ? array_size : dev_count;
- peda = (PENUM_DEV_ARRAY) irp->AssociatedIrp.SystemBuffer;
- RtlZeroMemory(peda, sizeof(ENUM_DEV_ARRAY) + (dev_count - 1) * sizeof(ENUM_DEV_ELEMENT));
-
- if (dev_count)
- {
- ListFirst(&dev_mgr->dev_list, pthis);
- for(i = 0, j = 0; i < dev_count; i++)
- {
- pdev = struct_ptr(pthis, USB_DEV, dev_link);
- ListNext(&dev_mgr->dev_list, pthis, pnext);
- pthis = pnext;
-
- lock_dev(pdev, FALSE);
- if (dev_state(pdev) == USB_DEV_STATE_ZOMB)
- {
- unlock_dev(pdev, FALSE);
- continue;
- }
-
- if (dev_state(pdev) < USB_DEV_STATE_ADDRESSED)
- {
- unlock_dev(pdev, FALSE);
- continue;
- }
-
- peda->dev_arr[i].dev_handle = (pdev->dev_id << 16);
- //may not get the desc yet
- if (pdev->pusb_dev_desc)
- {
- peda->dev_arr[i].product_id = pdev->pusb_dev_desc->idProduct;
- peda->dev_arr[i].vendor_id = pdev->pusb_dev_desc->idVendor;
- }
- else
- {
- peda->dev_arr[i].product_id = 0xffff;
- peda->dev_arr[i].vendor_id = 0xffff;
- }
- peda->dev_arr[i].dev_addr = pdev->dev_addr;
- unlock_dev(pdev, FALSE);
- j++;
- }
- }
- peda->dev_count = dev_count ? j : 0;
- KeReleaseSpinLock(&dev_mgr->dev_list_lock, old_irql);
-
- irp->IoStatus.Information =
- sizeof(ENUM_DEV_ARRAY) + (dev_count - 1) * sizeof(ENUM_DEV_ELEMENT);
- EXIT_DISPATCH(STATUS_SUCCESS, irp);
- }
- case IOCTL_GET_DEV_DESC:
- {
- GET_DEV_DESC_REQ gddr;
- PUSB_DESC_HEADER pusb_desc_header;
- PUSB_DEV pdev;
- LONG buf_size;
-
- if (irp_stack->Parameters.DeviceIoControl.InputBufferLength < sizeof(GET_DEV_DESC_REQ))
- {
- EXIT_DISPATCH(STATUS_INVALID_PARAMETER, irp);
- }
-
- if (irp_stack->Parameters.DeviceIoControl.OutputBufferLength < 8)
- {
- EXIT_DISPATCH(STATUS_INVALID_PARAMETER, irp);
- }
-
- status = STATUS_SUCCESS;
- buf_size = irp_stack->Parameters.DeviceIoControl.OutputBufferLength;
- RtlCopyMemory(&gddr, irp->AssociatedIrp.SystemBuffer, sizeof(GET_DEV_DESC_REQ));
- pusb_desc_header = irp->AssociatedIrp.SystemBuffer;
-
- if (gddr.desc_type != USB_DT_CONFIG && gddr.desc_type != USB_DT_DEVICE)
- {
- EXIT_DISPATCH(STATUS_INVALID_DEVICE_REQUEST, irp);
- }
-
- if (usb_query_and_lock_dev(dev_mgr, gddr.dev_handle, &pdev) != STATUS_SUCCESS)
- {
- EXIT_DISPATCH(STATUS_IO_DEVICE_ERROR, irp);
- }
-
- lock_dev(pdev, FALSE);
- if (dev_state(pdev) == USB_DEV_STATE_ZOMB)
- {
- status = STATUS_INVALID_DEVICE_STATE;
- goto ERROR_OUT;
- }
- if (dev_state(pdev) != USB_DEV_STATE_ADDRESSED &&
- dev_state(pdev) != USB_DEV_STATE_CONFIGURED)
- {
- status = STATUS_DEVICE_NOT_READY;
- goto ERROR_OUT;
- }
-
- if (pdev->pusb_dev_desc == NULL)
- {
- status = STATUS_DEVICE_NOT_READY;
- goto ERROR_OUT;
- }
-
- if (gddr.desc_type == USB_DT_DEVICE)
- {
- RtlCopyMemory(pusb_desc_header,
- pdev->pusb_dev_desc,
- buf_size > sizeof(USB_DEVICE_DESC)
- ? sizeof(USB_DEVICE_DESC) : buf_size);
-
- irp->IoStatus.Information =
- buf_size >= sizeof(USB_DEVICE_DESC) ? sizeof(USB_DEVICE_DESC) : buf_size;
- }
- else if (gddr.desc_type == USB_DT_CONFIG)
- {
- PUSB_CONFIGURATION_DESC pusb_config_desc;
- if (pdev->pusb_dev_desc->bNumConfigurations <= gddr.desc_idx)
- {
- status = STATUS_INVALID_PARAMETER;
- goto ERROR_OUT;
- }
-
- pusb_config_desc = usb_find_config_desc_by_idx((PUCHAR) & pdev->pusb_dev_desc[1],
- gddr.desc_idx,
- pdev->pusb_dev_desc->
- bNumConfigurations);
-
- if (pusb_config_desc == NULL)
- {
- status = STATUS_DEVICE_NOT_READY;
- goto ERROR_OUT;
- }
-
- RtlCopyMemory(pusb_desc_header,
- pusb_config_desc,
- buf_size >= pusb_config_desc->wTotalLength
- ? pusb_config_desc->wTotalLength : buf_size);
-
- irp->IoStatus.Information =
- buf_size >= pusb_config_desc->wTotalLength
- ? pusb_config_desc->wTotalLength : buf_size;
- }
- ERROR_OUT:
- unlock_dev(pdev, FALSE);
- usb_unlock_dev(pdev);
- EXIT_DISPATCH(status, irp);
- }
- case IOCTL_SUBMIT_URB_RD:
- case IOCTL_SUBMIT_URB_WR:
- case IOCTL_SUBMIT_URB_NOIO:
- {
- PURB purb;
- ULONG endp_idx, if_idx, user_buffer_length = 0;
- PUCHAR user_buffer = NULL;
- PUSB_DEV pdev;
- DEV_HANDLE endp_handle;
- PUSB_ENDPOINT pendp;
-
- if (irp_stack->Parameters.DeviceIoControl.InputBufferLength < sizeof(URB))
- {
- EXIT_DISPATCH(STATUS_INVALID_PARAMETER, irp);
- }
-
- purb = (PURB) irp->AssociatedIrp.SystemBuffer;
- endp_handle = purb->endp_handle;
-
- if (ctrl_code == IOCTL_SUBMIT_URB_RD || ctrl_code == IOCTL_SUBMIT_URB_WR)
- {
- if (irp_stack->MajorFunction == IRP_MJ_DEVICE_CONTROL)
- {
- user_buffer_length = irp_stack->Parameters.DeviceIoControl.OutputBufferLength;
- if (user_buffer_length == 0)
- EXIT_DISPATCH(STATUS_INVALID_PARAMETER, irp);
- user_buffer = MmGetSystemAddressForMdl(irp->MdlAddress);
- }
- else
- {
- if (purb->data_buffer == NULL || purb->data_length == 0)
- EXIT_DISPATCH(STATUS_INVALID_PARAMETER, irp);
- user_buffer_length = purb->data_length;
- user_buffer = purb->data_buffer;
- }
- }
-
- if (usb_query_and_lock_dev(dev_mgr, endp_handle & ~0xffff, &pdev) != STATUS_SUCCESS)
- {
- EXIT_DISPATCH(STATUS_IO_DEVICE_ERROR, irp);
- }
-
-
- lock_dev(pdev, FALSE);
- if (dev_state(pdev) == USB_DEV_STATE_ZOMB || (dev_state(pdev) < USB_DEV_STATE_ADDRESSED))
-
- {
- status = STATUS_INVALID_DEVICE_STATE;
- goto ERROR_OUT1;
- }
-
- if (dev_state(pdev) == USB_DEV_STATE_ADDRESSED && !default_endp_handle(endp_handle))
- {
- status = STATUS_DEVICE_NOT_READY;
- goto ERROR_OUT1;
- }
-
- if_idx = if_idx_from_handle(endp_handle);
- endp_idx = endp_idx_from_handle(endp_handle);
-
- //if_idx exceeds the upper limit
- if (pdev->usb_config)
- {
- if (if_idx >= pdev->usb_config->if_count
- || endp_idx >= pdev->usb_config->interf[if_idx].endp_count)
- {
- if (!default_endp_handle(endp_handle))
- {
- status = STATUS_INVALID_DEVICE_STATE;
- goto ERROR_OUT1;
- }
- }
- }
-
- endp_from_handle(pdev, endp_handle, pendp);
- // FIXME: don't know what evil will let loose
- if (endp_type(pendp) != USB_ENDPOINT_XFER_CONTROL)
- {
- if (user_buffer_length > 0x100000)
- {
- status = STATUS_INVALID_PARAMETER;
- goto ERROR_OUT1;
- }
- }
-
- purb->pirp = irp;
- purb->context = dev_mgr;
- purb->reference = ctrl_code;
-
- if (ctrl_code == IOCTL_SUBMIT_URB_RD || ctrl_code == IOCTL_SUBMIT_URB_WR)
- {
- if (ctrl_code == IOCTL_SUBMIT_URB_RD)
- KeFlushIoBuffers(irp->MdlAddress, TRUE, TRUE);
- else
- KeFlushIoBuffers(irp->MdlAddress, FALSE, TRUE);
-
- purb->data_buffer = user_buffer;
- purb->data_length = user_buffer_length;
- purb->completion = disp_urb_completion;
- }
- else
- {
- purb->completion = disp_noio_urb_completion;
- }
-
- unlock_dev(pdev, FALSE);
-
- // we have to mark irp before the urb is scheduled to
- // avoid race condition
- IoMarkIrpPending(irp);
- ASSERT(dev_mgr_register_irp(dev_mgr, irp, purb));
- status = usb_submit_urb(dev_mgr, purb);
- if (status != STATUS_PENDING)
- {
- IoGetCurrentIrpStackLocation((irp))->Control &= ~SL_PENDING_RETURNED;
- dev_mgr_remove_irp(dev_mgr, irp);
- }
- usb_unlock_dev(pdev);
- if (status != STATUS_PENDING)
- {
- irp->IoStatus.Status = status;
- IoCompleteRequest(irp, IO_NO_INCREMENT);
- }
- return status;
- ERROR_OUT1:
- unlock_dev(pdev, FALSE);
- usb_unlock_dev(pdev);
- irp->IoStatus.Information = 0;
- EXIT_DISPATCH(status, irp);
- }
- default:
- {
- irp->IoStatus.Information = 0;
- EXIT_DISPATCH(STATUS_NOT_IMPLEMENTED, irp);
- }
- }
- }
- default:
- {
- irp->IoStatus.Information = 0;
- break;
- }
- }
- EXIT_DISPATCH(STATUS_INVALID_DEVICE_REQUEST, irp);
-}
-
-/*#define IOCTL_GET_DEV_COUNT CTL_CODE( FILE_HCD_DEV_TYPE, 4093, METHOD_BUFFERED, FILE_ANY_ACCESS )
-//input_buffer and input_buffer_length is zero, output_buffer is to receive a dword value of the
-//dev count, output_buffer_length must be no less than sizeof( long ).
-
-#define IOCTL_ENUM_DEVICES CTL_CODE( FILE_HCD_DEV_TYPE, 4094, METHOD_BUFFERED, FILE_ANY_ACCESS )
-//input_buffer is a dword value to indicate the count of elements in the array
-//input_buffer_length is sizeof( long ), output_buffer is to receive a
-//structure ENUM_DEV_ARRAY where dev_count is the elements hold in this array.
-
-#define IOCTL_GET_DEV_DESC CTL_CODE( FILE_HCD_DEV_TYPE, 4095, METHOD_BUFFERED, FILE_ANY_ACCESS )
-//input_buffer is a structure GET_DEV_DESC_REQ, and the input_buffer_length is
-//no less than sizeof( input_buffer ), output_buffer is a buffer to receive the
-//requested dev's desc, and output_buffer_length specifies the length of the
-//buffer
-
-#define IOCTL_SUBMIT_URB_RD CTL_CODE( FILE_HCD_DEV_TYPE, 4096, METHOD_IN_DIRECT, FILE_ANY_ACCESS )
-#define IOCTL_SUBMIT_URB_WR CTL_CODE( FILE_HCD_DEV_TYPE, 4097, METHOD_OUT_DIRECT, FILE_ANY_ACCESS )
-// input_buffer is a URB, and input_buffer_length is equal to or greater than
-// sizeof( URB ); the output_buffer is a buffer to receive data from or send data
-// to device. only the following urb fields can be accessed, others must be zeroed.
-// DEV_HANDLE endp_handle;
-// UCHAR setup_packet[8]; //for control pipe
-// the choosing of IOCTL_SUBMIT_URB_RD or IOCTL_SUBMIT_URB_WR should be determined
-// by the current URB, for example, a request string from device will use XXX_RD,
-// and a write to the bulk endpoint will use XXX_WR
-
-#define IOCTL_SUBMIT_URB_NOIO CTL_CODE( FILE_HCD_DEV_TYPE, 4098, METHOD_BUFFERED, FILE_ANY_ACCESS )
-// input_buffer is a URB, and input_buffer_length is equal to or greater than
-// sizeof( URB ); the output_buffer is null and no output_buffer_length,
-// only the following fields in urb can be accessed, others must be zeroed.
-// DEV_HANDLE endp_handle;
-// UCHAR setup_packet[8]; //for control pipe
-*/
diff --git a/reactos/drivers/usb/nt4compat/usbdrv/ehci.c b/reactos/drivers/usb/nt4compat/usbdrv/ehci.c
deleted file mode 100644
index 0c03e323c07..00000000000
--- a/reactos/drivers/usb/nt4compat/usbdrv/ehci.c
+++ /dev/null
@@ -1,6328 +0,0 @@
-/**
- * ehci.c - USB driver stack project for Windows NT 4.0
- *
- * Copyright (c) 2002-2004 Zhiming mypublic99@yahoo.com
- *
- * This program/include file is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program/include file is distributed in the hope that it will be
- * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
- * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program (in the main directory of the distribution, the file
- * COPYING); if not, write to the Free Software Foundation,Inc., 59 Temple
- * Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "usbdriver.h"
-#include "ehci.h"
-
-//----------------------------------------------------------
-// ehci routines
-//#define DEMO
-
-#define DEFAULT_ENDP( enDP ) \
-( enDP->flags & USB_ENDP_FLAG_DEFAULT_ENDP )
-
-#define dev_from_endp( enDP ) \
-( DEFAULT_ENDP( enDP )\
- ? ( ( PUSB_DEV )( enDP )->pusb_if )\
- : ( ( enDP )->pusb_if->pusb_config->pusb_dev ) )
-
-#define endp_state( enDP ) ( ( enDP )->flags & USB_ENDP_FLAG_STAT_MASK )
-
-#define endp_num( enDP ) \
-( DEFAULT_ENDP( enDP )\
- ? 0 \
- : ( ( enDP )->pusb_endp_desc->bEndpointAddress & 0x0f ) )
-
-#define endp_dir( enDP ) \
-( DEFAULT_ENDP( enDP )\
- ? 0L\
- : ( ( enDP )->pusb_endp_desc->bEndpointAddress & USB_DIR_IN ) ? 1 : 0 )
-
-#define dev_set_state( pdEV, staTE ) \
-( pdEV->flags = ( ( pdEV )->flags & ( ~USB_DEV_STATE_MASK ) ) | ( staTE ) )
-
-#define endp_max_packet_size( enDP ) \
-( DEFAULT_ENDP( enDP )\
- ? ( ( ( PUSB_DEV )enDP->pusb_if )->pusb_dev_desc ? \
- ( ( PUSB_DEV )enDP->pusb_if )->pusb_dev_desc->bMaxPacketSize0\
- : 8 )\
- : ( enDP->pusb_endp_desc->wMaxPacketSize & 0x7ff ) )
-
-#define endp_mult_count( endp ) ( ( ( endp->pusb_endp_desc->wMaxPacketSize & 0x1800 ) >> 11 ) + 1 )
-
-#define release_adapter( padapTER ) HalPutDmaAdapter(padapTER)
-
-#define get_int_idx( _urb, _idx ) \
-{\
- UCHAR interVAL;\
- interVAL = ( UCHAR )( ( _urb )->pipe >> 24 );\
- for( _idx = 1; _idx < 9; _idx++ )\
- {\
- interVAL >>= 1;\
- if( !interVAL )\
- break;\
- }\
- _idx --;\
-}
-
-#define ehci_insert_urb_to_schedule( eHCI, pURB, rET ) \
-{\
- SYNC_PARAM sync_param;\
- sync_param.ehci = eHCI;\
- sync_param.context = ( pURB );\
- sync_param.ret = FALSE;\
-\
- rET = KeSynchronizeExecution( eHCI->pdev_ext->ehci_int, ehci_sync_insert_urb_schedule, &sync_param );\
-}
-
-#define EHCI_ERROR_INT ( STS_FATAL | STS_ERR )
-#define EHCI_QH_ERROR( qh_contENT ) ( ( qh_contENT )->cur_qtd.status & ( QTD_STS_HALT | QTD_STS_DBE | QTD_STS_BABBLE | QTD_STS_XACT | QTD_STS_MMF ) )
-#define EHCI_QTD_ERROR( qtd_contENT ) ( ( qtd_contENT )->status & ( QTD_STS_HALT | QTD_STS_DBE | QTD_STS_BABBLE | QTD_STS_XACT | QTD_STS_MMF ) )
-
-#define EHCI_READ_PORT_ULONG( pul ) ( *pul )
-#define EHCI_WRITE_PORT_ULONG( pul, src ) \
-{\
- ULONG cmd_reg;\
- *pul = ( ULONG )src;\
- cmd_reg = EHCI_READ_PORT_ULONG( ehci->port_base + EHCI_USBCMD );\
- if( cmd_reg == 0 )\
- cmd_reg++;\
-}
-
-#define EHCI_READ_PORT_UCHAR( pch ) ( *pch )
-#define EHCI_WRITE_PORT_UCHAR( pch, src ) ( *pch = ( UCHAR )src )
-
-#define EHCI_READ_PORT_USHORT( psh ) ( *psh )
-#define EHCI_WRITE_PORT_USHORT( psh, src ) ( *psh = ( USHORT )src )
-
-#define press_doorbell( eHCI ) \
-{\
- ULONG tmp;\
- tmp = EHCI_READ_PORT_ULONG( ( PULONG )( ( eHCI )->port_base + EHCI_USBCMD ) );\
- tmp |= CMD_IAAD;\
- EHCI_WRITE_PORT_ULONG( ( PULONG )( ( eHCI )->port_base + EHCI_USBCMD ), tmp );\
-}
-#define ehci_from_hcd( hCD ) ( struct_ptr( ( hCD ), EHCI_DEV, hcd_interf ) )
-
-#define qh_from_list_entry( pentry ) ( ( PEHCI_QH )( ( ( ULONG )struct_ptr( pentry, EHCI_ELEM_LINKS, elem_link )->phys_part ) & PHYS_PART_ADDR_MASK ) )
-#define qtd_from_list_entry( pentry ) ( ( PEHCI_QTD )( ( ( ULONG )struct_ptr( pentry, EHCI_ELEM_LINKS, elem_link )->phys_part ) & PHYS_PART_ADDR_MASK ) )
-#define itd_from_list_entry( pentry ) ( ( PEHCI_ITD )( ( ( ULONG )struct_ptr( pentry, EHCI_ELEM_LINKS, elem_link )->phys_part ) & PHYS_PART_ADDR_MASK ) )
-#define sitd_from_list_entry( pentry ) ( ( PEHCI_SITD )( ( ( ULONG )struct_ptr( pentry, EHCI_ELEM_LINKS, elem_link )->phys_part ) & PHYS_PART_ADDR_MASK ) )
-#define fstn_from_list_entry( pentry ) ( ( PEHCI_FSTN )( ( ( ULONG )struct_ptr( pentry, EHCI_ELEM_LINKS, elem_link )->phys_part ) & PHYS_PART_ADDR_MASK ) )
-
-#define qh_from_schedule( pentry ) ( ( PEHCI_QH )( ( ( ULONG )struct_ptr( pentry, EHCI_ELEM_LINKS, sched_link )->phys_part ) & PHYS_PART_ADDR_MASK ) )
-#define itd_from_schedule( pentry ) ( ( PEHCI_ITD )( ( ( ULONG )struct_ptr( pentry, EHCI_ELEM_LINKS, sched_link )->phys_part ) & PHYS_PART_ADDR_MASK ) )
-#define sitd_from_schedule( pentry ) ( ( PEHCI_SITD )( ( ( ULONG )struct_ptr( pentry, EHCI_ELEM_LINKS, sched_link )->phys_part ) & PHYS_PART_ADDR_MASK ) )
-#define fstn_from_schedule( pentry ) ( ( PEHCI_FSTN )( ( ( ULONG )struct_ptr( pentry, EHCI_ELEM_LINKS, sched_link )->phys_part ) & PHYS_PART_ADDR_MASK ) )
-
-#define elem_type( ptr, from_list ) ( from_list ? ( ( ( ( ULONG )struct_ptr( ptr, EHCI_ELEM_LINKS, elem_link)->phys_part ) & PHYS_PART_TYPE_MASK ) >> 1 ) \
- : ( ( ( ( ULONG )struct_ptr( ptr, EHCI_ELEM_LINKS, sched_link)->phys_part ) & PHYS_PART_TYPE_MASK ) >> 1 ) )
-
-// #define elem_type_list_entry( pentry ) ( ( qh_from_schedule( pentry )->hw_next & 0x06 ) >> 1 )
-#define elem_type_list_entry( pentry ) ( elem_type( pentry, TRUE ) )
-
-#define get_parent_hs_hub( pDEV, parent_HUB, port_IDX ) \
-{\
- parent_HUB = pDEV->parent_dev;\
- port_IDX = pdev->port_idx;\
- while( parent_HUB )\
- {\
- if( ( parent_HUB->flags & USB_DEV_CLASS_MASK ) != USB_DEV_CLASS_HUB )\
- {\
- parent_HUB = NULL;\
- break;\
- }\
- if( ( parent_HUB->flags & USB_DEV_FLAG_HIGH_SPEED ) == 0 )\
- {\
- port_IDX = parent_HUB->port_idx;\
- parent_HUB = parent_HUB->parent_dev;\
- continue;\
- }\
- break;\
- }\
-}
-
-#define init_elem_phys_part( pelnk ) RtlZeroMemory( ( PVOID )( ( ( ULONG )( pelnk )->phys_part ) & PHYS_PART_ADDR_MASK ), get_elem_phys_part_size( ( ( ( ULONG )( pelnk )->phys_part ) & 0x06 ) >> 1 ) )
-#define REAL_INTERVAL ( 1 << pipe_content->interval )
-
-#define elem_safe_free( ptHIS, single ) \
-{\
- UCHAR em_type; \
- em_type = ( UCHAR )elem_type( ptHIS, TRUE ); \
- if( ptHIS )\
- {\
- if( em_type == INIT_LIST_FLAG_QTD )\
- {\
- elem_pool_lock( qtd_pool, TRUE );\
- if( single )\
- elem_pool_free_elem( qtd_from_list_entry( ptHIS )->elem_head_link );\
- else \
- elem_pool_free_elems( qtd_from_list_entry( ptHIS )->elem_head_link );\
- elem_pool_unlock( qtd_pool, TRUE );\
- }\
- else if( em_type == INIT_LIST_FLAG_ITD )\
- {\
- elem_pool_lock( itd_pool, TRUE );\
- if( single )\
- elem_pool_free_elem( itd_from_list_entry( ptHIS )->elem_head_link );\
- else \
- elem_pool_free_elems( itd_from_list_entry( ptHIS )->elem_head_link );\
- elem_pool_unlock( itd_pool, TRUE );\
- }\
- else if( em_type == INIT_LIST_FLAG_SITD )\
- {\
- elem_pool_lock( sitd_pool, TRUE );\
- if( single )\
- elem_pool_free_elem( sitd_from_list_entry( ptHIS )->elem_head_link );\
- else \
- elem_pool_free_elems( sitd_from_list_entry( ptHIS )->elem_head_link );\
- elem_pool_unlock( sitd_pool, TRUE );\
- }\
- else if( em_type == INIT_LIST_FLAG_FSTN )\
- {\
- elem_pool_lock( fstn_pool, TRUE );\
- if( single )\
- elem_pool_free_elem( fstn_from_list_entry( ptHIS )->elem_head_link );\
- else \
- elem_pool_free_elems( fstn_from_list_entry( ptHIS )->elem_head_link );\
- elem_pool_unlock( fstn_pool, TRUE );\
- }\
- else if( em_type == INIT_LIST_FLAG_QH )\
- {\
- elem_pool_lock( qh_pool, TRUE );\
- if( single )\
- elem_pool_free_elem( qh_from_list_entry( ptHIS )->elem_head_link );\
- else \
- elem_pool_free_elems( qh_from_list_entry( ptHIS )->elem_head_link );\
- elem_pool_unlock( qh_pool, TRUE );\
- }\
- }\
-}
-
-#ifndef min
-#define min( a, b ) ( ( a ) > ( b ) ? ( b ) : ( a ) )
-#endif
-#ifndef max
-#define max( a, b ) ( ( a ) > ( b ) ? ( a ) : ( b ) )
-#endif
-
-#define CLR_RH2_PORTSTAT( port_idx, x ) \
-{\
- PULONG addr; \
- addr = ( PULONG )( ehci->port_base + port_idx ); \
- status = EHCI_READ_PORT_ULONG( addr ); \
- status = ( status & 0xfffffd5 ) & ~( x ); \
- EHCI_WRITE_PORT_ULONG( addr, ( ULONG )status ); \
-}
-
-#define SET_RH2_PORTSTAT( port_idx, x ) \
-{\
- PULONG addr; \
- addr = ( PULONG )( ehci->port_base + port_idx ); \
- status = EHCI_READ_PORT_ULONG( addr ); \
- if( x & PORT_PR ) \
- status = ( status & 0xffffffd1 ) | ( x ); \
- else \
- status = ( status & 0xffffffd5 ) | ( x ); \
- EHCI_WRITE_PORT_ULONG( addr, ( ULONG )status ); \
-}
-
-#define ehci_from_hcd( hCD ) ( struct_ptr( ( hCD ), EHCI_DEV, hcd_interf ) )
-#define ehci_from_dev( dEV ) ( ehci_from_hcd( dEV->hcd ) )
-
-#define ehci_copy_overlay( pQHC, pTDC ) \
-{\
- LONG td_size;\
- PEHCI_QH pqh1;\
- PEHCI_QTD ptd1;\
- pqh1 = ( PEHCI_QH )( pQHC );\
- ptd1 = ( PEHCI_QTD )( pTDC );\
- td_size = get_elem_phys_part_size( INIT_LIST_FLAG_QTD );\
- ( pQHC )->cur_qtd_ptr = ptd1->phys_addr;\
- RtlZeroMemory( &( pQHC )->cur_qtd, td_size );\
- ( pQHC )->cur_qtd.data_toggle = ( pTDC )->data_toggle;\
- pqh1->hw_qtd_next = ptd1->phys_addr;\
- pqh1->hw_alt_next = EHCI_PTR_TERM;\
-}
-
-//declarations
-typedef struct
-{
- union
- {
- PUHCI_DEV uhci;
- PEHCI_DEV ehci;
- };
- PVOID context;
- ULONG ret;
-
-} SYNC_PARAM, *PSYNC_PARAM;
-
-PDEVICE_OBJECT
-ehci_alloc(PDRIVER_OBJECT drvr_obj, PUNICODE_STRING reg_path, ULONG bus_addr, PUSB_DEV_MANAGER dev_mgr);
-
-BOOLEAN ehci_init_schedule(PEHCI_DEV ehci, PADAPTER_OBJECT padapter);
-
-BOOLEAN ehci_release(PDEVICE_OBJECT pdev, PUSB_DEV_MANAGER dev_mgr);
-
-static VOID ehci_stop(PEHCI_DEV ehci);
-
-BOOLEAN ehci_destroy_schedule(PEHCI_DEV ehci);
-
-BOOLEAN NTAPI ehci_sync_insert_urb_schedule(PVOID context);
-
-VOID ehci_init_hcd_interface(PEHCI_DEV ehci);
-
-NTSTATUS ehci_rh_submit_urb(PUSB_DEV rh, PURB purb);
-
-NTSTATUS ehci_dispatch_irp(IN PDEVICE_OBJECT DeviceObject, IN PIRP irp);
-
-VOID ehci_generic_urb_completion(PURB purb, PVOID context);
-
-static NTSTATUS ehci_internal_submit_bulk(PEHCI_DEV ehci, PURB purb);
-
-static NTSTATUS ehci_internal_submit_int(PEHCI_DEV ehci, PURB purb);
-
-static NTSTATUS ehci_internal_submit_ctrl(PEHCI_DEV ehci, PURB purb);
-
-static NTSTATUS ehci_internal_submit_iso(PEHCI_DEV ehci, PURB purb);
-
-static ULONG ehci_scan_iso_error(PEHCI_DEV ehci, PURB purb);
-
-BOOLEAN ehci_claim_bandwidth(PEHCI_DEV ehci, PURB purb, BOOLEAN claim_bw); //true to claim band-width, false to free band-width
-
-static VOID ehci_insert_bulk_schedule(PEHCI_DEV ehci, PURB purb);
-
-#define ehci_insert_control_schedule ehci_insert_bulk_schedule
-
-static VOID ehci_insert_int_schedule(PEHCI_DEV ehci, PURB purb);
-
-static VOID ehci_insert_iso_schedule(PEHCI_DEV ehci, PURB purb);
-
-#define ehci_remove_control_from_schedule ehci_remove_bulk_from_schedule
-
-PDEVICE_OBJECT ehci_probe(PDRIVER_OBJECT drvr_obj, PUNICODE_STRING reg_path, PUSB_DEV_MANAGER dev_mgr);
-
-PDEVICE_OBJECT ehci_create_device(PDRIVER_OBJECT drvr_obj, PUSB_DEV_MANAGER dev_mgr);
-
-BOOLEAN ehci_delete_device(PDEVICE_OBJECT pdev, PUSB_DEV_MANAGER dev_mgr);
-
-VOID ehci_get_capabilities(PEHCI_DEV ehci, PBYTE base);
-
-BOOLEAN NTAPI ehci_isr(PKINTERRUPT interrupt, PVOID context);
-
-BOOLEAN ehci_start(PHCD hcd);
-
-extern VOID rh_timer_svc_reset_port_completion(PUSB_DEV dev, PVOID context);
-
-extern VOID rh_timer_svc_int_completion(PUSB_DEV dev, PVOID context);
-
-extern USB_DEV_MANAGER g_dev_mgr;
-
-#ifndef INCLUDE_EHCI
-ULONG debug_level = DBGLVL_MAXIMUM;
-PDRIVER_OBJECT usb_driver_obj = NULL;
-
-//pending endpoint pool funcs
-VOID
-ehci_wait_ms(PEHCI_DEV ehci, LONG ms)
-{
- LARGE_INTEGER lms;
- if (ms <= 0)
- return;
-
- lms.QuadPart = -10 * ms;
- KeSetTimer(&ehci->reset_timer, lms, NULL);
-
- KeWaitForSingleObject(&ehci->reset_timer, Executive, KernelMode, FALSE, NULL);
-
- return;
-}
-
-BOOLEAN
-init_pending_endp_pool(PUHCI_PENDING_ENDP_POOL pool)
-{
- int i;
- if (pool == NULL)
- return FALSE;
-
- pool->pending_endp_array =
- usb_alloc_mem(NonPagedPool, sizeof(UHCI_PENDING_ENDP) * UHCI_MAX_PENDING_ENDPS);
- InitializeListHead(&pool->free_que);
- pool->free_count = 0;
- pool->total_count = UHCI_MAX_PENDING_ENDPS;
- KeInitializeSpinLock(&pool->pool_lock);
-
- for(i = 0; i < MAX_TIMER_SVCS; i++)
- {
- free_pending_endp(pool, &pool->pending_endp_array[i]);
- }
-
- return TRUE;
-
-}
-
-BOOLEAN
-free_pending_endp(PUHCI_PENDING_ENDP_POOL pool, PUHCI_PENDING_ENDP pending_endp)
-{
- if (pool == NULL || pending_endp == NULL)
- {
- return FALSE;
- }
-
- RtlZeroMemory(pending_endp, sizeof(UHCI_PENDING_ENDP));
- InsertTailList(&pool->free_que, (PLIST_ENTRY) & pending_endp->endp_link);
- pool->free_count++;
-
- return TRUE;
-}
-
-PUHCI_PENDING_ENDP
-alloc_pending_endp(PUHCI_PENDING_ENDP_POOL pool, LONG count)
-{
- PUHCI_PENDING_ENDP new;
- if (pool == NULL || count != 1)
- return NULL;
-
- if (pool->free_count <= 0)
- return NULL;
-
- new = (PUHCI_PENDING_ENDP) RemoveHeadList(&pool->free_que);
- pool->free_count--;
- return new;
-}
-
-BOOLEAN
-destroy_pending_endp_pool(PUHCI_PENDING_ENDP_POOL pool)
-{
- if (pool == NULL)
- return FALSE;
-
- InitializeListHead(&pool->free_que);
- pool->free_count = pool->total_count = 0;
- usb_free_mem(pool->pending_endp_array);
- pool->pending_endp_array = NULL;
-
- return TRUE;
-
-}
-#else
-#define ehci_wait_ms uhci_wait_ms
-extern VOID uhci_wait_ms(PEHCI_DEV ehci, LONG ms);
-
-extern BOOLEAN init_pending_endp_pool(PUHCI_PENDING_ENDP_POOL pool);
-
-extern BOOLEAN free_pending_endp(PUHCI_PENDING_ENDP_POOL pool, PUHCI_PENDING_ENDP pending_endp);
-
-extern PUHCI_PENDING_ENDP alloc_pending_endp(PUHCI_PENDING_ENDP_POOL pool, LONG count);
-
-extern BOOLEAN destroy_pending_endp_pool(PUHCI_PENDING_ENDP_POOL pool);
-
-#endif
-
-//end of pending endpoint pool funcs
-
-static VOID NTAPI
-ehci_cancel_pending_endp_urb(IN PVOID Parameter)
-{
- PLIST_ENTRY abort_list;
- PUSB_DEV pdev;
- PURB purb;
- USE_BASIC_NON_PENDING_IRQL;
-
- abort_list = (PLIST_ENTRY) Parameter;
-
- if (abort_list == NULL)
- return;
-
- while (IsListEmpty(abort_list) == FALSE)
- {
- //these devs are protected by purb's ref-count
- purb = (PURB) RemoveHeadList(abort_list);
- pdev = purb->pdev;
- // purb->status is set when they are added to abort_list
-
- ehci_generic_urb_completion(purb, purb->context);
-
- lock_dev(pdev, FALSE);
- pdev->ref_count--;
- unlock_dev(pdev, FALSE);
- }
- usb_free_mem(abort_list);
- return;
-}
-
-static BOOLEAN
-ehci_process_pending_endp(PEHCI_DEV ehci)
-{
- PUSB_DEV pdev;
- LIST_ENTRY temp_list, abort_list;
- PLIST_ENTRY pthis;
- PURB purb;
- PUSB_ENDPOINT pendp;
- NTSTATUS can_submit = STATUS_SUCCESS;
- PWORK_QUEUE_ITEM pwork_item;
- PLIST_ENTRY cancel_list;
- PUSB_DEV pparent = NULL;
- UCHAR port_idx = 0;
- BOOLEAN tt_needed;
- UCHAR hub_addr = 0;
- USE_BASIC_IRQL;
-
- if (ehci == NULL)
- return FALSE;
-
- InitializeListHead(&temp_list);
- InitializeListHead(&abort_list);
-
- purb = NULL;
- ehci_dbg_print(DBGLVL_MEDIUM, ("ehci_process_pending_endp(): entering..., ehci=0x%x\n", ehci));
-
- lock_pending_endp_list(&ehci->pending_endp_list_lock);
- while (IsListEmpty(&ehci->pending_endp_list) == FALSE)
- {
-
- ehci_dbg_print(DBGLVL_MAXIMUM, ("ehci_process_pending_endp(): pending_endp_list=0x%x\n",
- &ehci->pending_endp_list));
-
- tt_needed = FALSE;
- pthis = RemoveHeadList(&ehci->pending_endp_list);
- pendp = ((PUHCI_PENDING_ENDP) pthis)->pendp;
- pdev = dev_from_endp(pendp);
- lock_dev(pdev, TRUE);
-
- if (dev_state(pdev) == USB_DEV_STATE_ZOMB)
- {
- unlock_dev(pdev, TRUE);
- free_pending_endp(&ehci->pending_endp_pool, struct_ptr(pthis, UHCI_PENDING_ENDP, endp_link));
- //delegate to ehci_remove_device for remiving the purb queue on the endpoint
- continue;
- }
- if ((pdev->flags & USB_DEV_FLAG_HIGH_SPEED) == 0)
- {
- // prepare split transaction
- unlock_dev(pdev, TRUE);
-
- // pparent won't be removed when pending_endp_list_lock is acquired.
- get_parent_hs_hub(pdev, pparent, port_idx);
-
- if (pparent == NULL)
- {
- TRAP();
- ehci_dbg_print(DBGLVL_MEDIUM,
- ("ehci_process_pending_endp(): full/low speed device with no parent!!!\n"));
- free_pending_endp(&ehci->pending_endp_pool, struct_ptr(pthis, UHCI_PENDING_ENDP, endp_link));
- continue;
- }
-
- if (hub_lock_tt(pparent, port_idx, (UCHAR) endp_type(pendp)) == FALSE)
- {
- lock_dev(pdev, TRUE);
- if (dev_state(pdev) != USB_DEV_STATE_ZOMB)
- {
- // reinsert the pending-endp to the list
- InsertTailList(&temp_list, pthis);
- unlock_dev(pdev, TRUE);
- }
- else
- {
- // delegate to ehci_remove_device for purb removal
- unlock_dev(pdev, TRUE);
- free_pending_endp(&ehci->pending_endp_pool,
- struct_ptr(pthis, UHCI_PENDING_ENDP, endp_link));
- }
- continue;
- }
-
- // backup the hub address for future use
- hub_addr = pparent->dev_addr;
-
- lock_dev(pdev, TRUE);
- if (dev_state(pdev) == USB_DEV_STATE_ZOMB)
- {
- unlock_dev(pdev, TRUE);
- free_pending_endp(&ehci->pending_endp_pool, struct_ptr(pthis, UHCI_PENDING_ENDP, endp_link));
- hub_unlock_tt(pparent, port_idx, (UCHAR) endp_type(pendp));
- continue;
- }
- tt_needed = TRUE;
- // go on processing
- }
-
- if (endp_state(pendp) == USB_ENDP_FLAG_STALL)
- {
- while (IsListEmpty(&pendp->urb_list) == FALSE)
- {
- purb = (PURB) RemoveHeadList(&pendp->urb_list);
- purb->status = USB_STATUS_ENDPOINT_HALTED;
- InsertTailList(&abort_list, (LIST_ENTRY *) purb);
- }
- InitializeListHead(&pendp->urb_list);
- unlock_dev(pdev, TRUE);
- free_pending_endp(&ehci->pending_endp_pool, struct_ptr(pthis, UHCI_PENDING_ENDP, endp_link));
- if (tt_needed)
- hub_unlock_tt(pparent, port_idx, (UCHAR) endp_type(pendp));
- continue;
- }
-
- if (IsListEmpty(&pendp->urb_list) == FALSE)
- {
- purb = (PURB) RemoveHeadList(&pendp->urb_list);
- ASSERT(purb);
- }
- else
- {
- InitializeListHead(&pendp->urb_list);
- unlock_dev(pdev, TRUE);
- free_pending_endp(&ehci->pending_endp_pool, struct_ptr(pthis, UHCI_PENDING_ENDP, endp_link));
- if (tt_needed)
- hub_unlock_tt(pparent, port_idx, (UCHAR) endp_type(pendp));
- continue;
- }
-
- if (tt_needed)
- {
- ((PURB_HS_CONTEXT_CONTENT) & purb->hs_context)->hub_addr = hub_addr;
- ((PURB_HS_CONTEXT_CONTENT) & purb->hs_context)->port_idx = port_idx;
- }
-
- // if can_submit is STATUS_SUCCESS, the purb is inserted into the schedule
- switch (endp_type(pendp))
- {
- case USB_ENDPOINT_XFER_BULK:
- {
- can_submit = ehci_internal_submit_bulk(ehci, purb);
- break;
- }
- case USB_ENDPOINT_XFER_CONTROL:
- {
- can_submit = ehci_internal_submit_ctrl(ehci, purb);
- break;
- }
- case USB_ENDPOINT_XFER_INT:
- {
- can_submit = ehci_internal_submit_int(ehci, purb);
- break;
- }
- case USB_ENDPOINT_XFER_ISOC:
- {
- can_submit = ehci_internal_submit_iso(ehci, purb);
- break;
- }
- }
-
- if (can_submit == STATUS_NO_MORE_ENTRIES)
- {
- //no enough bandwidth or tds
- InsertHeadList(&pendp->urb_list, &purb->urb_link);
- InsertTailList(&temp_list, pthis);
- }
- else
- {
- // otherwise error or success
- free_pending_endp(&ehci->pending_endp_pool, struct_ptr(pthis, UHCI_PENDING_ENDP, endp_link));
-
- if (can_submit != STATUS_SUCCESS)
- {
- //abort these URBs
- InsertTailList(&abort_list, (LIST_ENTRY *) purb);
- purb->status = can_submit;
- }
- }
- unlock_dev(pdev, TRUE);
- if (can_submit != STATUS_SUCCESS && tt_needed)
- {
- hub_unlock_tt(pparent, port_idx, (UCHAR) endp_type(pendp));
- }
- }
-
- if (IsListEmpty(&temp_list) == FALSE)
- {
- //re-append them to the pending_endp_list
- ListFirst(&temp_list, pthis);
- RemoveEntryList(&temp_list);
- MergeList(&ehci->pending_endp_list, pthis);
- }
- unlock_pending_endp_list(&ehci->pending_endp_list_lock);
-
- if (IsListEmpty(&abort_list) == FALSE)
- {
- PLIST_ENTRY pthis;
- cancel_list = (PLIST_ENTRY) usb_alloc_mem(NonPagedPool, sizeof(WORK_QUEUE_ITEM) + sizeof(LIST_ENTRY));
- ASSERT(cancel_list);
-
- ListFirst(&abort_list, pthis);
- RemoveEntryList(&abort_list);
- InsertTailList(pthis, cancel_list);
-
- pwork_item = (PWORK_QUEUE_ITEM) & cancel_list[1];
-
- // we do not need to worry the ehci_cancel_pending_endp_urb running when the
- // driver is unloading since purb-reference count will prevent the dev_mgr to
- // quit till all the reference count to the dev drop to zero.
- ExInitializeWorkItem(pwork_item, ehci_cancel_pending_endp_urb, (PVOID) cancel_list);
- ExQueueWorkItem(pwork_item, DelayedWorkQueue);
- }
- return TRUE;
-}
-
-NTSTATUS
-ehci_submit_urb(PEHCI_DEV ehci, PUSB_DEV pdev, PUSB_ENDPOINT pendp, PURB purb)
-{
- int i;
- PUHCI_PENDING_ENDP pending_endp;
- NTSTATUS status;
- USE_BASIC_IRQL;
-
- if (ehci == NULL)
- return STATUS_INVALID_PARAMETER;
-
- if (pdev == NULL || pendp == NULL || purb == NULL)
- {
- // give a chance to those pending urb, especially for clearing hub tt
- ehci_process_pending_endp(ehci);
- return STATUS_INVALID_PARAMETER;
- }
-
- lock_pending_endp_list(&ehci->pending_endp_list_lock);
- lock_dev(pdev, TRUE);
-
- if (dev_state(pdev) == USB_DEV_STATE_ZOMB)
- {
- status = purb->status = STATUS_DEVICE_DOES_NOT_EXIST;
- goto LBL_OUT;
- }
-
- if (dev_class(pdev) == USB_DEV_CLASS_ROOT_HUB)
- {
- unlock_dev(pdev, TRUE);
- unlock_pending_endp_list(&ehci->pending_endp_list_lock);
- status = ehci_rh_submit_urb(pdev, purb);
- return status;
- }
-
- if (pendp)
- purb->pendp = pendp;
- else
- purb->pendp = &pdev->default_endp;
-
- if (dev_from_endp(purb->pendp) != pdev)
- {
- status = purb->status = STATUS_INVALID_PARAMETER;
- goto LBL_OUT;
- }
-
- if (endp_state(purb->pendp) == USB_ENDP_FLAG_STALL)
- {
- status = purb->status = USB_STATUS_ENDPOINT_HALTED;
- goto LBL_OUT;
- }
-
- if ((pdev->flags & USB_DEV_FLAG_HIGH_SPEED) == 0)
- {
- // wait one ms
- usb_wait_ms_dpc(1);
- }
-
- purb->pdev = pdev;
- purb->rest_bytes = purb->data_length;
-
- if (endp_type(purb->pendp) == USB_ENDPOINT_XFER_BULK)
- purb->bytes_to_transfer = (purb->data_length > EHCI_MAX_SIZE_TRANSFER ? EHCI_MAX_SIZE_TRANSFER : purb->data_length); //multiple transfer for large data block
- else
- purb->bytes_to_transfer = purb->data_length;
-
- ehci_dbg_print(DBGLVL_MEDIUM, ("ehci_submit_urb(): bytes_to_transfer=0x%x\n", purb->bytes_to_transfer));
-
- purb->bytes_transfered = 0;
- InitializeListHead(&purb->trasac_list);
- purb->last_finished_td = &purb->trasac_list;
- purb->flags &= ~(URB_FLAG_STATE_MASK | URB_FLAG_IN_SCHEDULE | URB_FLAG_FORCE_CANCEL);
- purb->flags |= URB_FLAG_STATE_PENDING;
-
-
- i = IsListEmpty(&pendp->urb_list);
- InsertTailList(&pendp->urb_list, &purb->urb_link);
-
- pdev->ref_count++; //for purb reference
-
- if (i == FALSE)
- {
- //there is purb pending, simply queue it and return
- status = purb->status = STATUS_PENDING;
- goto LBL_OUT;
- }
- else if (usb_endp_busy_count(purb->pendp) && endp_type(purb->pendp) != USB_ENDPOINT_XFER_ISOC)
- {
- //
- //No purb waiting but purb overlap not allowed,
- //so leave it in queue and return, will be scheduled
- //later
- //
- status = purb->status = STATUS_PENDING;
- goto LBL_OUT;
- }
-
- pending_endp = alloc_pending_endp(&ehci->pending_endp_pool, 1);
- if (pending_endp == NULL)
- {
- //panic
- status = purb->status = STATUS_UNSUCCESSFUL;
- goto LBL_OUT2;
- }
-
- pending_endp->pendp = purb->pendp;
- InsertTailList(&ehci->pending_endp_list, &pending_endp->endp_link);
-
- unlock_dev(pdev, TRUE);
- unlock_pending_endp_list(&ehci->pending_endp_list_lock);
-
- ehci_process_pending_endp(ehci);
- return STATUS_PENDING;
-
- LBL_OUT2:
- pdev->ref_count--;
- RemoveEntryList(&purb->urb_link);
-
- LBL_OUT:
- unlock_dev(pdev, TRUE);
- unlock_pending_endp_list(&ehci->pending_endp_list_lock);
- ehci_process_pending_endp(ehci);
- return status;
-}
-
-static NTSTATUS
-ehci_set_error_code(PURB purb, ULONG raw_status)
-{
- PURB_HS_PIPE_CONTENT pipe_content;
-
- pipe_content = (PURB_HS_PIPE_CONTENT) & purb->pipe;
-
- //test if the purb is canceled
- if (purb->flags & URB_FLAG_FORCE_CANCEL)
- {
- purb->status = STATUS_CANCELLED;
- }
- else if (raw_status == 0)
- purb->status = STATUS_SUCCESS;
-
- else if (pipe_content->trans_type == USB_ENDPOINT_XFER_INT ||
- pipe_content->trans_type == USB_ENDPOINT_XFER_BULK ||
- pipe_content->trans_type == USB_ENDPOINT_XFER_CONTROL)
- {
-
- if (raw_status & QTD_STS_BABBLE)
- purb->status = USB_STATUS_DATA_OVERRUN;
-
- else if (raw_status & QTD_STS_HALT)
- purb->status = USB_STATUS_ENDPOINT_HALTED;
-
- else if (raw_status & QTD_STS_DBE)
- purb->status = USB_STATUS_BUFFER_OVERRUN;
-
- else if (raw_status & QTD_STS_XACT)
- purb->status = USB_STATUS_CRC; // crc is included in xact err.
-
- else if (raw_status & QTD_STS_MMF)
- purb->status = USB_STATUS_BTSTUFF;
-
- else
- purb->status = STATUS_UNSUCCESSFUL;
- }
- else if (pipe_content->trans_type == USB_ENDPOINT_XFER_ISOC)
- {
- if (pipe_content->speed_high)
- {
- if (raw_status & ITD_STS_BUFERR)
- purb->status = USB_STATUS_BUFFER_OVERRUN;
-
- else if (raw_status & ITD_STS_BABBLE)
- purb->status = USB_STATUS_BABBLE_DETECTED;
-
- else if (raw_status & ITD_STS_XACTERR) // Xact Err
- purb->status = USB_STATUS_CRC;
-
- else
- purb->status = STATUS_UNSUCCESSFUL;
-
- }
- else
- {
- if (raw_status & SITD_STS_ERR) // ERR is received from hub's tt
- purb->status = USB_STATUS_ERROR;
-
- else if (raw_status & SITD_STS_DBE)
- purb->status = USB_STATUS_BUFFER_OVERRUN;
-
- else if (raw_status & SITD_STS_BABBLE)
- purb->status = USB_STATUS_BABBLE_DETECTED;
-
- else if (raw_status & SITD_STS_XACTERR) // Xact Error
- purb->status = USB_STATUS_CRC;
-
- else if (raw_status & SITD_STS_MISSFRM) // missing microframe
- purb->status = USB_STATUS_DATA_TOGGLE_MISMATCH;
-
- else
- purb->status = STATUS_UNSUCCESSFUL;
- }
- }
- if (purb->status != STATUS_SUCCESS)
- {
- hcd_dbg_print(DBGLVL_MEDIUM, ("ehci_set_error_code(): error status 0x%x\n", raw_status));
- }
- return purb->status;
-}
-
-static BOOLEAN NTAPI
-ehci_sync_remove_urb_finished(PVOID context)
-{
- PEHCI_DEV ehci;
- PLIST_ENTRY pthis, pnext, ptemp;
- PURB purb;
- PSYNC_PARAM pparam;
-
- pparam = (PSYNC_PARAM) context;
- ehci = pparam->ehci;
- ptemp = (PLIST_ENTRY) pparam->context;
-
- if (ehci == NULL)
- {
- return (UCHAR) (pparam->ret = FALSE);
- }
-
- ListFirst(&ehci->urb_list, pthis);
- while (pthis)
- {
- //remove urbs not in the schedule
- ListNext(&ehci->urb_list, pthis, pnext);
- purb = (PURB) pthis;
-
- if ((purb->flags & URB_FLAG_IN_SCHEDULE) == 0)
- {
- //finished or canceled( not applied for split bulk ).
- RemoveEntryList(pthis);
- InsertTailList(ptemp, pthis);
- }
- pthis = pnext;
- }
- pparam->ret = TRUE;
- return (UCHAR) TRUE;
-}
-
-VOID NTAPI
-ehci_dpc_callback(PKDPC dpc, PVOID context, PVOID sysarg1, PVOID sysarg2)
-{
- PEHCI_DEV ehci;
-
- LIST_HEAD temp_list;
- PLIST_ENTRY pthis, pnext;
- PURB purb;
- PEHCI_QH pqh;
- PEHCI_QTD ptd;
- PUHCI_PENDING_ENDP pending_endp;
- PUSB_DEV pdev;
- PUSB_ENDPOINT pendp;
-
- BOOLEAN finished;
- LONG i;
- ULONG ehci_status, urb_status;
-
- SYNC_PARAM sync_param;
- UCHAR ep_type;
- USE_BASIC_NON_PENDING_IRQL;
-
- ehci = (PEHCI_DEV) context;
- if (ehci == NULL)
- return;
-
- ehci_status = (ULONG) sysarg1;
-
- InitializeListHead(&temp_list);
-
- sync_param.ehci = ehci;
- sync_param.context = (PVOID) & temp_list;
-
- ehci_dbg_print(DBGLVL_MAXIMUM, ("ehci_dpc_callback(): entering..., ehci=0x%x\n", ehci));
- //remove finished purb from ehci's purb-list
- KeSynchronizeExecution(ehci->pdev_ext->ehci_int, ehci_sync_remove_urb_finished, &sync_param);
-
- //release resources( itds, sitds, fstns, tds, and qhs ) allocated for the purb
- while (IsListEmpty(&temp_list) == FALSE)
- {
- //not in any public queue, if do not access into dev, no race
- //condition will occur
- purb = (PURB) RemoveHeadList(&temp_list);
- urb_status = purb->status;
- ep_type = endp_type(purb->pendp);
-
- if (ep_type == USB_ENDPOINT_XFER_ISOC)
- {
- // collect error for iso transfer
- urb_status = ehci_scan_iso_error(ehci, purb);
- }
-
- //the only place we do not use this lock on non-pending-endp-list data
- KeAcquireSpinLockAtDpcLevel(&ehci->pending_endp_list_lock);
- while (IsListEmpty(&purb->trasac_list) == FALSE)
- {
- UCHAR em_type;
- pthis = RemoveHeadList(&purb->trasac_list);
- em_type = (UCHAR) elem_type(pthis, TRUE);
-
- if (em_type == INIT_LIST_FLAG_QH)
- {
- pqh = qh_from_list_entry(pthis);
- elem_safe_free(pthis, TRUE);
- }
- else
- {
- //must be an itd, sitd chain
- InsertHeadList(&purb->trasac_list, pthis);
- for(i = 0, purb->bytes_transfered = 0; i < purb->td_count; i++)
- {
- PEHCI_QTD_CONTENT ptdc = NULL;
- PEHCI_ITD_CONTENT pitdc;
- PEHCI_SITD_CONTENT psitdc;
-
- em_type = (UCHAR) elem_type(pthis, TRUE);
-
- // accumulate data transfered in tds
- if (em_type == INIT_LIST_FLAG_QTD)
- {
- ptd = qtd_from_list_entry(pthis);
- ptdc = (PEHCI_QTD_CONTENT) ptd;
- if ((ptdc->status & QTD_STS_ACTIVE) == 0 && ((ptdc->status & QTD_ANY_ERROR) == 0))
- purb->bytes_transfered += ptd->bytes_to_transfer;
- }
- else if (em_type == INIT_LIST_FLAG_ITD)
- {
- int j;
- pitdc = (PEHCI_ITD_CONTENT) itd_from_list_entry(pthis);
- for(j = 0; j < 8; j++)
- {
- if ((pitdc->status_slot[j].status & ITD_STS_ACTIVE) == 0
- && (pitdc->status_slot[j].status & ITD_ANY_ERROR) == 0)
- purb->bytes_transfered += ptdc->bytes_to_transfer;
- }
- }
- else if (em_type == INIT_LIST_FLAG_SITD)
- {
- psitdc = (PEHCI_SITD_CONTENT) sitd_from_list_entry(pthis);
- if ((psitdc->status & SITD_STS_ACTIVE) == 0 && (psitdc->status & SITD_ANY_ERROR) == 0)
- purb->bytes_transfered += ptdc->bytes_to_transfer;
- }
- ListNext(&purb->trasac_list, pthis, pnext);
- pthis = pnext;
- }
-
- // check to see if an fstn is there
- ListFirstPrev(&purb->trasac_list, pthis);
- if (elem_type(pthis, TRUE) == INIT_LIST_FLAG_FSTN)
- {
- RemoveEntryList(pthis);
- elem_safe_free(pthis, TRUE);
- }
-
- ListFirst(&purb->trasac_list, pthis);
- RemoveEntryList(&purb->trasac_list);
-
- // free the tds
- elem_safe_free(pthis, FALSE);
-
- //termination condition
- InitializeListHead(&purb->trasac_list);
- purb->last_finished_td = NULL;
- }
- }
-
- if (ep_type == USB_ENDPOINT_XFER_ISOC || ep_type == USB_ENDPOINT_XFER_INT)
- ehci_claim_bandwidth(ehci, purb, FALSE); //release band-width
-
- KeReleaseSpinLockFromDpcLevel(&ehci->pending_endp_list_lock);
-
- ehci_set_error_code(purb, urb_status);
-
- pdev = dev_from_endp(purb->pendp);
- pendp = purb->pendp;
-
- // perform clear tt buffer if error on full/low bulk/control pipe
- if (ep_type == USB_ENDPOINT_XFER_BULK || ep_type == USB_ENDPOINT_XFER_CONTROL)
- {
- PURB_HS_PIPE_CONTENT pipe_content;
- PUSB_DEV phub;
- UCHAR port_idx;
-
- get_parent_hs_hub(pdev, phub, port_idx);
- pipe_content = (PURB_HS_PIPE_CONTENT) & purb->pipe;
-
- if (pipe_content->speed_high == 0 && purb->status != STATUS_SUCCESS)
- {
- // lets schedule an event to clear the tt buffer
- hub_post_clear_tt_event(phub, port_idx, purb->pipe);
- }
- else if (pipe_content->speed_high == 0)
- {
- if (phub == NULL)
- TRAP();
- else
- {
- // release tt if no error
- hub_unlock_tt(phub, (UCHAR) port_idx, (UCHAR) pipe_content->trans_type);
- }
- }
- }
-
- finished = TRUE;
-
- //since the ref_count for the purb is not released, we can safely have one
- //pointer to dev
-
- if (purb->status == USB_STATUS_BABBLE_DETECTED)
- {
- usb_dbg_print(DBGLVL_MEDIUM,
- ("ehci_dpc_callback(): alert!!!, babble detected, severe error, reset the whole bus\n"));
- // ehci_start( ehci );
- }
-
- if (ehci_status & STS_HALT) //&& !ehci->is_suspended
- {
- ehci_start(&ehci->hcd_interf);
- }
-
- //this will let the new request in ehci_generic_urb_completion to this endp
- //be processed rather than queued in the pending_endp_list
- lock_dev(pdev, TRUE);
- usb_endp_busy_count_dec(pendp);
- unlock_dev(pdev, TRUE);
-
- if (usb_success(purb->status) == FALSE)
- {
- // set error code and complete the purb and purb is invalid from this point
- ehci_generic_urb_completion(purb, purb->context);
- }
- else
- {
- if (ep_type == USB_ENDPOINT_XFER_BULK)
- {
- purb->rest_bytes -= purb->bytes_transfered;
- if (purb->rest_bytes)
- {
- finished = FALSE;
- }
- else
- {
- ehci_generic_urb_completion(purb, purb->context);
- }
- }
- else
- {
- ehci_generic_urb_completion(purb, purb->context);
- // DbgBreakPoint();
- //purb is now invalid
- }
- }
-
- KeAcquireSpinLockAtDpcLevel(&ehci->pending_endp_list_lock);
- lock_dev(pdev, TRUE);
-
- if (finished)
- pdev->ref_count--;
-
- if (urb_status && ((ep_type == USB_ENDPOINT_XFER_BULK) || (ep_type == USB_ENDPOINT_XFER_INT)))
- {
- // error on int or bulk pipe, cleared in usb_reset_pipe_completion
- pendp->flags &= ~USB_ENDP_FLAG_STAT_MASK;
- pendp->flags |= USB_ENDP_FLAG_STALL;
- }
-
- if (dev_state(pdev) == USB_DEV_STATE_ZOMB)
- {
- unlock_dev(pdev, TRUE);
- KeReleaseSpinLockFromDpcLevel(&ehci->pending_endp_list_lock);
- if (finished == FALSE)
- {
-
- purb->status = STATUS_DEVICE_DOES_NOT_EXIST;
- ehci_generic_urb_completion(purb, purb->context);
-
- lock_dev(pdev, TRUE);
- pdev->ref_count--;
- unlock_dev(pdev, TRUE);
- }
- continue;
- }
-
- if (finished && IsListEmpty(&pendp->urb_list) == TRUE)
- {
- unlock_dev(pdev, TRUE);
- KeReleaseSpinLockFromDpcLevel(&ehci->pending_endp_list_lock);
- continue;
- }
- else if (finished == TRUE)
- {
- //has purb in the endp's purb-list
- if (usb_endp_busy_count(pendp) > 0)
- {
- //the urbs still have chance to be sheduled but not this time
- unlock_dev(pdev, TRUE);
- KeReleaseSpinLockFromDpcLevel(&ehci->pending_endp_list_lock);
- continue;
- }
- }
-
- if (finished == FALSE)
- {
- //a split bulk transfer, ( not the high speed split transfer )
- purb->bytes_transfered = 0;
- purb->bytes_to_transfer =
- EHCI_MAX_SIZE_TRANSFER > purb->rest_bytes ? purb->rest_bytes : EHCI_MAX_SIZE_TRANSFER;
-
- //the purb is not finished
- purb->flags &= ~URB_FLAG_STATE_MASK;
- purb->flags |= URB_FLAG_STATE_PENDING;
-
- InsertHeadList(&pendp->urb_list, &purb->urb_link);
- }
-
- pending_endp = alloc_pending_endp(&ehci->pending_endp_pool, 1);
- if (!pending_endp)
- {
- unlock_dev(pdev, TRUE);
- KeReleaseSpinLockFromDpcLevel(&ehci->pending_endp_list_lock);
- return;
- }
- pending_endp->pendp = pendp;
- InsertTailList(&ehci->pending_endp_list, &pending_endp->endp_link);
-
- unlock_dev(pdev, TRUE);
- KeReleaseSpinLockFromDpcLevel(&ehci->pending_endp_list_lock);
- }
-
- //ah...exhausted, let's find some in the pending_endp_list to rock
- ehci_process_pending_endp(ehci);
- return;
-}
-
-static BOOLEAN NTAPI
-ehci_sync_cancel_urbs_dev(PVOID context)
-{
- //cancel all the urbs on one dev
- PEHCI_DEV ehci;
- PUSB_DEV pdev, dest_dev;
- PSYNC_PARAM sync_param;
- PLIST_ENTRY pthis, pnext;
- LONG count;
-
- sync_param = (PSYNC_PARAM) context;
- dest_dev = (PUSB_DEV) sync_param->context;
- ehci = sync_param->ehci;
-
- if (ehci == NULL || dest_dev == NULL)
- {
- return (UCHAR) (sync_param->ret = FALSE);
- }
- count = 0;
- ListFirst(&ehci->urb_list, pthis);
- while (pthis)
- {
- pdev = dev_from_endp(((PURB) pthis)->pendp);
- if (pdev == dest_dev)
- {
- ((PURB) pthis)->flags |= URB_FLAG_FORCE_CANCEL;
- }
- ListNext(&ehci->urb_list, pthis, pnext);
- pthis = pnext;
- count++;
- }
-
- if (count)
- {
- // signal an int for further process
- press_doorbell(ehci);
- }
- return (UCHAR) (sync_param->ret = TRUE);
-}
-
-BOOLEAN
-ehci_remove_device(PEHCI_DEV ehci, PUSB_DEV dev)
-{
- PUHCI_PENDING_ENDP ppending_endp;
- PLIST_ENTRY pthis, pnext;
- PURB purb;
- LIST_HEAD temp_list;
- int i, j, k;
- SYNC_PARAM sync_param;
-
- USE_BASIC_IRQL;
-
- if (ehci == NULL || dev == NULL)
- return FALSE;
-
- InitializeListHead(&temp_list);
-
- //free pending endp that has purb queued from pending endp list
- lock_pending_endp_list(&ehci->pending_endp_list_lock);
-
- ListFirst(&ehci->pending_endp_list, pthis);
-
- while (pthis)
- {
- ppending_endp = (PUHCI_PENDING_ENDP) pthis;
- ListNext(&ehci->pending_endp_list, pthis, pnext);
- if (dev_from_endp(ppending_endp->pendp) == dev)
- {
- RemoveEntryList(pthis);
- free_pending_endp(&ehci->pending_endp_pool, struct_ptr(pthis, UHCI_PENDING_ENDP, endp_link));
- }
- pthis = pnext;
- }
- unlock_pending_endp_list(&ehci->pending_endp_list_lock);
-
- //cancel all the urbs in the purb-list
- sync_param.ehci = ehci;
- sync_param.context = (PVOID) dev;
-
- KeSynchronizeExecution(ehci->pdev_ext->ehci_int, ehci_sync_cancel_urbs_dev, &sync_param);
-
- //cancel all the purb in the endp's purb-list
- k = 0;
- lock_dev(dev, FALSE);
- if (dev->usb_config)
- {
- //only for configed dev
- for(i = 0; i < dev->usb_config->if_count; i++)
- {
- for(j = 0; j < dev->usb_config->interf[i].endp_count; j++)
- {
- ListFirst(&dev->usb_config->interf[i].endp[j].urb_list, pthis);
- while (pthis)
- {
- ListNext(&dev->usb_config->interf[i].endp[j].urb_list, pthis, pnext);
-
- RemoveEntryList(pthis);
- InsertHeadList(&temp_list, pthis);
- pthis = pnext;
- k++;
- }
-
- }
- }
- }
- ListFirst(&dev->default_endp.urb_list, pthis);
-
- while (pthis)
- {
- ListNext(&dev->default_endp.urb_list, pthis, pnext);
-
- RemoveEntryList(pthis);
- InsertHeadList(&temp_list, pthis);
- pthis = pnext;
- k++;
- }
- unlock_dev(dev, FALSE);
-
- if (IsListEmpty(&temp_list) == FALSE)
- {
- for(i = 0; i < k; i++)
- {
- //complete those urbs with error
- pthis = RemoveHeadList(&temp_list);
- purb = (PURB) pthis;
- purb->status = STATUS_DEVICE_DOES_NOT_EXIST;
- {
- ehci_generic_urb_completion(purb, purb->context);
- }
- }
- }
-
- lock_dev(dev, FALSE) dev->ref_count -= k;
- unlock_dev(dev, FALSE);
-
- return TRUE;
-}
-
-static BOOLEAN
-ehci_insert_urb_schedule(PEHCI_DEV ehci, PURB purb)
-// must have dev_lock( ehci_process_pending_endp ) and frame_list_lock acquired
-{
- PURB_HS_PIPE_CONTENT pipe_content;
-
- if (ehci == NULL || purb == NULL)
- return FALSE;
-
- pipe_content = (PURB_HS_PIPE_CONTENT) & purb->pipe;
- switch (pipe_content->trans_type)
- {
- case USB_ENDPOINT_XFER_CONTROL:
- ehci_insert_control_schedule(ehci, purb);
- break;
- case USB_ENDPOINT_XFER_BULK:
- ehci_insert_bulk_schedule(ehci, purb);
- break;
- case USB_ENDPOINT_XFER_INT:
- ehci_insert_int_schedule(ehci, purb);
- break;
- case USB_ENDPOINT_XFER_ISOC:
- ehci_insert_iso_schedule(ehci, purb);
- break;
- default:
- return FALSE;
- }
-
- purb->flags &= ~URB_FLAG_STATE_MASK;
- purb->flags |= URB_FLAG_STATE_IN_PROCESS | URB_FLAG_IN_SCHEDULE;
- InsertTailList(&ehci->urb_list, &purb->urb_link);
-
- return TRUE;
-}
-
-static BOOLEAN
-ehci_insert_tds_qh(PEHCI_DEV ehci, PEHCI_QH pqh, PEHCI_QTD td_chain)
-{
- if (pqh == NULL || td_chain == NULL)
- return FALSE;
-
- UNREFERENCED_PARAMETER(ehci);
-
- ehci_copy_overlay((PEHCI_QH_CONTENT) pqh, (PEHCI_QTD_CONTENT) td_chain);
- InsertTailList(&td_chain->elem_head_link->elem_link, &pqh->elem_head_link->elem_link);
- return TRUE;
-}
-
-static BOOLEAN
-ehci_insert_qh_urb(PURB purb, PEHCI_QH pqh)
-{
- PLIST_ENTRY pthis, pnext;
- if (pqh == NULL || purb == NULL)
- return FALSE;
-
- InsertTailList(&pqh->elem_head_link->elem_link, &purb->trasac_list);
- ListFirst(&purb->trasac_list, pthis) while (pthis)
- {
- // note: fstn may in this chain
- struct_ptr(pthis, EHCI_ELEM_LINKS, elem_link)->purb = purb;
- ListNext(&purb->trasac_list, pthis, pnext);
- pthis = pnext;
- }
- return TRUE;
-}
-
-#define calc_td_count( pURB, start_aDDR, td_coUNT ) \
-{\
- LONG i, j, k;\
- td_coUNT = 0;\
- k = ( ( pURB )->bytes_to_transfer + max_packet_size - 1 ) / max_packet_size;\
- if( k != 0 )\
- {\
- LONG packets_per_td, packets_per_page;\
- packets_per_td = EHCI_QTD_MAX_TRANS_SIZE / max_packet_size;\
- packets_per_page = PAGE_SIZE / max_packet_size;\
- i = ( ( LONG )&( pURB )->data_buffer[ ( start_aDDR ) ] ) & ( PAGE_SIZE - 1 );\
- if( i )\
- {\
- i = PAGE_SIZE - i;\
- j = i & ( max_packet_size - 1 );\
- k -= ( EHCI_QTD_MAX_TRANS_SIZE - PAGE_SIZE + i - j ) / max_packet_size;\
- if( k < 0 )\
- td_coUNT = 1;\
- else\
- {\
- if( j )\
- i = packets_per_td - packets_per_page;\
- else\
- i = packets_per_td;\
- td_coUNT = 1 + ( k + i - 1 ) / i; \
- }\
- }\
- else\
- {\
- td_coUNT = ( k + packets_per_td - 1 ) / packets_per_td;\
- }\
- }\
-}
-
-static BOOLEAN
-ehci_fill_td_buf_ptr(PURB purb, LONG start_addr, // start idx into purb->data_buffer
- PLIST_ENTRY td_list, LONG td_count, ULONG toggle)
-// fill the tds' bytes_to_transfer and hw_buf, return next toggle value: true 1, false 0
-{
- LONG i, j, k, data_load;
- LONG packets_per_td, packets_per_page, bytes_to_transfer, max_packet_size;
- PLIST_ENTRY pthis, pnext;
- PEHCI_QTD_CONTENT ptdc;
- PEHCI_QTD ptd;
- PVOID ptr;
-
- if (purb == NULL || td_list == NULL || td_count == 0)
- return toggle;
-
- max_packet_size = 1 << ((PURB_HS_PIPE_CONTENT) & purb->pipe)->max_packet_size;
- packets_per_td = EHCI_QTD_MAX_TRANS_SIZE / max_packet_size;
- packets_per_page = PAGE_SIZE / max_packet_size;
-
- pthis = td_list;
- bytes_to_transfer = purb->bytes_to_transfer;
-
- i = ((LONG) & (purb)->data_buffer[(start_addr)]) & (PAGE_SIZE - 1);
- if (i)
- {
- i = PAGE_SIZE - i;
- j = i & (max_packet_size - 1);
- }
- else
- {
- i = j = 0;
- }
-
- while (bytes_to_transfer)
- {
- ptd = qtd_from_list_entry(pthis);
- ptd->hw_buf[0] = MmGetPhysicalAddress(&purb->data_buffer[start_addr]).LowPart;
- ptdc = (PEHCI_QTD_CONTENT) ptd;
-
- if (i != 0)
- {
- data_load = (LONG) (EHCI_QTD_MAX_TRANS_SIZE - PAGE_SIZE + i - j) < bytes_to_transfer
- ? (LONG) (EHCI_QTD_MAX_TRANS_SIZE - PAGE_SIZE + i - j) : bytes_to_transfer;
-
- ptdc->bytes_to_transfer = (USHORT) data_load;
- ptd->bytes_to_transfer = (USHORT) data_load;
-
- // subtract the header part
- data_load -= (i < data_load ? i : data_load);
-
- for(k = 1; data_load > 0; k++)
- {
- ptr = &purb->data_buffer[start_addr + i + (k - 1) * PAGE_SIZE];
- ptr = (PVOID) (((ULONG) ptr) & ~(PAGE_SIZE - 1));
- ptd->hw_buf[k] = MmGetPhysicalAddress(ptr).LowPart;
- data_load -= PAGE_SIZE < data_load ? PAGE_SIZE : data_load;
- }
- }
- else
- {
- // aligned on page boundary
- data_load = EHCI_QTD_MAX_TRANS_SIZE < bytes_to_transfer
- ? EHCI_QTD_MAX_TRANS_SIZE : bytes_to_transfer;
-
- ptdc->bytes_to_transfer = (USHORT) data_load;
- ptd->bytes_to_transfer = (USHORT) data_load;
-
- data_load -= (PAGE_SIZE < data_load ? PAGE_SIZE : data_load);
-
- for(k = 1; data_load > 0; k++)
- {
- ptr = &purb->data_buffer[start_addr + k * PAGE_SIZE];
- ptr = (PVOID) (((ULONG) ptr) & ~(PAGE_SIZE - 1));
- ptd->hw_buf[k] = MmGetPhysicalAddress(ptr).LowPart;
- data_load -= PAGE_SIZE < data_load ? PAGE_SIZE : data_load;
- }
- }
- ptdc->data_toggle = toggle;
- if (((ptdc->bytes_to_transfer + max_packet_size - 1) / max_packet_size) & 1)
- {
- //only odd num of transactions has effect
- toggle ^= 1;
- }
- start_addr += ptdc->bytes_to_transfer;
- bytes_to_transfer -= ptdc->bytes_to_transfer;
- ListNext(td_list, pthis, pnext);
- pthis = pnext;
- i = j;
- }
- return toggle;
-}
-
-static NTSTATUS
-ehci_internal_submit_bulk(PEHCI_DEV ehci, PURB purb)
-//
-// assume that the purb has its rest_bytes and bytes_to_transfer set
-// and bytes_transfered is zeroed.
-// dev_lock must be acquired outside
-// purb comes from dev's endpoint purb-list. it is already removed from
-// the endpoint purb-list.
-//
-{
-
- LONG max_packet_size, td_count, offset, bytes_to_transfer;
- PBYTE start_addr;
- PEHCI_QTD ptd;
- PEHCI_QH pqh;
- LIST_ENTRY td_list, *pthis, *pnext;
- BOOLEAN old_toggle, toggle, ret;
- UCHAR pid;
- LONG i, j;
- PURB_HS_PIPE_CONTENT pipe_content;
- PEHCI_QTD_CONTENT ptdc;
- PEHCI_QH_CONTENT pqhc;
- PEHCI_ELEM_LINKS pelnk;
- PEHCI_ELEM_LINKS plnk;
-
- if (ehci == NULL || purb == NULL)
- return STATUS_INVALID_PARAMETER;
-
- max_packet_size = endp_max_packet_size(purb->pendp);
- if (purb->bytes_to_transfer == 0)
- {
- return STATUS_INVALID_PARAMETER;
- }
-
- start_addr = &purb->data_buffer[purb->data_length - purb->rest_bytes];
- calc_td_count(purb, purb->data_length - purb->rest_bytes, td_count);
-
- elem_pool_lock(qtd_pool, TRUE);
- pelnk = elem_pool_alloc_elems(qtd_pool, td_count);
- elem_pool_unlock(qtd_pool, TRUE);
-
- if (pelnk == NULL)
- {
- return STATUS_UNSUCCESSFUL;
- }
- ptd = (PEHCI_QTD) ((ULONG) pelnk->phys_part & PHYS_PART_ADDR_MASK);
-
- InitializeListHead(&td_list);
- InsertTailList(&ptd->elem_head_link->elem_link, &td_list);
-
- ListFirst(&td_list, pthis);
- ListNext(&td_list, pthis, pnext);
-
- offset = 0;
-
- old_toggle = toggle = (purb->pendp->flags & USB_ENDP_FLAG_DATATOGGLE) ? TRUE : FALSE;
- bytes_to_transfer = purb->bytes_to_transfer;
- ehci_dbg_print(DBGLVL_MAXIMUM, ("ehci_internal_submit_bulk():dev toggle=%d\n", toggle));
-
- for(i = 1; i < 16; i++)
- {
- if ((max_packet_size >> i) == 0)
- break;
- }
- i--;
- i &= 0xf;
-
- purb->pipe = 0;
- pipe_content = (PURB_HS_PIPE_CONTENT) & purb->pipe;
- pipe_content->max_packet_size = i;
- pipe_content->endp_addr = endp_num(purb->pendp);
- pipe_content->dev_addr = dev_from_endp(purb->pendp)->dev_addr;
- pipe_content->trans_dir = endp_dir(purb->pendp);
- pipe_content->trans_type = USB_ENDPOINT_XFER_BULK;
- pipe_content->data_toggle = toggle;
- pipe_content->speed_high = (dev_from_endp(purb->pendp)->flags & USB_DEV_FLAG_HIGH_SPEED) ? 1 : 0;
- pipe_content->speed_low = (dev_from_endp(purb->pendp)->flags & USB_DEV_FLAG_LOW_SPEED) ? 1 : 0;
-
- pid = (((ULONG) purb->pendp->pusb_endp_desc->bEndpointAddress & USB_DIR_IN) ? QTD_PID_IN : QTD_PID_OUT);
-
- i = ((ULONG) start_addr) & (PAGE_SIZE - 1); // header part within first page
- if (i)
- {
- i = PAGE_SIZE - i;
- if (i < purb->bytes_to_transfer)
- j = i & (max_packet_size - 1);
- else
- j = 0;
- }
- else
- j = 0;
-
- // fill the page pointer and toggle
-
- toggle = ehci_fill_td_buf_ptr(purb, purb->data_length - purb->rest_bytes, pthis, td_count, toggle);
- while (pthis)
- {
- ptd = qtd_from_list_entry(pthis);
- ptdc = (PEHCI_QTD_CONTENT) ptd;
-
- // ptdc->alt_terminal = 1;
- // ptdc->alt_qtd = 0;
- ptd->hw_alt_next = EHCI_PTR_TERM;
- ptdc->pid = pid;
-
- // ptd->elem_head_link->purb = purb; will be filled later
- ptdc->err_count = 3;
- ptdc->status = 0x80; // active, and do_start_split for split transfer
- ptdc->cur_page = 0;
- // ptdc->data_toggle = toggle;
-
- if (pnext)
- {
- ptd->hw_next = qtd_from_list_entry(pnext)->phys_addr;
- }
- else
- {
- //Last one, enable ioc and short packet detect if necessary
- ptd->hw_next = EHCI_PTR_TERM;
- ptdc->ioc = TRUE;
- if (bytes_to_transfer < max_packet_size && (pid == QTD_PID_IN))
- {
- //ptd->status |= TD_CTRL_SPD;
- }
- }
-
- pthis = pnext;
-
- if (pthis)
- ListNext(&td_list, pthis, pnext);
- }
-
- ListFirst(&td_list, pthis);
- RemoveEntryList(&td_list);
-
- elem_pool_lock(qh_pool, TRUE);
-
- plnk = elem_pool_alloc_elem(qh_pool);
- if (plnk == NULL)
- {
- // free the qtds
- elem_safe_free(pthis, TRUE);
- if (qh_pool) elem_pool_unlock(qh_pool, TRUE);
- return STATUS_UNSUCCESSFUL;
- }
-
- pqh = (PEHCI_QH) ((ULONG) plnk->phys_part & PHYS_PART_ADDR_MASK);
- elem_pool_unlock(qh_pool, TRUE);
-
- if (pqh == NULL)
- {
- // free the qtds
- elem_safe_free(pthis, TRUE);
- return STATUS_NO_MORE_ENTRIES;
-
- }
-
- purb->td_count = td_count;
- pqhc = (PEHCI_QH_CONTENT) pqh;
- pqh->hw_next = EHCI_PTR_TERM; // filled later
- pqhc->dev_addr = pipe_content->dev_addr;
- pqhc->inactive = 0;
- pqhc->endp_addr = pipe_content->endp_addr;
- pqhc->data_toggle = 0; //pipe_content->data_toggle;
- pqhc->is_async_head = 0;
- pqhc->max_packet_size = (1 << pipe_content->max_packet_size);
- pqhc->is_ctrl_endp = 0;
- pqhc->reload_counter = EHCI_NAK_RL_COUNT;
-
- if (pipe_content->speed_high)
- pqhc->endp_spd = USB_SPEED_HIGH;
- else if (pipe_content->speed_low)
- pqhc->endp_spd = USB_SPEED_LOW;
- else
- pqhc->endp_spd = USB_SPEED_FULL;
-
- pqh->hw_info2 = 0;
- pqhc->mult = 1;
- pqh->hw_current = 0;
- pqh->hw_qtd_next = 0; // filled later
- pqh->hw_alt_next = EHCI_PTR_TERM;
- pqh->hw_token = 0; //indicate to advance queue before execution
-
- if (!pipe_content->speed_high)
- {
- pqhc->hub_addr = ((PURB_HS_CONTEXT_CONTENT) & purb->hs_context)->hub_addr;
- pqhc->port_idx = ((PURB_HS_CONTEXT_CONTENT) & purb->hs_context)->port_idx;
- }
-
- ptd = qtd_from_list_entry(pthis);
- ehci_insert_tds_qh(ehci, pqh, ptd);
- ehci_insert_qh_urb(purb, pqh);
- purb->pendp->flags =
- (purb->pendp->flags & ~USB_ENDP_FLAG_DATATOGGLE) | (toggle ? USB_ENDP_FLAG_DATATOGGLE : 0);
- usb_endp_busy_count_inc(purb->pendp);
- ehci_insert_urb_to_schedule(ehci, purb, ret);
-
- if (ret == FALSE)
- {
- // undo all we have done
- ListFirst(&pqh->elem_head_link->elem_link, pthis);
-
- RemoveEntryList(&purb->trasac_list);
- RemoveEntryList(&pqh->elem_head_link->elem_link); //remove qh from td_chain
-
- elem_safe_free(pthis, FALSE);
- elem_safe_free(&pqh->elem_head_link->elem_link, TRUE);
-
- InitializeListHead(&purb->trasac_list);
- // usb_endp_busy_count_dec( purb->pendp ); // the decrement is done in the dpc callback
- purb->pendp->flags =
- (purb->pendp->flags & ~USB_ENDP_FLAG_DATATOGGLE) | (old_toggle ? USB_ENDP_FLAG_DATATOGGLE : 0);
- return STATUS_UNSUCCESSFUL;
- }
- return STATUS_SUCCESS;
-}
-
-static NTSTATUS
-ehci_internal_submit_ctrl(PEHCI_DEV ehci, PURB purb)
-{
-
- LIST_ENTRY td_list, *pthis, *pnext;
- LONG i, td_count;
- LONG toggle;
- LONG max_packet_size, bytes_to_transfer, bytes_rest, start_idx;
-
- PEHCI_QTD ptd;
- PEHCI_QH pqh;
- PEHCI_QH_CONTENT pqhc;
- UCHAR dev_addr;
- BOOLEAN ret;
- PURB_HS_PIPE_CONTENT pipe_content;
- PEHCI_QTD_CONTENT ptdc;
- PEHCI_ELEM_LINKS pelnk;
- PUSB_DEV pdev;
-
- if (ehci == NULL || purb == NULL)
- return STATUS_INVALID_PARAMETER;
-
- bytes_rest = purb->rest_bytes;
- bytes_to_transfer = purb->bytes_to_transfer;
- max_packet_size = endp_max_packet_size(purb->pendp);
- start_idx = purb->data_length - purb->rest_bytes;
-
- calc_td_count(purb, start_idx, td_count);
- td_count += 2; // add setup td and handshake td
-
- elem_pool_lock(qtd_pool, TRUE);
- pelnk = elem_pool_alloc_elems(qtd_pool, td_count);
- elem_pool_unlock(qtd_pool, TRUE);
-
- if (pelnk == NULL)
- {
- return STATUS_NO_MORE_ENTRIES;
- }
-
- InsertTailList(&pelnk->elem_link, &td_list);
- ListFirst(&td_list, pthis);
- ListNext(&td_list, pthis, pnext);
-
- ptd = qtd_from_list_entry(pthis);
-
- pdev = dev_from_endp(purb->pendp);
- dev_addr = pdev->dev_addr;
-
- if (dev_state(pdev) <= USB_DEV_STATE_RESET) //only valid for control transfer
- dev_addr = 0;
-
- usb_dbg_print(DBGLVL_MAXIMUM, ("ehci_internal_submit_ctrl(): dev_addr =0x%x\n", dev_addr));
-
- // fill the setup packet
- ptdc = (PEHCI_QTD_CONTENT) ptd;
- ptd->hw_next = qtd_from_list_entry(pnext)->phys_addr;
- ptd->hw_alt_next = EHCI_PTR_TERM;
- ptdc->status = 0x80; // active
- ptdc->pid = QTD_PID_SETUP;
- ptdc->err_count = 3;
- ptdc->cur_page = 0;
- ptdc->ioc = 0;
- ptdc->bytes_to_transfer = sizeof(USB_CTRL_SETUP_PACKET);
- ptdc->data_toggle = 0;
- ptd->hw_buf[0] = MmGetPhysicalAddress(purb->setup_packet).LowPart;
-
- for(i = 1; i < 16; i++)
- {
- if ((max_packet_size >> i) == 0)
- break;
- }
- i--;
- i &= 0xf;
-
- purb->pipe = 0;
- pipe_content = (PURB_HS_PIPE_CONTENT) & purb->pipe;
- pipe_content->max_packet_size = i;
- pipe_content->endp_addr = endp_num(purb->pendp);
- pipe_content->dev_addr = dev_addr;
- pipe_content->speed_low = (pdev->flags & USB_DEV_FLAG_LOW_SPEED) ? 1 : 0;
- pipe_content->speed_high = (pdev->flags & USB_DEV_FLAG_HIGH_SPEED) ? 1 : 0;
- pipe_content->trans_type = USB_ENDPOINT_XFER_CONTROL;
-
- pthis = pnext;
- ListNext(&td_list, pthis, pnext);
-
- // all the tds's toggle and data_buffer pointer is filled here
- toggle = 1;
- ehci_fill_td_buf_ptr(purb, start_idx, pthis, td_count - 2, toggle);
-
- for(i = 0; ((i < td_count - 2) && pthis); i++)
- {
- //construct tds for DATA packets of data stage.
- ptd = qtd_from_list_entry(pthis);
- ptdc = (PEHCI_QTD_CONTENT) ptd;
- ptd->hw_alt_next = EHCI_PTR_TERM;
- ptdc->status = 0x80; // active and startXSplit
- ptdc->pid = ((purb->setup_packet[0] & USB_DIR_IN) ? QTD_PID_IN : QTD_PID_OUT);
- ptdc->err_count = 3;
- ptdc->cur_page = 0;
- ptdc->ioc = 0;
-
- if (pnext)
- ptd->hw_next = qtd_from_list_entry(pnext)->phys_addr;
- else
- ptd->hw_next = EHCI_PTR_TERM;
-
- pthis = pnext;
- if (pthis)
- ListNext(&td_list, pthis, pnext);
- }
-
- if (pthis)
- ptd->hw_next = qtd_from_list_entry(pthis)->phys_addr;
- else
- TRAP();
-
- // ListFirstPrev( &td_list, pthis );
- ptd = qtd_from_list_entry(pthis);
-
- //the last is an IN transaction
- ptdc = (PEHCI_QTD_CONTENT) ptd;
- ptd->hw_alt_next = EHCI_PTR_TERM;
- ptdc->status = 0x80;
- ptdc->pid = ((td_count > 2)
- ? ((purb->setup_packet[0] & USB_DIR_IN) ? QTD_PID_OUT : QTD_PID_IN) : QTD_PID_IN);
-
- ptdc->err_count = 3;
- ptdc->cur_page = 0;
- ptdc->ioc = 1;
- ptdc->bytes_to_transfer = 0;
- ptdc->data_toggle = 1;
- ptd->hw_next = EHCI_PTR_TERM;
-
- ListFirst(&td_list, pthis);
- RemoveEntryList(&td_list);
-
- ptd = qtd_from_list_entry(pthis);
- elem_pool_lock(qh_pool, TRUE);
- pelnk = elem_pool_alloc_elem(qh_pool);
- elem_pool_unlock(qh_pool, TRUE);
-
- if (pelnk == NULL)
- {
- elem_safe_free(pthis, FALSE);
- return STATUS_NO_MORE_ENTRIES;
-
- }
- pqh = (PEHCI_QH) ((ULONG) pelnk->phys_part & PHYS_PART_ADDR_MASK);
- pqhc = (PEHCI_QH_CONTENT) pqh;
-
- pqh->hw_alt_next = pqh->hw_next = EHCI_PTR_TERM;
-
- pqhc->dev_addr = dev_addr;
- pqhc->inactive = 0;
- pqhc->endp_addr = endp_num(purb->pendp);
-
- if (pipe_content->speed_high)
- pqhc->endp_spd = USB_SPEED_HIGH;
- else if (pipe_content->speed_low)
- pqhc->endp_spd = USB_SPEED_LOW;
- else
- pqhc->endp_spd = USB_SPEED_FULL;
-
- pqhc->data_toggle = 1; // use dt from qtd
- pqhc->is_async_head = 0;
- pqhc->max_packet_size = endp_max_packet_size(purb->pendp);
-
- if (pipe_content->speed_high == 0)
- pqhc->is_ctrl_endp = 1;
- else
- pqhc->is_ctrl_endp = 0;
-
- pqhc->reload_counter = EHCI_NAK_RL_COUNT;
-
- // DWORD 2
- pqh->hw_info2 = 0;
- pqhc->mult = 1;
-
- if (!pipe_content->speed_high)
- {
- pqhc->hub_addr = ((PURB_HS_CONTEXT_CONTENT) & purb->hs_context)->hub_addr;
- pqhc->port_idx = ((PURB_HS_CONTEXT_CONTENT) & purb->hs_context)->port_idx;
- }
-
- purb->td_count = td_count;
-
- ehci_insert_tds_qh(ehci, pqh, ptd);
- ehci_insert_qh_urb(purb, pqh);
-
- usb_endp_busy_count_inc(purb->pendp);
- ehci_insert_urb_to_schedule(ehci, purb, ret);
-
- if (ret == FALSE)
- {
- RemoveEntryList(&purb->trasac_list);
- RemoveEntryList(&pqh->elem_head_link->elem_link);
-
- elem_safe_free(&pqh->elem_head_link->elem_link, TRUE);
- elem_safe_free(pthis, FALSE);
-
- InitializeListHead(&purb->trasac_list);
- // usb_endp_busy_count_dec( purb->pendp );
- return STATUS_UNSUCCESSFUL;
- }
- return STATUS_SUCCESS;
-}
-
-static NTSTATUS
-ehci_internal_submit_int(PEHCI_DEV ehci, PURB purb)
-{
- LONG i, max_packet_size;
- PEHCI_QTD ptd;
- BOOLEAN ret;
- PUSB_DEV pdev;
- PURB_HS_PIPE_CONTENT pipe_content;
- UCHAR mult_trans, toggle, old_toggle;
- PEHCI_ELEM_LINKS pelnk;
- PEHCI_QTD_CONTENT ptdc;
- PEHCI_QH pqh;
- PEHCI_QH_CONTENT pqhc;
- PEHCI_FSTN pfstn;
-
- if (ehci == NULL || purb == NULL)
- return STATUS_INVALID_PARAMETER;
-
- old_toggle = toggle = (purb->pendp->flags & USB_ENDP_FLAG_DATATOGGLE) ? TRUE : FALSE;
- max_packet_size = endp_max_packet_size(purb->pendp);
- pdev = dev_from_endp(purb->pendp);
-
- if (max_packet_size == 0 || max_packet_size > 64)
- return STATUS_INVALID_PARAMETER;
-
- if ((pdev->flags & USB_DEV_FLAG_HIGH_SPEED) == 0)
- {
- if (max_packet_size < purb->data_length)
- return STATUS_INVALID_PARAMETER;
-
- for(i = 1; i < 16; i++)
- {
- if ((((ULONG) purb->pendp->pusb_endp_desc->bInterval) >> i) == 0)
- break;
- }
- i--;
- mult_trans = 1;
- }
- else
- {
- mult_trans = endp_mult_count(purb->pendp);
- if (max_packet_size * endp_mult_count(purb->pendp) < purb->data_length)
- return STATUS_INVALID_PARAMETER;
- i = purb->pendp->pusb_endp_desc->bInterval - 1;
- }
-
- purb->pipe = 0;
- pipe_content = (PURB_HS_PIPE_CONTENT) & purb->pipe;
- pipe_content->interval = i;
- pipe_content->trans_type = USB_ENDPOINT_XFER_INT; // bit 0-1
- pipe_content->speed_high = (pdev->flags & USB_DEV_FLAG_HIGH_SPEED) ? 1 : 0; // bit 5
- pipe_content->speed_low = (pdev->flags & USB_DEV_FLAG_LOW_SPEED) ? 1 : 0; // bit 6
- pipe_content->trans_dir = endp_dir(purb->pendp); // bit 7
- pipe_content->dev_addr = pdev->dev_addr; // bit 8-14
- pipe_content->endp_addr = endp_num(purb->pendp); // bit 15-18
- pipe_content->data_toggle = 1; // bit 19
- pipe_content->mult_count = mult_trans;
-
- // pipe_content->start_uframe : 3; // bit 28-30 will be filled later
-
- for(i = 1; i <= 16; i++)
- {
- if (((ULONG) max_packet_size) >> i)
- continue;
- else
- break;
- }
- i--;
- i &= 0xf;
-
- pipe_content->max_packet_size = i; // bit 20-23 log2( max_packet_size )
-
- if (ehci_claim_bandwidth(ehci, purb, TRUE) == FALSE)
- {
- // can not allocate bandwidth for it
- return STATUS_UNSUCCESSFUL;
- }
-
- // one qtd is enough
- elem_pool_lock(qtd_pool, TRUE);
- pelnk = elem_pool_alloc_elem(qtd_pool);
- elem_pool_unlock(qtd_pool, TRUE);
-
- if (pelnk == NULL)
- {
- ehci_claim_bandwidth(ehci, purb, FALSE);
- return STATUS_NO_MORE_ENTRIES;
- }
-
- ptd = (PEHCI_QTD) ((ULONG) pelnk->phys_part & PHYS_PART_ADDR_MASK);
- ptdc = (PEHCI_QTD_CONTENT) ptd;
- ptd->hw_next = EHCI_PTR_TERM;
- // DWORD 1
- ptd->hw_alt_next = EHCI_PTR_TERM;
- // DWORD 2
- ptdc->status = 0x80;
- ptdc->pid = pipe_content->trans_dir ? QTD_PID_IN : QTD_PID_OUT;
- ptdc->err_count = 3;
- ptdc->cur_page = 0;
- ptdc->ioc = 1;
- ptdc->bytes_to_transfer = purb->data_length;
- toggle = (UCHAR) ehci_fill_td_buf_ptr(purb, 0, &pelnk->elem_link, 1, toggle);
-
- elem_pool_lock(qh_pool, TRUE);
- pelnk = elem_pool_alloc_elem(qh_pool);
- elem_pool_unlock(qh_pool, TRUE);
- if (pelnk == NULL)
- {
- elem_safe_free(&ptd->elem_head_link->elem_link, TRUE);
- InitializeListHead(&purb->trasac_list);
- ehci_claim_bandwidth(ehci, purb, FALSE);
- return STATUS_NO_MORE_ENTRIES;
- }
- pqh = (PEHCI_QH) ((ULONG) pelnk->phys_part & PHYS_PART_ADDR_MASK);
- pqhc = (PEHCI_QH_CONTENT) pqh;
-
- pqh->hw_next = EHCI_PTR_TERM;
- pqhc->dev_addr = pdev->dev_addr;
- pqhc->inactive = 0;
- pqhc->endp_addr = endp_num(purb->pendp);
-
- if (pipe_content->speed_high)
- pqhc->endp_spd = USB_SPEED_HIGH;
- else if (pipe_content->speed_low)
- pqhc->endp_spd = USB_SPEED_LOW;
- else
- pqhc->endp_spd = USB_SPEED_FULL;
-
- pqhc->data_toggle = 0;
- pqhc->is_async_head = 0;
- pqhc->max_packet_size = endp_max_packet_size(purb->pendp);
- pqhc->is_ctrl_endp = 0;
- pqhc->reload_counter = 0;
-
- // DWORD 2
- pqh->hw_info2 = 0;
- pqhc->mult = mult_trans;
-
- if (pipe_content->speed_high)
- {
- if (pipe_content->interval == 0) // one poll per uframe
- pqhc->s_mask = 0xff;
- else if (pipe_content->interval == 1) // one poll every 2 uframe
- pqhc->s_mask = pipe_content->start_uframe == 0 ? 0x55 : 0xbb;
- else if (pipe_content->interval == 2)
- {
- pqhc->s_mask = 0x11;
- pqhc->s_mask <<= pipe_content->start_uframe;
- }
- else
- {
- pqhc->s_mask = 1 << (pipe_content->start_uframe);
- }
- pqhc->c_mask = 0;
- }
- else // full/low speed
- {
- pqhc->s_mask = 1 << pipe_content->start_uframe;
- if (pipe_content->start_uframe < 4)
- {
- pqhc->c_mask = 0x07 << (pipe_content->start_uframe + 2);
- }
- else if (pipe_content->start_uframe == 4)
- {
- pqhc->c_mask = 0xc1;
- }
- else if (pipe_content->start_uframe >= 5)
- {
- // we need fstn
- pqhc->c_mask = 0x03;
- if (pipe_content->start_uframe == 5)
- {
- pqhc->c_mask |= 0x80;
- }
- }
- if (pipe_content->start_uframe >= 4)
- {
- // chain an fstn
- elem_pool_lock(fstn_pool, TRUE);
- pelnk = elem_pool_alloc_elem(fstn_pool);
- elem_pool_unlock(fstn_pool, TRUE);
- if (pelnk == NULL)
- {
- elem_safe_free(&pqh->elem_head_link->elem_link, TRUE);
- elem_safe_free(&ptd->elem_head_link->elem_link, TRUE);
- InitializeListHead(&purb->trasac_list);
- ehci_claim_bandwidth(ehci, purb, FALSE);
- return STATUS_NO_MORE_ENTRIES;
- }
- pfstn = (PEHCI_FSTN) ((ULONG) pelnk->phys_part & PHYS_PART_ADDR_MASK);
- pfstn->hw_prev = ptd->phys_addr;
- pfstn->elem_head_link->purb = purb;
- InsertTailList(&ptd->elem_head_link->elem_link, &pfstn->elem_head_link->elem_link);
- }
- pqhc->hub_addr = ((PURB_HS_CONTEXT_CONTENT) & purb->hs_context)->hub_addr;
- pqhc->port_idx = ((PURB_HS_CONTEXT_CONTENT) & purb->hs_context)->port_idx;
- }
-
- // DWORD 3
- purb->td_count = 1;
-
- InitializeListHead(&purb->trasac_list);
- ehci_insert_tds_qh(ehci, pqh, ptd);
- ehci_insert_qh_urb(purb, pqh);
-
- purb->pendp->flags = (purb->pendp->flags & ~USB_ENDP_FLAG_DATATOGGLE) | (toggle << 31);
- usb_endp_busy_count_inc(purb->pendp);
-
- ehci_insert_urb_to_schedule(ehci, purb, ret);
-
- if (ret == FALSE)
- {
- RemoveEntryList(&purb->trasac_list);
- RemoveEntryList(&pqh->elem_head_link->elem_link);
-
- elem_safe_free(&pqh->elem_head_link->elem_link, TRUE);
- // an fstn may follow the td
- elem_safe_free(&ptd->elem_head_link->elem_link, FALSE);
-
- InitializeListHead(&purb->trasac_list);
- ehci_claim_bandwidth(ehci, purb, FALSE);
-
- purb->pendp->flags = (purb->pendp->flags & ~USB_ENDP_FLAG_DATATOGGLE) | ((toggle ^ 1) << 31);
- // usb_endp_busy_count_dec( purb->pendp );
-
- return STATUS_UNSUCCESSFUL;
- }
-
- return STATUS_SUCCESS;
-}
-
-
-static NTSTATUS
-ehci_internal_submit_iso(PEHCI_DEV ehci, PURB purb)
-{
- LONG i, j, td_count, temp;
- PEHCI_ITD pitd;
- PEHCI_SITD psitd;
- PEHCI_SITD_CONTENT psitdc;
- PEHCI_ITD_CONTENT pitdc;
- LIST_ENTRY td_list, *pthis, *pnext, *pprev;
- BOOLEAN ret;
- PURB_HS_PIPE_CONTENT pipe_content;
- PUSB_DEV pdev;
- PEHCI_ELEM_LINKS pelnk;
-
- if (ehci == NULL || purb == NULL)
- return STATUS_INVALID_PARAMETER;
-
- if (purb->iso_frame_count == 0)
- return STATUS_INVALID_PARAMETER;
-
- pdev = dev_from_endp(purb->pendp);
- purb->pipe = 0;
- pipe_content = (PURB_HS_PIPE_CONTENT) & purb->pipe;
- pipe_content->trans_type = USB_ENDPOINT_XFER_ISOC; // bit 0-1
- pipe_content->speed_high = (pdev->flags & USB_DEV_FLAG_HIGH_SPEED) ? 1 : 0; // bit 5
- pipe_content->speed_low = 0; // bit 6
- pipe_content->trans_dir = endp_dir(purb->pendp); // bit 7
- pipe_content->dev_addr = pdev->dev_addr; // bit 8-14
- pipe_content->endp_addr = endp_num(purb->pendp); // bit 15-18
- pipe_content->data_toggle = 0; // bit 19
-
- ret = FALSE;
- purb->params[0] = j = endp_max_packet_size(purb->pendp);
-
- if (pipe_content->speed_high == 0)
- {
- // check to see if the frame data is too long to transfer
- if (purb->iso_frame_count >= (LONG) ehci->frame_count)
- return STATUS_INVALID_PARAMETER;
-
- for(i = 0; i < (LONG) purb->iso_frame_count; i++)
- {
- if (purb->iso_packet_desc[i].length > j)
- return STATUS_INVALID_PARAMETER;
- }
- }
- else
- {
- // excess the frame count limit
- if (purb->iso_frame_count >= (LONG) (ehci->frame_count << 3))
- return STATUS_INVALID_PARAMETER;
-
- for(i = 0; i < (LONG) purb->iso_frame_count; i++)
- {
- if (purb->iso_packet_desc[i].length > j * endp_mult_count(purb->pendp)) // 3 is max mult-transaction count
- return STATUS_INVALID_PARAMETER;
- }
-
- pipe_content->mult_count = endp_mult_count(purb->pendp);
- }
-
- pipe_content->max_packet_size = 0; // bit 20-23 log( max_packet_size ), not correct, should not be used
-
- if (pipe_content->speed_high == 0)
- {
- for(i = 1; i < 16; i++)
- {
- if ((((ULONG) purb->pendp->pusb_endp_desc->bInterval) >> i) == 0)
- break;
- }
- i--;
- }
- else
- {
- i = purb->pendp->pusb_endp_desc->bInterval - 1;
- }
-
- pipe_content->interval = i; // bit 24-27 the same definition as in USB2.0 spec, for high or full/low speed
-
- if (ehci_claim_bandwidth(ehci, purb, TRUE) == FALSE)
- return STATUS_UNSUCCESSFUL;
-
- if (pipe_content->speed_high == 0)
- {
- td_count = purb->iso_frame_count;
-
- // test to see if the last td needs one more sitd for pure complete-split
- if (pipe_content->trans_dir == 0)
- {
- j = (purb->iso_packet_desc[purb->iso_frame_count - 1].length + 187) / 188;
- if (purb->iso_packet_desc[purb->iso_frame_count - 1].params.start_uframe + 1 + j >= 8)
- {
- td_count++;
- ret = TRUE;
- }
- }
- elem_pool_lock(itd_pool, TRUE);
- pelnk = elem_pool_alloc_elems(itd_pool, td_count);
- elem_pool_unlock(itd_pool, TRUE);
-
- }
- else
- {
- i = REAL_INTERVAL;
- if (pipe_content->interval >= 3)
- {
- td_count = purb->iso_frame_count;
- j = 0;
- }
- else
- {
- j = purb->iso_start_frame & 0x07;
- if (j == 0)
- {
- td_count = (purb->iso_frame_count + 8 / i - 1) * i / 8;
- }
- else
- {
- j = 1 + (7 - j) / i; // the leading packets from the 8-trans boundary
- td_count = (j >= (LONG) purb->iso_frame_count ?
- 1 : 1 + (purb->iso_frame_count - j + 8 / i - 1) * i / 8);
- }
- }
-
- elem_pool_lock(sitd_pool, TRUE);
- pelnk = elem_pool_alloc_elems(sitd_pool, td_count);
- elem_pool_unlock(sitd_pool, TRUE);
- }
-
- if (pelnk == NULL)
- {
- ehci_claim_bandwidth(ehci, purb, FALSE);
- return STATUS_NO_MORE_ENTRIES;
- }
-
- InsertTailList(&pelnk->elem_link, &td_list);
- ListFirst(&td_list, pthis);
- pprev = pthis;
- purb->td_count = td_count;
-
- //set up offset for high speed and interval == 1
- if (pipe_content->speed_high && pipe_content->interval == 0)
- {
- for(i = 0; i < (LONG) purb->iso_frame_count; i++)
- {
- if (i == 0)
- purb->iso_packet_desc[i].offset = 0;
- else
- purb->iso_packet_desc[i].offset = purb->iso_packet_desc[i - 1].offset +
- purb->iso_packet_desc[i].length;
- }
- }
-
- i = 0, temp = 0;
-
- while (pthis)
- {
- init_elem_phys_part(struct_ptr(pthis, EHCI_ELEM_LINKS, elem_link));
- if (pipe_content->speed_high)
- {
- LONG start_uframe, k;
- LONG l, pk_idx, offset, start_uf, td_length;
- PULONG pbuf;
- ULONG phys_addr[8];
-
- pitd = itd_from_list_entry(pthis);
- pitdc = (PEHCI_ITD_CONTENT) pitd;
- start_uframe = purb->iso_start_frame & 0x07;
-
- // will be filled later
- pitd->hw_next = EHCI_PTR_TERM;
-
- // DWORD 9;
- pitdc->dev_addr = pdev->dev_addr;
- pitdc->endp_num = endp_num(purb->pendp);
-
- pitdc->max_packet_size = endp_max_packet_size(purb->pendp);
- pitdc->io_dir = pipe_content->trans_dir;
- pitdc->mult = endp_mult_count(purb->pendp);
-
- pbuf = pitd->hw_bufp;
- RtlZeroMemory(phys_addr, sizeof(phys_addr));
-
- if (pipe_content->interval < 3)
- {
- // this indicates one itd schedules more than one uframes
- // for multiple transactions described by iso_packet_desc
- if (i == 0)
- k = td_count == 1 ? purb->iso_frame_count : j; // the first itd
- else
- k = (LONG) (purb->iso_frame_count - i) <= 8 / REAL_INTERVAL
- ? (purb->iso_frame_count - i) : 8 / REAL_INTERVAL;
-
- // j is the header transactions out of the interval
- // aligned transactions per td
- if (j > 0 && i == 0) // handle the first itd
- start_uf = start_uframe;
- else
- start_uf = start_uframe % REAL_INTERVAL;
- }
- else
- {
- k = 1, start_uf = start_uframe & 0x07;
- }
-
-
- // calculate the data to transfer with this td
- td_length = 0;
- for(l = start_uf, pk_idx = i; pk_idx < i + k; pk_idx++, l += REAL_INTERVAL)
- {
- td_length += purb->iso_packet_desc[pk_idx].length;
- phys_addr[l] =
- MmGetPhysicalAddress(&purb->data_buffer[purb->iso_packet_desc[pk_idx].offset]).LowPart;
- }
-
- // fill the page pointer, and offset
- if (pipe_content->interval != 0)
- {
- for(l = start_uf, pk_idx = i; pk_idx < i + k; pk_idx++, l += REAL_INTERVAL)
- {
- pitdc->status_slot[l].offset = phys_addr[l] & (PAGE_SIZE - 1);
- pbuf[l >> pipe_content->interval] |= phys_addr[l] & (~(PAGE_SIZE - 1));
- pitdc->status_slot[l].page_sel = l >> pipe_content->interval;
- pitdc->status_slot[l].status = 0x08;
- pitdc->status_slot[l].trans_length = purb->iso_packet_desc[pk_idx].length;
- if (PAGE_SIZE - pitdc->status_slot[l].offset <
- (ULONG) purb->iso_packet_desc[pk_idx].length)
- {
- // fill the next page buf, we can not simply add
- // PAGE_SIZE to the phys_addr[ l ].
- pbuf[(l >> pipe_content->interval) + 1] |=
- MmGetPhysicalAddress((PBYTE)
- (((ULONG) & purb->
- data_buffer[purb->iso_packet_desc[pk_idx].
- offset]) & (~(PAGE_SIZE - 1))) +
- PAGE_SIZE).LowPart;
- }
- }
- }
- else // interval == 0
- {
- LONG m, n = 0, n2 = 0;
- // fill the page buffer first
- // calculate the page buffer needed
- offset = phys_addr[0] & (PAGE_SIZE - 1);
- if (offset != 0)
- {
- offset = PAGE_SIZE - offset;
- l = 1 + (td_length - offset + PAGE_SIZE - 1) / PAGE_SIZE;
- }
- else
- {
- l = (td_length + PAGE_SIZE - 1) / PAGE_SIZE;
- }
-
- if (l > 7)
- TRAP();
-
- // fill the hw_bufp array and PG field, pk_idx is index into hw_bufp
- for(pk_idx = 0; pk_idx < l; pk_idx++)
- {
- if (pk_idx == 0)
- {
- offset = phys_addr[start_uf] & (~(PAGE_SIZE - 1));
- pbuf[pk_idx] |= offset;
- n = pk_idx;
- pitdc->status_slot[0].page_sel = n;
- n2 = start_uf;
- }
- else
- {
- // scan to find if the buf pointer already filled in the td
- // since interval = 1, we do not need k * REAL_INTERVAL
- // k is transaction count for current td,
- // n is hw_bufp( pbuf ) index
- // n2 is the last phys_addr index we stopped
- for(m = n2; m < start_uf + k; m++)
- {
- // we can not determine the phys_addr[ x ] is piror
- // to offset if it is less than offset.
- // because phys_addr is discrete.
- // if( ( phys_addr[ m ] & ( ~( PAGE_SIZE - 1 ) ) ) < offset )
- // continue;
-
- if ((phys_addr[m] & (~(PAGE_SIZE - 1))) == (ULONG) offset)
- {
- pitdc->status_slot[m].page_sel = n;
- continue;
- }
- break;
- }
-
- if (m == start_uf + k)
- TRAP();
-
- offset = phys_addr[m] & (~(PAGE_SIZE - 1));
- pbuf[pk_idx] |= offset;
- n = pk_idx;
- n2 = m;
- pitdc->status_slot[m].page_sel = n;
- }
- }
- // fill offset and others
- for(l = start_uf, pk_idx = i; l < start_uf + k; l++, pk_idx++)
- {
- pitdc->status_slot[l].offset = (phys_addr[l] & (PAGE_SIZE - 1));
- pitdc->status_slot[l].status = 0x08;
- pitdc->status_slot[l].trans_length = purb->iso_packet_desc[pk_idx].length;
- }
- // exhausted
- }
- i += k;
- }
- else // full/low speed
- {
- psitd = sitd_from_list_entry(pthis);
- psitdc = (PEHCI_SITD_CONTENT) psitd;
- psitd->hw_next = EHCI_PTR_TERM;
-
- // DWORD 1;
- psitdc->dev_addr = pdev->dev_addr;
- psitdc->endp_num = endp_num(purb->pendp);
- psitdc->hub_addr = ((PURB_HS_CONTEXT_CONTENT) & purb->hs_context)->hub_addr;
- psitdc->port_idx = ((PURB_HS_CONTEXT_CONTENT) & purb->hs_context)->port_idx;
- psitdc->io_dir = endp_dir(purb->pendp);
-
- psitdc->status &= 0x80; // in DWORD 3
-
- // DWORD 2;
- j = (purb->iso_packet_desc[i].length + 187) / 188;
-
- if (psitdc->io_dir == 0)
- {
- for(; j > 0; j--)
- {
- psitdc->s_mask |= (1 << (j - 1));
- }
- psitdc->s_mask <<= purb->iso_packet_desc[i].params.start_uframe & 0x07;
- psitdc->c_mask = 0;
- }
- else
- {
- LONG k;
-
- psitdc->s_mask = 1 << purb->iso_packet_desc[i].params.start_uframe & 0x07;
- // iso split case 2b: ehci spec 1.0
- if (j == 6)
- j = 5;
-
- j = j - 1 + 2; // actual complete-split count
-
- psitdc->c_mask |= temp >> 8; // the previous sitd's complete split
- if (temp >> 8) // link back for sitd split completion
- {
- psitd->hw_backpointer = sitd_from_list_entry(pprev)->phys_addr;
- psitdc->status &= 0x82;
- }
- else
- {
- psitd->hw_backpointer = EHCI_PTR_TERM;
- }
-
- for(k = temp = 0; k < j; k++)
- {
- temp |= 1 << k;
- }
-
- temp <<= ((purb->iso_packet_desc[i].params.start_uframe & 0x07) + 2);
-
- // only uframe zero and one have complete split for prev sitd
- if ((temp >> 8) > 3)
- TRAP();
-
- psitdc->c_mask |= temp & 0xff;
- }
-
- // DWORD 3:
- psitdc->c_prog_mask = 0;
- psitdc->bytes_to_transfer = purb->iso_packet_desc[i].length;
- psitdc->page_sel = 0;
- psitdc->ioc = 0;
-
- // DWORD 4;
- j = (ULONG) ((PBYTE) purb->data_buffer + purb->iso_packet_desc[i].offset);
- psitd->hw_tx_results2 = MmGetPhysicalAddress((PVOID) j).LowPart;
-
- // DWORD 5;
- if (PAGE_SIZE - (j & (PAGE_SIZE - 1)) < (ULONG) purb->iso_packet_desc[i].length)
- {
- // need to fill another slot
- psitdc->page1 =
- MmGetPhysicalAddress((PVOID) ((j & ~(PAGE_SIZE - 1)) + PAGE_SIZE)).LowPart >> 12;
- }
-
- if (purb->iso_packet_desc[i].length > 188)
- psitdc->trans_pos = 0x00;
- else if (purb->iso_packet_desc[i].length <= 188)
- psitdc->trans_pos = 0x01;
-
- if (psitdc->io_dir == 0)
- psitdc->trans_count = (purb->iso_packet_desc[i].length + 187) / 188;
-
- }
- ListNext(&td_list, pthis, pnext);
- pprev = pthis;
- pthis = pnext;
-
- }
-
- if (pipe_content->speed_high == 0)
- {
- // has an extra sitd to fill at the tail
- if (ret)
- {
- ListFirstPrev(&td_list, pthis);
- init_elem_phys_part(struct_ptr(pthis, EHCI_ELEM_LINKS, elem_link));
-
- psitd = sitd_from_list_entry(pthis);
- psitdc = (PEHCI_SITD_CONTENT) psitd;
- psitd->hw_next = EHCI_PTR_TERM;
-
- // DWORD 1;
- psitdc->dev_addr = pdev->dev_addr;
- psitdc->endp_num = endp_num(purb->pendp);
- psitdc->hub_addr = ((PURB_HS_CONTEXT_CONTENT) & purb->hs_context)->hub_addr;
- psitdc->port_idx = ((PURB_HS_CONTEXT_CONTENT) & purb->hs_context)->port_idx;
- psitdc->io_dir = endp_dir(purb->pendp);
-
- psitdc->status &= 0x80; // in DWORD 3
-
- // DWORD 2;
- psitdc->s_mask = 0x04; // uframe 2, random selection
-
- psitdc->c_mask = 0x70; // complete split at uframe 4, 5, 6
- ListFirstPrev(pthis, pprev);
- psitd->hw_backpointer = sitd_from_list_entry(pprev)->phys_addr;
- psitdc->status &= 0x82;
-
- // DWORD 3:
- psitdc->c_prog_mask = 0;
- psitdc->bytes_to_transfer = 1; // purb->iso_packet_desc[ purb->iso_frame_count - 1 ].length;
- psitdc->page_sel = 0;
-
- j = (ULONG) ((PBYTE) purb->data_buffer + purb->iso_packet_desc[purb->iso_frame_count - 1].offset);
- // the last byte is overridden.
- j += purb->iso_packet_desc[purb->iso_frame_count - 1].length - 1;
- psitd->hw_tx_results2 = MmGetPhysicalAddress((PVOID) j).LowPart;
- }
-
- // set the interrupt
- ListFirstPrev(&td_list, pthis);
- psitdc = (PEHCI_SITD_CONTENT) sitd_from_list_entry(pthis);
- psitdc->ioc = 1;
- }
- else
- {
- // set the ioc
- ListFirstPrev(&td_list, pthis);
- pitdc = (PEHCI_ITD_CONTENT) itd_from_list_entry(pthis);
- for(i = 7; i >= 0; i--)
- {
- if (pitdc->status_slot[i].status == 0x08)
- {
- pitdc->status_slot[i].ioc = 1;
- break;
- }
- }
- if (i < 0)
- TRAP();
- }
-
- ListFirst(&td_list, pthis);
- // ListFirst( &purb->trasac_list, pthis )
- RemoveEntryList(&td_list);
- InsertTailList(pthis, &purb->trasac_list);
-
- while (pthis)
- {
- // fill the purb ptr
- struct_ptr(pthis, EHCI_ELEM_LINKS, elem_link)->purb = purb;
- ListNext(&purb->trasac_list, pthis, pnext);
- pthis = pnext;
- }
-
- //indirectly guarded by pending_endp_list_lock
- usb_endp_busy_count_inc(purb->pendp);
- ehci_insert_urb_to_schedule(ehci, purb, ret);
-
- if (ret == FALSE)
- {
- // usb_endp_busy_count_dec( purb->pendp );
-
- ListFirst(&purb->trasac_list, pthis);
- RemoveEntryList(&purb->trasac_list);
-
- elem_safe_free(pthis, FALSE);
- ehci_claim_bandwidth(ehci, purb, FALSE);
- return STATUS_UNSUCCESSFUL;
- }
- return STATUS_SUCCESS;
-}
-
-BOOLEAN NTAPI
-//this function used as the KeSynchronizeExecution param to delegate control to ehci_insert_urb_schedule
-ehci_sync_insert_urb_schedule(PVOID context)
-{
- PSYNC_PARAM sync_param;
- PEHCI_DEV ehci;
- PURB purb;
-
- sync_param = (PSYNC_PARAM) context;
- if (sync_param == NULL)
- return FALSE;
-
- ehci = sync_param->ehci;
- purb = (PURB) sync_param->context;
-
- if (ehci == NULL || purb == NULL)
- return (UCHAR) (sync_param->ret = FALSE);
-
- return (UCHAR) (sync_param->ret = ehci_insert_urb_schedule(ehci, purb));
-}
-
-static BOOLEAN NTAPI
-ehci_sync_cancel_urb(PVOID context)
-{
- //cancel a single purb
- PEHCI_DEV ehci;
- PSYNC_PARAM sync_param;
- PURB purb2, dest_urb;
- PLIST_ENTRY pthis, pnext;
- BOOLEAN found = FALSE;
-
- if (context == NULL)
- return FALSE;
-
- sync_param = (PSYNC_PARAM) context;
- ehci = sync_param->ehci;
- dest_urb = (PURB) sync_param->context;
-
- if (ehci == NULL || dest_urb == NULL)
- return (UCHAR) (sync_param->ret = FALSE);
-
- ListFirst(&ehci->urb_list, pthis);
- while (pthis)
- {
- purb2 = (PURB) pthis;
- if (purb2 == dest_urb)
- {
- found = TRUE;
- purb2->flags |= URB_FLAG_FORCE_CANCEL;
- break;
- }
- ListNext(&ehci->urb_list, pthis, pnext);
- pthis = pnext;
- }
-
- if (found)
- {
- press_doorbell(ehci);
- }
- return (UCHAR) (sync_param->ret = found);
-}
-
-NTSTATUS
-ehci_cancel_urb(PEHCI_DEV ehci, PUSB_DEV pdev, PUSB_ENDPOINT pendp, PURB purb)
-//note any fields of the purb can not be referenced unless it is found in some queue
-{
- PLIST_ENTRY pthis, pnext;
- BOOLEAN found;
- PURB purb2;
-
- SYNC_PARAM sync_param;
-
- USE_BASIC_NON_PENDING_IRQL;
-
- if (ehci == NULL || purb == NULL || pdev == NULL || pendp == NULL)
- return STATUS_INVALID_PARAMETER;
-
- lock_dev(pdev, FALSE);
-
- if (dev_state(pdev) == USB_DEV_STATE_ZOMB)
- {
- unlock_dev(pdev, FALSE);
- //delegate to remove device for this job
- return STATUS_DEVICE_DOES_NOT_EXIST;
- }
-
- if (dev_from_endp(pendp) != pdev)
- {
- unlock_dev(pdev, FALSE);
- return STATUS_INVALID_PARAMETER;
- }
-
- if (endp_state(pendp) == USB_ENDP_FLAG_STALL)
- {
- //it will be canceled in ehci_process_pending_endp
- unlock_dev(pdev, FALSE);
- return USB_STATUS_ENDPOINT_HALTED;
- }
-
- found = FALSE;
- ListFirst(&pendp->urb_list, pthis);
- while (pthis)
- {
- purb2 = (PURB) pthis;
- if (purb2 == purb)
- {
- found = TRUE;
- RemoveEntryList(pthis);
- InitializeListHead(pthis);
- break;
- }
- ListNext(&pendp->urb_list, pthis, pnext);
- pthis = pnext;
- }
- unlock_dev(pdev, FALSE);
-
- if (found)
- {
- purb->status = STATUS_CANCELLED;
-
- ehci_generic_urb_completion(purb, purb->context);
-
- lock_dev(pdev, FALSE);
- pdev->ref_count--;
- unlock_dev(pdev, FALSE);
- return STATUS_SUCCESS;
- }
-
- // search the purb in the purb-list and try to cancel
- sync_param.ehci = ehci;
- sync_param.context = purb;
-
- KeSynchronizeExecution(ehci->pdev_ext->ehci_int, ehci_sync_cancel_urb, &sync_param);
-
- found = sync_param.ret;
-
- if (found)
- return USB_STATUS_CANCELING;
-
- return STATUS_INVALID_PARAMETER;
-}
-
-VOID
-ehci_generic_urb_completion(PURB purb, PVOID context)
-{
- PUSB_DEV pdev;
- BOOLEAN is_ctrl = FALSE;
- USE_NON_PENDING_IRQL;
-
- old_irql = KeGetCurrentIrql();
- if (old_irql > DISPATCH_LEVEL)
- TRAP();
-
- if (old_irql < DISPATCH_LEVEL)
- KeRaiseIrql(DISPATCH_LEVEL, &old_irql);
-
- pdev = purb->pdev;
- if (purb == NULL)
- goto LBL_LOWER_IRQL;
-
- if (pdev == NULL)
- goto LBL_LOWER_IRQL;
-
- lock_dev(pdev, TRUE);
-
- if (dev_state(pdev) == USB_DEV_STATE_ZOMB)
- {
- // no need to do following statistics
- unlock_dev(pdev, TRUE);
- goto LBL_CLIENT_PROCESS;
- }
- if (usb_error(purb->status))
- {
- pdev->error_count++;
- }
-
- if (purb->pendp == &pdev->default_endp)
- {
- if (usb_halted(purb->status))
- {
- pdev->time_out_count++;
- if (pdev->time_out_count > 3)
- {
- dev_set_state(pdev, USB_DEV_STATE_ZOMB);
- ehci_dbg_print(DBGLVL_MAXIMUM,
- ("ehci_generic_urb_completion(): contiguous error 3 times, dev 0x%x is deactivated\n",
- pdev));
- }
- }
- else
- pdev->time_out_count = 0;
-
- }
-
- if (endp_type(purb->pendp) == USB_ENDPOINT_XFER_CONTROL)
- is_ctrl = TRUE;
-
- unlock_dev(pdev, TRUE);
-
- LBL_CLIENT_PROCESS:
- if (!is_ctrl)
- {
- if (purb->completion)
- purb->completion(purb, context);
- }
- else
- {
- if (purb->ctrl_req_context.ctrl_stack_count == 0)
- {
- if (purb->completion)
- purb->completion(purb, context);
- }
- else
- {
- // pstack = &purb->ctrl_req_stack[ purb->ctrl_req_context.ctrl_cur_stack ];
- // if( pstack->urb_completion )
- // pstack->urb_completion( purb, pstack->context );
- usb_call_ctrl_completion(purb);
- }
- }
-
- LBL_LOWER_IRQL:
- if (old_irql < DISPATCH_LEVEL)
- KeLowerIrql(old_irql);
-
- return;
-}
-
-NTSTATUS
-ehci_rh_submit_urb(PUSB_DEV pdev, PURB purb)
-{
- PUSB_DEV_MANAGER dev_mgr;
- PTIMER_SVC ptimer;
- PUSB_CTRL_SETUP_PACKET psetup;
- PEHCI_DEV ehci;
- NTSTATUS status;
- PHUB2_EXTENSION hub_ext;
- PUSB_PORT_STATUS ps, psret;
- LONG i;
- UCHAR port_count;
-
- USE_NON_PENDING_IRQL;
- if (pdev == NULL || purb == NULL)
- return STATUS_INVALID_PARAMETER;
-
- dev_mgr = dev_mgr_from_dev(pdev);
-
- KeAcquireSpinLock(&dev_mgr->timer_svc_list_lock, &old_irql);
- lock_dev(pdev, FALSE);
- if (dev_state(pdev) == USB_DEV_STATE_ZOMB)
- {
- unlock_dev(pdev, FALSE);
- KeReleaseSpinLock(&dev_mgr->timer_svc_list_lock, old_irql);
- return STATUS_DEVICE_DOES_NOT_EXIST;
- }
-
- ehci = ehci_from_hcd(pdev->hcd);
- psetup = (PUSB_CTRL_SETUP_PACKET) purb->setup_packet;
-
- hub_ext = ((PHUB2_EXTENSION) pdev->dev_ext);
- port_count = (UCHAR) ((PEHCI_HCS_CONTENT) & ehci->ehci_caps.hcs_params)->port_count;
-
- switch (endp_type(purb->pendp))
- {
- case USB_ENDPOINT_XFER_CONTROL:
- {
- if (psetup->bmRequestType == 0xa3 && psetup->bRequest == USB_REQ_GET_STATUS)
- {
- //get-port-status
- if (psetup->wIndex == 0 || psetup->wIndex > port_count || psetup->wLength < 4)
- {
- purb->status = STATUS_INVALID_PARAMETER;
- break;
- }
-
- i = EHCI_PORTSC + 4 * (psetup->wIndex - 1); // USBPORTSC1;
- status = EHCI_READ_PORT_ULONG((PULONG) (ehci->port_base + i));
- ps = &hub_ext->rh_port_status[psetup->wIndex];
-
- psret = (PUSB_PORT_STATUS) purb->data_buffer;
- ps->wPortStatus = 0;
-
- if (status & PORT_CCS)
- {
- ps->wPortStatus |= USB_PORT_STAT_CONNECTION;
- }
- if (status & PORT_PE)
- {
- ps->wPortStatus |= USB_PORT_STAT_ENABLE;
- ps->wPortStatus |= USB_PORT_STAT_HIGH_SPEED; // ehci spec
- }
- if (status & PORT_PR)
- {
- ps->wPortStatus |= USB_PORT_STAT_RESET;
- }
- if (status & PORT_SUSP)
- {
- ps->wPortStatus |= USB_PORT_STAT_SUSPEND;
- }
- if (PORT_USB11(status))
- {
- ps->wPortStatus |= USB_PORT_STAT_LOW_SPEED;
- }
-
- //always power on
- ps->wPortStatus |= USB_PORT_STAT_POWER;
-
- //now set change field
- if ((status & PORT_CSC) && !(ps->wPortStatus & USB_PORT_STAT_LOW_SPEED))
- {
- ps->wPortChange |= USB_PORT_STAT_C_CONNECTION;
- }
- if ((status & PORT_PEC) && !(ps->wPortStatus & USB_PORT_STAT_LOW_SPEED))
- {
- ps->wPortChange |= USB_PORT_STAT_C_ENABLE;
- }
-
- //don't touch other fields, might be filled by
- //other function
-
- usb_dbg_print(DBGLVL_MAXIMUM,
- ("ehci_rh_submit_urb(): get port status, wPortStatus=0x%x, wPortChange=0x%x, address=0x%x\n",
- ps->wPortStatus, ps->wPortChange, ps));
-
- psret->wPortChange = ps->wPortChange;
- psret->wPortStatus = ps->wPortStatus;
-
- purb->status = STATUS_SUCCESS;
-
- break;
- }
- else if (psetup->bmRequestType == 0x23 && psetup->bRequest == USB_REQ_CLEAR_FEATURE)
- {
- //clear-port-feature
- if (psetup->wIndex == 0 || psetup->wIndex > port_count)
- {
- purb->status = STATUS_INVALID_PARAMETER;
- break;
- }
-
- i = EHCI_PORTSC + 4 * (psetup->wIndex - 1); // USBPORTSC1;
- ps = &hub_ext->rh_port_status[psetup->wIndex];
-
- purb->status = STATUS_SUCCESS;
- switch (psetup->wValue)
- {
- case USB_PORT_FEAT_C_CONNECTION:
- {
- SET_RH2_PORTSTAT(i, USBPORTSC_CSC);
- status = EHCI_READ_PORT_ULONG((PULONG) (ehci->port_base + i));
- usb_dbg_print(DBGLVL_MAXIMUM,
- ("ehci_rh_submit_urb(): clear csc, port%d=0x%x\n", psetup->wIndex));
- ps->wPortChange &= ~USB_PORT_STAT_C_CONNECTION;
- break;
- }
- case USB_PORT_FEAT_C_ENABLE:
- {
- SET_RH2_PORTSTAT(i, USBPORTSC_PEC);
- status = EHCI_READ_PORT_ULONG((PULONG) (ehci->port_base + i));
- usb_dbg_print(DBGLVL_MAXIMUM,
- ("ehci_rh_submit_urb(): clear pec, port%d=0x%x\n", psetup->wIndex));
- ps->wPortChange &= ~USB_PORT_STAT_C_ENABLE;
- break;
- }
- case USB_PORT_FEAT_C_RESET:
- {
- ps->wPortChange &= ~USB_PORT_STAT_C_RESET;
- //the reset signal is down in rh_timer_svc_reset_port_completion
- // enable or not is set by host controller
- // status = EHCI_READ_PORT_ULONG( ( PUSHORT ) ( ehci->port_base + i ) );
- usb_dbg_print(DBGLVL_MAXIMUM,
- ("ehci_rh_submit_urb(): clear pr, enable pe, port%d=0x%x\n",
- psetup->wIndex));
- break;
- }
- case USB_PORT_FEAT_ENABLE:
- {
- ps->wPortStatus &= ~USB_PORT_STAT_ENABLE;
- CLR_RH2_PORTSTAT(i, USBPORTSC_PE);
- status = EHCI_READ_PORT_ULONG((PULONG) (ehci->port_base + i));
- usb_dbg_print(DBGLVL_MAXIMUM,
- ("ehci_rh_submit_urb(): clear pe, port%d=0x%x\n", psetup->wIndex));
- break;
- }
- default:
- purb->status = STATUS_UNSUCCESSFUL;
- }
- break;
- }
- else if (psetup->bmRequestType == 0xd3 && psetup->bRequest == HUB_REQ_GET_STATE)
- {
- // get bus state
- if (psetup->wIndex == 0 || psetup->wIndex > port_count || psetup->wLength == 0)
- {
- purb->status = STATUS_INVALID_PARAMETER;
- break;
- }
-
- i = EHCI_PORTSC + 4 * (psetup->wIndex - 1); // USBPORTSC1;
- status = EHCI_READ_PORT_ULONG((PULONG) (ehci->port_base + i));
- purb->data_buffer[0] = (status & USBPORTSC_LS);
-
- // reverse the order
- purb->data_buffer[0] ^= 0x3;
- purb->status = STATUS_SUCCESS;
- break;
- }
- else if (psetup->bmRequestType == 0x23 && psetup->bRequest == USB_REQ_SET_FEATURE)
- {
- //reset port
- if (psetup->wValue != USB_PORT_FEAT_RESET)
- {
- purb->status = STATUS_INVALID_PARAMETER;
- ehci_dbg_print(DBGLVL_MAXIMUM,
- ("ehci_rh_submit_urb(): set feature with wValue=0x%x\n", psetup->wValue));
- break;
- }
-
- i = EHCI_PORTSC + 4 * (psetup->wIndex - 1); // USBPORTSC1;
-
- ptimer = alloc_timer_svc(&dev_mgr->timer_svc_pool, 1);
- if (!ptimer)
- {
- purb->status = STATUS_NO_MEMORY;
- break;
- }
-
- ptimer->threshold = 0; // within [ 50ms, 60ms ], one tick is 10 ms
- ptimer->context = (ULONG) purb;
- ptimer->pdev = pdev;
- ptimer->func = rh_timer_svc_reset_port_completion;
-
- //start the timer
- pdev->ref_count += 2; //one for timer and one for purb
-
- status = EHCI_READ_PORT_ULONG((PULONG) (ehci->port_base + i));
- usb_dbg_print(DBGLVL_MAXIMUM,
- ("ehci_rh_submit_urb(): reset port, port%d=0x%x\n", psetup->wIndex, status));
- InsertTailList(&dev_mgr->timer_svc_list, &ptimer->timer_svc_link);
- purb->status = STATUS_PENDING;
- }
- else
- {
- purb->status = STATUS_INVALID_PARAMETER;
- }
- break;
- }
- case USB_ENDPOINT_XFER_INT:
- {
- ptimer = alloc_timer_svc(&dev_mgr->timer_svc_pool, 1);
- if (!ptimer)
- {
- purb->status = STATUS_NO_MEMORY;
- break;
- }
- ptimer->threshold = RH_INTERVAL;
- ptimer->context = (ULONG) purb;
- ptimer->pdev = pdev;
- ptimer->func = rh_timer_svc_int_completion;
-
- //start the timer
- InsertTailList(&dev_mgr->timer_svc_list, &ptimer->timer_svc_link);
-
- usb_dbg_print(DBGLVL_MAXIMUM,
- ("ehci_rh_submit_urb(): current rh's ref_count=0x%x\n", pdev->ref_count));
- pdev->ref_count += 2; //one for timer and one for purb
-
- purb->status = STATUS_PENDING;
- break;
- }
- case USB_ENDPOINT_XFER_BULK:
- case USB_ENDPOINT_XFER_ISOC:
- default:
- {
- purb->status = STATUS_INVALID_PARAMETER;
- break;
- }
- }
- unlock_dev(pdev, FALSE);
- KeReleaseSpinLock(&dev_mgr->timer_svc_list_lock, old_irql);
- return purb->status;
-}
-
-//must have rh dev_lock acquired
-BOOLEAN
-ehci_rh_reset_port(PHCD hcd, UCHAR port_idx)
-{
- ULONG i;
- PEHCI_DEV ehci;
- ULONG status;
- UCHAR port_count;
-
- if (hcd == NULL)
- return FALSE;
-
- ehci = ehci_from_hcd(hcd);
- port_count = (UCHAR) ((PEHCI_HCS_CONTENT) & ehci->ehci_caps.hcs_params)->port_count;
-
- if (port_idx < 1 || port_idx > port_count)
- return FALSE;
-
- i = (ULONG) (EHCI_PORTSC + 4 * (port_idx - 1));
-
- // assert the reset signal,(implicitly disable the port)
- SET_RH2_PORTSTAT(i, PORT_PR);
-
- usb_wait_ms_dpc(50);
- // clear the reset signal, delay port enable till clearing port feature
- CLR_RH2_PORTSTAT(i, PORT_PR);
-
- // wait the port stable
- usb_wait_ms_dpc(2);
-
- status = EHCI_READ_PORT_ULONG((PULONG) (ehci->port_base + i));
- if (!(status & PORT_PE))
- {
- // release the ownership from ehci to companion hc
- status |= PORT_OWNER;
- EHCI_WRITE_PORT_ULONG((PULONG) (ehci->port_base + i), status);
- // the host controller will set PORTSC automatically
- return FALSE;
- }
- usb_wait_us_dpc(10);
- // SET_RH_PORTSTAT( i, PORT_PE );
-
- //recovery time 10ms
- usb_wait_ms_dpc(10);
-
- // clear PORT_PEC and PORT_PCC
- SET_RH2_PORTSTAT(i, 0x0a);
-
- status = EHCI_READ_PORT_ULONG((PULONG) (ehci->port_base + i));
- usb_dbg_print(DBGLVL_MAXIMUM, ("ehci_rh_reset_port(): status after written=0x%x\n", status));
- return TRUE;
-}
-
-NTSTATUS
-ehci_dispatch_irp(IN PDEVICE_OBJECT DeviceObject, IN PIRP irp)
-{
- PEHCI_DEVICE_EXTENSION pdev_ext;
- PUSB_DEV_MANAGER dev_mgr;
- PEHCI_DEV ehci;
-
- pdev_ext = DeviceObject->DeviceExtension;
- ehci = pdev_ext->ehci;
-
- dev_mgr = ehci->hcd_interf.hcd_get_dev_mgr(&ehci->hcd_interf);
- return dev_mgr_dispatch(dev_mgr, irp);
-}
-
-//the following are for hcd interface methods
-VOID
-ehci_set_dev_mgr(PHCD hcd, PUSB_DEV_MANAGER dev_mgr)
-{
- hcd->dev_mgr = dev_mgr;
-}
-
-PUSB_DEV_MANAGER
-ehci_get_dev_mgr(PHCD hcd)
-{
- return hcd->dev_mgr;
-}
-
-ULONG
-ehci_get_type(PHCD hcd)
-{
- return HCD_TYPE_EHCI; // ( hcd->flags & HCD_TYPE_MASK );
-}
-
-VOID
-ehci_set_id(PHCD hcd, UCHAR id)
-{
- hcd->flags &= ~HCD_ID_MASK;
- hcd->flags |= (HCD_ID_MASK & id);
-}
-
-UCHAR
-ehci_get_id(PHCD hcd)
-{
- return (UCHAR) (hcd->flags & HCD_ID_MASK);
-}
-
-
-UCHAR
-ehci_alloc_addr(PHCD hcd)
-{
- LONG i;
- if (hcd == NULL)
- return 0;
-
- for(i = 1; i < MAX_DEVS; i++)
- {
- if (hcd->dev_addr_map[i >> 3] & (1 << (i & 7)))
- {
- continue;
- }
- else
- {
- break;
- }
- }
-
- if (i >= MAX_DEVS)
- return 0xff;
-
- hcd->dev_addr_map[i >> 3] |= (1 << (i & 7));
- hcd->conn_count++;
- return (BYTE) i;
-}
-
-VOID
-ehci_free_addr(PHCD hcd, UCHAR addr)
-{
- if (addr & 0x80)
- return;
-
- if (hcd == NULL)
- return;
-
- hcd->dev_addr_map[addr >> 3] &= ~(1 << (addr & 7));
- return;
-
-}
-
-NTSTATUS
-ehci_submit_urb2(PHCD hcd, PUSB_DEV pdev, PUSB_ENDPOINT pendp, PURB purb)
-{
- return ehci_submit_urb(ehci_from_hcd(hcd), pdev, pendp, purb);
-}
-
-PUSB_DEV
-ehci_get_root_hub(PHCD hcd)
-{
- return ehci_from_hcd(hcd)->root_hub;
-}
-
-VOID
-ehci_set_root_hub(PHCD hcd, PUSB_DEV root_hub)
-{
- if (hcd == NULL || root_hub == NULL)
- return;
- ehci_from_hcd(hcd)->root_hub = root_hub;
- return;
-}
-
-BOOLEAN
-ehci_remove_device2(PHCD hcd, PUSB_DEV pdev)
-{
- if (hcd == NULL || pdev == NULL)
- return FALSE;
-
- return ehci_remove_device(ehci_from_hcd(hcd), pdev);
-}
-
-BOOLEAN
-ehci_hcd_release(PHCD hcd)
-{
- PEHCI_DEV ehci;
- PEHCI_DEVICE_EXTENSION pdev_ext;
-
- if (hcd == NULL)
- return FALSE;
-
- ehci = ehci_from_hcd(hcd);
- pdev_ext = ehci->pdev_ext;
- return ehci_release(pdev_ext->pdev_obj, hcd->dev_mgr);
-}
-
-NTSTATUS
-ehci_cancel_urb2(PHCD hcd, PUSB_DEV pdev, PUSB_ENDPOINT pendp, PURB purb)
-{
- PEHCI_DEV ehci;
- if (hcd == NULL)
- return STATUS_INVALID_PARAMETER;
-
- ehci = ehci_from_hcd(hcd);
- return ehci_cancel_urb(ehci, pdev, pendp, purb);
-}
-
-BOOLEAN
-ehci_rh_get_dev_change(PHCD hcd, PBYTE buf) //must have the rh dev_lock acquired
-{
- PEHCI_DEV ehci;
- LONG port_count, i;
- ULONG status;
-
- if (hcd == NULL)
- return FALSE;
-
- ehci = ehci_from_hcd(hcd);
- port_count = HCS_N_PORTS(ehci->ehci_caps.hcs_params);
- for(i = 0; i < port_count; i++)
- {
- status = EHCI_READ_PORT_ULONG((PULONG) (ehci->port_base + EHCI_PORTSC + (i << 2)));
- ehci_dbg_print(DBGLVL_MAXIMUM, ("ehci_rh_get_dev_change(): erh port%d status=0x%x\n", i, status));
-
- if (status & (PORT_PEC | PORT_CSC | PORT_OCC))
- {
- buf[(i + 1) >> 3] |= (1 << ((i + 1) & 7));
- }
- }
- return TRUE;
-}
-
-NTSTATUS
-ehci_hcd_dispatch(PHCD hcd, LONG disp_code, PVOID param)
-{
- PEHCI_DEV ehci;
-
- if (hcd == NULL)
- return STATUS_INVALID_PARAMETER;
- ehci = ehci_from_hcd(hcd);
- switch (disp_code)
- {
- case HCD_DISP_READ_PORT_COUNT:
- {
- if (param == NULL)
- return STATUS_INVALID_PARAMETER;
- *((PUCHAR) param) = (UCHAR) HCS_N_PORTS(ehci->ehci_caps.hcs_params);
- return STATUS_SUCCESS;
- }
- case HCD_DISP_READ_RH_DEV_CHANGE:
- {
- if (ehci_rh_get_dev_change(hcd, param) == FALSE)
- return STATUS_INVALID_PARAMETER;
- return STATUS_SUCCESS;
- }
- }
- return STATUS_NOT_IMPLEMENTED;
-}
-
-//------------------------------------------------------------------------------
-// EHCI routines follows
-//
-VOID ehci_init_int8_qh(PEHCI_QH_CONTENT qh);
-
-BOOLEAN NTAPI
-ehci_cal_cpu_freq(PVOID context)
-{
- usb_cal_cpu_freq();
- return TRUE;
-}
-
-PDEVICE_OBJECT
-ehci_probe(PDRIVER_OBJECT drvr_obj, PUNICODE_STRING reg_path, PUSB_DEV_MANAGER dev_mgr)
-{
- LONG bus, i, j, ret = 0;
- PCI_SLOT_NUMBER slot_num;
- PPCI_COMMON_CONFIG pci_config;
- PDEVICE_OBJECT pdev;
- BYTE buffer[sizeof(PCI_COMMON_CONFIG)];
- PEHCI_DEVICE_EXTENSION pdev_ext;
- LONG count = 0;
-
- slot_num.u.AsULONG = 0;
- pci_config = (PPCI_COMMON_CONFIG) buffer;
- pdev = NULL;
-
- //scan the PCI buses to find ehci controller
- for (bus = 0; bus <= PCI_MAX_BRIDGE_NUMBER; bus++) //Yes, it should be <=
- {
- for(i = 0; i <= PCI_MAX_DEVICES; i++)
- {
- slot_num.u.bits.DeviceNumber = i;
- for(j = 0; j <= PCI_MAX_FUNCTION; j++)
- {
- slot_num.u.bits.FunctionNumber = j;
-
- ret = HalGetBusData(PCIConfiguration,
- bus, slot_num.u.AsULONG, pci_config, PCI_COMMON_HDR_LENGTH);
-
- if (ret == 0) /*no this bus */
- break;
-
- if (ret == 2) /*no device on the slot */
- break;
-
- if (pci_config->BaseClass == 0x0c && pci_config->SubClass == 0x03
- && pci_config->ProgIf == 0x20)
- {
- //well, we find our usb host controller( EHCI ), create device
- pdev = ehci_alloc(drvr_obj, reg_path, ((bus << 8) | (i << 3) | j), dev_mgr);
- if (pdev)
-#ifdef _MULTI_EHCI
- count++;
-#else
- goto LBL_LOOPOUT;
-#endif
- }
- }
-
- if (ret == 0)
- break;
- }
- }
-
-#ifndef _MULTI_EHCI
-LBL_LOOPOUT:
-#endif
- DbgPrint("Found %d EHCI controllers\n", count);
-
- if (pdev)
- {
- pdev_ext = pdev->DeviceExtension;
- if (pdev_ext)
- {
- // acquire higher irql to eliminate pre-empty
- KeSynchronizeExecution(pdev_ext->ehci_int, ehci_cal_cpu_freq, NULL);
- }
- }
- return pdev;
-}
-
-PDEVICE_OBJECT
-ehci_alloc(PDRIVER_OBJECT drvr_obj, PUNICODE_STRING reg_path, ULONG bus_addr, PUSB_DEV_MANAGER dev_mgr)
-{
-
- LONG frd_num, prd_num;
- PDEVICE_OBJECT pdev;
- PEHCI_DEVICE_EXTENSION pdev_ext;
- ULONG vector, addr_space;
- LONG bus, i;
- KIRQL irql;
- KAFFINITY affinity;
-
- DEVICE_DESCRIPTION dev_desc;
- CM_PARTIAL_RESOURCE_DESCRIPTOR *pprd;
- PCI_SLOT_NUMBER slot_num;
- NTSTATUS status;
-
-
- pdev = ehci_create_device(drvr_obj, dev_mgr);
-
- if (pdev == NULL)
- return NULL;
-
- pdev_ext = pdev->DeviceExtension;
-
- pdev_ext->pci_addr = bus_addr;
- bus = (bus_addr >> 8);
-
- slot_num.u.AsULONG = 0;
- slot_num.u.bits.DeviceNumber = ((bus_addr & 0xff) >> 3);
- slot_num.u.bits.FunctionNumber = (bus_addr & 0x07);
-
- //now create adapter object
- RtlZeroMemory(&dev_desc, sizeof(dev_desc));
-
- dev_desc.Version = DEVICE_DESCRIPTION_VERSION;
- dev_desc.Master = TRUE;
- dev_desc.ScatterGather = TRUE;
- dev_desc.Dma32BitAddresses = TRUE;
- dev_desc.BusNumber = bus;
- dev_desc.InterfaceType = PCIBus;
- dev_desc.MaximumLength = EHCI_MAX_SIZE_TRANSFER;
-
- pdev_ext->map_regs = 2; // we do not use it seriously
-
- pdev_ext->padapter = HalGetAdapter(&dev_desc, &pdev_ext->map_regs);
-
- ehci_dbg_print(DBGLVL_MAXIMUM, ("ehci_alloc(): padapter=0x%x\n", pdev_ext->padapter));
- if (pdev_ext->padapter == NULL)
- {
- //fatal error
- ehci_delete_device(pdev, dev_mgr);
- return NULL;
- }
-
- DbgPrint("ehci_alloc(): reg_path=0x%x, \n \
- ehci_alloc(): PCIBus=0x%x, bus=0x%x, bus_addr=0x%x \n \
- ehci_alloc(): slot_num=0x%x, &res_list=0x%x \n \
- ehci_alloc(): adapter=0x%x \n", (DWORD) reg_path, (DWORD) PCIBus, (DWORD) bus, (DWORD) bus_addr, (DWORD) slot_num.u.AsULONG, (DWORD) & pdev_ext->res_list, pdev_ext->padapter);
-
- //let's allocate resources for this device
- DbgPrint("ehci_alloc(): about to assign slot res\n");
- if ((status = HalAssignSlotResources(reg_path, NULL, //no class name yet
- drvr_obj, NULL, //no support of another ehci controller
- PCIBus,
- bus, slot_num.u.AsULONG, &pdev_ext->res_list)) != STATUS_SUCCESS)
- {
- DbgPrint("ehci_alloc(): error assign slot res, 0x%x\n", status);
- release_adapter(pdev_ext->padapter);
- pdev_ext->padapter = NULL;
- ehci_delete_device(pdev, dev_mgr);
- return NULL;
- }
-
- //parse the resource list
- for(frd_num = 0; frd_num < (LONG) pdev_ext->res_list->Count; frd_num++)
- {
- for(prd_num = 0; prd_num < (LONG) pdev_ext->res_list->List[frd_num].PartialResourceList.Count;
- prd_num++)
- {
- pprd = &pdev_ext->res_list->List[frd_num].PartialResourceList.PartialDescriptors[prd_num];
- if (pprd->Type == CmResourceTypePort)
- {
- RtlCopyMemory(&pdev_ext->res_port, &pprd->u.Port, sizeof(pprd->u.Port));
-
- }
- else if (pprd->Type == CmResourceTypeInterrupt)
- {
- RtlCopyMemory(&pdev_ext->res_interrupt, &pprd->u.Interrupt, sizeof(pprd->u.Interrupt));
- }
- else if (pprd->Type == CmResourceTypeMemory)
- {
- RtlCopyMemory(&pdev_ext->res_memory, &pprd->u.Memory, sizeof(pprd->u.Memory));
- }
- }
- }
-
- //for port, translate them to system address
- addr_space = 0;
- if (HalTranslateBusAddress(PCIBus, bus, pdev_ext->res_port.Start, &addr_space, //io space
- &pdev_ext->ehci->ehci_reg_base) != (BOOLEAN) TRUE)
- {
- DbgPrint("ehci_alloc(): error, can not translate bus address\n");
- release_adapter(pdev_ext->padapter);
- pdev_ext->padapter = NULL;
- ehci_delete_device(pdev, dev_mgr);
- return NULL;
- }
-
- DbgPrint("ehci_alloc(): address space=0x%x\n, reg_base=0x%x\n",
- addr_space, pdev_ext->ehci->ehci_reg_base.u.LowPart);
-
- if (addr_space == 0)
- {
- //port has been mapped to memory space
- pdev_ext->ehci->port_mapped = TRUE;
- pdev_ext->ehci->port_base = (PBYTE) MmMapIoSpace(pdev_ext->ehci->ehci_reg_base,
- pdev_ext->res_port.Length, FALSE);
-
- //fatal error can not map the registers
- if (pdev_ext->ehci->port_base == NULL)
- {
- release_adapter(pdev_ext->padapter);
- pdev_ext->padapter = NULL;
- ehci_delete_device(pdev, dev_mgr);
- return NULL;
- }
- }
- else
- {
- //io space
- pdev_ext->ehci->port_mapped = FALSE;
- pdev_ext->ehci->port_base = (PBYTE) pdev_ext->ehci->ehci_reg_base.LowPart;
- }
-
- //before we connect the interrupt, we have to init ehci
- pdev_ext->ehci->pdev_ext = pdev_ext;
-
- //init ehci_caps
- // i = ( ( PEHCI_HCS_CONTENT )( &pdev_ext->ehci->ehci_caps.hcs_params ) )->length;
-
- ehci_get_capabilities(pdev_ext->ehci, pdev_ext->ehci->port_base);
- i = pdev_ext->ehci->ehci_caps.length;
- pdev_ext->ehci->port_base += i;
-
- if (ehci_init_schedule(pdev_ext->ehci, pdev_ext->padapter) == FALSE)
- {
- release_adapter(pdev_ext->padapter);
- pdev_ext->padapter = NULL;
- ehci_delete_device(pdev, dev_mgr);
- return NULL;
- }
-
- InitializeListHead(&pdev_ext->ehci->urb_list);
- KeInitializeSpinLock(&pdev_ext->ehci->pending_endp_list_lock);
- InitializeListHead(&pdev_ext->ehci->pending_endp_list);
-
- ehci_dbg_print(DBGLVL_MAXIMUM, ("ehci_alloc(): pending_endp_list=0x%x\n",
- &pdev_ext->ehci->pending_endp_list));
-
- init_pending_endp_pool(&pdev_ext->ehci->pending_endp_pool);
-
- KeInitializeTimer(&pdev_ext->ehci->reset_timer);
-
- vector = HalGetInterruptVector(PCIBus,
- bus,
- pdev_ext->res_interrupt.level,
- pdev_ext->res_interrupt.vector, &irql, &affinity);
-
- KeInitializeDpc(&pdev_ext->ehci_dpc, ehci_dpc_callback, (PVOID) pdev_ext->ehci);
-
- //connect the interrupt
- DbgPrint("ehci_alloc(): the int=0x%x\n", vector);
- if (IoConnectInterrupt(&pdev_ext->ehci_int, ehci_isr, pdev_ext->ehci, NULL, //&pdev_ext->ehci->frame_list_lock,
- vector, irql, irql, LevelSensitive, TRUE, //share the vector
- affinity, FALSE) //No float save
- != STATUS_SUCCESS)
- {
- ehci_release(pdev, dev_mgr);
- return NULL;
- }
-
- return pdev;
-}
-
-PDEVICE_OBJECT
-ehci_create_device(PDRIVER_OBJECT drvr_obj, PUSB_DEV_MANAGER dev_mgr)
-{
- NTSTATUS status;
- PDEVICE_OBJECT pdev;
- PEHCI_DEVICE_EXTENSION pdev_ext;
-
- UNICODE_STRING dev_name;
- UNICODE_STRING symb_name;
-
- STRING string, another_string;
- CHAR str_dev_name[64], str_symb_name[64];
- UCHAR hcd_id;
-
- if (drvr_obj == NULL)
- return NULL;
-
- //note: hcd count wont increment till the hcd is registered in dev_mgr
- sprintf(str_dev_name, "%s%d", EHCI_DEVICE_NAME, dev_mgr->hcd_count);
- sprintf(str_symb_name, "%s%d", EHCI_DOS_DEVICE_NAME, dev_mgr->hcd_count);
-
- RtlInitString(&string, str_dev_name);
- RtlAnsiStringToUnicodeString(&dev_name, &string, TRUE);
-
- pdev = NULL;
- status = IoCreateDevice(drvr_obj,
- sizeof(EHCI_DEVICE_EXTENSION) + sizeof(EHCI_DEV),
- &dev_name, FILE_EHCI_DEV_TYPE, 0, FALSE, &pdev);
-
- if (status != STATUS_SUCCESS || pdev == NULL)
- {
- RtlFreeUnicodeString(&dev_name);
- ehci_dbg_print(DBGLVL_MAXIMUM, ("ehci_create_device(): error create device 0x%x\n", status));
- return NULL;
- }
-
- pdev_ext = pdev->DeviceExtension;
- RtlZeroMemory(pdev_ext, sizeof(EHCI_DEVICE_EXTENSION) + sizeof(EHCI_DEV));
-
- pdev_ext->dev_ext_hdr.type = NTDEV_TYPE_HCD;
- pdev_ext->dev_ext_hdr.dispatch = ehci_dispatch_irp;
- pdev_ext->dev_ext_hdr.start_io = NULL; //we do not support startio
- pdev_ext->dev_ext_hdr.dev_mgr = dev_mgr;
-
- pdev_ext->pdev_obj = pdev;
- pdev_ext->pdrvr_obj = drvr_obj;
-
- pdev_ext->ehci = (PEHCI_DEV) & (pdev_ext[1]);
-
- RtlInitString(&another_string, str_symb_name);
- RtlAnsiStringToUnicodeString(&symb_name, &another_string, TRUE);
- //RtlInitUnicodeString( &symb_name, DOS_DEVICE_NAME );
-
- IoCreateSymbolicLink(&symb_name, &dev_name);
-
- ehci_dbg_print(DBGLVL_MAXIMUM,
- ("ehci_create_device(): dev=0x%x\n, pdev_ext= 0x%x, ehci=0x%x, dev_mgr=0x%x\n", pdev,
- pdev_ext, pdev_ext->ehci, dev_mgr));
-
- RtlFreeUnicodeString(&dev_name);
- RtlFreeUnicodeString(&symb_name);
-
- //register with dev_mgr though it is not initilized
- ehci_init_hcd_interface(pdev_ext->ehci);
- hcd_id = dev_mgr_register_hcd(dev_mgr, &pdev_ext->ehci->hcd_interf);
-
- pdev_ext->ehci->hcd_interf.hcd_set_id(&pdev_ext->ehci->hcd_interf, hcd_id);
- pdev_ext->ehci->hcd_interf.hcd_set_dev_mgr(&pdev_ext->ehci->hcd_interf, dev_mgr);
-
- return pdev;
-
-}
-
-VOID
-ehci_init_hcd_interface(PEHCI_DEV ehci)
-{
- ehci->hcd_interf.hcd_set_dev_mgr = ehci_set_dev_mgr;
- ehci->hcd_interf.hcd_get_dev_mgr = ehci_get_dev_mgr;
- ehci->hcd_interf.hcd_get_type = ehci_get_type;
- ehci->hcd_interf.hcd_set_id = ehci_set_id;
- ehci->hcd_interf.hcd_get_id = ehci_get_id;
- ehci->hcd_interf.hcd_alloc_addr = ehci_alloc_addr;
- ehci->hcd_interf.hcd_free_addr = ehci_free_addr;
- ehci->hcd_interf.hcd_submit_urb = ehci_submit_urb2;
- ehci->hcd_interf.hcd_generic_urb_completion = ehci_generic_urb_completion;
- ehci->hcd_interf.hcd_get_root_hub = ehci_get_root_hub;
- ehci->hcd_interf.hcd_set_root_hub = ehci_set_root_hub;
- ehci->hcd_interf.hcd_remove_device = ehci_remove_device2;
- ehci->hcd_interf.hcd_rh_reset_port = ehci_rh_reset_port;
- ehci->hcd_interf.hcd_release = ehci_hcd_release;
- ehci->hcd_interf.hcd_cancel_urb = ehci_cancel_urb2;
- ehci->hcd_interf.hcd_start = ehci_start;
- ehci->hcd_interf.hcd_dispatch = ehci_hcd_dispatch;
-
- ehci->hcd_interf.flags = HCD_TYPE_EHCI; //hcd types | hcd id
-}
-
-BOOLEAN
-ehci_init_schedule(PEHCI_DEV ehci, PADAPTER_OBJECT padapter)
-{
- PEHCI_DEVICE_EXTENSION pdev_ext;
- BOOLEAN ret = TRUE;
- LONG i;
- PEHCI_QH_CONTENT pqh_content;
- PEHCI_QH pqh;
- PEHCI_ELEM_LINKS pelnk;
-
- if (ehci == NULL)
- return FALSE;
-
- pdev_ext = ehci->pdev_ext;
- if (pdev_ext == NULL)
- return FALSE;
-
- // padapter = pdev_ext->padapter;
- if (ehci->frame_count == 0)
- ehci->frame_count = EHCI_DEFAULT_FRAMES;
-
- // allocate pools
- for(i = 0; i < 5; i++)
- {
- ret = elem_pool_init_pool(&ehci->elem_pools[i], i, padapter);
- if (ret == FALSE)
- break;
- }
-
- if (ret == FALSE)
- {
- i--;
- for(; i >= 0; i--)
- elem_pool_destroy_pool(&ehci->elem_pools[i]);
- return FALSE;
- }
-
- // allocate periodic frame list
- ehci->frame_list =
- HalAllocateCommonBuffer(padapter,
- sizeof(ULONG) * ehci->frame_count, &ehci->frame_list_phys_addr, FALSE);
- if (ehci->frame_list == NULL)
- goto ERROR_OUT;
-
- RtlZeroMemory(ehci->frame_list, sizeof(ULONG) * ehci->frame_count);
- ehci->frame_list_cpu = usb_alloc_mem(NonPagedPool, sizeof(LIST_HEAD) * ehci->frame_count);
-
- if (ehci->frame_list_cpu == NULL)
- goto ERROR_OUT;
-
- for(i = 0; i < (LONG) ehci->frame_count; i++)
- {
- InitializeListHead(&ehci->frame_list_cpu[i].td_link);
- }
-
- for(i = 0; i < 8; i++)
- {
- InitializeListHead(&ehci->periodic_list_cpu[i]);
- }
-
- InitializeListHead(&ehci->async_list_cpu);
-
- // init frame band budget array
- ehci->frame_bw = usb_alloc_mem(NonPagedPool, sizeof(USHORT) * ehci->frame_count * 8);
- if (ehci->frame_bw == NULL)
- goto ERROR_OUT;
-
- for(i = 0; i < (LONG) ehci->frame_count * 8; i++)
- {
- ehci->frame_bw[i] = EHCI_MAX_SYNC_BUS_TIME;
- }
- ehci->min_bw = EHCI_MAX_SYNC_BUS_TIME;
-
- // chain the 1ms interrupt qh to the schedule
- if ((pelnk = elem_pool_alloc_elem(&ehci->elem_pools[EHCI_QH_POOL_IDX])) == NULL)
- goto ERROR_OUT;
-
- pqh_content = (PEHCI_QH_CONTENT) ((ULONG) pelnk->phys_part & PHYS_PART_ADDR_MASK);
- ehci_init_int8_qh(pqh_content);
-
- // chain qh to the shadow list
- InsertTailList(&ehci->periodic_list_cpu[EHCI_SCHED_INT8_INDEX], &pelnk->sched_link);
-
- // chain it to the periodic schedule, we use it as a docking point
- // for req of 8- uframes request
- pqh = (PEHCI_QH) pqh_content;
-
- for(i = 0; i < (LONG) ehci->frame_count; i++)
- {
- ehci->frame_list[i] = pqh->phys_addr;
- }
-
- // allocate fstn
- /*if( ( pelnk = elem_pool_alloc_elem( &ehci->elem_pools[ EHCI_FSTN_POOL_IDX ] ) ) == NULL )
- goto ERROR_OUT;
-
- pfstn = ( PEHCI_FSTN )( ( ULONG )pelnk->phys_part & PHYS_PART_ADDR_MASK );
- pfstn->hw_next = EHCI_PTR_TERM;
- pfstn->hw_prev = EHCI_PTR_TERM | ( INIT_LIST_FLAG_QH << 1 );
- InsertTailList( &ehci->periodic_list_cpu[ EHCI_SCHED_FSTN_INDEX ], &pelnk->sched_link );
- pqh->hw_next = pfstn->phys_addr; */
-
- // allocate for async list head
- if ((pelnk = elem_pool_alloc_elem(&ehci->elem_pools[EHCI_QH_POOL_IDX])) == NULL)
- goto ERROR_OUT;
-
- // init the async list head
- pqh = (PEHCI_QH) ((ULONG) pelnk->phys_part & PHYS_PART_ADDR_MASK);
- pqh_content = (PEHCI_QH_CONTENT) pqh;
- ehci_init_int8_qh(pqh_content);
- pqh->hw_next = pqh->phys_addr;
- pqh_content->s_mask = 0;
- pqh_content->is_async_head = 1;
- pqh_content->endp_addr = 0;
- ehci->skel_async_qh = pqh;
- InsertTailList(&ehci->async_list_cpu, &pqh->elem_head_link->sched_link);
- return TRUE;
-
- ERROR_OUT:
- ehci_destroy_schedule(ehci);
- return FALSE;
-}
-
-BOOLEAN
-ehci_destroy_schedule(PEHCI_DEV ehci)
-{
- LONG i;
- if (ehci == NULL)
- return FALSE;
-
- if (ehci->frame_bw)
- usb_free_mem(ehci->frame_bw);
- ehci->frame_bw = NULL;
-
- if (ehci->frame_list_cpu)
- usb_free_mem(ehci->frame_list_cpu);
- ehci->frame_list_cpu = NULL;
-
- if (ehci->frame_list)
- HalFreeCommonBuffer(ehci->pdev_ext->padapter,
- sizeof(ULONG) * ehci->frame_count,
- ehci->frame_list_phys_addr, ehci->frame_list, FALSE);
-
- ehci->frame_list = NULL;
- ehci->frame_list_phys_addr.LowPart = 0;
- ehci->frame_list_phys_addr.HighPart = 0;
-
- for(i = 0; i < 5; i++)
- elem_pool_destroy_pool(&ehci->elem_pools[i]);
-
- return TRUE;
-}
-
-VOID
-ehci_init_int8_qh(PEHCI_QH_CONTENT qh)
-{
- if (qh == NULL)
- return;
- // DWORD 0
- qh->terminal = EHCI_PTR_TERM;
- qh->ptr_type = 0;
- qh->reserved = 0;
- qh->next_link = 0;
-
- // DWORD 1
- qh->dev_addr = 126; // a fake addr
- qh->inactive = 0;
- qh->endp_addr = 1; // a fake endp
- qh->endp_spd = USB_SPEED_HIGH;
- qh->data_toggle = 0;
- qh->is_async_head = 0;
- qh->max_packet_size = 64;
- qh->is_ctrl_endp = 0;
- qh->reload_counter = 0;
-
- // DWORD 2
- qh->s_mask = 0x80; // we are interrupt qh
- qh->c_mask = 0;
- qh->hub_addr = 0;
- qh->port_idx = 0;
- qh->mult = 1;
-
- // DWORD 3
- qh->cur_qtd_ptr = 0; // a terminal
-
- // overlay
- // !active and !halted
- RtlZeroMemory(&qh->cur_qtd, get_elem_phys_part_size(INIT_LIST_FLAG_QTD));
- qh->cur_qtd.alt_terminal = 1; // don't use this
- qh->cur_qtd.terminal = 1;
- qh->cur_qtd.status = QTD_STS_HALT;
-}
-
-VOID
-ehci_get_capabilities(PEHCI_DEV ehci, PBYTE base)
-// fetch capabilities register from ehci
-{
- PEHCI_CAPS pcap;
- PEHCI_HCS_CONTENT phcs;
- LONG i;
-
- if (ehci == NULL)
- return;
-
- pcap = &ehci->ehci_caps;
- pcap->length = EHCI_READ_PORT_UCHAR((PUCHAR) (base + 0));
- pcap->reserved = EHCI_READ_PORT_UCHAR((PUCHAR) (base + 1));
- pcap->hci_version = EHCI_READ_PORT_USHORT((PUSHORT) (base + 2));
- pcap->hcs_params = EHCI_READ_PORT_ULONG((PULONG) (base + 4));
- pcap->hcc_params = EHCI_READ_PORT_ULONG((PULONG) (base + 8));
-
- phcs = (PEHCI_HCS_CONTENT) & pcap->hcs_params;
- if (phcs->port_rout_rules)
- {
- for(i = 0; i < 8; i++)
- pcap->portroute[i] = EHCI_READ_PORT_UCHAR((PUCHAR) (base + 12 + i));
- }
- return;
-}
-
-BOOLEAN
-ehci_delete_device(PDEVICE_OBJECT pdev, PUSB_DEV_MANAGER dev_mgr)
-{
- STRING string;
- UNICODE_STRING symb_name;
- CHAR str_symb_name[64];
- PEHCI_DEVICE_EXTENSION pdev_ext;
-
- if (pdev == NULL)
- return FALSE;
-
- pdev_ext = pdev->DeviceExtension;
-
- sprintf(str_symb_name,
- "%s%d", EHCI_DOS_DEVICE_NAME, pdev_ext->ehci->hcd_interf.hcd_get_id(&pdev_ext->ehci->hcd_interf));
-
- RtlInitString(&string, str_symb_name);
- RtlAnsiStringToUnicodeString(&symb_name, &string, TRUE);
- IoDeleteSymbolicLink(&symb_name);
- RtlFreeUnicodeString(&symb_name);
-
- dev_mgr_deregister_hcd(dev_mgr, pdev_ext->ehci->hcd_interf.hcd_get_id(&pdev_ext->ehci->hcd_interf));
-
- if (pdev_ext->res_list)
- ExFreePool(pdev_ext->res_list); // not allocated by usb_alloc_mem
-
- IoDeleteDevice(pdev);
- ehci_dbg_print(DBGLVL_MAXIMUM, ("ehci_delete_device(): device deleted\n"));
- return TRUE;
-}
-
-VOID
-ehci_stop(PEHCI_DEV ehci)
-{
- PBYTE base;
- PEHCI_USBCMD_CONTENT usbcmd;
- LONG tmp;
-
- base = ehci->port_base;
- // turn off all the interrupt
- EHCI_WRITE_PORT_ULONG((PULONG) (base + EHCI_USBINTR), 0);
- tmp = EHCI_READ_PORT_ULONG((PULONG) (base + EHCI_USBCMD));
- usbcmd = (PEHCI_USBCMD_CONTENT) & tmp;
- usbcmd->run_stop = 0;
- EHCI_WRITE_PORT_ULONG((PULONG) (base + EHCI_USBCMD), tmp);
-}
-
-BOOLEAN
-ehci_release(PDEVICE_OBJECT pdev, PUSB_DEV_MANAGER dev_mgr)
-{
- PEHCI_DEVICE_EXTENSION pdev_ext;
- PEHCI_DEV ehci;
-
- if (pdev == NULL)
- return FALSE;
-
- pdev_ext = pdev->DeviceExtension;
-
- if (pdev_ext == NULL)
- return FALSE;
-
- ehci = pdev_ext->ehci;
- if (ehci == NULL)
- return FALSE;
-
- ehci_stop(ehci);
-
- if (pdev_ext->ehci_int)
- {
- IoDisconnectInterrupt(pdev_ext->ehci_int);
- pdev_ext->ehci_int = NULL;
- }
- else
- TRAP();
- destroy_pending_endp_pool(&pdev_ext->ehci->pending_endp_pool);
-
- ehci_destroy_schedule(ehci);
-
- release_adapter(pdev_ext->padapter);
- pdev_ext->padapter = NULL;
-
- ehci_delete_device(pdev, dev_mgr);
-
- return FALSE;
-
-}
-
-BOOLEAN
-ehci_start(PHCD hcd)
-{
- ULONG tmp;
- PBYTE base;
- PEHCI_USBCMD_CONTENT usbcmd;
- PEHCI_DEV ehci;
-
- if (hcd == NULL)
- return FALSE;
-
- ehci = struct_ptr(hcd, EHCI_DEV, hcd_interf);
- base = ehci->port_base;
-
- // stop the controller
- tmp = EHCI_READ_PORT_ULONG((PULONG) (base + EHCI_USBCMD));
- usbcmd = (PEHCI_USBCMD_CONTENT) & tmp;
- usbcmd->run_stop = 0;
- EHCI_WRITE_PORT_ULONG((PULONG) (base + EHCI_USBCMD), tmp);
-
- // wait the controller stop( ehci spec, 16 microframe )
- usb_wait_ms_dpc(2);
-
- // reset the controller
- usbcmd = (PEHCI_USBCMD_CONTENT) & tmp;
- usbcmd->hcreset = TRUE;
- EHCI_WRITE_PORT_ULONG((PULONG) (base + EHCI_USBCMD), tmp);
-
- for(;;)
- {
- // interval.QuadPart = -100 * 10000; // 10 ms
- // KeDelayExecutionThread( KernelMode, FALSE, &interval );
- KeStallExecutionProcessor(10);
- tmp = EHCI_READ_PORT_ULONG((PULONG) (base + EHCI_USBCMD));
- if (!usbcmd->hcreset)
- break;
- }
-
- // prepare the registers
- EHCI_WRITE_PORT_ULONG((PULONG) (base + EHCI_CTRLDSSEGMENT), 0);
-
- // turn on all the int
- EHCI_WRITE_PORT_ULONG((PULONG) (base + EHCI_USBINTR),
- EHCI_USBINTR_INTE | EHCI_USBINTR_ERR | EHCI_USBINTR_ASYNC | EHCI_USBINTR_HSERR
- // EHCI_USBINTR_FLROVR | \ // it is noisy
- // EHCI_USBINTR_PC | // we detect it by polling
- );
- // write the list base reg
- EHCI_WRITE_PORT_ULONG((PULONG) (base + EHCI_PERIODICLISTBASE), ehci->frame_list_phys_addr.LowPart);
-
- EHCI_WRITE_PORT_ULONG((PULONG) (base + EHCI_ASYNCLISTBASE), ehci->skel_async_qh->phys_addr & ~(0x1f));
-
- usbcmd->int_threshold = 1;
- EHCI_WRITE_PORT_ULONG((PULONG) (base + EHCI_USBCMD), tmp);
-
- // let's rock
- usbcmd->run_stop = 1;
- EHCI_WRITE_PORT_ULONG((PULONG) (base + EHCI_USBCMD), tmp);
-
- // set the configuration flag
- EHCI_WRITE_PORT_ULONG((PULONG) (base + EHCI_CONFIGFLAG), 1);
-
- // enable the list traversaling
- usbcmd->async_enable = 1;
- usbcmd->periodic_enable = 1;
- EHCI_WRITE_PORT_ULONG((PULONG) (base + EHCI_USBCMD), tmp);
-
- return TRUE;
-}
-
-VOID
-ehci_run_stop(PEHCI_DEV ehci, BOOLEAN start)
-{
- PEHCI_USBCMD_CONTENT usbcmd;
- PEHCI_USBSTS_CONTENT usbsts;
- ULONG tmp;
- PBYTE base;
-
- if (ehci == NULL)
- return;
-
- base = ehci->port_base;
- usbcmd = (PEHCI_USBCMD_CONTENT) & tmp;
- usbsts = (PEHCI_USBSTS_CONTENT) & tmp;
-
- tmp = EHCI_READ_PORT_ULONG((PULONG) (base + EHCI_USBSTS));
- if (start && usbsts->hc_halted == 0)
- {
- TRAP();
- usb_dbg_print(DBGLVL_MEDIUM, ("ehci_run_stop(): WARNING: hc running, can not start again\n"));
- return;
- }
- tmp = EHCI_READ_PORT_ULONG((PULONG) (base + EHCI_USBCMD));
- usbcmd->run_stop = start ? 1 : 0;
- EHCI_WRITE_PORT_ULONG((PULONG) (base + EHCI_USBCMD), tmp);
- if (start)
- usb_wait_ms_dpc(2); //ehci spec 16 microframes
-}
-
-VOID
-ehci_find_min_bandwidth(PEHCI_DEV ehci)
-{
- LONG i;
- if (ehci == NULL)
- return;
-
- for(i = 0; i < (LONG) (ehci->frame_count << 3); i++)
- {
- ehci->min_bw = ehci->min_bw < ehci->frame_bw[i] ? ehci->min_bw : ehci->frame_bw[i];
- }
- return;
-}
-
-BOOLEAN
-ehci_claim_bw_for_int(PEHCI_DEV ehci, PURB purb, BOOLEAN release)
-// should have pending_endp_list_lock acquired, and purb->pipe prepared
-{
- PURB_HS_PIPE_CONTENT pipe_content;
- LONG i, j;
- ULONG interval, bus_time, ss_time, cs_time;
- BOOLEAN bw_avail;
- ULONG max_packet_size;
-
- if (ehci == NULL || purb == NULL)
- return FALSE;
-
- if (purb->pipe == 0)
- return FALSE;
-
- bw_avail = FALSE;
- pipe_content = (PURB_HS_PIPE_CONTENT) & purb->pipe;
- interval = REAL_INTERVAL;
- if (pipe_content->speed_high == 0)
- {
- // translate to high speed uframe count
- interval <<= 3;
- }
-
- if (interval > (ehci->frame_count << 3))
- interval = (ehci->frame_count << 3);
-
- max_packet_size = (1 << pipe_content->max_packet_size);
- if (pipe_content->speed_high)
- {
- // this is a high speed endp
-
- bus_time = usb_calc_bus_time(USB_SPEED_HIGH,
- (pipe_content->trans_dir) << 7,
- FALSE, min(purb->data_length, (LONG) max_packet_size));
-
- // multiple transactions per uframe
- if (purb->data_length > (LONG) max_packet_size)
- {
- bus_time *= (purb->data_length) / max_packet_size;
- bus_time += usb_calc_bus_time(USB_SPEED_HIGH,
- (pipe_content->trans_dir) << 7,
- FALSE, purb->data_length % max_packet_size);
- }
- bus_time = (bus_time + 1) >> 1;
-
- if (release)
- {
- for(i = pipe_content->start_uframe + (purb->int_start_frame << 3);
- i < (LONG) (ehci->frame_count << 3); i += interval)
- {
- ehci->frame_bw[i] += (USHORT) bus_time;
- }
- goto LBL_OUT;
- }
- if (bus_time < ehci->min_bw)
- {
- // start the poll from uframe zero of each frame
- bw_avail = TRUE;
- pipe_content->start_uframe = 0;
- for(i = 0; i < (LONG) (ehci->frame_count << 3); i += interval)
- {
- ehci->frame_bw[i] -= (USHORT) bus_time;
- if (ehci->frame_bw[i] < ehci->min_bw)
- ehci->min_bw = ehci->frame_bw[i];
- }
- }
- else // bother to find a pattern
- {
- for(j = 0; j < (LONG) interval; j++)
- {
- for(i = j; i < (LONG) (ehci->frame_count << 3); i += interval)
- {
- if (ehci->frame_bw[i] < bus_time)
- break;
- }
- if (i > (LONG) (ehci->frame_count << 3))
- {
- bw_avail = TRUE;
- break;
- }
- }
- if (bw_avail)
- {
- for(i = j; i < (LONG) (ehci->frame_count << 3); i += interval)
- {
- ehci->frame_bw[i] -= (USHORT) bus_time;
- if (ehci->frame_bw[i] < ehci->min_bw)
- ehci->min_bw = ehci->frame_bw[i];
- }
- pipe_content->start_uframe = j & 7;
- purb->int_start_frame = j >> 3;
- }
- }
- }
- else // full/low speed pipe
- {
- // split condition is considered
- if (pipe_content->trans_dir)
- {
- // an input interrupt, with handshake
- // 55 is 144 - 90 + 1, turnaround time is one byte not the worst case 90 bytes,
- // refer to ehci-1.0 table 4-5 p64
- ss_time = 231 * 25 / 12;
- // cs_time = ( 55 * 8 + ( LONG )( ( ( 19 + 7 * 8 * purb->data_length ) / 6 ) ) ) * 25 / 12;
- cs_time = (55 * 8 + (LONG) (((7 * 8 * purb->data_length) / 6))) * 25 / 12;
- }
- else
- {
- // according to ehci-1.0 table 4-5 p64
- ss_time = (49 * 8 + (LONG) (((7 * 8 * purb->data_length) / 6))) * 25 / 12;
- // 287 = 237 + 48( handshake ) + 8( turn around time )
- cs_time = 287 * 25 / 12;
- }
- ss_time >>= 1, cs_time >>= 1;
- if (release)
- {
- for(i = pipe_content->start_uframe + (purb->int_start_frame << 3);
- i < (LONG) (ehci->frame_count << 3); i += interval)
- {
- ehci->frame_bw[i] += (USHORT) ss_time;
- ehci->frame_bw[i + 2] += (USHORT) cs_time;
- ehci->frame_bw[i + 3] += (USHORT) cs_time;
- if ((i & 0x07) != 0x06)
- ehci->frame_bw[i + 4] += (USHORT) cs_time;
- }
- goto LBL_OUT;
- }
- if (ss_time < ehci->min_bw && cs_time < ehci->min_bw)
- {
- pipe_content->start_uframe = 0;
- bw_avail = TRUE;
- for(i = 0; i < (LONG) (ehci->frame_count << 3); i += interval)
- {
- ehci->frame_bw[i] -= (USHORT) ss_time;
- ehci->min_bw = min(ehci->frame_bw[i], ehci->min_bw);
- ehci->frame_bw[i + 2] -= (USHORT) cs_time;
- ehci->min_bw = min(ehci->frame_bw[i + 2], ehci->min_bw);
- ehci->frame_bw[i + 3] -= (USHORT) cs_time;
- ehci->min_bw = min(ehci->frame_bw[i + 3], ehci->min_bw);
- if ((i & 0x07) != 0x06)
- {
- ehci->frame_bw[i + 4] -= (USHORT) cs_time;
- ehci->min_bw = min(ehci->frame_bw[i + 4], ehci->min_bw);
- }
- }
- }
- else
- {
- for(j = 0; j < (LONG) interval; j++)
- {
- if ((j & 0x7) == 7) // start-split not allowed at this uframe
- continue;
-
- for(i = j; i < (LONG) (ehci->frame_count << 3); i += interval)
- {
- if (ehci->frame_bw[i] < ss_time)
- break;
- if (ehci->frame_bw[i + 2] < cs_time)
- break;
- if (ehci->frame_bw[i + 3] < cs_time)
- break;
- if ((i & 0x7) != 6)
- if (ehci->frame_bw[i + 4] < cs_time)
- break;
- }
- if (i > (LONG) (ehci->frame_count << 3))
- {
- bw_avail = TRUE;
- break;
- }
- }
-
- pipe_content->start_uframe = j & 7;
- purb->int_start_frame = j >> 3;
-
- for(i = j; i < (LONG) (ehci->frame_count << 3); i += interval)
- {
- ehci->frame_bw[i] -= (USHORT) ss_time;
- ehci->min_bw = min(ehci->frame_bw[i], ehci->min_bw);
- ehci->frame_bw[i + 2] -= (USHORT) cs_time;
- ehci->min_bw = min(ehci->frame_bw[i + 2], ehci->min_bw);
- ehci->frame_bw[i + 3] -= (USHORT) cs_time;
- ehci->min_bw = min(ehci->frame_bw[i + 3], ehci->min_bw);
- if ((i & 0x7) != 6)
- {
- ehci->frame_bw[i + 4] -= (USHORT) cs_time;
- ehci->min_bw = min(ehci->frame_bw[i + 4], ehci->min_bw);
- }
- }
- }
- }
-
- LBL_OUT:
- if (!release)
- return bw_avail;
- else
- {
- ehci_find_min_bandwidth(ehci);
- return TRUE;
- }
-}
-
-LONG
-ehci_get_cache_policy(PEHCI_DEV ehci)
-{
- PEHCI_HCC_CONTENT hcc_content;
-
- hcc_content = (PEHCI_HCC_CONTENT) & ehci->ehci_caps;
- if (hcc_content->iso_sched_threshold >= 8)
- return 16;
- if (hcc_content->iso_sched_threshold == 0)
- return 2;
- return hcc_content->iso_sched_threshold + 2;
-}
-
-// 25/12 is bus-time per bit ( 1000 / 480 )
-#define BEST_BUDGET_TIME_UFRAME ( ( 188 * 7 / 6 ) * 25 / 12 )
-
-// in: 231 is sum of split token + host ipg + token, 8 is bus turn-around time, 67 is full speed data token in DATA packet
-// out: 49 byte is sum of split token+ host ipg + token + host ipg + data packet
-#define iso_max_data_load( dir ) ( dir == USB_DIR_IN ? \
- ( ( 188 * 8 - 231 - 8 - 67 + ( 8 - 1 ) ) / 8 ) : ( 188 - 49 ) )
-
-#define iso_uframes_data_load( dir, data_load, uf_cnt )
-
-BOOLEAN
-ehci_claim_bw_for_iso(PEHCI_DEV ehci, PURB purb, BOOLEAN release)
-{
- PURB_HS_PIPE_CONTENT pipe_content;
- LONG i, j, k;
- ULONG interval, bus_time, ss_time, cs_time, remainder;
- BOOLEAN bw_avail;
- ULONG cur_uframe, start_uframe = 0, max_time, max_packet_size;
- PBYTE base;
- if (ehci == NULL || purb == NULL)
- return FALSE;
-
- pipe_content = (PURB_HS_PIPE_CONTENT) & purb->pipe;
- base = ehci->port_base;
- cur_uframe = EHCI_READ_PORT_ULONG((PULONG) (base + EHCI_FRINDEX)) + 1;
- bw_avail = FALSE;
-
- max_packet_size = purb->params[0]; //( 1 << pipe_content->max_packet_size );
-
- if (pipe_content->speed_high)
- {
- interval = REAL_INTERVAL;
- if (purb->iso_frame_count == 0 || purb->iso_frame_count + 2 * 8 > (LONG) (ehci->frame_count << 3))
- return FALSE;
-
- for(i = 0, max_time = 0; i < (LONG) purb->iso_frame_count; i++)
- {
- bus_time = usb_calc_bus_time(USB_SPEED_HIGH,
- (pipe_content->trans_dir) << 7,
- TRUE, min(purb->iso_packet_desc[i].length, (LONG) max_packet_size));
- // NOTE: we did not use endp_mult_count here, because the comparison is enough
- // to calculate the bandwidth
- if (purb->iso_packet_desc[i].length > (LONG) max_packet_size)
- {
- // multiple transactions per uframe
- bus_time *= purb->iso_packet_desc[i].length / max_packet_size;
- bus_time += usb_calc_bus_time(USB_SPEED_HIGH,
- (pipe_content->trans_dir) << 7,
- TRUE, purb->iso_packet_desc[i].length % max_packet_size);
- }
- bus_time = (bus_time + 1) >> 1;
- max_time = max(bus_time, max_time);
- purb->iso_packet_desc[i].bus_time = bus_time;
- }
-
- if (release)
- {
- // it is a release operation
- for(i = purb->iso_start_frame, k = 0; k < (LONG) purb->iso_frame_count;
- k++, i = (i + interval) % (ehci->frame_count << 3))
- {
- ehci->frame_bw[i] += (USHORT) purb->iso_packet_desc[k].bus_time;
- }
- ehci_find_min_bandwidth(ehci);
- return TRUE;
- }
-
- if (max_time < ehci->min_bw)
- {
- start_uframe = cur_uframe + ehci_get_cache_policy(ehci); // avoid cache
- for(i = start_uframe, j = 0; j < (LONG) purb->iso_frame_count;
- i = (i + interval) % (ehci->frame_count << 3), j++)
- {
- ehci->frame_bw[i] -= (USHORT) purb->iso_packet_desc[j].bus_time;
- ehci->min_bw = min(ehci->frame_bw[j], ehci->min_bw);
- }
- purb->iso_start_frame = start_uframe;
- return TRUE;
- }
- else // max_time >= ehci->min_bw
- {
- for(j = 0; j < (LONG) interval; j++)
- {
- start_uframe = cur_uframe + ehci_get_cache_policy(ehci) + j;
- for(i = start_uframe, k = 0; k < (LONG) purb->iso_frame_count;
- k++, i = (i + interval) % (ehci->frame_count << 3))
- {
- if (ehci->frame_bw[i] < (USHORT) purb->iso_packet_desc[k].bus_time)
- {
- break;
- }
- }
-
- if (k < (LONG) purb->iso_frame_count)
- continue;
- bw_avail = TRUE;
- break;
- }
- if (bw_avail)
- {
- // allocate the bandwidth
- for(i = start_uframe, k = 0; k < (LONG) purb->iso_frame_count;
- k++, i = (i + interval) % (ehci->frame_count << 3))
- {
- ehci->frame_bw[i] -= (USHORT) purb->iso_packet_desc[k].bus_time;
- ehci->min_bw = min(ehci->min_bw, ehci->frame_bw[i]);
- }
- purb->iso_start_frame = start_uframe;
- }
- }
- }
- else // not high speed endpoint
- {
- // split transfer
- if (purb->iso_frame_count == 0 || purb->iso_frame_count + 2 > (LONG) ehci->frame_count)
- return FALSE;
-
- if (max_packet_size > 1023)
- return FALSE;
-
- remainder = 0;
-
- //
- // calculate for each frame
- // in: 231 is sum of split token + host ipg + token, 8 is bus turn-around time, 67 is full speed data token in DATA packet
- // out: 49 byte is sum of split token+ host ipg + token + host ipg + data packet
- // bit-stuffing is for high speed bus transfer
- //
-
- if (pipe_content->trans_dir)
- {
- // an input transfer, no handshake
- ss_time = 231 * 25 / 12;
- // cs_time = ( 231 + 8 + 67 + ( LONG )( ( ( 19 + 7 * 8 * 188 ) / 6 ) ) ) * 25 / 12;
- cs_time = (231 + 8 + 67 + (LONG) (((7 * 8 * 188) / 6))) * 25 / 12;
- }
- else
- {
- // an output transfer according to ehci-1.0 table 4-5 p64
- // ss_time = ( 49 * 8 + ( LONG )( ( ( 19 + 7 * 8 * 188 ) / 6 ) ) ) * 25 / 12;
- ss_time = (49 * 8 + (LONG) (((7 * 8 * 188) / 6))) * 25 / 12;
- cs_time = 0;
- for(i = 0; i < (LONG) purb->iso_frame_count; i++)
- {
- // remainder = ( 49 * 8 + ( LONG )( ( ( 19 + 7 * 8 * ( purb->iso_packet_desc[ i ].length % 188 ) ) / 6 ) ) ) * 25 / 12;
- remainder =
- (49 * 8 + (LONG) (((7 * 8 * (purb->iso_packet_desc[i].length % 188)) / 6))) * 25 / 12;
- remainder >>= 1;
- purb->iso_packet_desc[i].params.bus_time = (USHORT) remainder;
- }
- }
-
- ss_time >>= 1;
- cs_time >>= 1;
- cur_uframe = (cur_uframe + 7) & (~0x07);
-
- j = ehci->frame_count << 3;
- if (release)
- {
- if (pipe_content->trans_dir)
- {
- for(i = 0; i < (LONG) purb->iso_frame_count; i++)
- {
- ehci->frame_bw[purb->iso_packet_desc[i].params.start_uframe] += (USHORT) ss_time;
- for(k = 0; k < (purb->iso_packet_desc[i].length + 187) / 188; k++)
- {
- ehci->frame_bw[(cur_uframe + 0x12 + (i << 3) + k) % j] += (USHORT) cs_time;
- }
-
- // two extra complete-split
- ehci->frame_bw[(cur_uframe + 0x12 + (i << 3) + k) % j] += (USHORT) cs_time;
- ehci->frame_bw[(cur_uframe + 0x13 + (i << 3) + k) % j] += (USHORT) cs_time;
- }
- }
- else
- {
- for(i = 0; i < (LONG) purb->iso_frame_count; i++)
- {
- for(k = 0; k < (purb->iso_packet_desc[i].length + 187) / 188; k++)
- {
- ehci->frame_bw[(cur_uframe + 0x10 + (i << 3) + k) % j] += (USHORT) ss_time;
- }
- }
- }
- ehci_find_min_bandwidth(ehci);
- }
-
- // search for available bw
- if (ss_time < ehci->min_bw && cs_time < ehci->min_bw)
- {
- if (pipe_content->trans_dir)
- {
- for(i = 0; i < (LONG) purb->iso_frame_count; i++)
- {
- ehci->frame_bw[(cur_uframe + 0x10 + (i << 3)) % j] -= (USHORT) ss_time;
- ehci->min_bw = min(ehci->frame_bw[(cur_uframe + 0x10 + (i << 3)) % j], ehci->min_bw);
-
- for(k = 0; k < (purb->iso_packet_desc[i].length + 187) / 188; k++)
- {
- ehci->frame_bw[(cur_uframe + 0x12 + (i << 3) + k) % j] -= (USHORT) cs_time;
- ehci->min_bw =
- min(ehci->frame_bw[(cur_uframe + 0x12 + (i << 3) + k) % j], ehci->min_bw);
- }
-
- // two extra complete-split
- ehci->frame_bw[(cur_uframe + 0x12 + (i << 3) + k) % j] -= (USHORT) cs_time;
- ehci->min_bw = min(ehci->frame_bw[cur_uframe + 0x12 + (i << 3) + k], ehci->min_bw);
- ehci->frame_bw[(cur_uframe + 0x13 + (i << 3) + k) % j] -= (USHORT) cs_time;
- ehci->min_bw = min(ehci->frame_bw[cur_uframe + 0x13 + (i << 3) + k], ehci->min_bw);
- }
- }
- else // iso output
- {
- for(i = 0; i < (LONG) purb->iso_frame_count; i++)
- {
- for(k = 0; k < (purb->iso_packet_desc[i].length + 187) / 188; k++)
- {
- ehci->frame_bw[(cur_uframe + 0x10 + (i << 3) + k) % j] -= (USHORT) ss_time;
- ehci->min_bw =
- min(ehci->frame_bw[(cur_uframe + 0x11 + (i << 3) + k) % j], ehci->min_bw);
- }
- }
- }
- purb->iso_start_frame = 0;
- for(i = 0; i < (LONG) purb->iso_frame_count; i++)
- {
- if (i == 0)
- purb->iso_packet_desc[i].params.start_uframe = (USHORT) (cur_uframe + 0x10);
- else
- purb->iso_packet_desc[i].params.start_uframe =
- purb->iso_packet_desc[i - 1].params.start_uframe + 0x8;
- }
- bw_avail = TRUE;
- }
- else // take the pain to find one
- {
- BOOLEAN large;
- long temp, base;
-
- for(j = (cur_uframe >> 3) + 2; j != (LONG) (cur_uframe >> 3); j = (j + 1) % ehci->frame_count)
- {
- temp = 0;
-
- for(i = 0; i < (LONG) purb->iso_frame_count; i++)
- {
- large = purb->iso_packet_desc[i].length > 579;
- base = (purb->iso_packet_desc[i].length + 187) / 188;
-
- if (base > 6)
- return FALSE;
-
- if (pipe_content->trans_dir)
- {
- // input split iso, for those large than 579, schedule it at the uframe boundary
- for(temp = 0; temp < (large == FALSE) ? (8 - base - 1) : 1; temp++)
- {
- k = (((j + i) << 3) + temp) % (ehci->frame_count << 3);
- if (ehci->frame_bw[k] > ss_time)
- continue;
-
- k = base;
- while (k != 0)
- {
- if (ehci->
- frame_bw[(((j + i) << 3) + 1 + temp + k) % (ehci->frame_count << 3)] <
- cs_time)
- break;
- k--;
- }
- if (k > 0) // not available
- continue;
-
- // the first following extra cs
- k = (((j + i) << 3) + 2 + temp + base) % (ehci->frame_count << 3);
- if (ehci->frame_bw[k] < cs_time)
- continue;
-
- if (base < 6)
- {
- // very large one does not have this second extra cs
- if (ehci->frame_bw[(k + 1) % (ehci->frame_count << 3)] < cs_time)
- continue;
- }
- }
-
- if (temp == 8 - 1 - base) // no bandwidth for ss
- break;
- }
- else // output
- {
- // note: 8 - 1 - base has different meaning from the above
- // it is to avoid the ss on H-Frame 7, but the above one is
- // the latency of the classic bus.
- for(temp = 0; temp < 8 - 1 - base; temp++)
- {
- if (ehci->frame_bw[((j + i) << 3) % (ehci->frame_count << 3) + temp] > ss_time)
- continue;
-
- for(k = temp; k < temp + base; k++)
- {
- if (ehci->frame_bw[((j + i) << 3) % (ehci->frame_count << 3) + k] < ss_time)
- break;
- }
- }
-
- if (temp == 8 - 1 - base)
- break;
- }
-
- purb->iso_packet_desc[i].params.start_uframe =
- (USHORT) ((((j + i) << 3) + temp) % (ehci->frame_count << 3));
- // next frame
- }
- if (i < (LONG) purb->iso_frame_count)
- {
- // skip to the next section
- j = (j + i) % (ehci->frame_count << 3);
- continue;
- }
- bw_avail = TRUE;
- break;
- }
- // FIXME: Should we claim bw for the last complete split sitd? this is not done
- // yet.
- if (bw_avail)
- {
- if (pipe_content->trans_dir)
- {
- // input iso
- for(i = 0; i < (LONG) purb->iso_frame_count; i++)
- {
- j = purb->iso_packet_desc[i].length;
- temp = (purb->iso_packet_desc[i].params.start_uframe) % (ehci->frame_count << 3);
- ehci->frame_bw[temp] -= (USHORT) ss_time;
- for(k = 0; k < (j + 187) / 188; j++)
- {
- ehci->frame_bw[temp + 2 + k] -= (USHORT) cs_time;
- }
- ehci->frame_bw[temp + 2 + k] -= (USHORT) cs_time;
- if ((j + 187) / 188 < 6) //ehci restriction
- {
- ehci->frame_bw[temp + 3 + k] -= (USHORT) cs_time;
- }
- }
- }
- else //output iso
- {
- for(i = 0; i < (LONG) purb->iso_frame_count; i++)
- {
- j = purb->iso_packet_desc[i].length;
- temp = (purb->iso_packet_desc[i].params.start_uframe) % (ehci->frame_count << 3);
- for(k = 0; k < j / 188; j++)
- {
- ehci->frame_bw[temp + k] -= (USHORT) ss_time;
- }
- if (j % 188)
- ehci->frame_bw[temp + k] -= purb->iso_packet_desc[i].params.bus_time;
- }
- }
- }
- }
- }
- return bw_avail;
-}
-
-BOOLEAN
-ehci_claim_bandwidth(PEHCI_DEV ehci, PURB purb, BOOLEAN claim_bw) //true to claim band-width, false to free band-width
-// should have pending_endp_list_lock acquired, and purb->pipe prepared
-{
- PURB_HS_PIPE_CONTENT pipe_content;
- BOOLEAN ret;
-
- if (ehci == NULL || purb == NULL)
- return FALSE;
-
- ret = FALSE;
- pipe_content = (PURB_HS_PIPE_CONTENT) & purb->pipe;
- if (pipe_content->trans_type == USB_ENDPOINT_XFER_ISOC)
- {
- ret = ehci_claim_bw_for_iso(ehci, purb, claim_bw ? FALSE : TRUE);
- }
- else if (pipe_content->trans_type == USB_ENDPOINT_XFER_INT)
- {
- ret = ehci_claim_bw_for_int(ehci, purb, claim_bw ? FALSE : TRUE);
- }
- else
- TRAP();
- return ret;
-}
-
-BOOLEAN
-ehci_can_remove(PURB purb, BOOLEAN door_bell_rings, ULONG cur_frame)
-// test if the purb can be removed from the schedule, by current frame index and
-// purb states
-{
- PURB_HS_PIPE_CONTENT pipe_content;
- ULONG interval;
-
- pipe_content = (PURB_HS_PIPE_CONTENT) & purb->pipe;
- interval = REAL_INTERVAL;
-
- switch (purb->flags & URB_FLAG_STATE_MASK)
- {
- case URB_FLAG_STATE_PENDING:
- {
- // not impossible
- TRAP();
- break;
- }
- case URB_FLAG_STATE_IN_PROCESS:
- {
- break;
- }
- case URB_FLAG_STATE_DOORBELL:
- {
- if ((pipe_content->trans_type == USB_ENDPOINT_XFER_BULK ||
- pipe_content->trans_type == USB_ENDPOINT_XFER_CONTROL) && door_bell_rings == TRUE)
- {
- return TRUE;
- }
- else if ((pipe_content->trans_type == USB_ENDPOINT_XFER_BULK ||
- pipe_content->trans_type == USB_ENDPOINT_XFER_CONTROL))
- {
- break;
- }
- else
- {
- TRAP();
- break;
- }
- }
- case URB_FLAG_STATE_WAIT_FRAME:
- {
- // need more processing
- if ((purb->flags & URB_FLAG_FORCE_CANCEL) == 0)
- {
- TRAP();
- break;
- }
- if (pipe_content->trans_type == USB_ENDPOINT_XFER_INT)
- {
- return door_bell_rings;
- }
- else // isochronous can not be canceled
- {
- TRAP();
- break;
- }
- }
- }
- return FALSE;
-}
-
-NTSTATUS ehci_remove_urb_from_schedule(PEHCI_DEV ehci, PURB purb);
-
-static VOID
-ehci_deactivate_urb(PURB purb)
-{
- PURB_HS_PIPE_CONTENT pipe_content;
- PLIST_ENTRY pthis, pnext;
- PEHCI_QH_CONTENT pqh_content;
- PEHCI_QTD_CONTENT pqtd_content;
-
- if (purb == NULL)
- return;
-
- pipe_content = (PURB_HS_PIPE_CONTENT) & purb->pipe;
- switch (pipe_content->trans_type)
- {
- case USB_ENDPOINT_XFER_CONTROL:
- case USB_ENDPOINT_XFER_BULK:
- case USB_ENDPOINT_XFER_INT:
- {
- ListFirst(&purb->trasac_list, pthis);
- pqh_content = (PEHCI_QH_CONTENT) qh_from_list_entry(pthis);
- ListNext(&purb->trasac_list, pthis, pnext);
- do
- {
- pqtd_content = (PEHCI_QTD_CONTENT) qtd_from_list_entry(pthis);
- if (pqtd_content->status & QTD_STS_ACTIVE)
- {
- pqtd_content->status &= ~QTD_STS_ACTIVE;
- }
- ListNext(&purb->trasac_list, pthis, pnext);
- pthis = pnext;
-
- }
- while (pthis);
- break;
- }
- case USB_ENDPOINT_XFER_ISOC:
- {
- // fall through
- }
- default:
- TRAP();
- }
- return;
-}
-
-static VOID
-ehci_insert_bulk_schedule(PEHCI_DEV ehci, PURB purb)
-// list head is only a handle, the qh and qtd are following it.
-{
- PLIST_ENTRY list_head;
- PEHCI_QH pqh, pqhprev, pqhnext;
- PLIST_ENTRY pthis, pprev, pnext;
-
- if (ehci == NULL || purb == NULL)
- return;
-
- list_head = &purb->trasac_list;
- ListFirst(list_head, pthis);
- if (pthis == NULL)
- return;
-
- if (elem_type_list_entry(pthis) != INIT_LIST_FLAG_QH)
- return;
-
- pqh = qh_from_list_entry(pthis);
- // the last qh
- ListFirstPrev(&ehci->async_list_cpu, pprev);
- pqhprev = qh_from_schedule(pprev);
-
- // the first qh
- ListFirst(&ehci->async_list_cpu, pnext);
- pqhnext = qh_from_schedule(pnext);
-
- if (pprev == &ehci->async_list_cpu)
- {
- // always a qh in async list
- TRAP();
- return;
- }
- pqh->hw_next = pqhnext->phys_addr;
- InsertTailList(&ehci->async_list_cpu, &pqh->elem_head_link->sched_link);
- pqhprev->hw_next = pqh->phys_addr;
- return;
-}
-
-static VOID
-ehci_remove_bulk_from_schedule(PEHCI_DEV ehci, PURB purb)
-// executed in isr, and have frame_list_lock acquired, so
-// never try to acquire any spin-lock
-// remove the bulk purb from schedule, and mark it not in
-// the schedule
-{
- PLIST_ENTRY list_head;
- PEHCI_QH pqh, pqhprev, pqhnext;
- PEHCI_QH_CONTENT pqhc;
- PLIST_ENTRY pthis, pprev, pnext;
-
- if (ehci == NULL || purb == NULL)
- return;
-
- list_head = &purb->trasac_list;
- ListFirst(list_head, pthis);
- if (pthis == NULL)
- {
- TRAP();
- return;
- }
- pqh = qh_from_list_entry(pthis);
- pqhc = (PEHCI_QH_CONTENT) pqh;
-
- if (pqhc->is_async_head)
- TRAP();
-
- ListFirst(&pqh->elem_head_link->sched_link, pnext);
- ListFirstPrev(&pqh->elem_head_link->sched_link, pprev);
-
- if (pprev == &ehci->async_list_cpu)
- {
- // we will at least have a qh with H-bit 1 in the async-list
- TRAP();
- }
- else if (pnext == &ehci->async_list_cpu)
- {
- // remove the last one
- pqhprev = qh_from_schedule(pprev);
- ListFirst(&ehci->async_list_cpu, pnext);
- pqhnext = qh_from_schedule(pnext);
- pqhprev->hw_next = pqhnext->phys_addr;
- }
- else
- {
- pqhprev = qh_from_schedule(pprev);
- pqhnext = qh_from_schedule(pnext);
- pqhprev->hw_next = pqhnext->phys_addr;
- }
- RemoveEntryList(&pqh->elem_head_link->sched_link);
- return;
-}
-
-
-static VOID
-ehci_insert_fstn_schedule(PEHCI_DEV ehci, PURB purb)
-{
-
- PURB_HS_PIPE_CONTENT pipe_content, pc;
- PLIST_ENTRY pthis, list_head, pnext = NULL, pprev;
- PEHCI_QH pqhnext;
- PEHCI_FSTN pfstn;
- PURB purb1;
-
- ULONG interval, start_frame, start_uframe;
- LONG i;
-
- if (ehci == NULL || purb == NULL)
- return;
-
- pipe_content = (PURB_HS_PIPE_CONTENT) & purb->pipe;
- interval = (1 << (pipe_content->interval + 3));
- list_head = &purb->trasac_list;
- start_frame = purb->int_start_frame;
- start_uframe = (start_frame << 3) + 1; //( start_frame << 3 ) + pipe_content->start_uframe;
-
- if ((start_frame << 3) >= interval)
- TRAP();
-
- ListFirstPrev(list_head, pprev);
-
- if (elem_type_list_entry(pprev) != INIT_LIST_FLAG_FSTN)
- {
- TRAP();
- return;
- }
-
- pfstn = fstn_from_list_entry(pprev);
-
- if (interval == 8)
- {
- ListFirst(&ehci->periodic_list_cpu[EHCI_SCHED_INT8_INDEX], pthis);
-
- // skip the first one
- ListNext(&ehci->periodic_list_cpu[EHCI_SCHED_INT8_INDEX], pthis, pnext);
- pprev = pthis;
- pthis = pnext;
-
- while (pthis)
- {
- purb1 = qh_from_schedule(pthis)->elem_head_link->purb;
- pc = (PURB_HS_PIPE_CONTENT) & purb1->pipe;
- if (pc->speed_high)
- {
- TRAP();
- return;
- }
- if ((1 << (pc->interval + 3)) > (LONG) interval)
- {
- TRAP();
- continue;
- }
- else if ((1 << (pc->interval + 3) < (LONG) interval))
- {
- break;
- }
- else if (elem_type(pthis, FALSE) == INIT_LIST_FLAG_FSTN)
- {
- ListNext(&ehci->periodic_list_cpu[EHCI_SCHED_INT8_INDEX], pthis, pnext);
- pprev = pthis;
- pthis = pnext;
- }
- else if (pc->start_uframe <= 1)
- {
- ListNext(&ehci->periodic_list_cpu[EHCI_SCHED_INT8_INDEX], pthis, pnext);
- pprev = pthis;
- pthis = pnext;
- }
- break;
- }
- if (pprev == NULL)
- {
- TRAP();
- return;
- }
- if (pthis == NULL)
- {
- //the last one
- InsertTailList(&ehci->periodic_list_cpu[EHCI_SCHED_INT8_INDEX],
- &pfstn->elem_head_link->sched_link);
- }
- else
- {
- if (elem_type(pprev, FALSE) == INIT_LIST_FLAG_FSTN)
- {
- InsertHeadList(&fstn_from_schedule(pprev)->elem_head_link->sched_link,
- &pfstn->elem_head_link->sched_link);
- }
- else
- {
- InsertHeadList(&qh_from_schedule(pprev)->elem_head_link->sched_link,
- &pfstn->elem_head_link->sched_link);
- }
- }
- pfstn->hw_next = qh_from_schedule(pprev)->hw_next;
- qh_from_schedule(pprev)->hw_next = pfstn->phys_addr;
- }
- else
- {
- start_frame++;
- for(i = start_frame; i < (LONG) start_frame + 1; i += (interval >> 3))
- {
- list_head = &ehci->frame_list_cpu[i].td_link;
- ListFirst(list_head, pthis);
-
- pprev = list_head;
- while (pthis)
- {
- // skip itds and sitds
- if (elem_type(pthis, FALSE) == INIT_LIST_FLAG_ITD ||
- elem_type(pthis, FALSE) == INIT_LIST_FLAG_SITD)
- {
- ListNext(list_head, pthis, pnext);
- pprev = pthis;
- pthis = pnext;
- continue;
- }
- break;
- }
-
- while (pthis)
- {
- // find the insertion point
- ULONG u;
-
- pqhnext = qh_from_schedule(pthis);
- if (elem_type(pthis, FALSE) == INIT_LIST_FLAG_FSTN)
- purb1 = fstn_from_schedule(pthis)->elem_head_link->purb;
- else
- purb1 = pqhnext->elem_head_link->purb;
-
- if (purb1 == NULL)
- TRAP();
-
- pc = (PURB_HS_PIPE_CONTENT) & purb1->pipe;
- u = 1 << (pc->speed_high ? (1 << pc->interval) : (1 << (pc->interval + 3)));
-
- if (u > interval)
- {
- ListNext(list_head, pthis, pnext);
- pprev = pthis;
- pthis = pnext;
- continue;
- }
- else if (u == interval)
- {
- if (start_uframe >=
- (elem_type(pthis, FALSE) == INIT_LIST_FLAG_FSTN ?
- 1 : pc->start_uframe) + (purb1->int_start_frame << 3))
- {
- ListNext(list_head, pthis, pnext);
- pprev = pthis;
- pthis = pnext;
- continue;
- }
- else
- break;
- }
- else if (u < interval)
- {
- break;
- }
- }
-
- if (pprev == list_head)
- {
- // insert to the list head
- pnext = pfstn->elem_head_link->sched_link.Flink = list_head->Flink;
- list_head->Flink = &pfstn->elem_head_link->sched_link;
- pfstn->hw_next = ehci->frame_list[i]; // point to following node
- ehci->frame_list[i] = pfstn->phys_addr;
- }
- else
- {
- pnext = pfstn->elem_head_link->sched_link.Flink = pprev->Flink;
- pprev->Flink = &pfstn->elem_head_link->sched_link;
-
- // fstn can be handled correctly
- pfstn->hw_next = qh_from_schedule(pprev)->hw_next;
- qh_from_schedule(pprev)->hw_next = pfstn->phys_addr;
- }
- }
- // the pointer to next node of this fstn is alway same across the frame list.
- for(i = start_frame + (interval >> 3); i < (LONG) ehci->frame_count; i += (interval >> 3))
- {
- pprev = list_head = &ehci->frame_list_cpu[i].td_link;
- ListFirst(list_head, pthis);
-
- while (pthis)
- {
- if (pthis == pnext)
- {
- break;
- }
- pprev = pthis;
- ListNext(list_head, pthis, pthis);
- }
-
- pprev->Flink = &pfstn->elem_head_link->sched_link;
- if (pprev == list_head)
- ehci->frame_list[i] = pfstn->phys_addr;
- else
- qh_from_schedule(pprev)->hw_next = pfstn->phys_addr;
- }
- }
-}
-
-static VOID
-ehci_remove_fstn_from_schedule(PEHCI_DEV ehci, PURB purb)
-{
- PURB_HS_PIPE_CONTENT pipe_content;
- PLIST_ENTRY pthis, list_head, pnext, pprev;
- PEHCI_FSTN pfstn;
-
- ULONG interval, start_frame, start_uframe;
- LONG i;
-
- if (ehci == NULL || purb == NULL)
- return;
-
- pipe_content = (PURB_HS_PIPE_CONTENT) & purb->pipe;
- interval = (1 << (pipe_content->interval + 3));
- list_head = &purb->trasac_list;
- start_frame = purb->int_start_frame;
- start_uframe = 1;
-
- if ((start_frame << 3) >= interval)
- TRAP();
- start_frame++;
-
- ListFirstPrev(list_head, pprev);
- if (elem_type_list_entry(pprev) != INIT_LIST_FLAG_FSTN)
- {
- TRAP();
- return;
- }
-
- pfstn = fstn_from_list_entry(pprev);
- if (interval < 8)
- {
- TRAP();
- return;
- }
- if (interval == 8)
- {
- ListFirstPrev(&pfstn->elem_head_link->sched_link, pprev);
- qh_from_schedule(pprev)->hw_next = pfstn->hw_next;
- RemoveEntryList(&pfstn->elem_head_link->sched_link);
- }
- else
- {
- for(i = start_frame; i < (LONG) ehci->frame_count; i++)
- {
- ListFirst(&ehci->frame_list_cpu[i].td_link, pthis);
- if (pthis == NULL)
- {
- TRAP();
- return;
- }
- pprev = &ehci->frame_list_cpu[i].td_link;
- while (pthis && pthis != &pfstn->elem_head_link->sched_link)
- {
- pprev = pthis;
- ListNext(&ehci->frame_list_cpu[i].td_link, pthis, pnext);
- pthis = pnext;
- }
- if (pthis == NULL)
- {
- TRAP();
- return;
- }
- qh_from_schedule(pprev)->hw_next = pfstn->hw_next;
- pprev->Flink = pfstn->elem_head_link->sched_link.Flink;
- }
- }
- return;
-}
-
-static VOID
-ehci_insert_int_schedule(PEHCI_DEV ehci, PURB purb)
-{
- PURB_HS_PIPE_CONTENT pipe_content, pc;
- PLIST_ENTRY pthis, list_head, pnext = NULL, pprev;
- PEHCI_ELEM_LINKS elem_link;
- PEHCI_QH pqh, pqhprev, pqhnext;
- PURB purb1;
-
- ULONG interval, u, start_frame, start_uframe;
- LONG i;
- UCHAR need_fstn;
-
- if (ehci == NULL || purb == NULL)
- return;
-
- pipe_content = (PURB_HS_PIPE_CONTENT) & purb->pipe;
- interval = REAL_INTERVAL;
- start_uframe = (purb->int_start_frame << 3) + pipe_content->start_uframe;
- start_frame = purb->int_start_frame;
- need_fstn = FALSE;
- list_head = &purb->trasac_list;
-
- ListFirst(list_head, pthis);
- if (pthis == NULL)
- return;
-
- pqh = qh_from_list_entry(pthis);
-
- if (!pipe_content->speed_high)
- {
- interval = (interval << 3);
- ListFirstPrev(list_head, pprev);
- if (elem_type_list_entry(pprev) == INIT_LIST_FLAG_FSTN)
- need_fstn = TRUE;
- }
-
- if (interval < 16)
- {
- pqhprev = pqhnext = NULL;
- if (interval == 1)
- {
- list_head = &ehci->periodic_list_cpu[EHCI_SCHED_FSTN_INDEX];
- ListFirst(list_head, pthis);
- InsertTailList(list_head, &pqh->elem_head_link->sched_link);
- ListFirstPrev(&pqh->elem_head_link->sched_link, pprev);
- pqh->hw_next = EHCI_PTR_TERM;
- if (pprev == pthis)
- {
- fstn_from_schedule(pthis)->hw_next = pqh->phys_addr;
- }
- else
- {
- qh_from_schedule(pthis)->hw_next = pqh->phys_addr;
- }
- }
- else // interval == 2 or 4 or 8
- {
- list_head = &ehci->periodic_list_cpu[EHCI_SCHED_INT8_INDEX];
- ListFirst(list_head, pthis);
- pprev = NULL;
- while (pthis)
- {
- elem_link = struct_ptr(pthis, EHCI_ELEM_LINKS, sched_link);
- purb1 = elem_link->purb;
- pc = (PURB_HS_PIPE_CONTENT) purb1->pipe;
- u = (pc->speed_high ? (1 << pc->interval) : (1 << (pc->interval + 3)));
-
- if (interval < u)
- {
- ListFirstPrev(pthis, pprev);
- break;
- }
- else if (interval > u)
- {
- ListNext(list_head, pthis, pnext);
- pprev = pthis;
- pthis = pnext;
- continue;
- }
- // FIXME: is this right to fix fstn's start_uf 1???
- else if (start_uframe <=
- (elem_type(pthis, FALSE) == INIT_LIST_FLAG_FSTN ?
- 1 : pc->start_uframe) + (purb1->int_start_frame << 3))
- {
- ListNext(list_head, pthis, pnext);
- pprev = pthis;
- pthis = pnext;
- continue;
- }
- else // interval is equal, and start_uframe is greater
- {
- ListFirstPrev(pthis, pprev);
- break;
- }
- }
- if (pprev == NULL)
- {
- // at least one dummy qh is there
- TRAP();
- }
- else if (pnext == NULL)
- {
- // the last one in this chain, fstn can be handled correctly
- InsertTailList(list_head, &pqh->elem_head_link->sched_link);
- pqhprev = qh_from_schedule(pprev);
- pqh->hw_next = pqhprev->hw_next;
- pqhprev->hw_next = pqh->phys_addr;
- }
- else
- {
- pqhprev = qh_from_schedule(pprev);
- if (elem_type(pprev, FALSE) == INIT_LIST_FLAG_QH)
- {
- InsertHeadList(&pqhprev->elem_head_link->sched_link, &pqh->elem_head_link->sched_link);
- }
- else if (elem_type(pprev, FALSE) == INIT_LIST_FLAG_FSTN)
- {
- InsertHeadList(&fstn_from_schedule(pprev)->elem_head_link->sched_link,
- &pqh->elem_head_link->sched_link);
- }
- pqh->hw_next = pqhprev->hw_next;
- pqhprev->hw_next = pqh->phys_addr;
- }
- }
- }
- else // interval >= 16
- {
- if ((start_frame << 3) >= interval)
- TRAP();
-
- for(i = start_frame; i < (LONG) start_frame + 1; i += (interval >> 3))
- {
- list_head = &ehci->frame_list_cpu[i].td_link;
- ListFirst(list_head, pthis);
-
- pprev = list_head;
- while (pthis)
- {
- // skip itds and sitds
- if (elem_type(pthis, FALSE) == INIT_LIST_FLAG_ITD ||
- elem_type(pthis, FALSE) == INIT_LIST_FLAG_SITD)
- {
- ListNext(list_head, pthis, pnext);
- pprev = pthis;
- pthis = pnext;
- continue;
- }
- break;
- }
-
- while (pthis)
- {
- // find the insertion point
-
- pqhnext = qh_from_schedule(pthis);
- if (elem_type(pthis, FALSE) == INIT_LIST_FLAG_FSTN)
- purb1 = fstn_from_schedule(pthis)->elem_head_link->purb;
- else
- purb1 = pqhnext->elem_head_link->purb;
-
- if (purb1 == NULL)
- TRAP();
-
- pc = (PURB_HS_PIPE_CONTENT) & purb1->pipe;
- u = 1 << (pc->speed_high ? (1 << pc->interval) : (1 << (pc->interval + 3)));
-
- if (u > interval)
- {
- ListNext(list_head, pthis, pnext);
- pprev = pthis;
- pthis = pnext;
- continue;
- }
- else if (u == interval)
- {
- if (start_uframe >=
- (elem_type(pthis, FALSE) == INIT_LIST_FLAG_FSTN ?
- 1 : pc->start_uframe) + (purb1->int_start_frame << 3))
- {
- ListNext(list_head, pthis, pnext);
- pprev = pthis;
- pthis = pnext;
- continue;
- }
- else
- break;
- }
- else if (u < interval)
- {
- break;
- }
- }
- if (pprev == list_head)
- {
- // insert to the list head
- pnext = pqh->elem_head_link->sched_link.Flink = list_head->Flink;
- list_head->Flink = &pqh->elem_head_link->sched_link;
- pqh->hw_next = ehci->frame_list[i]; // point to following node
- ehci->frame_list[i] = pqh->phys_addr;
- }
- else
- {
- pnext = pqh->elem_head_link->sched_link.Flink = pprev->Flink;
- pprev->Flink = &pqh->elem_head_link->sched_link;
-
- // fstn can be handled correctly
- pqh->hw_next = qh_from_schedule(pprev)->hw_next;
- qh_from_schedule(pprev)->hw_next = pqh->phys_addr;
- }
- }
- for(i = start_frame + (interval >> 3); i < (LONG) ehci->frame_count; i += (interval >> 3))
- {
- pprev = list_head = &ehci->frame_list_cpu[i].td_link;
- ListFirst(list_head, pthis);
-
- while (pthis)
- {
- if (pthis == pnext)
- {
- break;
- }
- pprev = pthis;
- ListNext(list_head, pthis, pthis);
- }
-
- pprev->Flink = &pqh->elem_head_link->sched_link;
- if (pprev == list_head)
- ehci->frame_list[i] = pqh->phys_addr;
- else
- qh_from_schedule(pprev)->hw_next = pqh->phys_addr;
- }
- }
-
- if (need_fstn)
- ehci_insert_fstn_schedule(ehci, purb);
-
- return;
-}
-
-static VOID
-ehci_remove_int_from_schedule(PEHCI_DEV ehci, PURB purb)
-{
- PURB_HS_PIPE_CONTENT pipe_content;
- PLIST_ENTRY pthis, list_head, pnext, pprev, pcur;
- PEHCI_QH pqh, pqhprev;
-
- ULONG interval, start_frame, start_uframe;
- LONG i;
-
- if (ehci == NULL || purb == NULL)
- return;
-
- pipe_content = (PURB_HS_PIPE_CONTENT) & purb->pipe;
- interval = REAL_INTERVAL;
- start_uframe = (purb->int_start_frame << 3) + pipe_content->start_uframe;
- start_frame = purb->int_start_frame;
-
- ListFirst(&purb->trasac_list, pthis);
- if (pthis == NULL)
- return;
-
- pqh = qh_from_list_entry(pthis);
- list_head = &purb->trasac_list;
-
- if (IsListEmpty(list_head))
- {
- TRAP();
- return;
- }
-
- if (!pipe_content->speed_high)
- {
- interval = (interval << 3);
- }
-
- if (interval >= 256 * 8)
- return;
-
- if (interval < 16)
- {
- ListFirstPrev(&pqh->elem_head_link->sched_link, pprev);
- RemoveEntryList(&pqh->elem_head_link->sched_link);
- if (interval > 1)
- {
- pqhprev = qh_from_schedule(pprev);
- pqhprev->hw_next = pqh->hw_next;
- }
- else
- {
- ListFirst(&ehci->frame_list_cpu[EHCI_SCHED_FSTN_INDEX].td_link, list_head);
- if (elem_type(pprev, FALSE) == INIT_LIST_FLAG_FSTN)
- {
- fstn_from_schedule(list_head)->hw_next = pqh->hw_next;
- }
- else
- {
- qh_from_schedule(pprev)->hw_next = pqh->hw_next;
- }
- }
- }
- else if (interval >= 16)
- {
- ListFirst(list_head, pthis);
- pthis = &pqh->elem_head_link->sched_link;
-
- for(i = start_uframe; i < (LONG) (ehci->frame_count << 3); i += interval)
- {
- ListFirst(&ehci->frame_list_cpu[i].td_link, pcur);
- pprev = NULL;
- while (pthis != pcur && pcur)
- {
- ListNext(&ehci->frame_list_cpu[i].td_link, pcur, pnext);
- pprev = pcur;
- pcur = pnext;
- }
-
- if (pcur == NULL)
- {
- TRAP();
- continue;
- }
- else if (pprev == NULL)
- {
- // the first one in the frame list
- ehci->frame_list_cpu[i].td_link.Flink = pthis->Flink;
- ehci->frame_list[i] = qh_from_schedule(pthis)->hw_next;
- }
- else
- {
- if (elem_type(pprev, FALSE) == INIT_LIST_FLAG_QH)
- {
- qh_from_schedule(pprev)->elem_head_link->sched_link.Flink =
- pqh->elem_head_link->sched_link.Flink;
- qh_from_schedule(pprev)->hw_next = pqh->hw_next;
- }
- else if (elem_type(pprev, FALSE) == INIT_LIST_FLAG_ITD)
- {
- itd_from_schedule(pprev)->elem_head_link->sched_link.Flink =
- pqh->elem_head_link->sched_link.Flink;
- itd_from_schedule(pprev)->hw_next = pqh->hw_next;
- }
- else if (elem_type(pprev, FALSE) == INIT_LIST_FLAG_SITD)
- {
- sitd_from_schedule(pprev)->elem_head_link->sched_link.Flink =
- pqh->elem_head_link->sched_link.Flink;
- sitd_from_schedule(pprev)->hw_next = pqh->hw_next;
- }
- else if (elem_type(pprev, FALSE) == INIT_LIST_FLAG_FSTN)
- {
- fstn_from_schedule(pprev)->elem_head_link->sched_link.Flink =
- pqh->elem_head_link->sched_link.Flink;
- fstn_from_schedule(pprev)->hw_next = pqh->hw_next;
- }
- else
- TRAP();
- }
- }
- }
-
- ListFirstPrev(&purb->trasac_list, pprev);
- if (elem_type_list_entry(pprev) == INIT_LIST_FLAG_FSTN)
- ehci_remove_fstn_from_schedule(ehci, purb);
- return;
-}
-
-static VOID
-ehci_insert_iso_schedule(PEHCI_DEV ehci, PURB purb)
-{
- PURB_HS_PIPE_CONTENT pipe_content;
- PLIST_ENTRY pthis, list_head, pnext;
-
- ULONG interval, start_frame;
- LONG i;
-
- if (ehci == NULL || purb == NULL)
- return;
-
- pipe_content = (PURB_HS_PIPE_CONTENT) & purb->pipe;
-
- interval = 8;
- if (pipe_content->speed_high)
- interval = REAL_INTERVAL;
-
- start_frame = purb->iso_start_frame;
-
- ListFirst(&purb->trasac_list, pthis);
- if (pthis == NULL)
- {
- TRAP();
- return;
- }
-
- list_head = &purb->trasac_list;
- if (IsListEmpty(list_head))
- {
- TRAP();
- return;
- }
-
- i = start_frame;
- while (pthis)
- {
- if (pipe_content->speed_high)
- {
- itd_from_list_entry(pthis)->elem_head_link->sched_link.Flink =
- ehci->frame_list_cpu[i].td_link.Flink;
- itd_from_list_entry(pthis)->hw_next = ehci->frame_list[i];
-
- ehci->frame_list[i] = itd_from_list_entry(pthis)->phys_addr;
- ehci->frame_list_cpu[i].td_link.Flink = pthis;
- }
- else
- {
- sitd_from_list_entry(pthis)->elem_head_link->sched_link.Flink =
- ehci->frame_list_cpu[i].td_link.Flink;
- sitd_from_list_entry(pthis)->hw_next = ehci->frame_list[i];
-
- ehci->frame_list[i] = sitd_from_list_entry(pthis)->phys_addr;
- ehci->frame_list_cpu[i].td_link.Flink = pthis;
- }
-
- ListNext(list_head, pthis, pnext);
- pthis = pnext;
-
- if (interval <= 8)
- i++;
- else
- i += (interval >> 3);
- }
- return;
-}
-
-static VOID
-ehci_remove_iso_from_schedule(PEHCI_DEV ehci, PURB purb)
-{
- PURB_HS_PIPE_CONTENT pipe_content;
- PLIST_ENTRY pthis, list_head, pnext, pprev, pcur;
-
- ULONG interval, start_frame;
- LONG i;
-
- if (ehci == NULL || purb == NULL)
- return;
-
- pipe_content = (PURB_HS_PIPE_CONTENT) & purb->pipe;
-
- interval = 8;
- if (pipe_content->speed_high)
- interval = REAL_INTERVAL;
-
- start_frame = purb->iso_start_frame;
-
- ListFirst(&purb->trasac_list, pthis);
- if (pthis == NULL)
- {
- TRAP();
- return;
- }
-
- list_head = &purb->trasac_list;
- if (IsListEmpty(list_head))
- {
- TRAP();
- return;
- }
-
- i = start_frame;
- while (pthis)
- {
- // for the possible existance of sitd back pointer, we can not use for(...)
- ListFirst(&ehci->frame_list_cpu[i].td_link, pcur);
- pprev = &ehci->frame_list_cpu[i].td_link;
- while (pcur)
- {
- if (pcur != pthis)
- {
- ListNext(&ehci->frame_list_cpu[i].td_link, pcur, pnext);
- pprev = pcur;
- pcur = pnext;
- continue;
- }
- break;
- }
-
- if (pcur == NULL)
- {
- TRAP();
- }
- pprev->Flink = pcur->Flink;
- if (pprev != &ehci->frame_list_cpu[i].td_link)
- qh_from_schedule(pprev)->hw_next = qh_from_schedule(pcur)->hw_next;
- else
- ehci->frame_list[i] = qh_from_schedule(pcur)->hw_next;
-
- ListNext(list_head, pthis, pnext);
- pthis = pnext;
-
- if (interval <= 8)
- i++;
- else
- i += (interval >> 3);
- }
- return;
-}
-
-NTSTATUS
-ehci_isr_removing_urb(PEHCI_DEV ehci, PURB purb, BOOLEAN doorbell_rings, ULONG cur_frame)
-{
- UCHAR type;
- PLIST_ENTRY pthis;
- PURB_HS_PIPE_CONTENT pipe_content;
- PEHCI_ITD_CONTENT pitd_content;
- PEHCI_SITD_CONTENT psitd_content;
- PEHCI_QH_CONTENT pqh_content;
- PEHCI_QTD_CONTENT pqtd_content;
- LONG i;
-
- if (purb == NULL || ehci == NULL)
- return STATUS_INVALID_PARAMETER;
-
- if ((purb->flags & URB_FLAG_STATE_MASK) == URB_FLAG_STATE_FINISHED)
- return STATUS_SUCCESS;
-
- type = 0;
- pipe_content = (PURB_HS_PIPE_CONTENT) & purb->pipe;
-
- switch (purb->flags & URB_FLAG_STATE_MASK)
- {
- case URB_FLAG_STATE_IN_PROCESS:
- {
- // determine the removal type: complete, error or cancel
- ListFirst(&purb->trasac_list, pthis);
- if (purb->flags & URB_FLAG_FORCE_CANCEL)
- {
- type = 3;
- }
- else
- {
- if (pipe_content->trans_type == USB_ENDPOINT_XFER_BULK ||
- pipe_content->trans_type == USB_ENDPOINT_XFER_INT ||
- pipe_content->trans_type == USB_ENDPOINT_XFER_CONTROL)
- {
- pqh_content =
- (PEHCI_QH_CONTENT) ((ULONG) struct_ptr(pthis, EHCI_ELEM_LINKS, elem_link)->
- phys_part & PHYS_PART_ADDR_MASK);
- if (EHCI_QH_ERROR(pqh_content))
- {
- purb->status = pqh_content->cur_qtd.status;
- type = 2;
- }
- else
- {
- pqtd_content = &pqh_content->cur_qtd;
- if (pqtd_content->terminal && ((pqtd_content->status & QTD_STS_ACTIVE) == 0))
- {
- type = 1;
- }
- // else, not finished
- }
- }
- else if (pipe_content->trans_type == USB_ENDPOINT_XFER_ISOC)
- {
- // FIXME: do we need to check if current frame falls out of the
- // frame range of iso transfer
- // inspect the last td to determine if finished
- ListFirstPrev(&purb->trasac_list, pthis);
- if (pthis)
- {
- if (pipe_content->speed_high)
- {
- pitd_content =
- (PEHCI_ITD_CONTENT) ((ULONG) struct_ptr(pthis, EHCI_ELEM_LINKS, elem_link)->
- phys_part & PHYS_PART_ADDR_MASK);
- for(i = 0; i < 8; i++)
- {
- if (pitd_content->status_slot[i].trans_length &&
- pitd_content->status_slot[i].status & 0x08)
- {
- break;
- }
- }
- if (i == 8)
- {
- // the itds are all inactive
- type = 1;
- }
- }
- else
- {
- psitd_content =
- (PEHCI_SITD_CONTENT) ((ULONG) struct_ptr(pthis, EHCI_ELEM_LINKS, elem_link)->
- phys_part & PHYS_PART_ADDR_MASK);
- if ((psitd_content->status & 0x80) == 0)
- {
- type = 1;
- }
- }
- }
- else // empty transaction list in purb
- TRAP();
- }
- else // unknown transfer type
- TRAP();
-
- } // end of not force cancel
-
- if (type == 0)
- return STATUS_SUCCESS;
-
- switch (type)
- {
- case 1:
- {
- if (pipe_content->trans_type == USB_ENDPOINT_XFER_CONTROL ||
- pipe_content->trans_type == USB_ENDPOINT_XFER_BULK)
- {
- ehci_remove_bulk_from_schedule(ehci, purb);
- purb->flags &= ~URB_FLAG_STATE_MASK;
- purb->flags |= URB_FLAG_STATE_DOORBELL;
- purb->status = 0;
- press_doorbell(ehci);
- return STATUS_SUCCESS;
- }
- else if (pipe_content->trans_type == USB_ENDPOINT_XFER_ISOC)
- {
- ehci_remove_iso_from_schedule(ehci, purb);
- }
- else if (pipe_content->trans_type == USB_ENDPOINT_XFER_INT)
- {
- ehci_remove_int_from_schedule(ehci, purb);
- }
- else // unknown transfer type
- TRAP();
-
- purb->flags &= ~URB_FLAG_STATE_MASK;
- purb->flags |= URB_FLAG_STATE_FINISHED;
-
- // notify dpc the purb can be completed;
- purb->flags &= ~URB_FLAG_IN_SCHEDULE;
- purb->status = 0;
-
- return STATUS_SUCCESS;
- }
- case 2:
- {
- if (pipe_content->trans_type == USB_ENDPOINT_XFER_CONTROL ||
- pipe_content->trans_type == USB_ENDPOINT_XFER_BULK)
- {
- ehci_deactivate_urb(purb);
- ehci_remove_bulk_from_schedule(ehci, purb);
- purb->flags &= ~URB_FLAG_STATE_MASK;
- purb->flags |= URB_FLAG_STATE_DOORBELL;
- press_doorbell(ehci);
- }
- else if (pipe_content->trans_type == USB_ENDPOINT_XFER_INT)
- {
- ehci_remove_int_from_schedule(ehci, purb);
-
- purb->flags &= ~URB_FLAG_STATE_MASK;
- purb->flags |= URB_FLAG_STATE_FINISHED;
- purb->flags &= ~URB_FLAG_IN_SCHEDULE;
- }
- else // unknown transfer or iso transfer
- TRAP();
- return STATUS_SUCCESS;
- }
- case 3:
- {
- if (pipe_content->trans_type == USB_ENDPOINT_XFER_CONTROL ||
- pipe_content->trans_type == USB_ENDPOINT_XFER_BULK ||
- pipe_content->trans_type == USB_ENDPOINT_XFER_INT)
- {
- ehci_deactivate_urb(purb);
- if (pipe_content->trans_type == USB_ENDPOINT_XFER_BULK ||
- pipe_content->trans_type == USB_ENDPOINT_XFER_CONTROL)
- ehci_remove_bulk_from_schedule(ehci, purb);
- else
- ehci_remove_int_from_schedule(ehci, purb);
-
- purb->flags &= ~URB_FLAG_STATE_MASK;
- purb->flags |= URB_FLAG_STATE_DOORBELL;
-
- press_doorbell(ehci);
-
- }
- else // unknown transfer or iso transfer
- DO_NOTHING;
- purb->status = 0;
- return STATUS_SUCCESS;
- }
- default:
- TRAP();
- }
- break;
- }
- case URB_FLAG_STATE_DOORBELL:
- {
- if (doorbell_rings == FALSE)
- return STATUS_SUCCESS;
-
- purb->flags &= ~URB_FLAG_STATE_MASK;
- purb->flags |= URB_FLAG_STATE_FINISHED;
- purb->flags &= ~URB_FLAG_IN_SCHEDULE;
- return STATUS_SUCCESS;
- }
- }
- return STATUS_SUCCESS;
-}
-
-static ULONG
-ehci_scan_iso_error(PEHCI_DEV ehci, PURB purb)
-// we only report the first error of the ITDs, purb->status is the status code
-// return the raw status for ehci_set_error_code
-{
- PURB_HS_PIPE_CONTENT pipe_content;
- PEHCI_SITD_CONTENT psitd_content;
- PEHCI_ITD_CONTENT pitd_content;
- PLIST_ENTRY pthis, pnext;
- LONG i;
-
- if (ehci == NULL || purb == NULL)
- return 0;
-
- pipe_content = (PURB_HS_PIPE_CONTENT) & purb->pipe;
- if (pipe_content->trans_type != USB_ENDPOINT_XFER_ISOC)
- {
- return 0;
- }
-
- ListFirst(&purb->trasac_list, pthis);
- if (pipe_content->speed_high)
- {
- while (pthis)
- {
- pitd_content = (PEHCI_ITD_CONTENT) itd_from_list_entry(pthis);
- for(i = 0; i < 8; i++)
- {
- if (pitd_content->status_slot[i].status & ITD_ANY_ERROR)
- break;
- }
- if (i < 8)
- {
- // error occured
- return purb->status = pitd_content->status_slot[i].status;
- }
- ListNext(&purb->trasac_list, pthis, pnext);
- pthis = pnext;
- }
- }
- else
- {
- while (pthis)
- {
- psitd_content = (PEHCI_SITD_CONTENT) sitd_from_list_entry(pthis);
- if (psitd_content->status & SITD_ANY_ERROR)
- {
- // error occured
- if (psitd_content->s_mask == 0x04 &&
- psitd_content->c_mask == 0x70 && psitd_content->bytes_to_transfer == 1)
- return purb->status = 0;
-
- return purb->status = psitd_content->status;
- }
- ListNext(&purb->trasac_list, pthis, pnext);
- pthis = pnext;
- }
- }
- return 0;
-}
-
-BOOLEAN NTAPI
-ehci_isr(PKINTERRUPT interrupt, PVOID context)
- // we can not use endp here for it is within the dev scope, and
- // we can not acquire the dev-lock, fortunately we saved some
- // info in purb->pipe in ehci_internal_submit_XXX.
-{
-
- PEHCI_DEV ehci;
- ULONG status;
-#if DBG
- ULONG urb_count;
-#endif
- PLIST_ENTRY pthis, pnext;
- PURB purb;
- BOOLEAN door_bell_rings;
- ULONG cur_frame;
- /*
- * Read the interrupt status, and write it back to clear the
- * interrupt cause
- */
- ehci = (PEHCI_DEV) context;
- if (ehci == NULL)
- return FALSE;
-
- status = EHCI_READ_PORT_ULONG((PULONG) (ehci->port_base + EHCI_USBSTS));
- cur_frame = EHCI_READ_PORT_ULONG((PULONG) (ehci->port_base + EHCI_FRINDEX));
-
- status &= (EHCI_ERROR_INT | STS_INT | STS_IAA);
- if (!status) /* shared interrupt, not mine */
- {
- ehci_dbg_print(DBGLVL_MAXIMUM, ("ehci_isr(): not our int\n"));
- return FALSE;
- }
-
- /* clear it */
- EHCI_WRITE_PORT_ULONG((PULONG) (ehci->port_base + EHCI_USBSTS), status);
-
- if (status & EHCI_ERROR_INT)
- {
- ehci_dbg_print(DBGLVL_MAXIMUM, ("ehci_isr(): current ehci status=0x%x\n", status));
- }
- else
- {
- ehci_dbg_print(DBGLVL_MAXIMUM, ("ehci_isr(): congratulations, no error occurs\n"));
- }
-
-
- if (status & STS_FATAL)
- {
- DbgPrint("ehci_isr(): host system error, PCI problems?\n");
- for(;;);
-
- }
-
- if (status & STS_HALT) //&& !ehci->is_suspended
- {
- DbgPrint("ehci_isr(): host controller halted. very bad\n");
- /* FIXME: Reset the controller, fix the offending TD */
- // reset is performed in dpc
- }
-
-
- door_bell_rings = ((status & STS_IAA) != 0);
-
- // scan to remove those due
-#if DBG
- urb_count = dbg_count_list(&ehci->urb_list);
- ehci_dbg_print(DBGLVL_MAXIMUM, ("ehci_isr(): urb# in process is %d\n", urb_count));
-#endif
-
- ListFirst(&ehci->urb_list, pthis);
- while (pthis)
- {
- purb = (PURB) pthis;
- ehci_isr_removing_urb(ehci, purb, door_bell_rings, cur_frame);
- ListNext(&ehci->urb_list, pthis, pnext);
- pthis = pnext;
- }
-
- KeInsertQueueDpc(&ehci->pdev_ext->ehci_dpc, (PVOID) status, 0);
- return TRUE;
-}
-
-#ifndef INCLUDE_EHCI
-VOID
-ehci_unload(IN PDRIVER_OBJECT DriverObject)
-{
- PDEVICE_OBJECT pdev;
- PEHCI_DEVICE_EXTENSION pdev_ext;
- PUSB_DEV_MANAGER dev_mgr;
- LONG i;
-
- pdev = DriverObject->DeviceObject;
-
- if (pdev == NULL)
- return;
-
- pdev_ext = pdev->DeviceExtension;
- if (pdev_ext == NULL)
- return;
-
- dev_mgr = &g_dev_mgr;
- if (dev_mgr == NULL)
- return;
- //
- // set the termination flag
- //
- dev_mgr->term_flag = TRUE;
- //
- // wake up the thread if it is
- //
- KeSetEvent(&dev_mgr->wake_up_event, 0, FALSE);
- KeWaitForSingleObject(dev_mgr->pthread, Executive, KernelMode, TRUE, NULL);
- ObDereferenceObject(dev_mgr->pthread);
- dev_mgr->pthread = NULL;
-
- dev_mgr_release_hcd(dev_mgr);
- return;
-}
-
-NTSTATUS
-generic_dispatch_irp(IN PDEVICE_OBJECT dev_obj, IN PIRP irp)
-{
- PDEVEXT_HEADER dev_ext;
-
- dev_ext = (PDEVEXT_HEADER) dev_obj->DeviceExtension;
-
- if (dev_ext && dev_ext->dispatch)
- return dev_ext->dispatch(dev_obj, irp);
-
- irp->IoStatus.Information = 0;
-
- EXIT_DISPATCH(STATUS_UNSUCCESSFUL, irp);
-}
-
-VOID
-generic_start_io(IN PDEVICE_OBJECT dev_obj, IN PIRP irp)
-{
- PDEVEXT_HEADER dev_ext;
-
- KIRQL old_irql;
-
- IoAcquireCancelSpinLock(&old_irql);
- if (irp != dev_obj->CurrentIrp || irp->Cancel)
- {
- IoReleaseCancelSpinLock(old_irql);
- return;
- }
- else
- {
- IoSetCancelRoutine(irp, NULL);
- IoReleaseCancelSpinLock(old_irql);
- }
-
- dev_ext = (PDEVEXT_HEADER) dev_obj->DeviceExtension;
-
- if (dev_ext && dev_ext->start_io)
- {
- dev_ext->start_io(dev_obj, irp);
- return;
- }
-
- irp->IoStatus.Information = 0;
- irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
-
- IoStartNextPacket(dev_obj, FALSE);
- IoCompleteRequest(irp, IO_NO_INCREMENT);
-}
-
-NTSTATUS
-NTAPI
-DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
-{
- NTSTATUS ntStatus = STATUS_SUCCESS;
- BOOLEAN fRes;
-
-#if DBG
- // should be done before any debug output is done.
- // read our debug verbosity level from the registry
- //NetacOD_GetRegistryDword( NetacOD_REGISTRY_PARAMETERS_PATH, //absolute registry path
- // L"DebugLevel", // REG_DWORD ValueName
- // &gDebugLevel ); // Value receiver
-
- // debug_level = DBGLVL_MAXIMUM;
-#endif
-
- ehci_dbg_print_cond(DBGLVL_MINIMUM, DEBUG_UHCI,
- ("Entering DriverEntry(), RegistryPath=\n %ws\n", RegistryPath->Buffer));
-
- // Remember our driver object, for when we create our child PDO
- usb_driver_obj = DriverObject;
-
- //
- // Create dispatch points for create, close, unload
- DriverObject->MajorFunction[IRP_MJ_CREATE] = generic_dispatch_irp;
- DriverObject->MajorFunction[IRP_MJ_CLOSE] = generic_dispatch_irp;
- DriverObject->DriverUnload = ehci_unload;
-
- // User mode DeviceIoControl() calls will be routed here
- DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = generic_dispatch_irp;
- DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = generic_dispatch_irp;
-
- // User mode ReadFile()/WriteFile() calls will be routed here
- DriverObject->MajorFunction[IRP_MJ_WRITE] = generic_dispatch_irp;
- DriverObject->MajorFunction[IRP_MJ_READ] = generic_dispatch_irp;
-
- DriverObject->MajorFunction[IRP_MJ_SHUTDOWN] = generic_dispatch_irp;
- DriverObject->MajorFunction[IRP_MJ_SCSI] = generic_dispatch_irp;
- DriverObject->MajorFunction[IRP_MJ_FLUSH_BUFFERS] = generic_dispatch_irp;
-
- DriverObject->DriverStartIo = generic_start_io;
- // routines for handling system PNP and power management requests
- //DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = generic_dispatch_irp;
-
- // The Functional Device Object (FDO) will not be created for PNP devices until
- // this routine is called upon device plug-in.
- RtlZeroMemory(&g_dev_mgr, sizeof(USB_DEV_MANAGER));
- g_dev_mgr.usb_driver_obj = DriverObject;
-
- ehci_probe(DriverObject, RegistryPath, &g_dev_mgr);
-
- if (dev_mgr_strobe(&g_dev_mgr) == FALSE)
- {
- dev_mgr_release_hcd(&g_dev_mgr);
- return STATUS_UNSUCCESSFUL;
- }
-
- dev_mgr_start_hcd(&g_dev_mgr);
- ehci_dbg_print_cond(DBGLVL_DEFAULT, DEBUG_UHCI, ("DriverEntry(): exiting... (%x)\n", ntStatus));
- return STATUS_SUCCESS;
-}
-#endif
-
-//note: the initialization will be in the following order
-// dev_mgr_strobe
-// ehci_start
-
-// to kill dev_mgr_thread:
-// dev_mgr->term_flag = TRUE;
-// KeSetEvent( &dev_mgr->wake_up_event );
-// this piece of code must run at passive-level
-//
-//
diff --git a/reactos/drivers/usb/nt4compat/usbdrv/ehci.h b/reactos/drivers/usb/nt4compat/usbdrv/ehci.h
deleted file mode 100644
index 4ea31e55eea..00000000000
--- a/reactos/drivers/usb/nt4compat/usbdrv/ehci.h
+++ /dev/null
@@ -1,808 +0,0 @@
-/*
- * Copyright (c) 2001-2002 by David Brownell
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#ifndef __EHCI_H__
-#define __EHCI_H__
-
-#define EHCI_QH_SIZE sizeof( EHCI_QH )
-#define EHCI_ITD_SIZE sizeof( EHCI_ITD )
-#define EHCI_SITD_SIZE sizeof( EHCI_SITD )
-#define EHCI_FSTN_SIZE sizeof( EHCI_FSTN )
-#define EHCI_QTD_SIZE sizeof( EHCI_QTD )
-
-#define INIT_LIST_FLAG_TYPE 0x0f
-#define INIT_LIST_FLAG_ITD 0x00
-#define INIT_LIST_FLAG_QH 0x01
-#define INIT_LIST_FLAG_SITD 0x02
-#define INIT_LIST_FLAG_FSTN 0x03
-#define INIT_LIST_FLAG_QTD 0x04
-
-#define EHCI_MAX_SIZE_TRANSFER 0x100000 // 1 MB per transfer
-#define EHCI_MAX_ELEMS_POOL 1024
-#define EHCI_MAX_LISTS_POOL 0x08
-#define EHCI_MAX_QHS_LIST 256 // 4 pages
-#define EHCI_MAX_ITDS_LIST ( PAGE_SIZE / EHCI_ITD_SIZE * 2 ) // 2 pages
-#define EHCI_MAX_SITDS_LIST ( PAGE_SIZE / EHCI_SITD_SIZE )// 1 page
-#define EHCI_MAX_FSTNS_LIST ( PAGE_SIZE / EHCI_FSTN_SIZE )// 1 page
-#define EHCI_MAX_QTDS_LIST 256 // 4 pages
-
-#define EHCI_PTR_TERM 0x01
-#define EHCI_NAK_RL_COUNT 0x04
-
-#define EHCI_QTD_MAX_TRANS_SIZE 20480
-#define PHYS_PART_TYPE_MASK 0x01f
-#define PHYS_PART_ADDR_MASK ( ~PHYS_PART_TYPE_MASK )
-
-typedef struct _EHCI_ELEM_LINKS
-{
- LIST_ENTRY elem_link; // link for one urb request
- LIST_ENTRY sched_link; // to shadow link of schedule
- struct _EHCI_ELEM_POOL* pool_link;
- struct _EHCI_ELEM_LIST* list_link; // opaque to client, which list this td belongs to
- PVOID phys_part; // point to EHCI_XXX, the lower 5 bits is used to indicate the type of the element
- PURB purb;
-
-} EHCI_ELEM_LINKS, *PEHCI_ELEM_LINKS;
-
-typedef struct _INIT_ELEM_LIST_CONTEXT
-{
- PADAPTER_OBJECT padapter;
- struct _EHCI_ELEM_POOL *pool;
-
-} INIT_ELEM_LIST_CONTEXT, *PINIT_ELEM_LIST_CONTEXT;
-
-typedef VOID ( *PDESTROY_ELEM_LIST )( struct _EHCI_ELEM_LIST* plist );
-typedef PLIST_ENTRY ( *PGET_LIST_HEAD )( struct _EHCI_ELEM_LIST* plist );
-typedef LONG ( *PGET_TOTAL_COUNT )( struct _EHCI_ELEM_LIST* plist );
-typedef LONG ( *PGET_ELEM_SIZE )( struct _EHCI_ELEM_LIST* plist );
-typedef LONG ( *PGET_LINK_OFFSET )( struct _EHCI_ELEM_LIST* plist );
-typedef LONG ( *PADD_REF )( struct _EHCI_ELEM_LIST* plist );
-typedef LONG ( *PRELEASE_REF )( struct _EHCI_ELEM_LIST* plist );
-typedef LONG ( *PGET_REF )( struct _EHCI_ELEM_LIST* plist );
-
-typedef struct _EHCI_ELEM_LIST
-{
- PDESTROY_ELEM_LIST destroy_list;
- PGET_LIST_HEAD get_list_head;
- PGET_TOTAL_COUNT get_total_count;
- PGET_ELEM_SIZE get_elem_size;
- PGET_LINK_OFFSET get_link_offset;
- PADD_REF add_ref;
- PRELEASE_REF release_ref;
- PGET_REF get_ref;
-
- // private area
- LONG flags; // contails element's type info
- LONG total_count;
- LONG elem_size;
- LIST_HEAD free_list; // chains of all the elements
- struct _EHCI_ELEM_POOL *parent_pool;
- LONG reference;
-
- // used to represent the physical memory
- PPHYSICAL_ADDRESS phys_addrs; // array of non-contigous memory
- PBYTE *phys_bufs;
- PEHCI_ELEM_LINKS elem_head_buf;
- PADAPTER_OBJECT padapter;
-
-} EHCI_ELEM_LIST, *PEHCI_ELEM_LIST;
-
-BOOLEAN elem_pool_init_pool( struct _EHCI_ELEM_POOL* pool, LONG flags, PVOID context);
-VOID elem_pool_destroy_pool ( struct _EHCI_ELEM_POOL* pool );
-PEHCI_ELEM_LINKS elem_pool_alloc_elem ( struct _EHCI_ELEM_POOL* pool );
-VOID elem_pool_free_elem ( PEHCI_ELEM_LINKS elem_link );
-LONG elem_pool_get_total_count ( struct _EHCI_ELEM_POOL* pool );
-BOOLEAN elem_pool_is_empty ( struct _EHCI_ELEM_POOL* pool );
-LONG elem_pool_get_free_count ( struct _EHCI_ELEM_POOL* pool );
-LONG elem_pool_get_link_offset ( struct _EHCI_ELEM_POOL* pool );
-PEHCI_ELEM_LINKS elem_pool_alloc_elems ( struct _EHCI_ELEM_POOL* pool, LONG count );
-BOOLEAN elem_pool_free_elems( PEHCI_ELEM_LINKS elem_chains );
-LONG elem_pool_get_type( struct _EHCI_ELEM_POOL* pool );
-
-// the following are private functions
-BOOLEAN elem_pool_expand_pool( struct _EHCI_ELEM_POOL* pool, LONG elem_count );
-BOOLEAN elem_pool_collect_garbage( struct _EHCI_ELEM_POOL* pool );
-
-// lock operations
-BOOLEAN elem_pool_lock( struct _EHCI_ELEM_POOL* pool, BOOLEAN at_dpc );
-BOOLEAN elem_pool_unlock( struct _EHCI_ELEM_POOL* pool, BOOLEAN at_dpc );
-
-// helper
-LONG get_elem_phys_part_size( ULONG type );
-
-typedef struct _EHCI_ELEM_POOL
-{
- LONG flags;
- LONG free_count; // free count of all the lists currently allocated
- LONG link_offset; // a cache for elem_list->get_link_offset
- LONG list_count; // lists currently allocated
- PEHCI_ELEM_LIST elem_lists[ EHCI_MAX_LISTS_POOL ];
-
-} EHCI_ELEM_POOL, *PEHCI_ELEM_POOL;
-
-/*-------------------------------------------------------------------------*/
-
-#define QTD_NEXT(dma) cpu_to_le32((u32)dma)
-
-/*
- * EHCI Specification 0.95 Section 3.5
- * QTD: describe data transfer components (buffer, direction, ...)
- * See Fig 3-6 "Queue Element Transfer Descriptor Block Diagram".
- *
- * These are associated only with "QH" (Queue Head) structures,
- * used with control, bulk, and interrupt transfers.
- */
-#define QTD_TOGGLE (1 << 31) /* data toggle */
-#define QTD_LENGTH(tok) (((tok)>>16) & 0x7fff)
-#define QTD_IOC (1 << 15) /* interrupt on complete */
-#define QTD_CERR(tok) (((tok)>>10) & 0x3)
-#define QTD_PID(tok) (((tok)>>8) & 0x3)
-#define QTD_STS_ACTIVE (1 << 7) /* HC may execute this */
-#define QTD_STS_HALT (1 << 6) /* halted on error */
-#define QTD_STS_DBE (1 << 5) /* data buffer error (in HC) */
-#define QTD_STS_BABBLE (1 << 4) /* device was babbling (qtd halted) */
-#define QTD_STS_XACT (1 << 3) /* device gave illegal response */
-#define QTD_STS_MMF (1 << 2) /* incomplete split transaction */
-#define QTD_STS_STS (1 << 1) /* split transaction state */
-#define QTD_STS_PING (1 << 0) /* issue PING? */
-#define QTD_ANY_ERROR ( QTD_STS_HALT | QTD_STS_DBE | QTD_STS_XACT | QTD_STS_MMF | QTD_STS_BABBLE )
-
-#define QTD_PID_SETUP 0x02
-#define QTD_PID_IN 0x01
-#define QTD_PID_OUT 0x00
-
-#pragma pack( push, usb_align, 1 )
-
-typedef struct _EHCI_QTD_CONTENT
-{
- // DWORD 0
- ULONG terminal : 1;
- ULONG reserved : 4;
- ULONG next_qtd : 27;
-
- // DWORD 1
- ULONG alt_terminal : 1;
- ULONG reserved1 : 4;
- ULONG alt_qtd : 27;
-
- // DWORD 2
- ULONG status : 8;
- ULONG pid : 2;
- ULONG err_count : 2;
- ULONG cur_page : 3;
- ULONG ioc : 1;
- ULONG bytes_to_transfer : 15;
- ULONG data_toggle : 1;
-
- // DWORD 3
- ULONG cur_offset : 12;
- ULONG page0 : 20;
-
- // DWORD 4-
- ULONG pages[ 4 ];
-
-} EHCI_QTD_CONTENT, *PEHCI_QTD_CONTENT;
-
-typedef struct _EHCI_QTD
-{
- /* first part defined by EHCI spec */
- ULONG hw_next; /* see EHCI 3.5.1 */
- ULONG hw_alt_next; /* see EHCI 3.5.2 */
- ULONG hw_token; /* see EHCI 3.5.3 */
- ULONG hw_buf [5]; /* see EHCI 3.5.4 */
-
- /* the rest is HCD-private */
- PEHCI_ELEM_LINKS elem_head_link;
- ULONG phys_addr; /* qtd address */
- USHORT bytes_to_transfer; /* the bytes_to_transfer in hw_token will drop to zero when completed*/
- USHORT reserved2;
- ULONG reserved[ 5 ];
-
-} EHCI_QTD, *PEHCI_QTD; //__attribute__ ((aligned (32)));
-
-#define QTD_MASK cpu_to_le32 (~0x1f) /* mask NakCnt+T in qh->hw_alt_next */
-
-/*-------------------------------------------------------------------------*/
-
-/* type tag from {qh,itd,sitd,fstn}->hw_next */
-#define Q_NEXT_TYPE(dma) ((dma) & __constant_cpu_to_le32 (3 << 1))
-
-/* values for that type tag */
-#define Q_TYPE_ITD (0 << 1)
-#define Q_TYPE_QH (1 << 1)
-#define Q_TYPE_SITD (2 << 1)
-#define Q_TYPE_FSTN (3 << 1)
-
-/* next async queue entry, or pointer to interrupt/periodic QH */
-#define QH_NEXT(dma) (cpu_to_le32(((u32)dma)&~0x01f)|Q_TYPE_QH)
-
-/* for periodic/async schedules and qtd lists, mark end of list */
-#define EHCI_LIST_END __constant_cpu_to_le32(1) /* "null pointer" to hw */
-
-/*-------------------------------------------------------------------------*/
-
-/*
- * EHCI Specification 0.95 Section 3.6
- * QH: describes control/bulk/interrupt endpoints
- * See Fig 3-7 "Queue Head Structure Layout".
- *
- * These appear in both the async and (for interrupt) periodic schedules.
- */
-
-#define QH_HEAD 0x00008000
-#define QH_STATE_LINKED 1 /* HC sees this */
-#define QH_STATE_UNLINK 2 /* HC may still see this */
-#define QH_STATE_IDLE 3 /* HC doesn't see this */
-#define QH_STATE_UNLINK_WAIT 4 /* LINKED and on reclaim q */
-#define QH_STATE_COMPLETING 5 /* don't touch token.HALT */
-#define NO_FRAME ((unsigned short)~0) /* pick new start */
-
-typedef struct _EHCI_QH_CONTENT
-{
- // DWORD 0
- ULONG terminal : 1;
- ULONG ptr_type : 2;
- ULONG reserved : 2;
- ULONG next_link : 27;
-
- // DWORD 1
- ULONG dev_addr : 7;
- ULONG inactive : 1;
- ULONG endp_addr : 4;
- ULONG endp_spd : 2;
- ULONG data_toggle : 1;
- ULONG is_async_head : 1;
- ULONG max_packet_size : 11;
- ULONG is_ctrl_endp : 1;
- ULONG reload_counter : 4;
-
- // DWORD 2
- ULONG s_mask : 8;
- ULONG c_mask : 8;
- ULONG hub_addr : 7;
- ULONG port_idx : 7;
- ULONG mult : 2;
-
- // DWORD 3
- ULONG cur_qtd_ptr;
-
- // overlay
- EHCI_QTD_CONTENT cur_qtd;
-
-} EHCI_QH_CONTENT, *PEHCI_QH_CONTENT;
-
-typedef struct _EHCI_QH
-{
- /* first part defined by EHCI spec */
- ULONG hw_next; /* see EHCI 3.6.1 */
- ULONG hw_info1; /* see EHCI 3.6.2 */
- ULONG hw_info2; /* see EHCI 3.6.2 */
- ULONG hw_current; /* qtd list - see EHCI 3.6.4 */
-
- /* qtd overlay (hardware parts of a struct ehci_qtd) */
- ULONG hw_qtd_next;
- ULONG hw_alt_next;
- ULONG hw_token;
- ULONG hw_buf [5];
-
- /* the rest is HCD-private */
- PEHCI_ELEM_LINKS elem_head_link;
- ULONG phys_addr; /* address of qh */
- ULONG reserved[ 2 ];
-
-} EHCI_QH, *PEHCI_QH; // __attribute__ ((aligned (32)));
-
-/*-------------------------------------------------------------------------*/
-
-/*
- * EHCI Specification 0.95 Section 3.3
- * Fig 3-4 "Isochronous Transaction Descriptor (iTD)"
- *
- * Schedule records for high speed iso xfers
- */
-
-#define EHCI_ISOC_ACTIVE (1<<31) /* activate transfer this slot */
-#define EHCI_ISOC_BUF_ERR (1<<30) /* Data buffer error */
-#define EHCI_ISOC_BABBLE (1<<29) /* babble detected */
-#define EHCI_ISOC_XACTERR (1<<28) /* XactErr - transaction error */
-#define EHCI_ITD_LENGTH(tok) (((tok)>>16) & 0x7fff)
-#define EHCI_ITD_IOC (1 << 15) /* interrupt on complete */
-
-#define ITD_STS_ACTIVE 8
-#define ITD_STS_BUFERR 4
-#define ITD_STS_BABBLE 2
-#define ITD_STS_XACTERR 1
-
-#define ITD_ANY_ERROR ( ITD_STS_BUFERR | ITD_STS_BABBLE | ITD_STS_XACTERR )
-
-typedef struct _EHCI_ITD_STATUS_SLOT
-{
- ULONG offset : 12;
- ULONG page_sel : 3;
- ULONG ioc : 1;
- ULONG trans_length : 12;
- ULONG status : 4;
-
-} EHCI_ITD_STATUS_SLOT, *PEHCI_ITD_STATUS_SLOT;
-
-typedef struct _EHCI_ITD_CONTENT
-{
- // DWORD 0;
- ULONG terminal : 1;
- ULONG ptr_type : 2;
- ULONG reserved : 2;
- ULONG next_link : 27;
- // DWORD 1-8;
- EHCI_ITD_STATUS_SLOT status_slot[ 8 ];
- // DWORD 9;
- ULONG dev_addr : 7;
- ULONG reserved1 : 1;
- ULONG endp_num : 4;
- ULONG page0 : 20;
- // DWORD 10;
- ULONG max_packet_size : 11;
- ULONG io_dir : 1;
- ULONG page1 : 20;
- // DWORD 11;
- ULONG mult : 2;
- ULONG reserved2 : 10;
- ULONG page2 : 20;
- // DWORD 12-;
- ULONG pages[ 4 ];
-
-} EHCI_ITD_CONTENT, *PEHCI_ITD_CONTENT;
-
-typedef struct _EHCI_ITD {
-
- /* first part defined by EHCI spec */
- ULONG hw_next; /* see EHCI 3.3.1 */
- ULONG hw_transaction [8]; /* see EHCI 3.3.2 */
- ULONG hw_bufp [7]; /* see EHCI 3.3.3 */
-
- /* the rest is EHCI-private */
- PEHCI_ELEM_LINKS elem_head_link;
- ULONG phys_addr; /* for this itd */
- ULONG buf_phys_addr; /* buffer address */
- ULONG reserved[ 5 ];
-
-} EHCI_ITD, *PEHCI_ITD; // __attribute__ ((aligned (32)));
-
-/*-------------------------------------------------------------------------*/
-
-/*
- * EHCI Specification 0.95 Section 3.4
- * siTD, aka split-transaction isochronous Transfer Descriptor
- * ... describe low/full speed iso xfers through TT in hubs
- * see Figure 3-5 "Split-transaction Isochronous Transaction Descriptor (siTD)
- */
-#define SITD_STS_ACTIVE 0x80
-#define SITD_STS_ERR 0x40 // error from device
-#define SITD_STS_DBE 0x20 // data buffer error
-#define SITD_STS_BABBLE 0x10 // data more than expected
-#define SITD_STS_XACTERR 0x08 // general error on hc
-#define SITD_STS_MISSFRM 0x04 // missd micro frames
-#define SITD_STS_SC 0x02 // state is whether start-split( 0 ) or complete-split( 1 )
-#define SITD_STS_RESERVED 0x01
-#define SITD_ANY_ERROR ( SITD_STS_ERR | SITD_STS_DBE | SITD_STS_BABBLE | SITD_STS_XACTERR | SITD_STS_MISSFRM )
-
-typedef struct _EHCI_SITD_CONTENT
-{
- // DWORD 0;
- ULONG terminal : 1;
- ULONG ptr_type : 2;
- ULONG reserved : 2;
- ULONG next_link : 27;
- // DWORD 1;
- ULONG dev_addr : 7;
- ULONG reserved1 : 1;
- ULONG endp_num : 4;
- ULONG reserved2 : 4;
- ULONG hub_addr : 7;
- ULONG reserved3 : 1;
- ULONG port_idx : 7;
- ULONG io_dir : 1;
- // DWORD 2;
- ULONG s_mask : 8;
- ULONG c_mask : 8;
- ULONG reserved4 : 16;
- // DWORD 3:
- ULONG status : 8;
- ULONG c_prog_mask : 8;
- ULONG bytes_to_transfer : 10;
- ULONG reserved5 : 4;
- ULONG page_sel : 1;
- ULONG ioc : 1;
- // DWORD 4;
- ULONG cur_offset : 12;
- ULONG page0 : 20;
- // DWORD 5;
- ULONG trans_count : 3;
- ULONG trans_pos : 2;
- ULONG reserved6 : 7;
- ULONG page1 : 20;
- // DWORD 6;
- ULONG back_terminal : 1;
- ULONG reserved7 : 4;
- ULONG back_ptr : 27;
-
-} EHCI_SITD_CONTENT, *PEHCI_SITD_CONTENT;
-
-typedef struct _EHCI_SITD
-{
- /* first part defined by EHCI spec */
- ULONG hw_next;
- /* uses bit field macros above - see EHCI 0.95 Table 3-8 */
-
- ULONG hw_fullspeed_ep; /* see EHCI table 3-9 */
- ULONG hw_uframe; /* see EHCI table 3-10 */
- ULONG hw_tx_results1; /* see EHCI table 3-11 */
- ULONG hw_tx_results2; /* see EHCI table 3-12 */
- ULONG hw_tx_results3; /* see EHCI table 3-12 */
- ULONG hw_backpointer; /* see EHCI table 3-13 */
-
- /* the rest is HCD-private */
- PEHCI_ELEM_LINKS elem_head_link;
- ULONG phys_addr;
- ULONG buf_phys_addr; /* buffer address */
-
- USHORT usecs; /* start bandwidth */
- USHORT c_usecs; /* completion bandwidth */
- ULONG reserved[ 5 ];
-
-} EHCI_SITD, *PEHCI_SITD; // __attribute__ ((aligned (32)));
-
-/*-------------------------------------------------------------------------*/
-
-/*
- * EHCI Specification 0.96 Section 3.7
- * Periodic Frame Span Traversal Node (FSTN)
- *
- * Manages split interrupt transactions (using TT) that span frame boundaries
- * into uframes 0/1; see 4.12.2.2. In those uframes, a "save place" FSTN
- * makes the HC jump (back) to a QH to scan for fs/ls QH completions until
- * it hits a "restore" FSTN; then it returns to finish other uframe 0/1 work.
- */
-typedef struct _EHCI_FSTN
-{
- ULONG hw_next; /* any periodic q entry */
- ULONG hw_prev; /* qh or EHCI_LIST_END */
-
- /* the rest is HCD-private */
- PEHCI_ELEM_LINKS elem_head_link;
- ULONG phys_addr;
- ULONG reserved[ 4 ];
-
-} EHCI_FSTN, *PEHCI_FSTN; // __attribute__ ((aligned (32)));
-
-
-/* NOTE: urb->transfer_flags expected to not use this bit !!! */
-#define EHCI_STATE_UNLINK 0x8000 /* urb being unlinked */
-
-/*-------------------------------------------------------------------------*/
-
-/* EHCI register interface, corresponds to EHCI Revision 0.95 specification */
-
-/* Section 2.2 Host Controller Capability Registers */
-#define HCS_DEBUG_PORT(p) (((p)>>20)&0xf) /* bits 23:20, debug port? */
-#define HCS_INDICATOR(p) ((p)&(1 << 16)) /* true: has port indicators */
-#define HCS_N_CC(p) (((p)>>12)&0xf) /* bits 15:12, #companion HCs */
-#define HCS_N_PCC(p) (((p)>>8)&0xf) /* bits 11:8, ports per CC */
-#define HCS_PORTROUTED(p) ((p)&(1 << 7)) /* true: port routing */
-#define HCS_PPC(p) ((p)&(1 << 4)) /* true: port power control */
-#define HCS_N_PORTS(p) (((p)>>0)&0xf) /* bits 3:0, ports on HC */
-
-#define HCC_EXT_CAPS(p) (((p)>>8)&0xff) /* for pci extended caps */
-#define HCC_ISOC_CACHE(p) ((p)&(1 << 7)) /* true: can cache isoc frame */
-#define HCC_ISOC_THRES(p) (((p)>>4)&0x7) /* bits 6:4, uframes cached */
-#define HCC_CANPARK(p) ((p)&(1 << 2)) /* true: can park on async qh */
-#define HCC_PGM_FRAMELISTLEN(p) ((p)&(1 << 1)) /* true: periodic_size changes*/
-#define HCC_64BIT_ADDR(p) ((p)&(1)) /* true: can use 64-bit addr */
-
-/* 23:16 is r/w intr rate, in microframes; default "8" == 1/msec */
-#define CMD_PARK (1<<11) /* enable "park" on async qh */
-#define CMD_PARK_CNT(c) (((c)>>8)&3) /* how many transfers to park for */
-#define CMD_LRESET (1<<7) /* partial reset (no ports, etc) */
-#define CMD_IAAD (1<<6) /* "doorbell" interrupt async advance */
-#define CMD_ASE (1<<5) /* async schedule enable */
-#define CMD_PSE (1<<4) /* periodic schedule enable */
-/* 3:2 is periodic frame list size */
-#define CMD_RESET (1<<1) /* reset HC not bus */
-#define CMD_RUN (1<<0) /* start/stop HC */
-
-/* these STS_* flags are also intr_enable bits (USBINTR) */
-#define STS_IAA (1<<5) /* Interrupted on async advance */
-#define STS_FATAL (1<<4) /* such as some PCI access errors */
-#define STS_FLR (1<<3) /* frame list rolled over */
-#define STS_PCD (1<<2) /* port change detect */
-#define STS_ERR (1<<1) /* "error" completion (overflow, ...) */
-#define STS_INT (1<<0) /* "normal" completion (short, ...) */
-
-#define STS_ASS (1<<15) /* Async Schedule Status */
-#define STS_PSS (1<<14) /* Periodic Schedule Status */
-#define STS_RECL (1<<13) /* Reclamation */
-#define STS_HALT (1<<12) /* Not running (any reason) */
-
-/* 31:23 reserved */
-#define PORT_WKOC_E (1<<22) /* wake on overcurrent (enable) */
-#define PORT_WKDISC_E (1<<21) /* wake on disconnect (enable) */
-#define PORT_WKCONN_E (1<<20) /* wake on connect (enable) */
-/* 19:16 for port testing */
-/* 15:14 for using port indicator leds (if HCS_INDICATOR allows) */
-#define PORT_OWNER (1<<13) /* true: companion hc owns this port */
-#define PORT_POWER (1<<12) /* true: has power (see PPC) */
-#define PORT_USB11(x) (((x)&(3<<10))==(1<<10)) /* USB 1.1 device */
-/* 11:10 for detecting lowspeed devices (reset vs release ownership) */
-/* 9 reserved */
-#define PORT_PR (1<<8) /* reset port */
-#define PORT_SUSP (1<<7) /* suspend port */
-#define PORT_RESUME (1<<6) /* resume it */
-#define PORT_OCC (1<<5) /* over current change */
-#define PORT_OC (1<<4) /* over current active */
-#define PORT_PEC (1<<3) /* port enable change */
-#define PORT_PE (1<<2) /* port enable */
-#define PORT_CSC (1<<1) /* connect status change */
-#define PORT_CCS (1<<0) /* device connected */
-
-#define FLAG_CF (1<<0) /* true: we'll support "high speed" */
-
-typedef struct _EHCI_HCS_CONTENT
-{
- ULONG port_count : 4;
- ULONG port_power_control : 1;
- ULONG reserved : 2;
- ULONG port_rout_rules : 1;
- ULONG port_per_chc : 4;
- ULONG chc_count : 4;
- ULONG port_indicator : 1;
- ULONG reserved2 : 3;
- ULONG dbg_port_num : 4;
- ULONG reserved3 : 8;
-
-} EHCI_HCS_CONTENT, *PEHCI_HCS_CONTENT;
-
-typedef struct _EHCI_HCC_CONTENT
-{
- ULONG cur_addr_bits : 1; /* 0: 32 bit addressing 1: 64 bit addressing */
- ULONG var_frame_list : 1; /* 0: 1024 frames, 1: support other number of frames */
- ULONG park_mode : 1;
- ULONG reserved : 1;
- ULONG iso_sched_threshold : 4;
- ULONG eecp_capable : 8;
- ULONG reserved2 : 16;
-
-} EHCI_HCC_CONTENT, *PEHCI_HCC_CONTENT;
-
-typedef struct _EHCI_CAPS {
- UCHAR length; /* CAPLENGTH - size of this struct */
- UCHAR reserved; /* offset 0x1 */
- USHORT hci_version; /* HCIVERSION - offset 0x2 */
- ULONG hcs_params; /* HCSPARAMS - offset 0x4 */
-
- ULONG hcc_params; /* HCCPARAMS - offset 0x8 */
- UCHAR portroute [8]; /* nibbles for routing - offset 0xC */
-
-} EHCI_CAPS, *PEHCI_CAPS;
-
-/* Section 2.3 Host Controller Operational Registers */
-
-#define EHCI_USBCMD 0x00
-#define EHCI_USBSTS 0x04
-#define EHCI_USBINTR 0x08
-#define EHCI_FRINDEX 0x0c
-#define EHCI_CTRLDSSEGMENT 0x10
-#define EHCI_PERIODICLISTBASE 0x14
-#define EHCI_ASYNCLISTBASE 0x18
-#define EHCI_CONFIGFLAG 0x40
-#define EHCI_PORTSC 0x44
-
-#define EHCI_USBINTR_INTE 0x01
-#define EHCI_USBINTR_ERR 0x02
-#define EHCI_USBINTR_PC 0x04
-#define EHCI_USBINTR_FLROVR 0x08
-#define EHCI_USBINTR_HSERR 0x10
-#define EHCI_USBINTR_ASYNC 0x20
-
-typedef struct _EHCI_USBCMD_CONTENT
-{
- ULONG run_stop : 1;
- ULONG hcreset : 1;
- ULONG frame_list_size : 2;
- ULONG periodic_enable : 1;
- ULONG async_enable : 1;
- ULONG door_bell : 1;
- ULONG light_reset : 1;
- ULONG async_park_count : 2;
- ULONG reserved : 1;
- ULONG async_park_enable : 1;
- ULONG reserved1 : 4;
- ULONG int_threshold : 8;
- ULONG reserved2 : 8;
-
-} EHCI_USBCMD_CONTENT, *PEHCI_USBCMD_CONTENT;
-
-typedef struct _EHCI_USBSTS_CONTENT
-{
- ULONG ioc : 1;
- ULONG trasac_error : 1;
- ULONG port_change : 1;
- ULONG fl_rollover : 1;
- ULONG host_system_error : 1;
- ULONG async_advance : 1;
- ULONG reserved : 6;
- ULONG hc_halted : 1;
- ULONG reclaimation : 1;
- ULONG periodic_status : 1;
- ULONG async_status : 1;
- ULONG reserved1 : 16;
-
-} EHCI_USBSTS_CONTENT, *PEHCI_USBSTS_CONTENT;
-
-typedef struct _EHCI_RHPORTSC_CONTENT
-{
- ULONG cur_connect : 1;
- ULONG cur_connect_change : 1;
- ULONG port_enable : 1;
- ULONG port_enable_change : 1;
- ULONG over_current : 1;
- ULONG over_current_change : 1;
- ULONG force_port_resume : 1;
- ULONG suspend : 1;
- ULONG port_reset : 1;
- ULONG reserved : 1;
- ULONG line_status : 2;
- ULONG port_power : 1;
- ULONG port_owner : 1;
- ULONG port_indicator : 2;
- ULONG port_test : 4;
- ULONG we_connect : 1;
- ULONG we_disconnect : 1;
- ULONG we_over_current : 1;
- ULONG reserved1 : 9;
-
-} EHCI_RHPORTSC_CONTENT, *PEHCI_RHPORTSC_CONTENT;
-
-typedef struct _EHCI_REGS {
-
- ULONG command;
- ULONG status;
- ULONG intr_enable;
- ULONG frame_index; /* current microframe number */
- ULONG segment; /* address bits 63:32 if needed */
- ULONG frame_list; /* points to periodic list */
- ULONG async_next; /* address of next async queue head */
- ULONG reserved [9];
- ULONG configured_flag;
- ULONG port_status [0]; /* up to N_PORTS */
-
-} EHCI_REGS, *PEHCI_REGS;
-
-#pragma pack( pop, usb_align )
-
-/* ehci_hcd->lock guards shared data against other CPUs:
- * ehci_hcd: async, reclaim, periodic (and shadow), ...
- * hcd_dev: ep[]
- * ehci_qh: qh_next, qtd_list
- * ehci_qtd: qtd_list
- *
- * Also, hold this lock when talking to HC registers or
- * when updating hw_* fields in shared qh/qtd/... structures.
- */
-
-#define EHCI_MAX_ROOT_PORTS 15 /* see HCS_N_PORTS */
-
-#define EHCI_DEVICE_NAME "\\Device\\EHCI"
-
-#define EHCI_DOS_DEVICE_NAME "\\DosDevices\\EHCI"
-
-#define EHCI_ITD_POOL_IDX INIT_LIST_FLAG_ITD
-#define EHCI_QH_POOL_IDX INIT_LIST_FLAG_QH
-#define EHCI_SITD_POOL_IDX INIT_LIST_FLAG_SITD
-#define EHCI_FSTN_POOL_IDX INIT_LIST_FLAG_FSTN
-#define EHCI_QTD_POOL_IDX INIT_LIST_FLAG_QTD
-
-#define EHCI_DEFAULT_FRAMES UHCI_MAX_FRAMES
-#define EHCI_MAX_SYNC_BUS_TIME 50000 // stands for 100000 ns, only to get wrapped within one word
-
-#define EHCI_SCHED_INT8_INDEX 0
-#define EHCI_SCHED_INT4_INDEX 1
-#define EHCI_SCHED_INT2_INDEX 2
-#define EHCI_SCHED_FSTN_INDEX 3
-#define EHCI_SCHED_INT1_INDEX 4
-
-#define qtd_pool ( &ehci->elem_pools[ EHCI_QTD_POOL_IDX ] )
-#define qh_pool ( &ehci->elem_pools[ EHCI_QH_POOL_IDX ] )
-#define fstn_pool ( &ehci->elem_pools[ EHCI_FSTN_POOL_IDX ] )
-#define itd_pool ( &ehci->elem_pools[ EHCI_ITD_POOL_IDX ] )
-#define sitd_pool ( &ehci->elem_pools[ EHCI_SITD_POOL_IDX ] )
-
-
-typedef struct _EHCI_DEV
-{
- HCD hcd_interf;
-
- EHCI_CAPS ehci_caps;
-
- PHYSICAL_ADDRESS ehci_reg_base; // io space
- BOOLEAN port_mapped;
- PBYTE port_base; // note: added by ehci_caps.length, operational regs base addr, not the actural base
-
- ULONG frame_count;
- PHYSICAL_ADDRESS frame_list_phys_addr;
-
- KSPIN_LOCK frame_list_lock; // run at DIRQL
- PULONG frame_list; // periodic schedule
-
- PFRAME_LIST_CPU_ENTRY frame_list_cpu; // periodic schedule shadow
-
- LIST_HEAD urb_list; // active urb-list
-
- LIST_HEAD async_list_cpu;
- LIST_HEAD periodic_list_cpu[ 8 ]; // each slot for one periodic
- PEHCI_QH skel_async_qh;
-
-
- //
- // pools for device specific data
- //
- EHCI_ELEM_POOL elem_pools[ 5 ];
-
- //
- //for iso and int bandwidth claim, bandwidth schedule
- //
- KSPIN_LOCK pending_endp_list_lock; //lock to access the following two
- LIST_HEAD pending_endp_list;
- UHCI_PENDING_ENDP_POOL pending_endp_pool;
- PUSHORT frame_bw; //unit uFrame
- USHORT min_bw; //the bottle-neck of the bandwidths across frame-list
-
- KTIMER reset_timer; //used to reset the host controller
- struct _EHCI_DEVICE_EXTENSION *pdev_ext;
- PUSB_DEV root_hub; //root hub
-
-} EHCI_DEV, *PEHCI_DEV;
-
-typedef UHCI_PORT EHCI_MEMORY;
-
-typedef struct _EHCI_DEVICE_EXTENSION
-{
- //struct _USB_DEV_MANAGER *pdev_mgr;
- DEVEXT_HEADER dev_ext_hdr;
- PDEVICE_OBJECT pdev_obj;
- PDRIVER_OBJECT pdrvr_obj;
- PEHCI_DEV ehci;
-
- //device resources
- PADAPTER_OBJECT padapter;
- ULONG map_regs;
- PCM_RESOURCE_LIST res_list;
- ULONG pci_addr; // bus number | slot number | funciton number
- UHCI_INTERRUPT res_interrupt;
- union
- {
- UHCI_PORT res_port;
- EHCI_MEMORY res_memory;
- };
-
- PKINTERRUPT ehci_int;
- KDPC ehci_dpc;
-
-} EHCI_DEVICE_EXTENSION, *PEHCI_DEVICE_EXTENSION;
-
-/*-------------------------------------------------------------------------*/
-
-#endif /* __EHCI_H__ */
diff --git a/reactos/drivers/usb/nt4compat/usbdrv/etd.c b/reactos/drivers/usb/nt4compat/usbdrv/etd.c
deleted file mode 100644
index e3a4d32089f..00000000000
--- a/reactos/drivers/usb/nt4compat/usbdrv/etd.c
+++ /dev/null
@@ -1,643 +0,0 @@
-/**
- * etd.c - USB driver stack project for Windows NT 4.0
- *
- * Copyright (c) 2002-2004 Zhiming mypublic99@yahoo.com
- *
- * This program/include file is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program/include file is distributed in the hope that it will be
- * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
- * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program (in the main directory of the distribution, the file
- * COPYING); if not, write to the Free Software Foundation,Inc., 59 Temple
- * Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include
-#include "ehci.h"
-
-#define init_elem( ptr, type, ehci_elem_type ) \
-{\
- PEHCI_ELEM_LINKS tmp;\
- ptr = ( type* )( plist->phys_bufs[ i ] + sizeof( type ) * j );\
- ptr->hw_next = ehci_elem_type << 1;\
- if( ehci_elem_type == INIT_LIST_FLAG_QTD )\
- ptr->hw_next = 0;\
- tmp = ptr->elem_head_link = &plist->elem_head_buf[ i * elms_per_page + j ];\
- InitializeListHead( &tmp->elem_link );\
- InitializeListHead( &tmp->sched_link );\
- InsertTailList( &plist->free_list, &tmp->elem_link );\
- tmp->list_link = plist;\
- tmp->pool_link = pinit_ctx->pool;\
- tmp->phys_part = ( PVOID )( ( ULONG )ptr | ( ehci_elem_type << 1 ) );\
- if( ehci_elem_type != INIT_LIST_FLAG_QTD )\
- ptr->phys_addr = ( plist->phys_addrs[ i ].LowPart + sizeof( type ) * j ) | ( ehci_elem_type << 1 );\
- else \
- ptr->phys_addr = plist->phys_addrs[ i ].LowPart + sizeof( type ) * j ;\
-}
-
-// get the actual max list count of the pool, two limit, max_elem_pool and max_lists_pool
-#define get_max_lists_count( pOOL, max_liSTS ) \
-{\
- LONG ii1=0;\
- switch( elem_pool_get_type( pOOL ) )\
- {\
- case INIT_LIST_FLAG_QTD:\
- ii1 = EHCI_MAX_QTDS_LIST;\
- break;\
- case INIT_LIST_FLAG_FSTN:\
- ii1 = EHCI_MAX_QHS_LIST;\
- break;\
- case INIT_LIST_FLAG_SITD:\
- ii1 = EHCI_MAX_ITDS_LIST;\
- break;\
- case INIT_LIST_FLAG_QH: \
- ii1 = EHCI_MAX_SITDS_LIST;\
- break;\
- case INIT_LIST_FLAG_ITD: \
- ii1 = EHCI_MAX_FSTNS_LIST;\
- break;\
- }\
- max_liSTS = ( EHCI_MAX_ELEMS_POOL / ii1 ) > EHCI_MAX_LISTS_POOL ? EHCI_MAX_LISTS_POOL : ( EHCI_MAX_ELEMS_POOL / ii1 );\
-}
-
-VOID elem_list_destroy_elem_list(PEHCI_ELEM_LIST plist);
-
-PLIST_ENTRY elem_list_get_list_head(PEHCI_ELEM_LIST plist);
-
-LONG elem_list_get_total_count(PEHCI_ELEM_LIST plist);
-
-LONG elem_list_get_elem_size(PEHCI_ELEM_LIST plist);
-
-LONG elem_list_get_link_offset(PEHCI_ELEM_LIST plist);
-
-LONG elem_list_add_ref(PEHCI_ELEM_LIST plist);
-
-LONG elem_list_release_ref(PEHCI_ELEM_LIST plist);
-
-LONG elem_list_get_ref(PEHCI_ELEM_LIST plist);
-
-BOOLEAN
-elem_pool_lock(PEHCI_ELEM_POOL pool, BOOLEAN at_dpc)
-{
- UNREFERENCED_PARAMETER(pool);
- UNREFERENCED_PARAMETER(at_dpc);
-
- return TRUE;
-}
-
-BOOLEAN
-elem_pool_unlock(PEHCI_ELEM_POOL pool, BOOLEAN at_dpc)
-{
- UNREFERENCED_PARAMETER(pool);
- UNREFERENCED_PARAMETER(at_dpc);
-
- return TRUE;
-}
-
-LONG
-get_elem_phys_part_size(ULONG type)
-{
- // type is INIT_LIST_FLAG_XXX
- LONG size;
-
- size = 0;
- switch (type)
- {
- case INIT_LIST_FLAG_ITD:
- size = 64;
- break;
- case INIT_LIST_FLAG_SITD:
- size = 28;
- break;
- case INIT_LIST_FLAG_QTD:
- size = 32;
- break;
- case INIT_LIST_FLAG_QH:
- size = 48;
- break;
- case INIT_LIST_FLAG_FSTN:
- size = 8;
- break;
- }
- return size;
-}
-
-BOOLEAN
-elem_list_init_elem_list(PEHCI_ELEM_LIST plist, LONG init_flags, PVOID context, LONG count)
-{
- LONG pages, i, j, elms_per_page;
- PEHCI_QH pqh;
- PEHCI_ITD pitd;
- PEHCI_SITD psitd;
- PEHCI_QTD pqtd;
- PEHCI_FSTN pfstn;
- PINIT_ELEM_LIST_CONTEXT pinit_ctx;
-
- UNREFERENCED_PARAMETER(count);
-
- if (plist == NULL || context == NULL)
- return FALSE;
-
- RtlZeroMemory(plist, sizeof(EHCI_ELEM_LIST));
-
- pinit_ctx = context;
-
- plist->destroy_list = elem_list_destroy_elem_list;
- plist->get_list_head = elem_list_get_list_head;
- plist->get_total_count = elem_list_get_total_count;
- plist->get_elem_size = elem_list_get_elem_size;
- plist->get_link_offset = elem_list_get_link_offset;
- plist->add_ref = elem_list_add_ref;
- plist->release_ref = elem_list_release_ref;
- plist->get_ref = elem_list_get_ref;
-
- InitializeListHead(&plist->free_list);
-
- switch (init_flags & 0x0f)
- {
- case INIT_LIST_FLAG_ITD:
- plist->total_count = EHCI_MAX_ITDS_LIST;
- plist->elem_size = sizeof(EHCI_ITD);
- break;
- case INIT_LIST_FLAG_QH:
- plist->total_count = EHCI_MAX_QHS_LIST;
- plist->elem_size = sizeof(EHCI_QH);
- break;
- case INIT_LIST_FLAG_SITD:
- plist->total_count = EHCI_MAX_SITDS_LIST;
- plist->elem_size = sizeof(EHCI_SITD);
- break;
- case INIT_LIST_FLAG_FSTN:
- plist->total_count = EHCI_MAX_FSTNS_LIST;
- plist->elem_size = sizeof(EHCI_FSTN);
- break;
- case INIT_LIST_FLAG_QTD:
- plist->total_count = EHCI_MAX_QTDS_LIST;
- plist->elem_size = sizeof(EHCI_QTD);
- break;
- default:
- goto ERROR_OUT;
- }
- if (plist->elem_size & 0x1f)
- {
- plist->total_count = 0;
- goto ERROR_OUT;
- }
-
- plist->flags = init_flags;
- plist->parent_pool = pinit_ctx->pool;
- plist->padapter = pinit_ctx->padapter;
- pages = ((plist->elem_size * plist->total_count) + (PAGE_SIZE - 1)) / PAGE_SIZE;
- elms_per_page = PAGE_SIZE / plist->elem_size;
-
- plist->phys_addrs = usb_alloc_mem(NonPagedPool,
- (sizeof(PHYSICAL_ADDRESS) + sizeof(PBYTE)) * pages +
- sizeof(EHCI_ELEM_LINKS) * plist->total_count);
-
- if (plist->phys_addrs == NULL)
- {
- plist->total_count = 0;
- goto ERROR_OUT;
- }
-
- plist->phys_bufs = (PBYTE *) & plist->phys_addrs[pages];
- plist->elem_head_buf = (PEHCI_ELEM_LINKS) & plist->phys_bufs[pages];
- RtlZeroMemory(plist->phys_addrs,
- (sizeof(PHYSICAL_ADDRESS) + sizeof(PBYTE)) * pages +
- sizeof(EHCI_ELEM_LINKS) * plist->total_count);
-
- for(i = 0; i < pages; i++)
- {
- plist->phys_bufs[i] = HalAllocateCommonBuffer(plist->padapter,
- PAGE_SIZE, &plist->phys_addrs[i], FALSE);
-
- if (plist->phys_bufs[i] == NULL)
- {
- // failed, roll back
- for(j = i - 1; j >= 0; j--)
- HalFreeCommonBuffer(plist->padapter,
- PAGE_SIZE, plist->phys_addrs[j], plist->phys_bufs[j], FALSE);
- goto ERROR_OUT;
- }
- RtlZeroMemory(plist->phys_bufs[i], PAGE_SIZE);
- for(j = 0; j < elms_per_page; j++)
- {
- switch (init_flags & 0xf)
- {
- case INIT_LIST_FLAG_QH:
- {
- init_elem(pqh, EHCI_QH, INIT_LIST_FLAG_QH);
- break;
- }
- case INIT_LIST_FLAG_ITD:
- {
- init_elem(pitd, EHCI_ITD, INIT_LIST_FLAG_ITD);
- break;
- }
- case INIT_LIST_FLAG_QTD:
- {
- init_elem(pqtd, EHCI_QTD, INIT_LIST_FLAG_QTD);
- break;
- }
- case INIT_LIST_FLAG_SITD:
- {
- init_elem(psitd, EHCI_SITD, INIT_LIST_FLAG_SITD);
- break;
- }
- case INIT_LIST_FLAG_FSTN:
- {
- init_elem(pfstn, EHCI_FSTN, INIT_LIST_FLAG_FSTN);
- break;
- }
- default:
- TRAP();
- }
- }
- }
- return TRUE;
-
-ERROR_OUT:
- if (plist->phys_addrs != NULL)
- usb_free_mem(plist->phys_addrs);
-
- RtlZeroMemory(plist, sizeof(EHCI_ELEM_LIST));
- return FALSE;
-}
-
-VOID
-elem_list_destroy_elem_list(PEHCI_ELEM_LIST plist)
-{
- LONG i, pages;
-
- if (plist == NULL)
- return;
-
- pages = (plist->total_count * plist->elem_size + PAGE_SIZE - 1) / PAGE_SIZE;
- for(i = 0; i < pages; i++)
- HalFreeCommonBuffer(plist->padapter, PAGE_SIZE, plist->phys_addrs[i], plist->phys_bufs[i], FALSE);
-
- usb_free_mem(plist->phys_addrs);
- RtlZeroMemory(plist, sizeof(EHCI_ELEM_LIST));
-}
-
-PLIST_ENTRY
-elem_list_get_list_head(PEHCI_ELEM_LIST plist)
-{
- if (plist == NULL)
- return NULL;
- return &plist->free_list;
-}
-
-LONG
-elem_list_get_total_count(PEHCI_ELEM_LIST plist)
-{
- if (plist == NULL)
- return 0;
- return plist->total_count;
-}
-
-LONG
-elem_list_get_elem_size(PEHCI_ELEM_LIST plist)
-{
- if (plist == NULL)
- return 0;
- return plist->elem_size;
-}
-
-LONG
-elem_list_get_link_offset(PEHCI_ELEM_LIST plist)
-{
- if (plist == NULL)
- return 0;
-
- return get_elem_phys_part_size(plist->flags & 0xf);
-}
-
-LONG
-elem_list_add_ref(PEHCI_ELEM_LIST plist)
-{
- plist->reference++;
- return plist->reference;
-}
-
-LONG
-elem_list_release_ref(PEHCI_ELEM_LIST plist)
-{
- plist->reference--;
- return plist->reference;
-}
-
-LONG
-elem_list_get_ref(PEHCI_ELEM_LIST plist)
-{
- return plist->reference;
-}
-
-//
-// pool methods
-//
-
-BOOLEAN
-elem_pool_init_pool(PEHCI_ELEM_POOL pool, LONG flags, PVOID context)
-{
- INIT_ELEM_LIST_CONTEXT init_ctx;
-
- if (pool == NULL || context == NULL)
- return FALSE;
-
- RtlZeroMemory(pool, sizeof(EHCI_ELEM_POOL));
-
- init_ctx.pool = pool;
- init_ctx.padapter = context;
-
- pool->elem_lists[0] = usb_alloc_mem(NonPagedPool, sizeof(EHCI_ELEM_LIST));
-
- if (pool->elem_lists[0] == NULL)
- return FALSE;
-
- if (elem_list_init_elem_list(pool->elem_lists[0], flags, &init_ctx, 0) == FALSE)
- {
- usb_free_mem(pool->elem_lists[0]);
- return FALSE;
- }
- pool->link_offset = pool->elem_lists[0]->get_link_offset(pool->elem_lists[0]);
- pool->free_count = pool->elem_lists[0]->get_total_count(pool->elem_lists[0]);
- pool->list_count = 1;
- pool->flags = flags;
-
- return TRUE;
-}
-
-LONG
-elem_pool_get_link_offset(PEHCI_ELEM_POOL elem_pool)
-{
- return elem_pool->link_offset;
-}
-
-LONG
-elem_pool_get_total_count(PEHCI_ELEM_POOL elem_pool)
-{
- return elem_pool->elem_lists[0]->get_total_count(elem_pool->elem_lists[0]) * elem_pool->list_count;
-}
-
-VOID
-elem_pool_destroy_pool(PEHCI_ELEM_POOL pool)
-{
- LONG i;
- if (pool == NULL)
- return;
- for(i = pool->list_count - 1; i >= 0; i--)
- {
- pool->elem_lists[i]->destroy_list(pool->elem_lists[i]);
- usb_free_mem(pool->elem_lists[i]);
- pool->elem_lists[i] = NULL;
- }
- RtlZeroMemory(pool, sizeof(EHCI_ELEM_POOL));
- return;
-}
-
-PEHCI_ELEM_LINKS
-elem_pool_alloc_elem(PEHCI_ELEM_POOL pool)
-{
- LONG i;
- PEHCI_ELEM_LIST pel = NULL;
- PLIST_HEAD lh;
- PEHCI_ELEM_LINKS elnk;
-
- if (pool == NULL)
- return NULL;
-
- for(i = 0; i < pool->list_count; i++)
- {
- pel = pool->elem_lists[i];
- if (pel->get_ref(pel) == pel->get_total_count(pel))
- continue;
- break;
- }
- if (i == pool->list_count)
- {
- if (elem_pool_expand_pool(pool, pel->get_total_count(pel)) == FALSE)
- return NULL;
- pel = pool->elem_lists[i];
- }
-
- lh = pel->get_list_head(pel);
- elnk = (PEHCI_ELEM_LINKS) RemoveHeadList(lh);
- InitializeListHead(&elnk->elem_link);
- InitializeListHead(&elnk->sched_link);
-
- pel->add_ref(pel);
- pool->free_count--;
-
- return elnk;
-}
-
-VOID
-elem_pool_free_elem(PEHCI_ELEM_LINKS elem_link)
-{
- PLIST_HEAD lh;
- LONG ref;
- PEHCI_ELEM_POOL pool;
- if (elem_link == NULL)
- return;
- pool = elem_link->pool_link;
- lh = elem_link->list_link->get_list_head(elem_link->list_link);
- if (lh == NULL)
- return;
- InsertHeadList(lh, &elem_link->elem_link);
- ref = elem_link->list_link->release_ref(elem_link->list_link);
- pool->free_count++;
- if (ref == 0)
- elem_pool_collect_garbage(pool);
- return;
-}
-
-BOOLEAN
-elem_pool_is_empty(PEHCI_ELEM_POOL pool)
-{
- PEHCI_ELEM_LIST pel;
-
- if (pool == NULL)
- return TRUE;
- pel = pool->elem_lists[0];
- return (BOOLEAN) (pool->list_count == 1 && pool->free_count == pel->get_total_count(pel));
-}
-
-LONG
-elem_pool_get_free_count(PEHCI_ELEM_POOL pool)
-{
- if (pool == NULL)
- return 0;
- return pool->free_count;
-}
-
-PEHCI_ELEM_LINKS
-elem_pool_alloc_elems(PEHCI_ELEM_POOL pool, LONG count)
-{
- LIST_HEAD lh;
- PLIST_ENTRY pthis;
- LONG i, alloc_count, max_pool_lists;
- PEHCI_ELEM_LIST pel;
- PEHCI_ELEM_LINKS elnk;
- // calculate to see if the count is affordable
-
- if (pool == NULL || count <= 0)
- return NULL;
-
- get_max_lists_count(pool, max_pool_lists);
- InitializeListHead(&lh);
- pel = pool->elem_lists[0];
- if (count <= pool->free_count)
- alloc_count = 0;
- else
- alloc_count = count - pool->free_count;
-
- if (alloc_count > pel->get_total_count(pel) * (max_pool_lists - pool->list_count))
- return NULL;
-
- for(i = 0; i < count; i++)
- {
- if ((elnk = elem_pool_alloc_elem(pool)) == NULL)
- {
- // undo what we have done
- while (IsListEmpty(&lh) == FALSE)
- {
- pthis = RemoveHeadList(&lh);
- elnk = struct_ptr(pthis, EHCI_ELEM_LINKS, elem_link);
- elem_pool_free_elem(elnk);
- }
- return NULL;
- }
- InsertTailList(&lh, &elnk->elem_link);
- }
- ListFirst(&lh, pthis);
- elnk = struct_ptr(pthis, EHCI_ELEM_LINKS, elem_link);
- RemoveEntryList(&lh);
- return elnk;
-}
-
-BOOLEAN
-elem_pool_free_elems(PEHCI_ELEM_LINKS elem_chains)
-{
- // note: no list head exists.
- LIST_HEAD lh;
- PEHCI_ELEM_LINKS elnk;
-
- InsertTailList(&elem_chains->elem_link, &lh);
- while (IsListEmpty(&lh) == FALSE)
- {
- elnk = (PEHCI_ELEM_LINKS) RemoveHeadList(&lh);
- elem_pool_free_elem(elnk);
- }
- return TRUE;
-}
-
-LONG
-elem_pool_get_type(PEHCI_ELEM_POOL pool)
-{
- if (pool == NULL)
- return -1;
- return (pool->flags & 0xf);
-}
-
-BOOLEAN
-elem_pool_expand_pool(PEHCI_ELEM_POOL pool, LONG elem_count)
-{
- LONG elem_cnt_list, list_count, i, j;
- INIT_ELEM_LIST_CONTEXT init_ctx;
-
- if (pool == NULL || elem_count <= 0 || elem_count > EHCI_MAX_ELEMS_POOL)
- return FALSE;
-
- init_ctx.pool = pool;
- init_ctx.padapter = pool->elem_lists[0]->padapter;
-
- elem_cnt_list = pool->elem_lists[0]->get_total_count(pool->elem_lists[0]);
- list_count = (elem_count + elem_cnt_list - 1) / elem_cnt_list;
- get_max_lists_count(pool, i);
-
- if (list_count + pool->list_count > i)
- return FALSE;
-
- for(i = pool->list_count; i < list_count + pool->list_count; i++)
- {
- pool->elem_lists[i] = usb_alloc_mem(NonPagedPool, sizeof(EHCI_ELEM_LIST));
- if (elem_list_init_elem_list(pool->elem_lists[i], pool->flags, &init_ctx, 0) == FALSE)
- break;
- }
-
- if (i < list_count + pool->list_count)
- {
- // undo all we have done
- for(j = pool->list_count; j < pool->list_count + i; j++)
- {
- pool->elem_lists[j]->destroy_list(pool->elem_lists[j]);
- usb_free_mem(pool->elem_lists[j]);
- pool->elem_lists[j] = NULL;
- }
- return FALSE;
- }
-
- // update pool
- pool->free_count += elem_cnt_list * list_count;
- pool->list_count += list_count;
- return TRUE;
-}
-
-BOOLEAN
-elem_pool_collect_garbage(PEHCI_ELEM_POOL pool)
-{
- LONG i, j, k, fl;
- LONG free_elem_lists[EHCI_MAX_LISTS_POOL - 1];
- PEHCI_ELEM_LIST pel;
-
- if (pool == NULL)
- return FALSE;
-
- for(i = 1, fl = 0; i < pool->list_count; i++)
- {
- if (pool->elem_lists[i]->get_ref(pool->elem_lists[i]) == 0)
- {
- free_elem_lists[fl++] = i;
- }
- }
- for(j = fl - 1; j >= 0; j--)
- {
- pel = pool->elem_lists[free_elem_lists[j]];
- pel->destroy_list(pel);
- usb_free_mem(pel);
-
- for(k = free_elem_lists[j] + 1; k < pool->list_count; k++)
- {
- // shrink the elem_lists
- pool->elem_lists[k - 1] = pool->elem_lists[k];
- }
- pool->elem_lists[k] = NULL;
- pel = pool->elem_lists[0];
- pool->free_count -= pel->get_total_count(pel);
- pool->list_count--;
- }
- return TRUE;
-}
-
-BOOLEAN
-elem_pool_can_transfer(PEHCI_ELEM_POOL pool, LONG td_count)
-{
- LONG i;
- if (pool == NULL || td_count <= 0)
- return FALSE;
- get_max_lists_count(pool, i);
- if ((i - pool->list_count)
- * pool->elem_lists[0]->get_total_count(pool->elem_lists[0]) + pool->free_count < td_count)
- return FALSE;
- return TRUE;
-}
-
-//----------------------------------------------------------
diff --git a/reactos/drivers/usb/nt4compat/usbdrv/events.h b/reactos/drivers/usb/nt4compat/usbdrv/events.h
deleted file mode 100644
index bbbe4f3144b..00000000000
--- a/reactos/drivers/usb/nt4compat/usbdrv/events.h
+++ /dev/null
@@ -1,148 +0,0 @@
-#ifndef __EVENTS_H
-#define __EVENTS_H
-
-//event definitions
-
-#define MAX_EVENTS 128
-#define MAX_TIMER_SVCS 24
-
-#define USB_EVENT_FLAG_ACTIVE 0x80000000
-
-#define USB_EVENT_FLAG_QUE_TYPE 0x000000FF
-#define USB_EVENT_FLAG_QUE_RESET 0x01
-#define USB_EVENT_FLAG_NOQUE 0x00
-
-#define USB_EVENT_DEFAULT 0x00 //as a placeholder
-#define USB_EVENT_INIT_DEV_MGR 0x01
-#define USB_EVENT_HUB_POLL 0x02
-#define USB_EVENT_WAIT_RESET_PORT 0x03
-#define USB_EVENT_CLEAR_TT_BUFFER 0x04
-
-typedef VOID ( *PROCESS_QUEUE )(
-PLIST_HEAD event_list,
-struct _USB_EVENT_POOL *event_pool,
-struct _USB_EVENT *usb_event,
-struct _USB_EVENT *out_event
-);
-
-typedef VOID ( *PROCESS_EVENT )(
-PUSB_DEV dev,
-ULONG event,
-ULONG context,
-ULONG param
-);
-
-typedef struct _USB_EVENT
-{
- LIST_ENTRY event_link;
- ULONG flags;
- ULONG event;
- PUSB_DEV pdev;
- ULONG context;
- ULONG param;
- struct _USB_EVENT *pnext; //vertical queue for serialized operation
- PROCESS_EVENT process_event;
- PROCESS_QUEUE process_queue;
-
-} USB_EVENT, *PUSB_EVENT;
-
-typedef struct _USB_EVENT_POOL
-{
- PUSB_EVENT event_array;
- LIST_HEAD free_que;
- LONG free_count;
- LONG total_count;
- KSPIN_LOCK pool_lock;
-
-} USB_EVENT_POOL, *PUSB_EVENT_POOL;
-
-BOOLEAN
-init_event_pool(
-PUSB_EVENT_POOL pool
-);
-
-BOOLEAN
-free_event(
-PUSB_EVENT_POOL pool,
-PUSB_EVENT pevent
-); //add qhs till pnext == NULL
-
-PUSB_EVENT
-alloc_event(
-PUSB_EVENT_POOL pool,
-LONG count
-); //null if failed
-
-BOOLEAN
-destroy_event_pool(
-PUSB_EVENT_POOL pool
-);
-
-VOID
-lock_event_pool(
-PUSB_EVENT_POOL pool
-);
-
-VOID
-unlock_event_pool(
-PUSB_EVENT_POOL pool
-);
-
-#define DEV_MGR_TIMER_INTERVAL_NS ( 10 * 1000 * 10 ) //unit 100 ns
-#define DEV_MGR_TIMER_INTERVAL_MS 10
-
-typedef VOID ( *TIMER_SVC_HANDLER )(PUSB_DEV dev, PVOID context);
-
-typedef struct _TIMER_SVC
-{
- LIST_ENTRY timer_svc_link;
- ULONG counter;
- ULONG threshold;
- ULONG context;
- PUSB_DEV pdev;
- TIMER_SVC_HANDLER func;
-
-} TIMER_SVC, *PTIMER_SVC;
-
-typedef struct _TIMER_SVC_POOL
-{
- PTIMER_SVC timer_svc_array;
- LIST_HEAD free_que;
- LONG free_count;
- LONG total_count;
- KSPIN_LOCK pool_lock;
-
-} TIMER_SVC_POOL, *PTIMER_SVC_POOL;
-
-BOOLEAN
-init_timer_svc_pool(
-PTIMER_SVC_POOL pool
-);
-BOOLEAN
-free_timer_svc(
-PTIMER_SVC_POOL pool,
-PTIMER_SVC ptimer
-);
-
-PTIMER_SVC
-alloc_timer_svc(
-PTIMER_SVC_POOL pool,
-LONG count
-); //null if failed
-
-BOOLEAN
-destroy_timer_svc_pool(
-PTIMER_SVC_POOL pool
-);
-
-VOID
-lock_timer_svc_pool(
-PTIMER_SVC_POOL pool
-);
-
-VOID
-unlock_timer_svc_pool(
-PTIMER_SVC_POOL pool
-);
-
-#endif
diff --git a/reactos/drivers/usb/nt4compat/usbdrv/gendrv.c b/reactos/drivers/usb/nt4compat/usbdrv/gendrv.c
deleted file mode 100644
index b9b4231ddb2..00000000000
--- a/reactos/drivers/usb/nt4compat/usbdrv/gendrv.c
+++ /dev/null
@@ -1,1847 +0,0 @@
-/**
- * gendrv.c - USB driver stack project for Windows NT 4.0
- *
- * Copyright (c) 2002-2004 Zhiming mypublic99@yahoo.com
- *
- * This program/include file is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program/include file is distributed in the hope that it will be
- * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
- * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program (in the main directory of the distribution, the file
- * COPYING); if not, write to the Free Software Foundation,Inc., 59 Temple
- * Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-//this driver is part of the dev manager responsible to manage non-driver device
-#include "usbdriver.h"
-#include "gendrv.h"
-
-#define if_dev( dev_obj ) \
-( ( ( ( PGENDRV_DEVICE_EXTENSION)dev_obj->DeviceExtension )->pdriver->driver_desc.flags & USB_DRIVER_FLAG_IF_CAPABLE ) != 0 )
-
-#define GENDRV_EXIT_DISPATCH( dev_OBJ, staTUS, iRp ) \
-{\
- iRp->IoStatus.Status = staTUS;\
- if( staTUS != STATUS_PENDING)\
- {\
- IoCompleteRequest( iRp, IO_NO_INCREMENT);\
- return staTUS;\
- }\
- IoMarkIrpPending( iRp );\
- IoStartPacket( dev_OBJ, iRp, NULL, gendrv_cancel_queued_irp ); \
- return STATUS_PENDING;\
-}
-
-#define GENDRV_COMPLETE_START_IO( dev_OBJ, staTUS, iRP ) \
-{\
- iRP->IoStatus.Status = staTUS;\
- if( staTUS != STATUS_PENDING )\
- {\
- IoStartNextPacket( dev_OBJ, TRUE );\
- IoCompleteRequest( iRP, IO_NO_INCREMENT );\
- }\
- return;\
-}
-
-extern POBJECT_TYPE NTSYSAPI IoDriverObjectType;
-
-extern VOID disp_urb_completion(PURB purb, PVOID context);
-
-
-VOID disp_noio_urb_completion(PURB purb, PVOID context);
-
-NTSYSAPI NTSTATUS NTAPI ZwLoadDriver(IN PUNICODE_STRING DriverServiceName);
-
-NTSYSAPI NTSTATUS NTAPI ZwClose(IN HANDLE Handle);
-
-NTSYSAPI
-NTSTATUS
-NTAPI
-ObOpenObjectByName(IN POBJECT_ATTRIBUTES ObjectAttributes,
- IN POBJECT_TYPE ObjectType OPTIONAL,
- IN KPROCESSOR_MODE AccessMode,
- IN OUT PACCESS_STATE AccessState OPTIONAL,
- IN ACCESS_MASK DesiredAccess OPTIONAL,
- IN OUT PVOID ParseContext OPTIONAL, OUT PHANDLE Handle);
-
-BOOLEAN gendrv_if_driver_destroy(PUSB_DEV_MANAGER dev_mgr, PUSB_DRIVER pdriver);
-
-VOID gendrv_set_cfg_completion(PURB purb, PVOID context);
-
-BOOLEAN gendrv_connect(PDEV_CONNECT_DATA param, DEV_HANDLE dev_handle);
-
-BOOLEAN gendrv_stop(PUSB_DEV_MANAGER dev_mgr, DEV_HANDLE dev_handle);
-
-BOOLEAN gendrv_disconnect(PUSB_DEV_MANAGER dev_mgr, DEV_HANDLE dev_handle);
-
-VOID gendrv_startio(IN PDEVICE_OBJECT dev_obj, IN PIRP irp);
-
-VOID NTAPI gendrv_cancel_queued_irp(PDEVICE_OBJECT pdev_obj, PIRP pirp);
-
-VOID gendrv_release_ext_drvr_entry(PGENDRV_DRVR_EXTENSION pdrvr_ext, PGENDRV_EXT_DRVR_ENTRY pentry);
-
-VOID gendrv_clean_up_queued_irps(PDEVICE_OBJECT dev_obj);
-
-PGENDRV_EXT_DRVR_ENTRY gendrv_alloc_ext_drvr_entry(PGENDRV_DRVR_EXTENSION pdrvr_ext);
-
-PDRIVER_OBJECT gendrv_open_ext_driver(PUNICODE_STRING unicode_string);
-
-NTSTATUS
-gendrv_get_key_value(IN HANDLE KeyHandle, IN PWSTR ValueName, OUT PKEY_VALUE_FULL_INFORMATION * Information);
-
-NTSTATUS
-gendrv_open_reg_key(OUT PHANDLE handle,
- IN HANDLE base_handle OPTIONAL,
- IN PUNICODE_STRING keyname, IN ACCESS_MASK desired_access, IN BOOLEAN create);
-
-BOOLEAN gendrv_do_disconnect(PUSB_DEV_MANAGER dev_mgr, DEV_HANDLE if_handle, BOOLEAN is_if);
-
-BOOLEAN gendrv_do_stop(PUSB_DEV_MANAGER dev_mgr, DEV_HANDLE dev_handle, BOOLEAN is_if);
-
-NTSTATUS gendrv_send_pnp_msg(ULONG msg, PDEVICE_OBJECT pdev_obj, PVOID pctx);
-
-BOOLEAN gendrv_delete_device(PUSB_DEV_MANAGER dev_mgr, PDEVICE_OBJECT dev_obj);
-
-PDEVICE_OBJECT gendrv_create_device(PUSB_DEV_MANAGER dev_mgr, PUSB_DRIVER gen_drvr, DEV_HANDLE dev_handle);
-
-PDRIVER_OBJECT gendrv_load_ext_drvr(PGENDRV_DRVR_EXTENSION pdrvr_ext, PUSB_DESC_HEADER pdesc);
-
-PDRIVER_OBJECT gendrv_find_drvr_by_key(PGENDRV_DRVR_EXTENSION pdrvr_ext, ULONG key);
-
-ULONG gendrv_make_key(PUSB_DESC_HEADER pdesc);
-
-BOOLEAN
-gendrv_driver_init(PUSB_DEV_MANAGER dev_mgr, PUSB_DRIVER pdriver)
-{
- PGENDRV_DRVR_EXTENSION pdrvr_ext;
-
- if (dev_mgr == NULL || pdriver == NULL)
- return FALSE;
-
- pdriver->driver_desc.flags = USB_DRIVER_FLAG_DEV_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 = 0; // Configuration Value
- pdriver->driver_desc.if_num = 0; // Interface Number
- pdriver->driver_desc.if_class = 0xff; // Interface Class
- pdriver->driver_desc.if_sub_class = 0xff; // Interface SubClass
- pdriver->driver_desc.if_protocol = 0xff; // Interface Protocol
-
- pdriver->driver_desc.driver_name = "USB generic dev driver"; // Driver name for Name Registry
- pdriver->driver_desc.dev_class = USB_CLASS_VENDOR_SPEC;
- pdriver->driver_desc.dev_sub_class = 0; // Device Subclass
- pdriver->driver_desc.dev_protocol = 0; // Protocol Info.
-
- pdriver->driver_ext = usb_alloc_mem(NonPagedPool, sizeof(GENDRV_DRVR_EXTENSION));
- if (!pdriver->driver_ext)
- {
- usb_dbg_print(DBGLVL_MAXIMUM, ("gendrv_driver_init(): memory allocation failed!\n"));
- return FALSE;
- }
-
- pdriver->driver_ext_size = sizeof(GENDRV_DRVR_EXTENSION);
-
- RtlZeroMemory(pdriver->driver_ext, pdriver->driver_ext_size);
- pdrvr_ext = (PGENDRV_DRVR_EXTENSION) pdriver->driver_ext;
-
- // InitializeListHead( &pdrvr_ext->dev_list );
- InitializeListHead(&pdrvr_ext->ext_drvr_list);
- pdrvr_ext->ext_drvr_count = 0;
- ExInitializeFastMutex(&pdrvr_ext->drvr_ext_mutex);
-
- pdriver->disp_tbl.version = 1;
- pdriver->disp_tbl.dev_connect = gendrv_connect;
- pdriver->disp_tbl.dev_disconnect = gendrv_disconnect;
- pdriver->disp_tbl.dev_stop = gendrv_stop;
- pdriver->disp_tbl.dev_reserved = NULL;
-
- return TRUE;
-}
-
-BOOLEAN
-gendrv_driver_destroy(PUSB_DEV_MANAGER dev_mgr, PUSB_DRIVER pdriver)
-{
- return gendrv_if_driver_destroy(dev_mgr, pdriver);
-}
-
-BOOLEAN
-gendrv_connect(PDEV_CONNECT_DATA param, DEV_HANDLE dev_handle)
-{
- PURB purb;
- PUSB_CTRL_SETUP_PACKET psetup;
- NTSTATUS status;
- PUCHAR buf;
- LONG i;
- PUSB_CONFIGURATION_DESC pconfig_desc;
- PUSB_DEV_MANAGER dev_mgr;
-
- if (param == NULL || dev_handle == 0)
- return FALSE;
-
- dev_mgr = param->dev_mgr;
-
- // let's set the configuration
- purb = usb_alloc_mem(NonPagedPool, sizeof(URB));
- if (purb == NULL)
- return FALSE;
-
- buf = usb_alloc_mem(NonPagedPool, 512);
- if (buf == NULL)
- {
- usb_dbg_print(DBGLVL_MAXIMUM, ("gendrv_connect(): can not alloc buf\n"));
- usb_free_mem(purb);
- return FALSE;
- }
-
- // before we set the configuration, let's search to find if there
- // exist interfaces we supported
- psetup = (PUSB_CTRL_SETUP_PACKET) (purb)->setup_packet;
- urb_init((purb));
- purb->endp_handle = dev_handle | 0xffff;
- purb->data_buffer = buf;
- purb->data_length = 512;
- purb->completion = NULL; // this is an immediate request, no completion required
- purb->context = NULL;
- purb->reference = 0;
- psetup->bmRequestType = 0x80;
- psetup->bRequest = USB_REQ_GET_DESCRIPTOR;
- psetup->wValue = USB_DT_CONFIG << 8;
- psetup->wIndex = 0;
- psetup->wLength = 512;
-
- status = usb_submit_urb(dev_mgr, purb);
- if (status == STATUS_PENDING)
- {
- TRAP();
- usb_free_mem(buf);
- usb_free_mem(purb);
- return FALSE;
- }
-
- // check the config desc valid
- pconfig_desc = (PUSB_CONFIGURATION_DESC) buf;
- if (pconfig_desc->wTotalLength > 512)
- {
- usb_free_mem(buf);
- usb_free_mem(purb);
- usb_dbg_print(DBGLVL_MAXIMUM, ("gendrv_connect(): error, bad configuration desc\n"));
- return FALSE;
- }
-
- i = pconfig_desc->bConfigurationValue;
- usb_free_mem(buf);
- buf = NULL;
-
- //set the configuration
- urb_init(purb);
- purb->endp_handle = dev_handle | 0xffff;
- purb->data_buffer = NULL;
- purb->data_length = 0;
- purb->completion = gendrv_set_cfg_completion;
- purb->context = dev_mgr;
- purb->reference = (ULONG) param->pdriver;
- psetup->bmRequestType = 0;
- psetup->bRequest = USB_REQ_SET_CONFIGURATION;
- psetup->wValue = (USHORT) i;
- psetup->wIndex = 0;
- psetup->wLength = 0;
-
- usb_dbg_print(DBGLVL_MAXIMUM, ("gendrv_connect(): start config the device, cfgval=%d\n", i));
- status = usb_submit_urb(dev_mgr, purb);
-
- if (status != STATUS_PENDING)
- {
- usb_free_mem(purb);
-
- if (status == STATUS_SUCCESS)
- return TRUE;
-
- return FALSE;
- }
-
- return TRUE;
-}
-
-BOOLEAN
-gendrv_event_select_driver(PUSB_DEV pdev, //always null. we do not use this param
- ULONG event, ULONG context, ULONG param)
-{
- //
- // try to search the registry to find one driver.
- // if found, create the PDO, load the driver.
- // and call its AddDevice.
- //
- LONG i;
- PUSB_DRIVER pdrvr;
- PGENDRV_DRVR_EXTENSION pdrvr_ext;
- PGENDRV_EXT_DRVR_ENTRY pentry;
- PGENDRV_DEVICE_EXTENSION pdev_ext;
- PUSB_CONFIGURATION_DESC pconfig_desc;
- PUSB_DEV_MANAGER dev_mgr;
-
- PDEVICE_OBJECT pdev_obj;
- PDRIVER_OBJECT pdrvr_obj;
- PLIST_ENTRY pthis, pnext;
-
- USE_BASIC_NON_PENDING_IRQL;
-
- UNREFERENCED_PARAMETER(context);
- UNREFERENCED_PARAMETER(event);
-
- if (pdev == NULL)
- return FALSE;
-
- usb_dbg_print(DBGLVL_MAXIMUM, ("gendrv_event_select_driver(): entering...\n"));
-
- pdrvr = (PUSB_DRIVER) param;
- //original code: pconfig_desc = (PUSB_CONFIGURATION_DESC) pdev->desc_buf[sizeof(USB_DEVICE_DESC)];
- pconfig_desc = (PUSB_CONFIGURATION_DESC) &pdev->desc_buf[sizeof(USB_DEVICE_DESC)];
- pdrvr_ext = (PGENDRV_DRVR_EXTENSION) pdrvr->driver_ext;
-
- //
- // well, let's do the hard work to see if there is a class driver
- // for this device.
- // in the event routine, we have no need to check if the device is zomb or
- // not, it must be alive there.
- //
- i = gendrv_make_key((PUSB_DESC_HEADER) pdev->pusb_dev_desc);
- if (i == -1)
- {
- return FALSE;
- }
-
- pdrvr_obj = gendrv_find_drvr_by_key(pdrvr_ext, (ULONG) i);
- if (!pdrvr_obj)
- {
- if ((pdrvr_obj = gendrv_load_ext_drvr(pdrvr_ext, (PUSB_DESC_HEADER) pdev->pusb_dev_desc)) == NULL)
- return FALSE;
- }
-
- dev_mgr = dev_mgr_from_dev(pdev);
- pdev_obj = gendrv_create_device(dev_mgr, pdrvr, usb_make_handle(pdev->dev_id, 0, 0));
- if (pdev_obj == NULL)
- {
- goto ERROR_OUT;
- }
-
- lock_dev(pdev, FALSE);
- if (dev_state(pdev) == USB_DEV_STATE_ZOMB ||
- dev_mgr_set_driver(dev_mgr, usb_make_handle(pdev->dev_id, 0, 0), pdrvr, pdev) == FALSE)
- {
- unlock_dev(pdev, FALSE);
- gendrv_delete_device(dev_mgr, pdev_obj);
- goto ERROR_OUT;
- }
-
- if (pdev->usb_config)
- {
- pdev->dev_obj = pdev_obj;
- }
-
- unlock_dev(pdev, FALSE);
-
- pdev_ext = (PGENDRV_DEVICE_EXTENSION) pdev_obj->DeviceExtension;
- pdev_ext->desc_buf = usb_alloc_mem(NonPagedPool, 512);
- if (!pdev_ext->desc_buf)
- {
- usb_dbg_print(DBGLVL_MAXIMUM, ("gendrv_event_select_driver(): memory allocation failed!\n"));
- goto ERROR_OUT;
- }
-
- RtlCopyMemory(pdev_ext->desc_buf, pconfig_desc, 512);
-
- // insert the device to the dev_list
- ExAcquireFastMutex(&pdrvr_ext->drvr_ext_mutex);
- ListFirst(&pdrvr_ext->ext_drvr_list, pthis);
- pentry = NULL;
- while (pthis)
- {
- pentry = (PGENDRV_EXT_DRVR_ENTRY) pthis;
- if (pentry->pext_drvr == pdrvr_obj)
- break;
- ListNext(&pdrvr_ext->ext_drvr_list, pthis, pnext);
- pthis = pnext;
- pentry = NULL;
- }
- ASSERT(pentry);
- InsertTailList(&pentry->dev_list, &pdev_ext->dev_obj_link);
- pdev_ext->ext_drvr_entry = pentry;
- pentry->ref_count++;
- ExReleaseFastMutex(&pdrvr_ext->drvr_ext_mutex);
-
- // notify the class driver, some device comes
- gendrv_send_pnp_msg(GENDRV_MSG_ADDDEVICE, pdev_obj, pdrvr_obj);
- usb_unlock_dev(pdev);
- return TRUE;
-
- ERROR_OUT:
-
- usb_unlock_dev(pdev);
- return FALSE;
-}
-
-VOID
-gendrv_set_cfg_completion(PURB purb, PVOID context)
-{
- DEV_HANDLE dev_handle;
- PUSB_DEV_MANAGER dev_mgr;
- PUSB_DRIVER pdriver;
- NTSTATUS status;
- PUSB_DEV pdev;
- PUSB_EVENT pevent;
- USE_BASIC_NON_PENDING_IRQL;
-
- if (purb == NULL || context == NULL)
- return;
-
- dev_handle = purb->endp_handle & ~0xffff;
- dev_mgr = (PUSB_DEV_MANAGER) context;
- pdriver = (PUSB_DRIVER) purb->reference;
-
- if (purb->status != STATUS_SUCCESS)
- {
- usb_free_mem(purb);
- return;
- }
-
- usb_free_mem(purb);
- purb = NULL;
-
- // set the dev state
- status = usb_query_and_lock_dev(dev_mgr, dev_handle, &pdev);
- if (status != STATUS_SUCCESS)
- {
- usb_unlock_dev(pdev);
- return;
- }
- usb_unlock_dev(pdev); // safe to release the pdev ref since we are in urb completion
-
-
- KeAcquireSpinLockAtDpcLevel(&dev_mgr->event_list_lock);
- lock_dev(pdev, TRUE);
-
- if (dev_state(pdev) >= USB_DEV_STATE_BEFORE_ZOMB)
- {
- unlock_dev(pdev, TRUE);
- KeReleaseSpinLockFromDpcLevel(&dev_mgr->event_list_lock);
- return;
- }
-
- if (dev_mgr_set_driver(dev_mgr, dev_handle, pdriver, pdev) == FALSE)
- {
- unlock_dev(pdev, TRUE);
- KeReleaseSpinLockFromDpcLevel(&dev_mgr->event_list_lock);
- return;
- }
-
- //transit the state to configured
- pdev->flags &= ~USB_DEV_STATE_MASK;
- pdev->flags |= USB_DEV_STATE_CONFIGURED;
-
- pevent = alloc_event(&dev_mgr->event_pool, 1);
- if (pevent == NULL)
- {
- unlock_dev(pdev, TRUE);
- KeReleaseSpinLockFromDpcLevel(&dev_mgr->event_list_lock);
- return;
- }
-
- pevent->flags = USB_EVENT_FLAG_ACTIVE;
- pevent->event = USB_EVENT_DEFAULT;
- pevent->pdev = pdev;
- pevent->context = 0;
- pevent->param = (ULONG) pdriver;
- pevent->pnext = 0; //vertical queue for serialized operation
- pevent->process_event = (PROCESS_EVENT) gendrv_event_select_driver;
- pevent->process_queue = event_list_default_process_queue;
-
- InsertTailList(&dev_mgr->event_list, &pevent->event_link);
- KeSetEvent(&dev_mgr->wake_up_event, 0, FALSE);
- unlock_dev(pdev, TRUE);
- KeReleaseSpinLockFromDpcLevel(&dev_mgr->event_list_lock);
-
- return;
-}
-
-
-BOOLEAN
-gendrv_stop(PUSB_DEV_MANAGER dev_mgr, DEV_HANDLE dev_handle)
-{
- if (dev_mgr == NULL)
- return FALSE;
- return gendrv_do_stop(dev_mgr, dev_handle, FALSE);
-}
-
-BOOLEAN
-gendrv_disconnect(PUSB_DEV_MANAGER dev_mgr, DEV_HANDLE dev_handle)
-{
- if (dev_mgr == NULL)
- return FALSE;
- return gendrv_do_disconnect(dev_mgr, dev_handle, FALSE);
-}
-
-BOOLEAN
-gendrv_build_reg_string(PUSB_DESC_HEADER pdesc, PUNICODE_STRING pus)
-{
-
- CHAR desc_str[128];
- STRING atemp;
-
- if (pdesc == NULL || pus == NULL)
- return FALSE;
-
- if (pdesc->bDescriptorType == USB_DT_DEVICE)
- {
- PUSB_DEVICE_DESC pdev_desc;
- pdev_desc = (PUSB_DEVICE_DESC) pdesc;
- sprintf(desc_str, "%sv_%04x&p_%04x",
- "\\Registry\\Machine\\System\\CurrentControlSet\\Services\\ehci\\device\\",
- pdev_desc->idVendor, pdev_desc->idProduct);
- }
- else if (pdesc->bDescriptorType == USB_DT_INTERFACE)
- {
- PUSB_INTERFACE_DESC pif_desc;
- pif_desc = (PUSB_INTERFACE_DESC) pdesc;
- sprintf(desc_str, "%sc_%04x&s_%04x&p_%04x",
- "\\Registry\\Machine\\System\\CurrentControlSet\\Services\\ehci\\interface\\",
- pif_desc->bInterfaceClass, pif_desc->bInterfaceSubClass, pif_desc->bInterfaceProtocol);
- }
- else
- return FALSE;
-
- RtlInitString(&atemp, desc_str);
- RtlAnsiStringToUnicodeString(pus, &atemp, TRUE);
- return TRUE;
-}
-
-ULONG
-gendrv_make_key(PUSB_DESC_HEADER pdesc)
-{
- PUSB_DEVICE_DESC pdev_desc;
- PUSB_INTERFACE_DESC pif_desc;
-
- if (pdesc == NULL)
- return (ULONG) - 1;
- if (pdesc->bDescriptorType == USB_DT_DEVICE)
- {
- pdev_desc = (PUSB_DEVICE_DESC) pdesc;
- return ((((ULONG) pdev_desc->idVendor) << 16) | pdev_desc->idProduct);
- }
- else if (pdesc->bDescriptorType == USB_DT_INTERFACE)
- {
- pif_desc = (PUSB_INTERFACE_DESC) pdesc;
- return ((((ULONG) pif_desc->bInterfaceClass) << 16) |
- (((ULONG) pif_desc->bInterfaceSubClass) << 8) | ((ULONG) pif_desc->bInterfaceProtocol));
- }
- return (ULONG) - 1;
-}
-
-PDRIVER_OBJECT
-gendrv_find_drvr_by_key(PGENDRV_DRVR_EXTENSION pdrvr_ext, ULONG key)
-{
- PGENDRV_EXT_DRVR_ENTRY pentry;
- PLIST_ENTRY pthis, pnext;
- if (pdrvr_ext == NULL || key == (ULONG) - 1)
- return NULL;
-
- ExAcquireFastMutex(&pdrvr_ext->drvr_ext_mutex);
- ListFirst(&pdrvr_ext->ext_drvr_list, pthis);
- while (pthis)
- {
- pentry = (PGENDRV_EXT_DRVR_ENTRY) pthis;
- if (pentry->drvr_key == key)
- {
- ExReleaseFastMutex(&pdrvr_ext->drvr_ext_mutex);
- return pentry->pext_drvr;
- }
- ListNext(&pdrvr_ext->ext_drvr_list, pthis, pnext);
- pthis = pnext;
- }
- ExReleaseFastMutex(&pdrvr_ext->drvr_ext_mutex);
-
- return NULL;
-}
-
-PDRIVER_OBJECT
-gendrv_load_ext_drvr(PGENDRV_DRVR_EXTENSION pdrvr_ext, PUSB_DESC_HEADER pdesc)
-{
- PDRIVER_OBJECT pdrvr_obj;
- PGENDRV_EXT_DRVR_ENTRY pentry;
- UNICODE_STRING usz, svc_name, svc_key, utemp;
- PKEY_VALUE_FULL_INFORMATION val_info;
- PWCHAR val_buf;
- HANDLE handle;
- NTSTATUS status;
-
- if (pdrvr_ext == NULL || pdesc == NULL)
- return NULL;
-
- // try to search and load driver from outside
- handle = NULL;
- RtlZeroMemory(&svc_key, sizeof(svc_key));
- val_info = NULL;
- RtlInitUnicodeString(&usz, L"");
- gendrv_build_reg_string(pdesc, &usz);
-DbgPrint("UHCI: Trying to load driver %wZ\n", &usz);
- if (gendrv_open_reg_key(&handle, NULL, &usz, KEY_READ, FALSE) != STATUS_SUCCESS)
- {
- goto ERROR_OUT;
- }
- if (gendrv_get_key_value(handle, L"service", &val_info) != STATUS_SUCCESS)
- {
- goto ERROR_OUT;
- }
-
- if (val_info->DataLength > 32)
- goto ERROR_OUT;
-
- val_buf = (PWCHAR) (((PBYTE) val_info) + val_info->DataOffset);
- svc_key.Length = 0, svc_key.MaximumLength = 255;
- svc_key.Buffer = usb_alloc_mem(NonPagedPool, 256);
-
- RtlInitUnicodeString(&utemp, L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\");
- RtlAppendUnicodeStringToString(&svc_key, &utemp);
- RtlInitUnicodeString(&svc_name, val_buf);
- RtlAppendUnicodeStringToString(&svc_key, &svc_name);
-
- status = ZwLoadDriver(&svc_key);
- if (status != STATUS_SUCCESS)
- goto ERROR_OUT;
-
- svc_key.Length = 0;
- RtlZeroMemory(svc_key.Buffer, 128);
- RtlInitUnicodeString(&svc_key, L"\\Driver\\");
- RtlAppendUnicodeStringToString(&svc_key, &svc_name);
- pdrvr_obj = gendrv_open_ext_driver(&svc_key);
- if (pdrvr_obj == NULL)
- goto ERROR_OUT;
-
- ExAcquireFastMutex(&pdrvr_ext->drvr_ext_mutex);
-
- // insert the driver to the drvr list
- pentry = gendrv_alloc_ext_drvr_entry(pdrvr_ext);
- if (pentry == NULL)
- {
- ExReleaseFastMutex(&pdrvr_ext->drvr_ext_mutex);
- ObDereferenceObject(pdrvr_obj);
- goto ERROR_OUT;
- }
- pentry->pext_drvr = pdrvr_obj;
- InsertTailList(&pdrvr_ext->ext_drvr_list, &pentry->drvr_link);
- pdrvr_ext->ext_drvr_count++;
- ExReleaseFastMutex(&pdrvr_ext->drvr_ext_mutex);
- ZwClose(handle);
- return pdrvr_obj;
-
-ERROR_OUT:
- RtlFreeUnicodeString(&usz);
- if (val_info != NULL)
- {
- usb_free_mem(val_info);
- val_info = NULL;
- }
- if (svc_key.Buffer)
- usb_free_mem(svc_key.Buffer);
-
- if (handle)
- ZwClose(handle);
-
- return NULL;
-}
-
-VOID
-gendrv_release_drvr(PGENDRV_DRVR_EXTENSION pdrvr_ext, PDRIVER_OBJECT pdrvr_obj)
-{
- PLIST_ENTRY pthis, pnext;
- PGENDRV_EXT_DRVR_ENTRY pentry;
-
- if (pdrvr_ext == NULL || pdrvr_obj == NULL)
- return;
- ExAcquireFastMutex(&pdrvr_ext->drvr_ext_mutex);
- ListFirst(&pdrvr_ext->ext_drvr_list, pthis);
- while (pthis)
- {
- pentry = (PGENDRV_EXT_DRVR_ENTRY) pthis;
- if (pentry->pext_drvr == pdrvr_obj)
- {
- ASSERT(pentry->ref_count);
- ExReleaseFastMutex(&pdrvr_ext->drvr_ext_mutex);
- return;
- }
- ListNext(&pdrvr_ext->ext_drvr_list, pthis, pnext);
- pthis = pnext;
- }
- ExReleaseFastMutex(&pdrvr_ext->drvr_ext_mutex);
-}
-
-NTSTATUS
-gendrv_send_pnp_msg(ULONG msg, PDEVICE_OBJECT pdev_obj, PVOID pctx)
-{
- if (pdev_obj == NULL)
- return STATUS_INVALID_PARAMETER;
-
- switch (msg)
- {
- case GENDRV_MSG_ADDDEVICE:
- {
- PDRIVER_OBJECT pdrvr_obj;
- if (pctx == NULL)
- return STATUS_INVALID_PARAMETER;
- pdrvr_obj = (PDRIVER_OBJECT) pctx;
- if (pdrvr_obj->DriverExtension)
- {
- return pdrvr_obj->DriverExtension->AddDevice(pdrvr_obj, pdev_obj);
- }
- return STATUS_IO_DEVICE_ERROR;
- }
- case GENDRV_MSG_STOPDEVICE:
- case GENDRV_MSG_DISCDEVICE:
- {
- NTSTATUS status;
- IO_STACK_LOCATION *irpstack;
- IRP *irp;
- // IRP_MJ_PNP_POWER
- irp = IoAllocateIrp(2, FALSE);
- if (irp == NULL)
- return STATUS_NO_MEMORY;
-
- irpstack = IoGetNextIrpStackLocation(irp);
- irpstack->MajorFunction = IRP_MJ_PNP_POWER;
- irpstack->MinorFunction =
- (msg == GENDRV_MSG_STOPDEVICE) ? IRP_MN_STOP_DEVICE : IRP_MN_REMOVE_DEVICE;
- status = IoCallDriver(pdev_obj, irp);
- ASSERT(status != STATUS_PENDING);
- status = irp->IoStatus.Status;
- IoFreeIrp(irp);
- return STATUS_MORE_PROCESSING_REQUIRED;
- }
- }
- return STATUS_INVALID_PARAMETER;
-}
-
-
-BOOLEAN
-gendrv_if_connect(PDEV_CONNECT_DATA params, DEV_HANDLE if_handle)
-{
- //
- // try to search the registry to find one driver.
- // if found, create the PDO, load the driver.
- // and call its AddDevice.
- //
- LONG if_idx, i;
- NTSTATUS status;
- PUSB_DEV pdev;
- PUSB_DRIVER pdrvr;
- PUSB_INTERFACE_DESC pif_desc;
- PGENDRV_DEVICE_EXTENSION pdev_ext;
- PUSB_CONFIGURATION_DESC pconfig_desc;
- PUSB_DEV_MANAGER dev_mgr;
- PGENDRV_DRVR_EXTENSION pdrvr_ext;
- PGENDRV_EXT_DRVR_ENTRY pentry;
-
- PDEVICE_OBJECT pdev_obj;
- PDRIVER_OBJECT pdrvr_obj;
- PLIST_ENTRY pthis, pnext;
- USE_BASIC_NON_PENDING_IRQL;
-
- pdev = NULL;
- usb_dbg_print(DBGLVL_MAXIMUM, ("gendrv_if_connect(): entering...\n"));
-
- if (params == NULL)
- return FALSE;
-
- dev_mgr = params->dev_mgr;
- pdrvr = params->pdriver;
- pdrvr_ext = (PGENDRV_DRVR_EXTENSION) pdrvr->driver_ext;
-
- status = usb_query_and_lock_dev(dev_mgr, if_handle, &pdev);
- if (status != STATUS_SUCCESS)
- {
- goto ERROR_OUT;
- }
- // obtain the pointer to the config desc, the dev won't go away in this routine
- pconfig_desc = pdev->usb_config->pusb_config_desc; //
- usb_unlock_dev(pdev);
- pdev = NULL;
-
- if_idx = if_idx_from_handle(if_handle);
- pif_desc = (PUSB_INTERFACE_DESC) (&pconfig_desc[1]);
-
- for(i = 0; i < if_idx; i++)
- {
- //search for our if
- if (usb_skip_if_and_altif((PUCHAR *) & pif_desc) == FALSE)
- break;
- }
- if (pif_desc == NULL)
- return FALSE;
-
- //
- // well, let's do the hard work to see if there is a class driver
- // for this device.
- //
- i = gendrv_make_key((PUSB_DESC_HEADER) pif_desc);
- if (i == -1)
- {
- return FALSE;
- }
-
- pdrvr_obj = gendrv_find_drvr_by_key(pdrvr_ext, (ULONG) i);
- if (!pdrvr_obj)
- {
- if ((pdrvr_obj = gendrv_load_ext_drvr(pdrvr_ext, (PUSB_DESC_HEADER) pif_desc)) == NULL)
- return FALSE;
- }
-
-
- pdev_obj = gendrv_create_device(dev_mgr, pdrvr, if_handle);
- if (pdev_obj == NULL)
- {
- goto ERROR_OUT;
- }
-
- lock_dev(pdev, FALSE);
- if (dev_state(pdev) == USB_DEV_STATE_ZOMB ||
- dev_mgr_set_if_driver(dev_mgr, if_handle, pdrvr, pdev) == FALSE)
- {
- unlock_dev(pdev, FALSE);
- gendrv_delete_device(dev_mgr, pdev_obj);
- goto ERROR_OUT;
- }
-
- if (pdev->usb_config)
- {
- pdev->usb_config->interf[if_idx].if_ext = pdev_obj;
- pdev->usb_config->interf[if_idx].if_ext_size = 0;
- }
-
- unlock_dev(pdev, FALSE);
-
- pdev_ext = (PGENDRV_DEVICE_EXTENSION) pdev_obj->DeviceExtension;
- pdev_ext->desc_buf = usb_alloc_mem(NonPagedPool, 512);
- if (!pdev_ext->desc_buf)
- {
- usb_dbg_print(DBGLVL_MAXIMUM, ("gendrv_if_connect(): memory allocation failed!\n"));
- goto ERROR_OUT;
- }
-
- RtlCopyMemory(pdev_ext->desc_buf, pconfig_desc, 512);
- pdev_ext->if_ctx.pif_desc =
- (PUSB_INTERFACE_DESC) & pdev_ext->desc_buf[(PBYTE) pif_desc - (PBYTE) pconfig_desc];
-
- // insert the device to the dev_list
- ExAcquireFastMutex(&pdrvr_ext->drvr_ext_mutex);
- ListFirst(&pdrvr_ext->ext_drvr_list, pthis);
- pentry = NULL;
- while (pthis)
- {
- pentry = (PGENDRV_EXT_DRVR_ENTRY) pthis;
- if (pentry->pext_drvr == pdrvr_obj)
- break;
- ListNext(&pdrvr_ext->ext_drvr_list, pthis, pnext);
- pthis = pnext;
- pentry = NULL;
- }
- ASSERT(pentry);
- InsertTailList(&pentry->dev_list, &pdev_ext->dev_obj_link);
- pdev_ext->ext_drvr_entry = pentry;
- pentry->ref_count++;
- ExReleaseFastMutex(&pdrvr_ext->drvr_ext_mutex);
-
- // notify the class driver, some device comes
- gendrv_send_pnp_msg(GENDRV_MSG_ADDDEVICE, pdev_obj, pdrvr_obj);
- usb_unlock_dev(pdev);
- return TRUE;
-
- ERROR_OUT:
-
- usb_unlock_dev(pdev);
- return FALSE;
-}
-
-BOOLEAN
-gendrv_do_stop(PUSB_DEV_MANAGER dev_mgr, DEV_HANDLE dev_handle, BOOLEAN is_if)
-{
- PUSB_DEV pdev;
- PDEVICE_OBJECT pdev_obj;
- ULONG if_idx;
-
- if (dev_mgr == NULL)
- return FALSE;
-
- // clean up the irps
- if_idx = if_idx_from_handle(dev_handle);
- if (usb_query_and_lock_dev(dev_mgr, dev_handle, &pdev) != STATUS_SUCCESS)
- {
- return FALSE;
- }
- if (is_if && pdev->usb_config)
- pdev_obj = (PDEVICE_OBJECT) pdev->usb_config->interf[if_idx].if_ext;
- else
- pdev_obj = pdev->dev_obj;
-
- gendrv_clean_up_queued_irps(pdev_obj);
- usb_unlock_dev(pdev);
-
- // send message to class drivers.
- gendrv_send_pnp_msg(GENDRV_MSG_STOPDEVICE, pdev_obj, NULL);
-
- return TRUE;
-}
-
-BOOLEAN
-gendrv_if_stop(PUSB_DEV_MANAGER dev_mgr, DEV_HANDLE dev_handle)
-{
- if (dev_mgr == NULL)
- return FALSE;
-
- return gendrv_do_stop(dev_mgr, dev_handle, TRUE);
-}
-
-BOOLEAN
-gendrv_do_disconnect(PUSB_DEV_MANAGER dev_mgr, DEV_HANDLE if_handle, BOOLEAN is_if)
-{
- PUSB_DEV pdev;
- PDEVICE_OBJECT dev_obj = NULL;
- NTSTATUS status;
- PUSB_DRIVER pdrvr;
- PGENDRV_DRVR_EXTENSION pdrvr_ext = NULL;
- PGENDRV_DEVICE_EXTENSION pdev_ext = NULL;
- ULONG if_idx;
-
- status = usb_query_and_lock_dev(dev_mgr, if_handle, &pdev);
- if (pdev == NULL)
- {
- return FALSE;
- }
- if (status == STATUS_SUCCESS)
- {
- // must be a bug
- TRAP();
- }
- if_idx = if_idx_from_handle(if_handle);
- if (pdev->usb_config)
- {
- if (is_if)
- {
- pdrvr = pdev->usb_config->interf[if_idx].pif_drv;
- dev_obj = (PDEVICE_OBJECT) pdev->usb_config->interf[if_idx].if_ext;
- }
- else
- {
- pdrvr = pdev->dev_driver;
- dev_obj = pdev->dev_obj;
- }
-
- if (dev_obj == NULL)
- {
- // it means no driver was found for the device and thus no device object created
- // we just do nothing here
- return TRUE;
- }
-
- pdrvr_ext = (PGENDRV_DRVR_EXTENSION) pdrvr->driver_ext;
- pdev_ext = (PGENDRV_DEVICE_EXTENSION) dev_obj->DeviceExtension;
- }
- else
- TRAP();
- pdev = NULL;
-
- // remove the device from the list
- ExAcquireFastMutex(&pdrvr_ext->drvr_ext_mutex);
- RemoveEntryList(&pdev_ext->dev_obj_link);
- pdev_ext->ext_drvr_entry->ref_count--;
- ExReleaseFastMutex(&pdrvr_ext->drvr_ext_mutex);
-
- // send message to class driver
- gendrv_send_pnp_msg(GENDRV_MSG_DISCDEVICE, dev_obj, NULL);
- // delete the device object
- gendrv_delete_device(dev_mgr, dev_obj);
- return TRUE;
-}
-
-BOOLEAN
-gendrv_if_disconnect(PUSB_DEV_MANAGER dev_mgr, DEV_HANDLE if_handle)
-{
- return gendrv_do_disconnect(dev_mgr, if_handle, TRUE);
-}
-
-BOOLEAN
-gendrv_if_driver_init(PUSB_DEV_MANAGER dev_mgr, PUSB_DRIVER pdriver)
-{
- PGENDRV_DRVR_EXTENSION pdrvr_ext;
- if (dev_mgr == NULL || pdriver == NULL)
- return FALSE;
-
- pdriver->driver_desc.flags = USB_DRIVER_FLAG_IF_CAPABLE;
- pdriver->driver_desc.vendor_id = 0x0000; // USB Vendor ID
- pdriver->driver_desc.product_id = 0x0000; // USB Product ID.
- pdriver->driver_desc.release_num = 0x100; // Release Number of Device
-
- pdriver->driver_desc.config_val = 0; // Configuration Value
- pdriver->driver_desc.if_num = 0; // Interface Number
- pdriver->driver_desc.if_class = 0x0; // Interface Class
- pdriver->driver_desc.if_sub_class = 0x0; // Interface SubClass
- pdriver->driver_desc.if_protocol = 0x0; // Interface Protocol
-
- pdriver->driver_desc.driver_name = "USB generic interface driver"; // Driver name for Name Registry
- pdriver->driver_desc.dev_class = 0;
- pdriver->driver_desc.dev_sub_class = 0; // Device Subclass
- pdriver->driver_desc.dev_protocol = 0; // Protocol Info.
-
- //we have no extra data sturcture currently
-
- pdriver->disp_tbl.version = 1;
- pdriver->disp_tbl.dev_connect = gendrv_if_connect;
- pdriver->disp_tbl.dev_disconnect = gendrv_if_disconnect;
- pdriver->disp_tbl.dev_stop = gendrv_if_stop;
- pdriver->disp_tbl.dev_reserved = NULL;
-
- pdriver->driver_ext = usb_alloc_mem(NonPagedPool, sizeof(GENDRV_DRVR_EXTENSION));
- if (!pdriver->driver_ext) return FALSE;
-
- pdriver->driver_ext_size = sizeof(GENDRV_DRVR_EXTENSION);
-
- RtlZeroMemory(pdriver->driver_ext, pdriver->driver_ext_size);
- pdrvr_ext = (PGENDRV_DRVR_EXTENSION) pdriver->driver_ext;
-
- // InitializeListHead( &pdrvr_ext->dev_list );
- InitializeListHead(&pdrvr_ext->ext_drvr_list);
- pdrvr_ext->ext_drvr_count = 0;
- ExInitializeFastMutex(&pdrvr_ext->drvr_ext_mutex);
-
- return TRUE;
-}
-
-BOOLEAN
-gendrv_if_driver_destroy(PUSB_DEV_MANAGER dev_mgr, PUSB_DRIVER pdriver)
-{
- PGENDRV_DRVR_EXTENSION pdrvr_ext;
- PLIST_ENTRY pthis;
- PGENDRV_EXT_DRVR_ENTRY pentry;
- if (dev_mgr == NULL || pdriver == NULL)
- return FALSE;
-
- if (pdriver->driver_ext)
- {
- // should we lock it?
- // ExAcquireFastMutex( &pdrvr_ext->drvr_ext_mutex );
- pdrvr_ext = (PGENDRV_DRVR_EXTENSION) pdriver->driver_ext;
- if (pdrvr_ext->ext_drvr_count)
- {
- while (IsListEmpty(&pdrvr_ext->ext_drvr_list))
- {
- pthis = RemoveHeadList(&pdrvr_ext->ext_drvr_list);
- pentry = (PGENDRV_EXT_DRVR_ENTRY) pthis;
- if (pentry->pext_drvr)
- {
- if (pentry->ref_count)
- {
- // FIXME: really fail?
- continue;
- }
- ObDereferenceObject(pentry->pext_drvr);
- gendrv_release_ext_drvr_entry(pdrvr_ext, pentry);
- }
- }
- pdrvr_ext->ext_drvr_count = 0;
- }
-
- usb_free_mem(pdriver->driver_ext);
- pdriver->driver_ext = NULL;
- pdriver->driver_ext_size = 0;
- }
- return TRUE;
-}
-
-PDRIVER_OBJECT
-gendrv_open_ext_driver(PUNICODE_STRING unicode_string)
-{
- NTSTATUS status;
- OBJECT_ATTRIBUTES oa;
- HANDLE drvr_handle;
- UNICODE_STRING oname;
- PDRIVER_OBJECT pdrvr = NULL;
-
- RtlZeroMemory(&oa, sizeof(oa));
- oa.Length = sizeof(oa);
- oa.ObjectName = &oname;
- oa.Attributes = OBJ_CASE_INSENSITIVE;
- RtlInitUnicodeString(&oname, L"");
- RtlAppendUnicodeStringToString(&oname, unicode_string);
-
- status = ObOpenObjectByName(&oa, IoDriverObjectType, // object type
- KernelMode, // access mode
- NULL, // access state
- FILE_READ_DATA, // STANDARD_RIGHTS_READ, access right
- NULL,
- &drvr_handle);
-
- if (status != STATUS_SUCCESS)
- {
- return NULL;
- }
- ObReferenceObjectByHandle(drvr_handle,
- FILE_READ_DATA,
- IoDriverObjectType,
- KernelMode,
- (PVOID)&pdrvr,
- NULL); // OUT POBJECT_HANDLE_INFORMATION HandleInformation OPTIONAL
-
- ZwClose(drvr_handle);
- return pdrvr;
-}
-
-BOOLEAN
-gendrv_close_ext_driver(PDRIVER_OBJECT pdrvr)
-{
- if (pdrvr == NULL)
- return FALSE;
- ObDereferenceObject(pdrvr);
- return TRUE;
-}
-
-NTSTATUS
-gendrv_dispatch(PDEVICE_OBJECT dev_obj, PIRP irp)
-{
- IO_STACK_LOCATION *irpstack;
- PUSB_DEV_MANAGER dev_mgr;
- PDEVEXT_HEADER ext_hdr;
- NTSTATUS status;
-
- if (dev_obj == NULL || irp == NULL)
- return STATUS_INVALID_PARAMETER;
-
- ext_hdr = dev_obj->DeviceExtension;
- dev_mgr = ext_hdr->dev_mgr;
-
- irpstack = IoGetNextIrpStackLocation(irp);
- switch (irpstack->MajorFunction)
- {
- case IRP_MJ_PNP_POWER:
- {
- irp->IoStatus.Information = 0;
- GENDRV_EXIT_DISPATCH(dev_obj, STATUS_SUCCESS, irp);
- }
- case IRP_MJ_INTERNAL_DEVICE_CONTROL:
- {
- status = STATUS_NOT_SUPPORTED;
- if (irpstack->Parameters.DeviceIoControl.IoControlCode == IOCTL_SUBMIT_URB_RD ||
- irpstack->Parameters.DeviceIoControl.IoControlCode == IOCTL_SUBMIT_URB_WR ||
- irpstack->Parameters.DeviceIoControl.IoControlCode == IOCTL_SUBMIT_URB_NOIO)
- {
- PURB purb;
- DEV_HANDLE endp_handle;
- PGENDRV_DEVICE_EXTENSION pdev_ext;
-
- pdev_ext = dev_obj->DeviceExtension;
- if (irpstack->Parameters.DeviceIoControl.InputBufferLength < sizeof(URB))
- {
- GENDRV_EXIT_DISPATCH(dev_obj, STATUS_INVALID_PARAMETER, irp);
- }
-
- purb = (PURB) irp->AssociatedIrp.SystemBuffer;
- endp_handle = purb->endp_handle;
- if (purb->data_buffer == NULL || purb->data_length == 0)
- {
- if (irpstack->Parameters.DeviceIoControl.IoControlCode != IOCTL_SUBMIT_URB_NOIO)
- {
- GENDRV_EXIT_DISPATCH(dev_obj, STATUS_INVALID_PARAMETER, irp);
- }
- }
- if (!default_endp_handle(endp_handle))
- {
- //no permit to other interface if interface dev
- if (if_dev(dev_obj) && if_idx_from_handle(endp_handle) != pdev_ext->if_ctx.if_idx)
- GENDRV_EXIT_DISPATCH(dev_obj, STATUS_INVALID_PARAMETER, irp);
- }
-
- GENDRV_EXIT_DISPATCH(dev_obj, STATUS_PENDING, irp);
- }
- else if (irpstack->Parameters.DeviceIoControl.IoControlCode == IOCTL_GET_DEV_DESC)
- {
- // this is a synchronous call, route to dev_mgr_dispatch
- return dev_mgr_dispatch(dev_mgr, irp);
- }
- else if (irpstack->Parameters.DeviceIoControl.IoControlCode == IOCTL_GET_DEV_HANDLE)
- {
- PGENDRV_DEVICE_EXTENSION pdev_ext;
- pdev_ext = dev_obj->DeviceExtension;
- if (irpstack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(LONG))
- GENDRV_EXIT_DISPATCH(dev_obj, STATUS_INVALID_PARAMETER, irp);
-
- *((PLONG) irp->AssociatedIrp.SystemBuffer) = pdev_ext->dev_handle;
- irp->IoStatus.Information = sizeof(LONG);
- GENDRV_EXIT_DISPATCH(dev_obj, STATUS_SUCCESS, irp);
- }
- GENDRV_EXIT_DISPATCH(dev_obj, STATUS_NOT_SUPPORTED, irp);
- }
- case IRP_MJ_DEVICE_CONTROL:
- {
- status = STATUS_NOT_SUPPORTED;
- if (irpstack->Parameters.DeviceIoControl.IoControlCode == IOCTL_SUBMIT_URB_RD ||
- irpstack->Parameters.DeviceIoControl.IoControlCode == IOCTL_SUBMIT_URB_WR ||
- irpstack->Parameters.DeviceIoControl.IoControlCode == IOCTL_SUBMIT_URB_NOIO)
- {
- PURB purb;
- DEV_HANDLE endp_handle;
- PGENDRV_DEVICE_EXTENSION pdev_ext;
-
- pdev_ext = dev_obj->DeviceExtension;
- if (irpstack->Parameters.DeviceIoControl.InputBufferLength < sizeof(URB))
- {
- GENDRV_EXIT_DISPATCH(dev_obj, STATUS_INVALID_PARAMETER, irp);
- }
-
- purb = (PURB) irp->AssociatedIrp.SystemBuffer;
- endp_handle = purb->endp_handle;
- if (!default_endp_handle(endp_handle))
- {
- //no permit to other interface if interface dev
- if (if_dev(dev_obj) && if_idx_from_handle(endp_handle) != pdev_ext->if_ctx.if_idx)
- GENDRV_EXIT_DISPATCH(dev_obj, STATUS_INVALID_PARAMETER, irp);
- }
-
- GENDRV_EXIT_DISPATCH(dev_obj, STATUS_PENDING, irp);
- }
- else if (irpstack->Parameters.DeviceIoControl.IoControlCode == IOCTL_GET_DEV_DESC)
- {
- // this is a synchronous call, route to dev_mgr_dispatch
- return dev_mgr_dispatch(dev_mgr, irp);
- }
- else if (irpstack->Parameters.DeviceIoControl.IoControlCode == IOCTL_GET_DEV_HANDLE)
- {
- PGENDRV_DEVICE_EXTENSION pdev_ext;
- pdev_ext = dev_obj->DeviceExtension;
- if (irpstack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(LONG))
- GENDRV_EXIT_DISPATCH(dev_obj, STATUS_INVALID_PARAMETER, irp);
-
- *((PLONG) irp->AssociatedIrp.SystemBuffer) = pdev_ext->dev_handle;
- irp->IoStatus.Information = sizeof(LONG);
- GENDRV_EXIT_DISPATCH(dev_obj, STATUS_SUCCESS, irp);
- }
- GENDRV_EXIT_DISPATCH(dev_obj, STATUS_NOT_SUPPORTED, irp);
- }
- }
- irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
- irp->IoStatus.Information = 0;
- IoCompleteRequest(irp, IO_NO_INCREMENT);
-
- return STATUS_NOT_SUPPORTED;
-}
-
-BOOLEAN
-gendrv_init_dev_ext_hdr(PDEVICE_OBJECT dev_obj, PUSB_DEV_MANAGER dev_mgr)
-{
- PDEVEXT_HEADER dev_hdr = NULL;
- if (dev_obj == NULL || dev_mgr == NULL)
- return FALSE;
-
- dev_hdr = (PDEVEXT_HEADER) dev_obj->DeviceExtension;
- dev_hdr->type = NTDEV_TYPE_CLIENT_DEV;
- dev_hdr->dispatch = gendrv_dispatch;
- dev_hdr->start_io = (PDRIVER_STARTIO) gendrv_startio;
- return TRUE;
-}
-
-PDEVICE_OBJECT
-gendrv_create_device(PUSB_DEV_MANAGER dev_mgr, PUSB_DRIVER gen_drvr, DEV_HANDLE dev_handle)
-{
- BOOLEAN is_if;
- PDEVICE_OBJECT pdev;
- PGENDRV_DEVICE_EXTENSION pdev_ext;
- ULONG dev_id;
- PGENDRV_DRVR_EXTENSION pdrvr_ext;
- CHAR dev_name[64];
- STRING string;
- UNICODE_STRING name_string, symb_link;
- NTSTATUS status;
-
- if (dev_mgr == NULL || gen_drvr == NULL || dev_handle == 0)
- return NULL;
-
- is_if = (gen_drvr->driver_desc.flags & USB_DRIVER_FLAG_IF_CAPABLE) ? 1 : 0;
- usb_dbg_print(DBGLVL_MAXIMUM, ("gendrv_create_device(): entering...\n"));
- pdrvr_ext = (PGENDRV_DRVR_EXTENSION) gen_drvr->driver_ext;
- dev_id = (UCHAR) dev_id_from_handle(dev_handle);
-
- if (is_if == FALSE)
- sprintf(dev_name, "\\Device\\gendev_%d", (int)dev_id);
- else
- sprintf(dev_name, "\\Device\\genifdev_%d", (int)dev_id);
-
- RtlInitString(&string, dev_name);
- RtlAnsiStringToUnicodeString(&name_string, &string, TRUE);
- pdev = NULL;
-
- status = IoCreateDevice(dev_mgr->usb_driver_obj,
- sizeof(GENDRV_DEVICE_EXTENSION), &name_string, FILE_USB_DEV_TYPE, 0, TRUE, &pdev);
-
- if (status == STATUS_SUCCESS)
- {
- //
- // We do direct io
- //
- pdev->Flags |= DO_DIRECT_IO;
-
- pdev->Flags &= ~DO_DEVICE_INITIALIZING;
- pdev->StackSize = 2; //one for fdo, one for file device obj
-
- pdev_ext = (PGENDRV_DEVICE_EXTENSION) pdev->DeviceExtension;
-
- //may be accessed by other thread
-
- gendrv_init_dev_ext_hdr(pdev, dev_mgr);
-
- pdev_ext->dev_id = (UCHAR) dev_id;
- pdev_ext->pdo = pdev;
- pdev_ext->dev_handle = dev_handle;
- pdev_ext->dev_mgr = dev_mgr;
- pdev_ext->pdriver = gen_drvr;
-
- if (is_if == FALSE)
- sprintf(dev_name, "\\DosDevices\\gendev%d", (int)dev_id);
- else
- sprintf(dev_name, "\\DosDevices\\genifdev%d", (int)dev_id);
-
- RtlInitString(&string, dev_name);
- RtlAnsiStringToUnicodeString(&symb_link, &string, TRUE);
- IoCreateSymbolicLink(&symb_link, &name_string);
- RtlFreeUnicodeString(&symb_link);
- KeInitializeEvent(&pdev_ext->sync_event, SynchronizationEvent, FALSE);
- KeInitializeSpinLock(&pdev_ext->dev_lock);
-
- }
- RtlFreeUnicodeString(&name_string);
- return pdev;
-}
-
-
-
-VOID
-gendrv_deferred_delete_device(PVOID context)
-{
- PDEVICE_OBJECT dev_obj;
- PGENDRV_DEVICE_EXTENSION pdev_ext;
- PGENDRV_DRVR_EXTENSION pdrvr_ext;
- LARGE_INTEGER interval;
-
- if (context == NULL)
- return;
-
- dev_obj = (PDEVICE_OBJECT) context;
- pdev_ext = dev_obj->DeviceExtension;
- pdrvr_ext = (PGENDRV_DRVR_EXTENSION) pdev_ext->pdriver->driver_ext;
-
- interval.QuadPart = -20000; //two ms
-
- for(;;)
- {
- if (dev_obj->ReferenceCount)
- KeDelayExecutionThread(KernelMode, TRUE, &interval);
- else
- {
- KeDelayExecutionThread(KernelMode, TRUE, &interval);
- if (dev_obj->ReferenceCount == 0)
- break;
- }
- }
- usb_dbg_print(DBGLVL_MAXIMUM, ("gendrv_deferred_delete_device(): delete device, 0x%x\n", dev_obj));
-
- ExAcquireFastMutex(&pdrvr_ext->drvr_ext_mutex);
- RemoveEntryList(&pdev_ext->dev_obj_link);
- pdev_ext->ext_drvr_entry->ref_count--;
- ExReleaseFastMutex(&pdrvr_ext->drvr_ext_mutex);
-
- IoDeleteDevice(dev_obj);
- return;
-}
-
-BOOLEAN
-gendrv_delete_device(PUSB_DEV_MANAGER dev_mgr, PDEVICE_OBJECT dev_obj)
-{
- BOOLEAN is_if;
- PUSB_DRIVER pdrvr;
- PGENDRV_DEVICE_EXTENSION pdev_ext;
- CHAR dev_name[64];
- STRING string;
- UNICODE_STRING symb_link;
- PGENDRV_DRVR_EXTENSION pdrvr_ext;
-
- if (dev_mgr == NULL || dev_obj == 0)
- return FALSE;
-
- pdev_ext = (PGENDRV_DEVICE_EXTENSION) dev_obj->DeviceExtension;
- pdrvr = pdev_ext->pdriver;
- pdrvr_ext = (PGENDRV_DRVR_EXTENSION) pdrvr->driver_ext;
- is_if = (BOOLEAN) if_dev(dev_obj);
- if (is_if == FALSE)
- sprintf(dev_name, "\\DosDevices\\gendev%d", (int)pdev_ext->dev_id);
- else
- sprintf(dev_name, "\\DosDevices\\genifdev%d", (int)pdev_ext->dev_id);
-
- RtlInitString(&string, dev_name);
- RtlAnsiStringToUnicodeString(&symb_link, &string, TRUE);
- IoDeleteSymbolicLink(&symb_link);
- RtlFreeUnicodeString(&symb_link);
-
- if (pdev_ext->desc_buf)
- {
- usb_dbg_print(DBGLVL_MAXIMUM, ("gendrv_delete_device(): delete desc_buf\n"));
- usb_free_mem(pdev_ext->desc_buf);
- pdev_ext->desc_buf = NULL;
-
- }
-
- if (dev_obj->ReferenceCount == 0)
- {
- ExAcquireFastMutex(&pdrvr_ext->drvr_ext_mutex);
- RemoveEntryList(&pdev_ext->dev_obj_link);
- pdev_ext->ext_drvr_entry->ref_count--; //the ext_drvr_entry is actually in pdrvr_ext, so lock it.
- ExReleaseFastMutex(&pdrvr_ext->drvr_ext_mutex);
-
- IoDeleteDevice(dev_obj);
- return TRUE;
- }
-
- // borrow from umss's work routine
- return umss_schedule_workitem(dev_obj, gendrv_deferred_delete_device, NULL, 0);
-}
-
-// must have the drvr_ext_mutex acquired.
-PGENDRV_EXT_DRVR_ENTRY
-gendrv_alloc_ext_drvr_entry(PGENDRV_DRVR_EXTENSION pdrvr_ext)
-{
- LONG i;
- if (pdrvr_ext == NULL)
- return NULL;
- if (pdrvr_ext->ext_drvr_count == GENDRV_MAX_EXT_DRVR)
- return NULL;
- for(i = 0; i < GENDRV_MAX_EXT_DRVR; i++)
- {
- if (pdrvr_ext->ext_drvr_array[i].drvr_link.Flink == NULL &&
- pdrvr_ext->ext_drvr_array[i].drvr_link.Blink == NULL)
- {
- return &pdrvr_ext->ext_drvr_array[i];
- }
- }
- return NULL;
-}
-
-// must have the drvr_ext_mutex acquired.
-VOID
-gendrv_release_ext_drvr_entry(PGENDRV_DRVR_EXTENSION pdrvr_ext, PGENDRV_EXT_DRVR_ENTRY pentry)
-{
- if (pdrvr_ext == NULL || pentry == NULL)
- return;
- RtlZeroMemory(pentry, sizeof(GENDRV_EXT_DRVR_ENTRY));
- InitializeListHead(&pentry->dev_list);
- return;
-}
-
-NTSTATUS
-gendrv_open_reg_key(OUT PHANDLE handle,
- IN HANDLE base_handle OPTIONAL,
- IN PUNICODE_STRING keyname, IN ACCESS_MASK desired_access, IN BOOLEAN create)
-/*++
-
-Routine Description:
-
- Opens or creates a VOLATILE registry key using the name passed in based
- at the BaseHandle node.
-
-Arguments:
-
- Handle - Pointer to the handle which will contain the registry key that
- was opened.
-
- BaseHandle - Handle to the base path from which the key must be opened.
-
- KeyName - Name of the Key that must be opened/created.
-
- DesiredAccess - Specifies the desired access that the caller needs to
- the key.
-
- Create - Determines if the key is to be created if it does not exist.
-
-Return Value:
-
- The function value is the final status of the operation.
-
---*/
-{
- OBJECT_ATTRIBUTES object_attr;
- ULONG disposition;
-
- //
- // Initialize the object for the key.
- //
-
- InitializeObjectAttributes(&object_attr,
- keyname, OBJ_CASE_INSENSITIVE, base_handle, (PSECURITY_DESCRIPTOR) NULL);
-
- //
- // Create the key or open it, as appropriate based on the caller's
- // wishes.
- //
-
- if (create)
- {
- return ZwCreateKey(handle,
- desired_access,
- &object_attr, 0, (PUNICODE_STRING) NULL, REG_OPTION_VOLATILE, &disposition);
- }
- else
- {
- return ZwOpenKey(handle, desired_access, &object_attr);
- }
- return STATUS_INVALID_PARAMETER;
-}
-
-NTSTATUS
-gendrv_get_key_value(IN HANDLE KeyHandle, IN PWSTR ValueName, OUT PKEY_VALUE_FULL_INFORMATION * Information)
-/*++
-
-Routine Description:
-
- This routine is invoked to retrieve the data for a registry key's value.
- This is done by querying the value of the key with a zero-length buffer
- to determine the size of the value, and then allocating a buffer and
- actually querying the value into the buffer.
-
- It is the responsibility of the caller to free the buffer.
-
-Arguments:
-
- KeyHandle - Supplies the key handle whose value is to be queried
-
- ValueName - Supplies the null-terminated Unicode name of the value.
-
- Information - Returns a pointer to the allocated data buffer.
-
-Return Value:
-
- The function value is the final status of the query operation.
-
---*/
-{
- UNICODE_STRING unicodeString;
- NTSTATUS status;
- PKEY_VALUE_FULL_INFORMATION infoBuffer;
- ULONG keyValueLength;
-
- PAGED_CODE();
-
- RtlInitUnicodeString(&unicodeString, ValueName);
-
- //
- // Figure out how big the data value is so that a buffer of the
- // appropriate size can be allocated.
- //
-
- status = ZwQueryValueKey(KeyHandle,
- &unicodeString, KeyValueFullInformation, (PVOID) NULL, 0, &keyValueLength);
- if (status != STATUS_BUFFER_OVERFLOW && status != STATUS_BUFFER_TOO_SMALL)
- {
- return status;
- }
-
- //
- // Allocate a buffer large enough to contain the entire key data value.
- //
-
- infoBuffer = usb_alloc_mem(NonPagedPool, keyValueLength);
- if (!infoBuffer)
- {
- return STATUS_INSUFFICIENT_RESOURCES;
- }
-
- //
- // Query the data for the key value.
- //
-
- status = ZwQueryValueKey(KeyHandle,
- &unicodeString,
- KeyValueFullInformation, infoBuffer, keyValueLength, &keyValueLength);
- if (!NT_SUCCESS(status))
- {
- usb_free_mem(infoBuffer);
- return status;
- }
-
- //
- // Everything worked, so simply return the address of the allocated
- // buffer to the caller, who is now responsible for freeing it.
- //
-
- *Information = infoBuffer;
- return STATUS_SUCCESS;
-}
-
-VOID
-gendrv_startio(IN PDEVICE_OBJECT dev_obj, IN PIRP irp)
-{
- PIO_STACK_LOCATION irp_stack;
- ULONG ctrl_code;
- PUSB_DEV_MANAGER dev_mgr;
- USE_NON_PENDING_IRQL;
-
- if (dev_obj == NULL || irp == NULL)
- return;
-
- // standard process from walter oney
- IoAcquireCancelSpinLock(&old_irql);
- if (irp != dev_obj->CurrentIrp || irp->Cancel)
- {
- // already move on to other irp
- IoReleaseCancelSpinLock(old_irql);
- return;
- }
- else
- {
- (void)IoSetCancelRoutine(irp, NULL);
- }
- IoReleaseCancelSpinLock(old_irql);
-
- irp->IoStatus.Information = 0;
-
- irp_stack = IoGetCurrentIrpStackLocation(irp);
- ctrl_code = irp_stack->Parameters.DeviceIoControl.IoControlCode;
- dev_mgr = ((PDEVEXT_HEADER) dev_obj->DeviceExtension)->dev_mgr;
-
- if (irp_stack->MajorFunction != IRP_MJ_DEVICE_CONTROL &&
- irp_stack->MajorFunction != IRP_MJ_INTERNAL_DEVICE_CONTROL)
- {
- GENDRV_COMPLETE_START_IO(dev_obj, STATUS_INVALID_DEVICE_REQUEST, irp);
- }
-
- switch (ctrl_code)
- {
- case IOCTL_SUBMIT_URB_RD:
- case IOCTL_SUBMIT_URB_NOIO:
- case IOCTL_SUBMIT_URB_WR:
- {
- PURB purb;
- ULONG endp_idx, if_idx, user_buffer_length = 0;
- PUCHAR user_buffer = NULL;
- PUSB_DEV pdev;
- DEV_HANDLE endp_handle;
- PUSB_ENDPOINT pendp;
-
- NTSTATUS status;
-
- if (irp_stack->Parameters.DeviceIoControl.InputBufferLength < sizeof(URB))
- {
- GENDRV_COMPLETE_START_IO(dev_obj, STATUS_INVALID_PARAMETER, irp);
- }
-
- purb = (PURB) irp->AssociatedIrp.SystemBuffer;
- if (ctrl_code == IOCTL_SUBMIT_URB_RD || ctrl_code == IOCTL_SUBMIT_URB_WR)
- {
- if (irp_stack->MajorFunction == IRP_MJ_DEVICE_CONTROL)
- {
- user_buffer = MmGetSystemAddressForMdl(irp->MdlAddress);
- user_buffer_length = irp_stack->Parameters.DeviceIoControl.OutputBufferLength;
- if (user_buffer_length == 0)
- GENDRV_COMPLETE_START_IO(dev_obj, STATUS_INVALID_PARAMETER, irp);
- }
- else
- {
- if (purb->data_buffer == NULL || purb->data_length == 0)
- GENDRV_COMPLETE_START_IO(dev_obj, STATUS_INVALID_PARAMETER, irp);
- user_buffer = purb->data_buffer;
- user_buffer_length = purb->data_length;
- }
- }
-
- purb->reference = 0;
- endp_handle = purb->endp_handle;
-
- if (usb_query_and_lock_dev(dev_mgr, endp_handle & ~0xffff, &pdev) != STATUS_SUCCESS)
- {
- GENDRV_COMPLETE_START_IO(dev_obj, STATUS_IO_DEVICE_ERROR, irp);
- }
-
- lock_dev(pdev, FALSE);
- if (dev_state(pdev) == USB_DEV_STATE_ZOMB || (dev_state(pdev) < USB_DEV_STATE_ADDRESSED))
-
- {
- status = STATUS_INVALID_DEVICE_STATE;
- goto ERROR_OUT1;
- }
-
- if (dev_state(pdev) == USB_DEV_STATE_ADDRESSED && !default_endp_handle(endp_handle))
- {
- status = STATUS_DEVICE_NOT_READY;
- goto ERROR_OUT1;
- }
-
- if_idx = if_idx_from_handle(endp_handle);
- endp_idx = endp_idx_from_handle(endp_handle);
-
- //if_idx exceeds the upper limit
- if (pdev->usb_config)
- {
- if (if_idx >= pdev->usb_config->if_count
- || endp_idx >= pdev->usb_config->interf[if_idx].endp_count)
- {
- if (!default_endp_handle(endp_handle))
- {
- status = STATUS_INVALID_DEVICE_STATE;
- goto ERROR_OUT1;
- }
- }
- }
-
- endp_from_handle(pdev, endp_handle, pendp);
-
- // FIXME: don't know what evil will let loose
- if (endp_type(pendp) != USB_ENDPOINT_XFER_CONTROL)
- {
- if (user_buffer_length > 16)
- {
- status = STATUS_INVALID_PARAMETER;
- goto ERROR_OUT1;
- }
- }
-
- purb->pirp = irp;
- purb->context = dev_mgr;
- purb->reference = ctrl_code;
-
- if (ctrl_code == IOCTL_SUBMIT_URB_RD || ctrl_code == IOCTL_SUBMIT_URB_WR)
- {
- purb->data_buffer = user_buffer;
- purb->data_length = user_buffer_length;
- purb->completion = disp_urb_completion;
- }
- else
- {
- purb->completion = disp_noio_urb_completion;
- }
-
- unlock_dev(pdev, FALSE);
-
- //
- // we have to register irp before the urb is scheduled to
- // avoid race condition.
- //
- ASSERT(dev_mgr_register_irp(dev_mgr, irp, purb));
- //
- // the irp can not be canceled at this point, since it is
- // now the current irp and not in any urb queue. dev_mgr_cancel_irp
- // can not find it and simply return.
- //
- // FIXME: there is a time window that the irp is registered and
- // the urb is not queued. In the meantime, the cancel
- // request may come and cause the irp removed from the irp
- // queue while fail to cancel due to urb not in any urb queue .
- // Thus from that point on, the irp can not be canceled till it
- // is completed or hanging there forever.
- //
- status = usb_submit_urb(dev_mgr, purb);
- if (status != STATUS_PENDING)
- {
- // unmark the pending bit
- IoGetCurrentIrpStackLocation((irp))->Control &= ~SL_PENDING_RETURNED;
- dev_mgr_remove_irp(dev_mgr, irp);
- }
- usb_unlock_dev(pdev);
- if (status != STATUS_PENDING)
- {
- irp->IoStatus.Status = status;
- GENDRV_COMPLETE_START_IO(dev_obj, status, irp);
- }
- return;
-
- ERROR_OUT1:
- unlock_dev(pdev, FALSE);
- usb_unlock_dev(pdev);
- irp->IoStatus.Information = 0;
- GENDRV_COMPLETE_START_IO(dev_obj, status, irp);
- }
- }
- GENDRV_COMPLETE_START_IO(dev_obj, STATUS_INVALID_DEVICE_REQUEST, irp);
-}
-
-VOID
-gendrv_clean_up_queued_irps(PDEVICE_OBJECT dev_obj)
-{
- // called when device may not function or about to be removed, need cleanup
- KIRQL cancelIrql;
- PIRP irp, cur_irp;
- PKDEVICE_QUEUE_ENTRY packet;
- LIST_ENTRY cancel_irps, *pthis;
-
- //
- // cancel all the irps in the queue
- //
- if (dev_obj == NULL)
- return;
-
- InitializeListHead(&cancel_irps);
-
- // remove the irps from device queue
- IoAcquireCancelSpinLock(&cancelIrql);
- cur_irp = dev_obj->CurrentIrp;
- while ((packet = KeRemoveDeviceQueue(&dev_obj->DeviceQueue)))
- {
- irp = struct_ptr(packet, IRP, Tail.Overlay.DeviceQueueEntry);
- InsertTailList(&cancel_irps, &irp->Tail.Overlay.DeviceQueueEntry.DeviceListEntry);
- }
- IoReleaseCancelSpinLock(cancelIrql);
-
- // cancel the irps in process
- // we did not cancel the current irp, it will be done by hcd when
- // disconnect is detected.
- // remove_irp_from_list( &dev_mgr->irp_list, cur_irp, dev_mgr );
-
- while (IsListEmpty(&cancel_irps) == FALSE)
- {
- pthis = RemoveHeadList(&cancel_irps);
- irp = struct_ptr(pthis, IRP, Tail.Overlay.DeviceQueueEntry.DeviceListEntry);
- irp->IoStatus.Information = 0;
- irp->IoStatus.Status = STATUS_CANCELLED;
- IoCompleteRequest(irp, IO_NO_INCREMENT);
- }
- return;
-}
-
-VOID
-NTAPI
-gendrv_cancel_queued_irp(PDEVICE_OBJECT dev_obj, PIRP pirp)
-{
- // cancel routine for irps queued in the device queue
- PUSB_DEV_MANAGER dev_mgr;
- PDEVEXT_HEADER pdev_ext_hdr;
-
- pdev_ext_hdr = (PDEVEXT_HEADER) dev_obj->DeviceExtension;
- dev_mgr = pdev_ext_hdr->dev_mgr;
-
- if (dev_obj->CurrentIrp == pirp)
- {
- // just before start_io set the cancel routine to null
- IoReleaseCancelSpinLock(pirp->CancelIrql);
- // we did not IoStartNextPacket, leave it for dev_mgr_cancel_irp, that
- // is user have to call CancelIo again.
- return;
- }
-
- KeRemoveEntryDeviceQueue(&dev_obj->DeviceQueue, &pirp->Tail.Overlay.DeviceQueueEntry);
- IoReleaseCancelSpinLock(pirp->CancelIrql);
-
- pirp->IoStatus.Information = 0;
- pirp->IoStatus.Status = STATUS_CANCELLED;
- IoCompleteRequest(pirp, IO_NO_INCREMENT);
- // the device queue is moved on, no need to call IoStartNextPacket
- return;
-}
diff --git a/reactos/drivers/usb/nt4compat/usbdrv/gendrv.h b/reactos/drivers/usb/nt4compat/usbdrv/gendrv.h
deleted file mode 100644
index 9d64a9e314a..00000000000
--- a/reactos/drivers/usb/nt4compat/usbdrv/gendrv.h
+++ /dev/null
@@ -1,62 +0,0 @@
-#ifndef __GENDRV_H__
-#define __GENDRV_H__
-
-#define GENDRV_MAX_EXT_DRVR 2
-#define GENDRV_DRVR_FLAG_IF_DRVR 0x01
-
-#define GENDRV_MSG_ADDDEVICE 0x01
-#define GENDRV_MSG_STOPDEVICE 0x02
-#define GENDRV_MSG_DISCDEVICE 0x03
-
-typedef struct _GENDRV_EXT_DRVR_ENTRY
-{
- LIST_ENTRY drvr_link; // used for dynamic load/unload driver
- ULONG drvr_key; // used to find the driver loaded, the key
- // is ( vendor_id << 16 )|( product_id ) or
- // ( class_id << 16 ) | ( sub_class_id << 8 ) | ( protocol_id ))
- PDRIVER_OBJECT pext_drvr; // the external driver count
- ULONG ref_count; // number of devices attached
- LIST_HEAD dev_list; // link the devices by deviceExtension->dev_obj_link
-
-} GENDRV_EXT_DRVR_ENTRY, *PGENDRV_EXT_DRVR_ENTRY;
-
-typedef struct _GENDRV_DRVR_EXTENSION
-{
- FAST_MUTEX drvr_ext_mutex;
- ULONG ext_drvr_count; // loaded driver count
- LIST_HEAD ext_drvr_list;
- GENDRV_EXT_DRVR_ENTRY ext_drvr_array[ GENDRV_MAX_EXT_DRVR ];
-
-}GENDRV_DRVR_EXTENSION, *PGENDRV_DRVR_EXTENSION;
-
-typedef struct _GENDRV_IF_CTX
-{
- UCHAR if_idx; // valid for if device
- PUSB_INTERFACE_DESC pif_desc;
-
-} GENDRV_IF_CTX, *PGENDRV_IF_IDX;
-
-typedef struct _GENDRV_DEVICE_EXTENSION
-{
- //this structure is the device extension for dev_obj
- //created for the device.
- DEVEXT_HEADER dev_ext_hdr;
- ULONG flags;
- LIST_ENTRY dev_obj_link; // this link is used by the driver object to track the existing dev_objs
- PGENDRV_EXT_DRVR_ENTRY ext_drvr_entry;
-
- PDEVICE_OBJECT pdo; // Our device object
- DEV_HANDLE dev_handle; // handle to the usb_dev under
- PUCHAR desc_buf;
- UCHAR dev_id; // used to build symbolic link
- GENDRV_IF_CTX if_ctx;
-
- KEVENT sync_event;
- KSPIN_LOCK dev_lock;
-
- PUSB_DRIVER pdriver;
- PUSB_DEV_MANAGER dev_mgr;
-
-} GENDRV_DEVICE_EXTENSION, *PGENDRV_DEVICE_EXTENSION;
-
-#endif
diff --git a/reactos/drivers/usb/nt4compat/usbdrv/hcd.h b/reactos/drivers/usb/nt4compat/usbdrv/hcd.h
deleted file mode 100644
index 854e02e3746..00000000000
--- a/reactos/drivers/usb/nt4compat/usbdrv/hcd.h
+++ /dev/null
@@ -1,71 +0,0 @@
-#ifndef __HCD_H__
-#define __HCD_H__
-
-#define HCD_TYPE_MASK 0xf0
-#define HCD_TYPE_UHCI 0x10
-#define HCD_TYPE_OHCI 0x20
-#define HCD_TYPE_EHCI 0x30
-
-#define hcd_type( hCD ) ( ( ( hCD )->flags ) & HCD_TYPE_MASK )
-#define usb2( hCD ) ( hcd_type( hCD ) == HCD_TYPE_EHCI )
-
-#define HCD_ID_MASK 0xf
-
-#define HCD_DISP_READ_PORT_COUNT 1 // the param is a pointer to UCHAR
-#define HCD_DISP_READ_RH_DEV_CHANGE 2 // the param is a buffer to hold conn change on all the port
- // must have the rh dev_lock acquired
-
-struct _HCD;
-struct _USB_DEV_MANAGER;
-struct _USB_DEV;
-struct _USB_ENDPOINT;
-struct _URB;
-
-typedef VOID ( *PHCD_SET_DEV_MGR )( struct _HCD* hcd, struct _USB_DEV_MANAGER *dev_mgr );
-typedef struct _USB_DEV_MANAGER* ( *PHCD_GET_DEV_MGR )( struct _HCD* hcd );
-typedef ULONG ( *PHCD_GET_TYPE )( struct _HCD* hcd );
-typedef VOID ( *PHCD_SET_ID )( struct _HCD* hcd, UCHAR id );
-typedef UCHAR ( *PHCD_GET_ID )( struct _HCD* hcd );
-typedef UCHAR ( *PHCD_ALLOC_ADDR )( struct _HCD* hcd );
-typedef VOID ( *PHCD_FREE_ADDR )( struct _HCD* hcd, UCHAR addr );
-typedef NTSTATUS ( *PHCD_SUBMIT_URB )( struct _HCD* hcd, struct _USB_DEV *pdev, struct _USB_ENDPOINT *pendp, struct _URB *purb );
-typedef VOID ( *PHCD_GENERIC_URB_COMPLETION )( struct _URB *purb, PVOID context ); //we can get te hcd from purb
-typedef struct _USB_DEV* ( *PHCD_GET_ROOT_HUB )( struct _HCD* hcd );
-typedef VOID ( *PHCD_SET_ROOT_HUB )( struct _HCD* hcd, struct _USB_DEV *root_hub );
-typedef BOOLEAN ( *PHCD_REMOVE_DEVICE )( struct _HCD* hcd, struct _USB_DEV *pdev );
-typedef BOOLEAN ( *PHCD_RH_RESET_PORT )( struct _HCD* hcd, UCHAR port_idx ); //must have the rh dev_lock acquired
-typedef BOOLEAN ( *PHCD_RELEASE )( struct _HCD* hcd ); //must have the rh dev_lock acquired
-typedef NTSTATUS( *PHCD_CANCEL_URB)( struct _HCD* hcd, struct _USB_DEV *pdev, struct _USB_ENDPOINT* pendp, struct _URB *purb );
-typedef BOOLEAN ( *PHCD_START )( struct _HCD* hcd ); //must have the rh dev_lock acquired
-typedef NTSTATUS ( *PHCD_DISPATCH )( struct _HCD* hcd, LONG disp_code, PVOID param ); // locking depends on type of code
-
-typedef struct _HCD
-{
- PHCD_SET_DEV_MGR hcd_set_dev_mgr;
- PHCD_GET_DEV_MGR hcd_get_dev_mgr;
- PHCD_GET_TYPE hcd_get_type;
- PHCD_SET_ID hcd_set_id;
- PHCD_GET_ID hcd_get_id;
- PHCD_ALLOC_ADDR hcd_alloc_addr;
- PHCD_FREE_ADDR hcd_free_addr;
- PHCD_SUBMIT_URB hcd_submit_urb;
- PHCD_GENERIC_URB_COMPLETION hcd_generic_urb_completion;
- PHCD_GET_ROOT_HUB hcd_get_root_hub;
- PHCD_SET_ROOT_HUB hcd_set_root_hub;
- PHCD_REMOVE_DEVICE hcd_remove_device;
- PHCD_RH_RESET_PORT hcd_rh_reset_port;
- PHCD_RELEASE hcd_release;
- PHCD_CANCEL_URB hcd_cancel_urb;
- PHCD_START hcd_start;
- PHCD_DISPATCH hcd_dispatch;
-
- //interfaces for all the host controller
- ULONG flags; //hcd types | hcd id
- ULONG conn_count; //statics for connection activities
- struct _USB_DEV_MANAGER *dev_mgr; //pointer manager
- UCHAR dev_addr_map[ 128 / 8 ]; //bitmap for the device addrs
- struct _DEVICE_EXTENSION *pdev_ext;
-
-} HCD, *PHCD;
-
-#endif
diff --git a/reactos/drivers/usb/nt4compat/usbdrv/hub.c b/reactos/drivers/usb/nt4compat/usbdrv/hub.c
deleted file mode 100644
index 5a36821a96b..00000000000
--- a/reactos/drivers/usb/nt4compat/usbdrv/hub.c
+++ /dev/null
@@ -1,2800 +0,0 @@
-/**
- * hub.c - USB driver stack project for Windows NT 4.0
- *
- * Copyright (c) 2002-2004 Zhiming mypublic99@yahoo.com
- *
- * This program/include file is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program/include file is distributed in the hope that it will be
- * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
- * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program (in the main directory of the distribution, the file
- * COPYING); if not, write to the Free Software Foundation,Inc., 59 Temple
- * Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "usbdriver.h"
-
-//----------------------------------------------------------
-//event pool routines
-#define crash_machine() \
-{ ( ( PUSB_DEV ) 0 )->flags = 0x12345; }
-
-#define hub_if_from_dev( pdEV, pIF ) \
-{\
- int i;\
- for( i = 0; i < pdEV->usb_config->if_count; i ++ )\
- {\
- if( pdEV->usb_config->interf[ i ].pusb_if_desc->bInterfaceClass\
- == USB_CLASS_HUB )\
- {\
- break;\
- }\
- }\
-\
- if( i < pdEV->usb_config->if_count )\
- pIF = &pdev->usb_config->interf[ i ];\
- else\
- pIF = NULL;\
-\
-}
-
-extern ULONG cpu_clock_freq;
-
-BOOLEAN hub_check_reset_port_status(PUSB_DEV pdev, LONG port_idx);
-
-VOID hub_reexamine_port_status_queue(PUSB_DEV hub_dev, ULONG port_idx, BOOLEAN from_dpc);
-
-void hub_int_completion(PURB purb, PVOID pcontext);
-
-VOID hub_get_port_status_completion(PURB purb, PVOID context);
-
-VOID hub_clear_port_feature_completion(PURB purb, PVOID context);
-
-VOID hub_event_examine_status_que(PUSB_DEV pdev, ULONG event, ULONG context, //hub_ext
- ULONG param //port_idx
- );
-
-VOID hub_timer_wait_dev_stable(PUSB_DEV pdev,
- PVOID context //port-index
- );
-
-VOID hub_event_dev_stable(PUSB_DEV pdev,
- ULONG event,
- ULONG context, //hub_ext
- ULONG param //port_idx
- );
-
-VOID hub_post_esq_event(PUSB_DEV pdev, BYTE port_idx, PROCESS_EVENT pe);
-
-void hub_set_cfg_completion(PURB purb, PVOID pcontext);
-
-void hub_get_hub_desc_completion(PURB purb, PVOID pcontext);
-
-NTSTATUS hub_start_int_request(PUSB_DEV pdev);
-
-BOOLEAN hub_connect(PDEV_CONNECT_DATA init_param, DEV_HANDLE dev_handle);
-
-BOOLEAN hub_disconnect(PUSB_DEV_MANAGER dev_mgr, DEV_HANDLE dev_handle);
-
-BOOLEAN hub_stop(PUSB_DEV_MANAGER dev_mgr, DEV_HANDLE dev_handle);
-
-NTSTATUS hub_disable_port_request(PUSB_DEV pdev, UCHAR port_idx);
-
-VOID hub_start_reset_port_completion(PURB purb, PVOID context);
-
-BOOLEAN
-init_event_pool(PUSB_EVENT_POOL pool)
-{
- int i;
-
- if (pool == NULL)
- return FALSE;
-
- if ((pool->event_array = usb_alloc_mem(NonPagedPool, sizeof(USB_EVENT) * MAX_EVENTS)) == NULL)
- return FALSE;
-
- InitializeListHead(&pool->free_que);
- KeInitializeSpinLock(&pool->pool_lock);
- pool->total_count = MAX_EVENTS;
- pool->free_count = 0;
-
- for(i = 0; i < MAX_EVENTS; i++)
- {
- free_event(pool, &pool->event_array[i]);
- }
-
- return TRUE;
-}
-
-BOOLEAN
-free_event(PUSB_EVENT_POOL pool, PUSB_EVENT pevent)
-{
- if (pool == NULL || pevent == NULL)
- {
- return FALSE;
- }
-
- RtlZeroMemory(pevent, sizeof(USB_EVENT));
- InsertTailList(&pool->free_que, &pevent->event_link);
- pool->free_count++;
- usb_dbg_print(DBGLVL_MAXIMUM + 1,
- ("free_event(): alloced=0x%x, addr=0x%x\n", MAX_EVENTS - pool->free_count, pevent));
-
- return TRUE;
-}
-
-//null if failed
-PUSB_EVENT
-alloc_event(PUSB_EVENT_POOL pool, LONG count)
-{
- PUSB_EVENT NewEvent;
- if (pool == NULL || count != 1)
- return NULL;
-
- if (pool->free_count == 0)
- return NULL;
-
- NewEvent = (PUSB_EVENT) RemoveHeadList(&pool->free_que);
- pool->free_count--;
-
- usb_dbg_print(DBGLVL_MAXIMUM + 1,
- ("alloc_event(): alloced=0x%x, addr=0x%x\n", MAX_EVENTS - pool->free_count, NewEvent));
- return NewEvent;
-}
-
-BOOLEAN
-destroy_event_pool(PUSB_EVENT_POOL pool)
-{
- if (pool == NULL)
- return FALSE;
-
- InitializeListHead(&pool->free_que);
- pool->free_count = pool->total_count = 0;
- usb_free_mem(pool->event_array);
- pool->event_array = NULL;
-
- return TRUE;
-}
-
-VOID
-event_list_default_process_event(PUSB_DEV pdev, ULONG event, ULONG context, ULONG param)
-{
- UNREFERENCED_PARAMETER(param);
- UNREFERENCED_PARAMETER(context);
- UNREFERENCED_PARAMETER(event);
- UNREFERENCED_PARAMETER(pdev);
-}
-
-//----------------------------------------------------------
-//timer_svc pool routines
-
-BOOLEAN
-init_timer_svc_pool(PTIMER_SVC_POOL pool)
-{
- int i;
-
- if (pool == NULL)
- return FALSE;
-
- pool->timer_svc_array = usb_alloc_mem(NonPagedPool, sizeof(TIMER_SVC) * MAX_TIMER_SVCS);
- InitializeListHead(&pool->free_que);
- pool->free_count = 0;
- pool->total_count = MAX_TIMER_SVCS;
- KeInitializeSpinLock(&pool->pool_lock);
-
- for(i = 0; i < MAX_TIMER_SVCS; i++)
- {
- free_timer_svc(pool, &pool->timer_svc_array[i]);
- }
-
- return TRUE;
-}
-
-BOOLEAN
-free_timer_svc(PTIMER_SVC_POOL pool, PTIMER_SVC ptimer)
-{
- if (pool == NULL || ptimer == NULL)
- return FALSE;
-
- RtlZeroMemory(ptimer, sizeof(TIMER_SVC));
- InsertTailList(&pool->free_que, &ptimer->timer_svc_link);
- pool->free_count++;
-
- return TRUE;
-}
-
-//null if failed
-PTIMER_SVC
-alloc_timer_svc(PTIMER_SVC_POOL pool, LONG count)
-{
- PTIMER_SVC NewTimer;
-
- if (pool == NULL || count != 1)
- return NULL;
-
- if (pool->free_count <= 0)
- return NULL;
-
- NewTimer = (PTIMER_SVC) RemoveHeadList(&pool->free_que);
- pool->free_count--;
- return NewTimer;
-
-}
-
-BOOLEAN
-destroy_timer_svc_pool(PTIMER_SVC_POOL pool)
-{
- if (pool == NULL)
- return FALSE;
-
- usb_free_mem(pool->timer_svc_array);
- pool->timer_svc_array = NULL;
- InitializeListHead(&pool->free_que);
- pool->free_count = 0;
- pool->total_count = 0;
-
- return TRUE;
-}
-
-VOID
-event_list_default_process_queue(PLIST_HEAD event_list,
- PUSB_EVENT_POOL event_pool, PUSB_EVENT usb_event, PUSB_EVENT out_event)
-{
- //remove the first event from the event list, and copy it to
- //out_event
-
- if (event_list == NULL || event_pool == NULL || usb_event == NULL || out_event == NULL)
- return;
-
- RemoveEntryList(&usb_event->event_link);
- RtlCopyMemory(out_event, usb_event, sizeof(USB_EVENT));
- free_event(event_pool, usb_event);
- return;
-}
-
-BOOLEAN
-psq_enqueue(PPORT_STATUS_QUEUE psq, ULONG status)
-{
- if (psq == NULL)
- return FALSE;
-
- if (psq_is_full(psq))
- return FALSE;
-
- psq->port_status[psq->status_count].wPortChange = HIWORD(status);
- psq->port_status[psq->status_count].wPortStatus = LOWORD(status);
-
- psq->status_count++;
-
- usb_dbg_print(DBGLVL_MAXIMUM, ("psq_enqueue(): last status=0x%x, status count=0x%x, port_flag=0x%x\n",
- status, psq->status_count, psq->port_flags));
- return TRUE;
-
-}
-
-VOID
-psq_init(PPORT_STATUS_QUEUE psq)
-{
- RtlZeroMemory(psq, sizeof(PORT_STATUS_QUEUE));
- psq->port_flags = STATE_IDLE | USB_PORT_FLAG_DISABLE;
-}
-
-//return 0xffffffff if no element
-ULONG
-psq_outqueue(PPORT_STATUS_QUEUE psq)
-{
- ULONG status;
-
- if (psq == NULL)
- return 0;
-
- if (psq_is_empty(psq))
- return 0;
-
- status = ((PULONG) & psq->port_status)[0];
- psq->port_status[0] = psq->port_status[1];
- psq->port_status[1] = psq->port_status[2];
- psq->port_status[2] = psq->port_status[3];
- psq->status_count--;
-
- return status;
-}
-
-BOOLEAN
-psq_push(PPORT_STATUS_QUEUE psq, ULONG status)
-{
- if (psq == NULL)
- return FALSE;
-
- status = ((PULONG) & psq->port_status)[0];
- psq->port_status[3] = psq->port_status[2];
- psq->port_status[2] = psq->port_status[1];
- psq->port_status[1] = psq->port_status[0];
-
- ((PULONG) & psq->port_status)[0] = status;
-
- psq->status_count++;
- psq->status_count = ((4 > psq->status_count) ? psq->status_count : 4);
-
- return TRUE;
-}
-
-BOOLEAN
-hub_driver_init(PUSB_DEV_MANAGER dev_mgr, PUSB_DRIVER pdriver)
-{
- UNREFERENCED_PARAMETER(dev_mgr);
-
- //init driver structure, no PNP table functions
- pdriver->driver_desc.flags = USB_DRIVER_FLAG_DEV_CAPABLE;
- pdriver->driver_desc.vendor_id = 0xffff; // USB Vendor ID
- pdriver->driver_desc.product_id = 0xffff; // USB Product ID.
- pdriver->driver_desc.release_num = 0xffff; // Release Number of Device
-
- pdriver->driver_desc.config_val = 0; // Configuration Value
- pdriver->driver_desc.if_num = 0; // Interface Number
- pdriver->driver_desc.if_class = USB_CLASS_HUB; // Interface Class
- pdriver->driver_desc.if_sub_class = 0; // Interface SubClass
- pdriver->driver_desc.if_protocol = 0; // Interface Protocol
-
- pdriver->driver_desc.driver_name = "USB hub"; // Driver name for Name Registry
- pdriver->driver_desc.dev_class = USB_CLASS_HUB;
- pdriver->driver_desc.dev_sub_class = 0; // Device Subclass
- pdriver->driver_desc.dev_protocol = 0; // Protocol Info.
-
- //pdriver->driver_init = hub_driver_init; // initialized in dev_mgr_init_driver
- //pdriver->driver_destroy = hub_driver_destroy;
-
- pdriver->driver_ext = 0;
- pdriver->driver_ext_size = 0;
-
- pdriver->disp_tbl.version = 1;
- pdriver->disp_tbl.dev_connect = hub_connect;
- pdriver->disp_tbl.dev_disconnect = hub_disconnect;
- pdriver->disp_tbl.dev_stop = hub_stop;
- pdriver->disp_tbl.dev_reserved = NULL;
-
- return TRUE;
-}
-
-BOOLEAN
-hub_driver_destroy(PUSB_DEV_MANAGER dev_mgr, PUSB_DRIVER pdriver)
-{
- UNREFERENCED_PARAMETER(dev_mgr);
-
- pdriver->driver_ext = NULL;
- return TRUE;
-}
-
-void
-hub_reset_pipe_completion(PURB purb, //only for reference, can not be released
- PVOID context)
-{
- PUSB_DEV pdev;
- PUSB_ENDPOINT pendp;
-
- USE_BASIC_NON_PENDING_IRQL;
-
- UNREFERENCED_PARAMETER(context);
-
- if (purb == NULL)
- {
- return;
- }
-
- pdev = purb->pdev;
- pendp = purb->pendp;
-
- lock_dev(pdev, TRUE);
- if (dev_state(pdev) == USB_DEV_STATE_ZOMB)
- {
- unlock_dev(pdev, TRUE);
- return;
- }
-
- if (usb_error(purb->status))
- {
- //simply retry it
- unlock_dev(pdev, TRUE);
- //usb_free_mem( purb );
- return;
- }
- unlock_dev(pdev, TRUE);
-
- pdev = purb->pdev;
- hub_start_int_request(pdev);
- return;
-}
-
-NTSTATUS
-hub_start_int_request(PUSB_DEV pdev)
-{
- PURB purb;
- PUSB_INTERFACE pif;
- PHUB2_EXTENSION hub_ext;
- NTSTATUS status;
- PHCD hcd;
- USE_BASIC_NON_PENDING_IRQL;
-
- if (pdev == NULL)
- return STATUS_INVALID_PARAMETER;
-
- lock_dev(pdev, FALSE);
- if (dev_state(pdev) == USB_DEV_STATE_ZOMB)
- {
- unlock_dev(pdev, FALSE);
- return STATUS_DEVICE_DOES_NOT_EXIST;
- }
- purb = usb_alloc_mem(NonPagedPool, sizeof(URB));
-
- if (purb == NULL)
- {
- unlock_dev(pdev, FALSE);
- return STATUS_NO_MEMORY;
- }
-
- RtlZeroMemory(purb, sizeof(URB));
-
- purb->flags = 0;
- purb->status = STATUS_SUCCESS;
- hub_ext = hub_ext_from_dev(pdev);
- purb->data_buffer = hub_ext->int_data_buf;
- purb->data_length = (hub_ext->port_count + 7) / 8;
-
- hub_if_from_dev(pdev, pif);
- usb_dbg_print(DBGLVL_ULTRA, ("hub_start_int_request(): pdev=0x%x, pif=0x%x\n", pdev, pif));
- purb->pendp = &pif->endp[0];
- purb->pdev = pdev;
-
- purb->completion = hub_int_completion;
- purb->context = hub_ext;
-
- purb->pirp = NULL;
- purb->reference = 0;
- hcd = pdev->hcd;
- unlock_dev(pdev, FALSE);
-
- status = hcd->hcd_submit_urb(hcd, pdev, purb->pendp, purb);
- if (status != STATUS_PENDING)
- {
- usb_free_mem(purb);
- purb = NULL;
- }
-
- return status;
-}
-
-void
-hub_int_completion(PURB purb, PVOID pcontext)
-{
-
- PUSB_DEV pdev;
- PHUB2_EXTENSION hub_ext;
- ULONG port_idx;
- PUSB_CTRL_SETUP_PACKET psetup;
- NTSTATUS status;
- LONG i;
- PHCD hcd;
-
- USE_BASIC_NON_PENDING_IRQL;
-
- if (purb == NULL)
- return;
-
- if (pcontext == NULL)
- {
- usb_free_mem(purb);
- return;
- }
-
- usb_dbg_print(DBGLVL_ULTRA, ("hub_int_completion(): entering...\n"));
-
- pdev = purb->pdev;
- hub_ext = pcontext;
-
- lock_dev(pdev, TRUE);
- if (dev_state(pdev) == USB_DEV_STATE_ZOMB)
- {
- unlock_dev(pdev, TRUE);
- usb_free_mem(purb);
- return;
- }
-
- hcd = pdev->hcd;
-
- if (purb->status == STATUS_SUCCESS)
- {
-
- for(i = 1; i <= hub_ext->port_count; i++)
- {
- if (hub_ext->int_data_buf[i >> 3] & (1 << i))
- {
- break;
- }
- }
- if (i > hub_ext->port_count)
- {
- //no status change, re-initialize the int request
- unlock_dev(pdev, TRUE);
- usb_free_mem(purb);
- hub_start_int_request(pdev);
- return;
- }
-
- port_idx = (ULONG)i;
-
- //re-use the urb to get port status
- purb->pendp = &pdev->default_endp;
- purb->data_buffer = (PUCHAR) & hub_ext->port_status;
-
- purb->data_length = sizeof(USB_PORT_STATUS);
- purb->pdev = pdev;
-
- purb->context = hub_ext;
- purb->pdev = pdev;
- purb->completion = hub_get_port_status_completion;
- purb->reference = port_idx;
-
- psetup = (PUSB_CTRL_SETUP_PACKET) purb->setup_packet;
-
- psetup->bmRequestType = 0xa3; //host-device class other recepient
- psetup->bRequest = USB_REQ_GET_STATUS;
- psetup->wValue = 0;
- psetup->wIndex = (USHORT) port_idx;
- psetup->wLength = 4;
-
- purb->pirp = NULL;
- unlock_dev(pdev, TRUE);
-
- status = hcd->hcd_submit_urb(hcd, pdev, purb->pendp, purb);
- if (usb_error(status))
- {
- usb_free_mem(purb);
- purb = NULL;
- }
- else if (status == STATUS_SUCCESS)
- {
- // this is for root hub
- hcd->hcd_generic_urb_completion(purb, purb->context);
- }
- return;
- }
- else
- {
- unlock_dev(pdev, TRUE);
- if (usb_halted(purb->status))
- {
- //let's reset pipe
- usb_reset_pipe(pdev, purb->pendp, hub_reset_pipe_completion, NULL);
- }
- //unexpected error
- usb_free_mem(purb);
- purb = NULL;
- }
- return;
-}
-
-VOID
-hub_get_port_status_completion(PURB purb, PVOID context)
-{
- PUSB_DEV pdev;
- PUSB_ENDPOINT pendp;
- BYTE port_idx;
- PHUB2_EXTENSION hub_ext;
- PUSB_CTRL_SETUP_PACKET psetup;
- NTSTATUS status;
- PHCD hcd;
-
- USE_BASIC_NON_PENDING_IRQL;
-
- if (purb == NULL || context == NULL)
- return;
-
- usb_dbg_print(DBGLVL_MAXIMUM, ("hub_get_port_feature_completion(): entering...\n"));
-
- pdev = purb->pdev;
- pendp = purb->pendp;
-
- lock_dev(pdev, TRUE);
- if (dev_state(pdev) == USB_DEV_STATE_ZOMB)
- {
- unlock_dev(pdev, TRUE);
- usb_free_mem(purb);
- return;
- }
-
- hcd = pdev->hcd;
- if (usb_error(purb->status))
- {
- unlock_dev(pdev, TRUE);
-
- purb->status = 0;
- //simply retry the request refer to item 55 in document
- status = hcd->hcd_submit_urb(hcd, pdev, pendp, purb);
- if (status != STATUS_PENDING)
- {
- if (status == STATUS_SUCCESS)
- {
- hcd->hcd_generic_urb_completion(purb, purb->context);
-
- }
- else
- {
- //
- // must be fatal error
- // FIXME: better to pass it to the completion for further
- // processing?
- //
- usb_free_mem(purb);
- }
- }
- return;
- }
-
- hub_ext = hub_ext_from_dev(pdev);
- port_idx = (BYTE) purb->reference;
-
- usb_dbg_print(DBGLVL_MAXIMUM, ("hub_get_port_stataus_completion(): port_idx=0x%x, hcd =0x%x, \
- pdev=0x%x, purb=0x%x, hub_ext=0x%x, portsc=0x%x \n", port_idx, pdev->hcd, pdev,
- purb, hub_ext, *((PULONG) purb->data_buffer)));
-
- psq_enqueue(&hub_ext->port_status_queue[port_idx], *((PULONG) purb->data_buffer));
-
- //reuse the urb to clear the feature
- RtlZeroMemory(purb, sizeof(URB));
-
- purb->data_buffer = NULL;
- purb->data_length = 0;
- purb->pendp = &pdev->default_endp;
- purb->pdev = pdev;
-
- purb->context = (PVOID) & hub_ext->port_status;
- purb->pdev = pdev;
- purb->completion = hub_clear_port_feature_completion;
- purb->reference = port_idx;
-
- psetup = (PUSB_CTRL_SETUP_PACKET) purb->setup_packet;
-
- psetup->bmRequestType = 0x23; //host-device class port recepient
- psetup->bRequest = USB_REQ_CLEAR_FEATURE;
- psetup->wIndex = port_idx;
- psetup->wLength = 0;
- purb->pirp = NULL;
-
- if (hub_ext->port_status.wPortChange & USB_PORT_STAT_C_CONNECTION)
- {
- psetup->wValue = USB_PORT_FEAT_C_CONNECTION;
- }
- else if (hub_ext->port_status.wPortChange & USB_PORT_STAT_C_ENABLE)
- {
- psetup->wValue = USB_PORT_FEAT_C_ENABLE;
- }
- else if (hub_ext->port_status.wPortChange & USB_PORT_STAT_C_SUSPEND)
- {
- psetup->wValue = USB_PORT_FEAT_C_SUSPEND;
- }
- else if (hub_ext->port_status.wPortChange & USB_PORT_STAT_C_OVERCURRENT)
- {
- psetup->wValue = USB_PORT_FEAT_C_OVER_CURRENT;
- }
- else if (hub_ext->port_status.wPortChange & USB_PORT_STAT_C_RESET)
- {
- psetup->wValue = USB_PORT_FEAT_C_RESET;
- }
- unlock_dev(pdev, TRUE);
-
- status = hcd->hcd_submit_urb(hcd, pdev, pendp, purb);
-
- // if( status != STATUS_SUCCESS )
- if (status != STATUS_PENDING)
- {
- hcd->hcd_generic_urb_completion(purb, purb->context);
- }
- /*else if( usb_error( status ) )
- {
- usb_free_mem( purb );
- return;
- } */
- return;
-
-}
-
-VOID
-hub_clear_port_feature_completion(PURB purb, PVOID context)
-{
- BYTE port_idx;
- LONG i;
- BOOLEAN event_post, brh;
- ULONG pc;
- PHCD hcd;
- NTSTATUS status;
- PUSB_DEV pdev;
- PHUB2_EXTENSION hub_ext = NULL;
- PUSB_DEV_MANAGER dev_mgr;
-
- PUSB_CTRL_SETUP_PACKET psetup;
-
- USE_BASIC_NON_PENDING_IRQL;
-
- if (purb == NULL)
- return;
-
- if (context == NULL)
- {
- usb_free_mem(purb);
- return;
- }
-
- usb_dbg_print(DBGLVL_MAXIMUM, ("hub_clear_port_feature_completion(): entering...\n"));
-
- pdev = purb->pdev;
- port_idx = (BYTE) purb->reference;
-
- lock_dev(pdev, TRUE);
- dev_mgr = dev_mgr_from_dev(pdev);
- hcd = pdev->hcd;
- brh = (BOOLEAN) (dev_class(pdev) == USB_DEV_CLASS_ROOT_HUB);
-
- if (usb_error(purb->status))
- {
- unlock_dev(pdev, TRUE);
-
- purb->status = 0;
-
- // retry the request
- status = hcd->hcd_submit_urb(hcd, purb->pdev, purb->pendp, purb);
- if (status != STATUS_PENDING)
- {
- if (status == STATUS_SUCCESS)
- {
- hcd->hcd_generic_urb_completion(purb, purb->context);
- }
- else
- {
- //
- // FIXME: should we pass the error to the completion directly
- // instead of forstall it here?
- //
- // do not think the device is workable, no requests to it any more.
- // including the int polling
-
- if (purb)
- usb_free_mem(purb);
-
- if (port_idx)
- hub_check_reset_port_status(pdev, port_idx);
- }
- }
- return;
- }
-
- if (dev_state(pdev) == USB_DEV_STATE_ZOMB)
- {
- unlock_dev(pdev, TRUE);
- usb_free_mem(purb);
- return;
- }
-
- pc = ((PUSB_PORT_STATUS) context)->wPortChange;
-
- if (pc)
- {
- // the bits are tested in ascending order
- if (pc & USB_PORT_STAT_C_CONNECTION)
- {
- pc &= ~USB_PORT_STAT_C_CONNECTION;
- }
- else if (pc & USB_PORT_STAT_C_ENABLE)
- {
- pc &= ~USB_PORT_STAT_C_ENABLE;
- }
- else if (pc & USB_PORT_STAT_C_SUSPEND)
- {
- pc &= ~USB_PORT_STAT_C_SUSPEND;
- }
- else if (pc & USB_PORT_STAT_C_OVERCURRENT)
- {
- pc &= ~USB_PORT_STAT_C_OVERCURRENT;
- }
- else if (pc & USB_PORT_STAT_C_RESET)
- {
- pc &= ~USB_PORT_STAT_C_RESET;
- }
- }
- ((PUSB_PORT_STATUS) context)->wPortChange = (USHORT) pc;
-
- hub_ext = hub_ext_from_dev(pdev);
-
- if (pc)
- {
- //some other status change on the port still active
- psetup = (PUSB_CTRL_SETUP_PACKET) purb->setup_packet;
-
- if (hub_ext->port_status.wPortChange & USB_PORT_STAT_C_CONNECTION)
- {
- psetup->wValue = USB_PORT_FEAT_C_CONNECTION;
- }
- else if (hub_ext->port_status.wPortChange & USB_PORT_STAT_C_ENABLE)
- {
- psetup->wValue = USB_PORT_FEAT_C_ENABLE;
- }
- else if (hub_ext->port_status.wPortChange & USB_PORT_STAT_C_SUSPEND)
- {
- psetup->wValue = USB_PORT_FEAT_C_SUSPEND;
- }
- else if (hub_ext->port_status.wPortChange & USB_PORT_STAT_C_OVERCURRENT)
- {
- psetup->wValue = USB_PORT_FEAT_C_OVER_CURRENT;
- }
- else if (hub_ext->port_status.wPortChange & USB_PORT_STAT_C_RESET)
- {
- psetup->wValue = USB_PORT_FEAT_C_RESET;
- }
- unlock_dev(pdev, TRUE);
-
- status = hcd->hcd_submit_urb(hcd, pdev, purb->pendp, purb);
- if (status != STATUS_PENDING)
- {
- if (status == STATUS_SUCCESS)
- {
- usb_dbg_print(DBGLVL_MAXIMUM,
- ("hub_clear_port_status_completion(): port_idx=0x%x, hcd=0x%x, \
- pdev=0x%x, purb=0x%x, hub_ext=0x%x, wPortChange=0x%x \n",
- port_idx, pdev->hcd, pdev, purb, hub_ext, pc));
-
- hcd->hcd_generic_urb_completion(purb, purb->context);
- }
- else
- {
- usb_dbg_print(DBGLVL_MAXIMUM, (" hub_clear_port_feature_completion(): \
- error=0x%x\n", status));
-
- // usb_free_mem( purb );
- goto LBL_SCAN_PORT_STAT;
- }
- }
- return;
- }
-
- for(i = 1; i <= hub_ext->port_count; i++)
- {
- if (hub_ext->int_data_buf[i >> 3] & (1 << i))
- {
- break;
- }
- }
-
- //clear the port-change map, we have get port i's status.
- hub_ext->int_data_buf[i >> 3] &= ~(1 << i);
-
- //rescan to find some other port that has status change
- for(i = 1; i <= hub_ext->port_count; i++)
- {
- if (hub_ext->int_data_buf[i >> 3] & (1 << i))
- {
- break;
- }
- }
-
- if (i <= hub_ext->port_count)
- {
- //still has port-change pending, get the port status change
- port_idx = (UCHAR) i;
-
- //re-use the urb
- purb->data_buffer = (PUCHAR) & hub_ext->port_status;
- purb->data_length = sizeof(USB_PORT_STATUS);
- purb->pendp = &pdev->default_endp;
- purb->pdev = pdev;
-
- purb->context = hub_ext;
- purb->pdev = pdev;
- purb->completion = hub_get_port_status_completion;
- purb->reference = port_idx;
-
- psetup = (PUSB_CTRL_SETUP_PACKET) purb->setup_packet;
-
- psetup->bmRequestType = 0xa3; //host-device class other recepient
- psetup->bRequest = USB_REQ_GET_STATUS;
- psetup->wValue = 0;
- psetup->wIndex = port_idx;
- psetup->wLength = 4;
-
- purb->pirp = NULL;
-
- unlock_dev(pdev, TRUE);
-
- status = hcd->hcd_submit_urb(hcd, pdev, purb->pendp, purb);
- if (status != STATUS_PENDING)
- {
- if (status == STATUS_SUCCESS)
- {
- hcd->hcd_generic_urb_completion(purb, purb->context);
- }
- else
- { //must be fatal error
- // usb_free_mem( purb );
- goto LBL_SCAN_PORT_STAT;
- }
- }
- return;
- }
-
- unlock_dev(pdev, TRUE);
-
-LBL_SCAN_PORT_STAT:
-
- //all status changes are cleared
- if (purb)
- usb_free_mem(purb);
-
- purb = NULL;
-
- KeAcquireSpinLockAtDpcLevel(&dev_mgr->event_list_lock);
- lock_dev(pdev, TRUE);
-
- if (dev_state(pdev) == USB_DEV_STATE_ZOMB)
- {
- //
- // if reset is in process, the dev_mgr_disconnect_dev will continue
- // the following resets
- //
- unlock_dev(pdev, TRUE);
- KeReleaseSpinLockFromDpcLevel(&dev_mgr->event_list_lock);
- return;
- }
-
- //at last we wake up thread if some port have status change to process
- port_idx = 0;
- for(i = 1, event_post = FALSE; i <= hub_ext->port_count; i++)
- {
- if (psq_is_empty(&hub_ext->port_status_queue[i]) == FALSE)
- {
- if (port_state(hub_ext->port_status_queue[i].port_flags) == STATE_IDLE ||
- port_state(hub_ext->port_status_queue[i].port_flags) == STATE_WAIT_ADDRESSED)
- {
- // have status in the queue pending
- // STATE_WAIT_ADDRESSED is added to avoid some bad mannered
- // hub to disturb the reset process
- hub_post_esq_event(pdev, (BYTE) i, hub_event_examine_status_que);
- }
- else if (port_state(hub_ext->port_status_queue[i].port_flags) == STATE_WAIT_RESET_COMPLETE)
- {
- //there is only one reset at one time
- port_idx = (BYTE) i;
- }
- }
- }
-
- unlock_dev(pdev, TRUE);
- KeReleaseSpinLockFromDpcLevel(&dev_mgr->event_list_lock);
-
-
- if (port_idx)
- hub_check_reset_port_status(pdev, port_idx);
-
- //reinitialize the int request, here to reduce some uncertainty of concurrency
- hub_start_int_request(pdev);
-
- return;
-}
-
-VOID
-hub_event_examine_status_que(PUSB_DEV pdev,
- ULONG event,
- ULONG context, //hub_ext
- ULONG param //port_idx
- )
-{
- PHUB2_EXTENSION hub_ext;
- USB_PORT_STATUS ps;
- PUSB_DEV pchild_dev;
- PTIMER_SVC ptimer;
- PUSB_DEV_MANAGER dev_mgr;
-
- USE_NON_PENDING_IRQL;
-
- UNREFERENCED_PARAMETER(event);
-
- if (pdev == NULL || context == 0 || param == 0)
- return;
-
- while (TRUE)
- {
- lock_dev(pdev, FALSE);
- if (dev_state(pdev) == USB_DEV_STATE_ZOMB)
- {
- unlock_dev(pdev, FALSE);
- break;
- }
-
- dev_mgr = dev_mgr_from_dev(pdev);
- hub_ext = hub_ext_from_dev(pdev);
-
- if (psq_is_empty(&hub_ext->port_status_queue[param]))
- {
- set_port_state(hub_ext->port_status_queue[param].port_flags, STATE_IDLE);
- unlock_dev(pdev, FALSE);
- break;
- }
-
- *((ULONG *) & ps) = psq_outqueue(&hub_ext->port_status_queue[param]);
-
-
- pchild_dev = hub_ext->child_dev[param];
- hub_ext->child_dev[param] = 0;
-
- usb_dbg_print(DBGLVL_MAXIMUM,
- ("hub_event_examine_status_queue(): dev_addr=0x%x, port=0x%x, wPortChange=0x%x, wPortStatus=0x%x\n",
- pdev->dev_addr, param, ps.wPortChange, ps.wPortStatus));
-
- unlock_dev(pdev, FALSE);
-
- if (pchild_dev != NULL)
- dev_mgr_disconnect_dev(pchild_dev);
-
- if (((ps.wPortChange & USB_PORT_STAT_C_ENABLE) &&
- ((pdev->flags & USB_DEV_CLASS_MASK) != USB_DEV_CLASS_ROOT_HUB))
- || (ps.wPortChange & USB_PORT_STAT_C_OVERCURRENT)
- || (ps.wPortChange & USB_PORT_STAT_C_RESET)
- || ((ps.wPortChange & USB_PORT_STAT_C_CONNECTION) &&
- !(ps.wPortStatus & USB_PORT_STAT_CONNECTION)))
- {
- usb_dbg_print(DBGLVL_MAXIMUM,
- ("hub_event_examine_status_queue(): error occured, portc=0x%x, ports=0x%x\n",
- ps.wPortChange, ps.wPortStatus));
-
- lock_dev(pdev, FALSE);
- if (dev_state(pdev) == USB_DEV_STATE_ZOMB)
- {
- unlock_dev(pdev, FALSE);
- break;
- }
- if (psq_is_empty(&hub_ext->port_status_queue[param]))
- {
- set_port_state(hub_ext->port_status_queue[param].port_flags, STATE_IDLE);
- }
- else
- {
- set_port_state(hub_ext->port_status_queue[param].port_flags, STATE_EXAMINE_STATUS_QUE);
- }
- unlock_dev(pdev, FALSE);
- continue;
-
- }
- else if ((ps.wPortChange & USB_PORT_STAT_C_CONNECTION)
- && (ps.wPortStatus & USB_PORT_STAT_CONNECTION)
- && psq_is_empty(&hub_ext->port_status_queue[param]))
- {
- KeAcquireSpinLock(&dev_mgr->timer_svc_list_lock, &old_irql);
- lock_dev(pdev, TRUE);
- if (dev_state(pdev) == USB_DEV_STATE_ZOMB)
- {
- unlock_dev(pdev, TRUE);
- KeReleaseSpinLock(&dev_mgr->timer_svc_list_lock, old_irql);
- usb_dbg_print(DBGLVL_MAXIMUM, ("hub_event_examine_status_queue(): dev lost\n"));
- break;
- }
- ptimer = alloc_timer_svc(&dev_mgr->timer_svc_pool, 1);
- if (ptimer == NULL)
- {
- unlock_dev(pdev, TRUE);
- KeReleaseSpinLock(&dev_mgr->timer_svc_list_lock, old_irql);
- usb_dbg_print(DBGLVL_MAXIMUM,
- ("hub_event_examine_status_queue(): timer can not allocated\n"));
- break;
- }
-
- //a new connection
- usb_dbg_print(DBGLVL_MAXIMUM, ("hub_event_examine_status_queue(): new connection comes\n"));
-
- ptimer->counter = 0;
- ptimer->threshold = 21; //100 ms
-
- if (ps.wPortStatus & USB_PORT_STAT_LOW_SPEED)
- ptimer->threshold = 51; //500 ms
-
- ptimer->context = param;
- ptimer->pdev = pdev;
- ptimer->func = hub_timer_wait_dev_stable;
- InsertTailList(&dev_mgr->timer_svc_list, &ptimer->timer_svc_link);
- pdev->ref_count++;
- set_port_state(hub_ext->port_status_queue[param].port_flags, STATE_WAIT_STABLE);
- unlock_dev(pdev, TRUE);
- KeReleaseSpinLock(&dev_mgr->timer_svc_list_lock, old_irql);
- break;
-
- }
- else
- {
- usb_dbg_print(DBGLVL_MAXIMUM, ("hub_event_examine_status_queue(): unknown error\n"));
- continue;
- }
- }
- return;
-}
-
-VOID
-hub_timer_wait_dev_stable(PUSB_DEV pdev,
- PVOID context //port-index
- )
-{
-
- PHUB2_EXTENSION hub_ext;
- ULONG param;
- PUSB_DEV_MANAGER dev_mgr;
-
- USE_BASIC_NON_PENDING_IRQL;
-
- if (pdev == NULL || context == 0)
- return;
-
- dev_mgr = dev_mgr_from_dev(pdev);
- param = (ULONG) context;
- KeAcquireSpinLockAtDpcLevel(&dev_mgr->event_list_lock);
- lock_dev(pdev, TRUE);
-
- pdev->ref_count--;
-
- if (dev_state(pdev) == USB_DEV_STATE_ZOMB)
- {
- goto LBL_OUT;
- }
-
- hub_ext = hub_ext_from_dev(pdev);
-
- if (!psq_is_empty(&hub_ext->port_status_queue[param]))
- {
- //error occured, normally we should not receive event here
- set_port_state(hub_ext->port_status_queue[param].port_flags, STATE_EXAMINE_STATUS_QUE);
-
- hub_post_esq_event(pdev, (BYTE) param, hub_event_examine_status_que);
- }
- else
- {
- set_port_state(hub_ext->port_status_queue[param].port_flags, STATE_WAIT_RESET);
-
- hub_post_esq_event(pdev, (BYTE) param, hub_event_dev_stable);
-
- }
-
-LBL_OUT:
- unlock_dev(pdev, TRUE);
- KeReleaseSpinLockFromDpcLevel(&dev_mgr->event_list_lock);
- return;
-}
-
-VOID
-hub_event_dev_stable(PUSB_DEV pdev,
- ULONG event,
- ULONG context, //hub_ext
- ULONG param //port_idx
- )
-{
-
- PHUB2_EXTENSION hub_ext;
- PUSB_EVENT pevent, pevent1;
- PLIST_ENTRY pthis, pnext;
- BOOLEAN que_exist;
- PHCD hcd;
- PUSB_DEV_MANAGER dev_mgr;
- NTSTATUS status;
- PURB purb;
- PUSB_CTRL_SETUP_PACKET psetup;
-
- USE_NON_PENDING_IRQL;
-
- UNREFERENCED_PARAMETER(event);
-
- if (pdev == NULL || context == 0 || param == 0)
- return;
-
- dev_mgr = dev_mgr_from_dev(pdev);
- KeAcquireSpinLock(&dev_mgr->event_list_lock, &old_irql);
- lock_dev(pdev, TRUE);
-
- if (dev_state(pdev) == USB_DEV_STATE_ZOMB)
- goto LBL_OUT;
-
- hub_ext = hub_ext_from_dev(pdev);
- hcd = pdev->hcd;
-
- pevent = alloc_event(&dev_mgr->event_pool, 1);
- if (pevent == NULL)
- goto LBL_OUT;
-
- pevent->event = USB_EVENT_WAIT_RESET_PORT;
- pevent->pdev = pdev;
- pevent->context = (ULONG) hub_ext;
- pevent->param = param;
- pevent->flags = USB_EVENT_FLAG_QUE_RESET;
- pevent->process_event = NULL; //hub_event_reset_port_complete;
- pevent->process_queue = NULL; //hub_event_reset_process_queue;
- pevent->pnext = NULL;
-
- ListFirst(&dev_mgr->event_list, pthis);
- que_exist = FALSE;
-
- while (pthis)
- {
- //insert the event in to the wait-queue
- pevent1 = (PUSB_EVENT) pthis;
- if (pevent1->event == USB_EVENT_WAIT_RESET_PORT)
- {
- while (pevent1->pnext)
- pevent1 = pevent1->pnext;
-
- pevent1->pnext = pevent;
- que_exist = TRUE;
- break;
- }
- ListNext(&dev_mgr->event_list, pthis, pnext);
- pthis = pnext;
- }
-
- if (!que_exist)
- {
- //Let's start a reset port request
- InsertHeadList(&dev_mgr->event_list, &pevent->event_link);
- purb = usb_alloc_mem(NonPagedPool, sizeof(URB));
- if (!purb) goto LBL_OUT;
- RtlZeroMemory(purb, sizeof(URB));
-
- purb->data_buffer = NULL;
- purb->data_length = 0;
- purb->pendp = &pdev->default_endp;
-
- purb->context = hub_ext;
- purb->pdev = pdev;
- purb->completion = hub_start_reset_port_completion; //hub_int_completion;
- purb->reference = param;
-
- psetup = (PUSB_CTRL_SETUP_PACKET) purb->setup_packet;
-
- psetup->bmRequestType = 0x23; //host-device other recepient
- psetup->bRequest = USB_REQ_SET_FEATURE;
- psetup->wValue = USB_PORT_FEAT_RESET;
- psetup->wIndex = (USHORT) param;
- psetup->wLength = 0;
-
- purb->pirp = NULL;
- //enter another state
- set_port_state(hub_ext->port_status_queue[param].port_flags, STATE_WAIT_RESET_COMPLETE);
-
- unlock_dev(pdev, TRUE);
- KeReleaseSpinLock(&dev_mgr->event_list_lock, old_irql);
-
- status = hcd->hcd_submit_urb(hcd, pdev, purb->pendp, purb);
- if (status != STATUS_PENDING)
- {
- //must be fatal error
- usb_free_mem(purb);
- hub_reexamine_port_status_queue(pdev, param, FALSE);
- if (hub_remove_reset_event(pdev, param, FALSE))
- hub_start_next_reset_port(dev_mgr, FALSE);
- }
- return;
- }
-
-LBL_OUT:
- unlock_dev(pdev, TRUE);
- KeReleaseSpinLock(&dev_mgr->event_list_lock, old_irql);
- return;
-}
-
-VOID
-hub_start_reset_port_completion(PURB purb, PVOID context)
-{
- PUSB_DEV pdev;
- PUSB_ENDPOINT pendp;
- PUSB_DEV_MANAGER dev_mgr = NULL;
- NTSTATUS status = STATUS_SUCCESS;
- ULONG port_idx;
- PHCD hcd;
-
- USE_BASIC_NON_PENDING_IRQL;
- if (purb == NULL)
- return;
-
- if (context == NULL)
- {
- //fatal error no retry.
- usb_free_mem(purb);
- return;
- }
-
- pdev = purb->pdev;
- pendp = purb->pendp;
- port_idx = purb->reference;
-
- lock_dev(pdev, TRUE);
-
- if (dev_state(pdev) == USB_DEV_STATE_ZOMB)
- {
- unlock_dev(pdev, TRUE);
- usb_free_mem(purb);
- goto LBL_FREE_EVENT;
- }
-
- hcd = pdev->hcd;
- dev_mgr = dev_mgr_from_dev(pdev);
- unlock_dev(pdev, TRUE);
-
- status = purb->status;
- usb_free_mem(purb);
-
- if (!usb_error(status))
- {
- return;
- }
-
-LBL_FREE_EVENT:
- //since we have no patient to retry the dev, we should remove the event of
- //wait_reset_port on the port from the event list. and if possible, start
- //another reset process. note other port on the dev still have chance to be
- //reset if necessary.
- hub_reexamine_port_status_queue(pdev, port_idx, TRUE);
- if (hub_remove_reset_event(pdev, port_idx, TRUE))
- hub_start_next_reset_port(dev_mgr, TRUE);
- return;
-}
-
-
-VOID
-hub_set_address_completion(PURB purb, PVOID context)
-{
- PUSB_DEV pdev, hub_dev;
- PUSB_ENDPOINT pendp;
- PUSB_DEV_MANAGER dev_mgr;
- NTSTATUS status;
- ULONG port_idx;
- PHCD hcd;
- USE_BASIC_NON_PENDING_IRQL;
-
- hcd_dbg_print(DBGLVL_MAXIMUM, ("hub_set_address_completion: purb=%p context=%p\n", purb, context));
-
- if (purb == NULL)
- return;
-
- if (context == NULL)
- {
- //fatal error no retry.
- usb_free_mem(purb);
- return;
- }
-
- pdev = purb->pdev;
- pendp = purb->pendp;
- port_idx = purb->reference;
-
- lock_dev(pdev, TRUE);
-
- hcd = pdev->hcd;
- dev_mgr = dev_mgr_from_dev(pdev);
- hub_dev = pdev->parent_dev;
- port_idx = pdev->port_idx;
-
- if (dev_state(pdev) == USB_DEV_STATE_ZOMB)
- {
- unlock_dev(pdev, TRUE);
- usb_free_mem(purb);
- //some error occured, let's start the next reset event
- goto LBL_RESET_NEXT;
- }
-
- pdev->flags &= ~USB_DEV_STATE_MASK;
- pdev->flags |= USB_DEV_STATE_ADDRESSED;
-
- unlock_dev(pdev, TRUE);
- status = purb->status;
-
- if (usb_error(status))
- {
- //retry the urb
- purb->status = 0;
- hcd_dbg_print(DBGLVL_MAXIMUM, ("hub_set_address_completion: can not set address\n"));
- status = hcd->hcd_submit_urb(hcd, pdev, pendp, purb);
- //some error occured, disable the port
- if (status != STATUS_PENDING)
- {
- usb_free_mem(purb);
- status = hub_disable_port_request(hub_dev, (UCHAR) port_idx);
- }
- return;
- }
-
- usb_free_mem(purb);
- //let address settle
- usb_wait_ms_dpc(10);
-
- //let's config the dev
- dev_mgr_start_config_dev(pdev);
-
-LBL_RESET_NEXT:
- //second, remove the event in the queue
- hub_reexamine_port_status_queue(hub_dev, port_idx, TRUE);
- if (hub_remove_reset_event(hub_dev, port_idx, TRUE))
- hub_start_next_reset_port(dev_mgr, TRUE);
- return;
-};
-
-VOID
-hub_disable_port_completion(PURB purb, PVOID pcontext)
-{
- PUSB_DEV pdev;
- PUSB_DEV_MANAGER dev_mgr;
- UCHAR port_idx;
- PUSB_ENDPOINT pendp;
- PUSB_CTRL_SETUP_PACKET psetup;
-
- UNREFERENCED_PARAMETER(pcontext);
-
- if (purb == NULL)
- return;
-
- pdev = purb->pdev;
- pendp = purb->pendp;
- psetup = (PUSB_CTRL_SETUP_PACKET) purb->setup_packet;
- port_idx = (UCHAR) psetup->wIndex;
-
- dev_mgr = dev_mgr_from_dev(pdev);
-
- usb_free_mem(purb);
-
- hub_reexamine_port_status_queue(pdev, port_idx, TRUE);
- if (hub_remove_reset_event(pdev, port_idx, TRUE))
- hub_start_next_reset_port(dev_mgr, TRUE);
-
- return;
-}
-
-//caller should guarantee the validity of the dev
-NTSTATUS
-hub_disable_port_request(PUSB_DEV pdev, UCHAR port_idx)
-{
- PURB purb;
- PUSB_ENDPOINT pendp;
- PHUB2_EXTENSION hub_ext;
- PUSB_CTRL_SETUP_PACKET psetup;
- NTSTATUS status;
- PHCD hcd;
- USE_BASIC_NON_PENDING_IRQL;
-
- if (pdev == NULL || port_idx == 0)
- return STATUS_INVALID_PARAMETER;
-
- lock_dev(pdev, FALSE);
- if (dev_state(pdev) == USB_DEV_STATE_ZOMB)
- {
- unlock_dev(pdev, FALSE);
- return STATUS_DEVICE_DOES_NOT_EXIST;
- }
-
- purb = usb_alloc_mem(NonPagedPool, sizeof(URB));
- if (purb == NULL)
- {
- unlock_dev(pdev, FALSE);
- return STATUS_NO_MEMORY;
- }
-
- RtlZeroMemory(purb, sizeof(URB));
-
- purb->flags = 0;
- purb->status = STATUS_SUCCESS;
-
- hub_ext = hub_ext_from_dev(pdev);
-
- purb->data_buffer = NULL;
- purb->data_length = 0;
-
- pendp = purb->pendp = &pdev->default_endp;
- purb->pdev = pdev;
-
- purb->completion = hub_disable_port_completion;
- purb->context = hub_ext;
-
- purb->pirp = NULL;
- purb->reference = 0;
-
- psetup = (PUSB_CTRL_SETUP_PACKET) purb->setup_packet;
-
- psetup->bmRequestType = 0x23; //host-device other recepient
- psetup->bRequest = USB_REQ_CLEAR_FEATURE; //clear_feature
- psetup->wValue = USB_PORT_FEAT_ENABLE;
- psetup->wIndex = (USHORT) port_idx;
- psetup->wLength = 0;
-
- purb->pirp = NULL;
- //enter another state
- hcd = pdev->hcd;
- unlock_dev(pdev, FALSE);
-
- status = hcd->hcd_submit_urb(hcd, pdev, pendp, purb);
- if (status == STATUS_PENDING)
- return status;
-
- usb_free_mem(purb);
- return status;
-}
-
-
-BOOLEAN
-hub_remove_reset_event(PUSB_DEV pdev, ULONG port_idx, BOOLEAN from_dpc)
-{
- PUSB_DEV_MANAGER dev_mgr;
- PLIST_ENTRY pthis, pnext;
- PUSB_EVENT pevent, pnext_event;
- BOOLEAN found;
-
- KIRQL old_irql = 0;
-
- if (pdev == NULL)
- return FALSE;
-
- if (port_idx == 0)
- return FALSE;
-
- dev_mgr = dev_mgr_from_dev(pdev);
- found = FALSE;
-
- if (from_dpc)
- KeAcquireSpinLockAtDpcLevel(&dev_mgr->event_list_lock);
- else
- KeAcquireSpinLock(&dev_mgr->event_list_lock, &old_irql);
-
- ListFirst(&dev_mgr->event_list, pthis);
- while (pthis)
- {
- pevent = (PUSB_EVENT) pthis;
- if (pevent->event == USB_EVENT_WAIT_RESET_PORT &&
- (pevent->flags & USB_EVENT_FLAG_QUE_TYPE) == USB_EVENT_FLAG_QUE_RESET)
- {
- if (pevent->pdev == pdev && pevent->param == port_idx)
- {
- //remove it
- RemoveEntryList(&pevent->event_link);
- pnext_event = pevent->pnext;
- free_event(&dev_mgr->event_pool, pevent);
-
- if (pnext_event)
- InsertHeadList(&dev_mgr->event_list, &pnext_event->event_link);
-
- found = TRUE;
- break;
- }
- }
- ListNext(&dev_mgr->event_list, pthis, pnext);
- pthis = pnext;
- }
-
- if (from_dpc)
- KeReleaseSpinLockFromDpcLevel(&dev_mgr->event_list_lock);
- else
- KeReleaseSpinLock(&dev_mgr->event_list_lock, old_irql);
- return found;
-}
-
-BOOLEAN
-hub_start_next_reset_port(PUSB_DEV_MANAGER dev_mgr, BOOLEAN from_dpc)
-{
- PLIST_ENTRY pthis, pnext;
- PUSB_EVENT pevent, pnext_event;
- PUSB_DEV pdev = NULL;
- PHUB2_EXTENSION hub_ext;
- BOOLEAN bret;
- PURB purb = NULL;
- BOOLEAN processed;
- PUSB_CTRL_SETUP_PACKET psetup;
- PHCD hcd = NULL;
-
- USE_NON_PENDING_IRQL;
-
- if (dev_mgr == NULL)
- return FALSE;
-
- bret = FALSE;
- processed = FALSE;
-
- if (from_dpc)
- KeAcquireSpinLockAtDpcLevel(&dev_mgr->event_list_lock);
- else
- KeAcquireSpinLock(&dev_mgr->event_list_lock, &old_irql);
-
- ListFirst(&dev_mgr->event_list, pthis);
-
- while ((pevent = (PUSB_EVENT) pthis))
- {
- while (pevent->event == USB_EVENT_WAIT_RESET_PORT &&
- (pevent->flags & USB_EVENT_FLAG_QUE_TYPE) == USB_EVENT_FLAG_QUE_RESET)
- {
-
- processed = TRUE;
-
- pdev = pevent->pdev;
- lock_dev(pdev, TRUE);
-
- if (dev_state(pdev) == USB_DEV_STATE_ZOMB)
- {
- unlock_dev(pdev, TRUE);
- pnext_event = pevent->pnext;
- free_event(&dev_mgr->event_pool, pevent);
- pevent = pnext_event;
- if (pevent == NULL)
- {
- bret = FALSE;
- break;
- }
- continue;
- }
-
- purb = usb_alloc_mem(NonPagedPool, sizeof(URB));
- if (!purb)
- {
- if (from_dpc)
- KeReleaseSpinLockFromDpcLevel(&dev_mgr->event_list_lock);
- else
- KeReleaseSpinLock(&dev_mgr->event_list_lock, old_irql);
- return FALSE;
- }
-
- RtlZeroMemory(purb, sizeof(URB));
-
- purb->data_buffer = NULL;
- purb->data_length = 0;
- purb->pendp = &pdev->default_endp;
-
- hub_ext = hub_ext_from_dev(pdev);
- purb->context = hub_ext;
- purb->pdev = pdev;
- purb->completion = hub_start_reset_port_completion;
- purb->reference = pevent->param;
-
- psetup = (PUSB_CTRL_SETUP_PACKET) purb->setup_packet;
-
- psetup->bmRequestType = 0x23; //host-device other recepient
- psetup->bRequest = 3; //set_feature
- psetup->wValue = USB_PORT_FEAT_RESET;
- psetup->wIndex = (USHORT) pevent->param;
- psetup->wLength = 0;
-
- purb->pirp = NULL;
- hcd = pdev->hcd;
- set_port_state(hub_ext->port_status_queue[pevent->param].port_flags, STATE_WAIT_RESET_COMPLETE);
- unlock_dev(pdev, TRUE);
-
- bret = TRUE;
- break;
- }
-
- if (!processed)
- {
- ListNext(&dev_mgr->event_list, pthis, pnext);
- pthis = pnext;
- }
- else
- break;
- }
-
- if (from_dpc)
- KeReleaseSpinLockFromDpcLevel(&dev_mgr->event_list_lock);
- else
- KeReleaseSpinLock(&dev_mgr->event_list_lock, old_irql);
-
- if (processed && bret)
- {
- if (hcd->hcd_submit_urb(hcd, pdev, purb->pendp, purb) != STATUS_PENDING)
- {
- //fatal error
- usb_free_mem(purb);
- bret = FALSE;
- //do not know what to do
- }
- }
-
- if (pthis == NULL)
- bret = TRUE;
-
- return bret;
-}
-
-//
-//must have event-list-lock and dev-lock acquired
-//
-VOID
-hub_post_esq_event(PUSB_DEV pdev, BYTE port_idx, PROCESS_EVENT pe)
-{
- PUSB_DEV_MANAGER dev_mgr;
- PUSB_EVENT pevent;
-
- if (pdev == NULL || port_idx == 0 || pe == NULL)
- return;
-
- dev_mgr = dev_mgr_from_dev(pdev);
-
- pevent = alloc_event(&dev_mgr->event_pool, 1);
- if (!pevent) return;
- pevent->event = USB_EVENT_DEFAULT;
- pevent->process_queue = event_list_default_process_queue;
- pevent->process_event = pe;
- pevent->context = (ULONG) hub_ext_from_dev(pdev);
- pevent->param = port_idx;
- pevent->flags = USB_EVENT_FLAG_ACTIVE;
- pevent->pdev = pdev;
- pevent->pnext = NULL;
-
- InsertTailList(&dev_mgr->event_list, &pevent->event_link);
- KeSetEvent(&dev_mgr->wake_up_event, 0, FALSE);
- // usb_dbg_print( DBGLVL_MAXIMUM, ( "hub_post_esq_event(): current element in event list is 0x%x\n",
- // dbg_count_list( &dev_mgr->event_list ) ) );
- return;
-}
-
-// called only in hub_clear_port_feature_completion
-BOOLEAN
-hub_check_reset_port_status(PUSB_DEV pdev, LONG port_idx)
-{
- PUSB_DEV_MANAGER dev_mgr;
- PHUB2_EXTENSION hub_ext;
- BOOLEAN bReset;
- USB_PORT_STATUS port_status;
- PUSB_DEV pdev2;
- PURB purb2;
- PHCD hcd;
-
- PUSB_CTRL_SETUP_PACKET psetup;
- ULONG status;
-
- USE_BASIC_NON_PENDING_IRQL;
-
- //let's check whether the status change is a reset complete
- usb_dbg_print(DBGLVL_MAXIMUM, ("hub_check_reset_port_status(): entering...\n"));
- dev_mgr = dev_mgr_from_dev(pdev);
- KeAcquireSpinLockAtDpcLevel(&dev_mgr->dev_list_lock);
- lock_dev(pdev, TRUE);
-
- dev_mgr = dev_mgr_from_dev(pdev);
- hcd = pdev->hcd;
-
- if (dev_state(pdev) == USB_DEV_STATE_ZOMB)
- {
- unlock_dev(pdev, TRUE);
- KeReleaseSpinLockFromDpcLevel(&dev_mgr->dev_list_lock);
- return FALSE;
- }
-
- hub_ext = hub_ext_from_dev(pdev);
- port_status = psq_peek(&hub_ext->port_status_queue[port_idx], 0);
-
- bReset = FALSE;
- if (port_status.wPortChange & USB_PORT_STAT_C_RESET)
- bReset = TRUE;
-
- pdev2 = NULL;
- purb2 = NULL;
-
- if (bReset
- && (port_state(hub_ext->port_status_queue[port_idx].port_flags) == STATE_WAIT_RESET_COMPLETE)
- && (psq_count(&hub_ext->port_status_queue[port_idx]) == 1))
- {
- // a port-reset complete, empty the queue, keep the state
- psq_outqueue(&hub_ext->port_status_queue[port_idx]);
- set_port_state(hub_ext->port_status_queue[port_idx].port_flags, STATE_WAIT_ADDRESSED);
-
- //let's new a dev, and start the set-addr request
- if (hub_ext->child_dev[port_idx] == 0)
- {
- pdev2 = hub_ext->child_dev[port_idx] = dev_mgr_alloc_device(dev_mgr, hcd);
- if (pdev2)
- {
- purb2 = usb_alloc_mem(NonPagedPool, sizeof(URB));
- if (!purb2)
- {
- dev_mgr_free_device(dev_mgr, pdev2);
- pdev2 = hub_ext->child_dev[port_idx] = NULL;
- }
- else
- {
- if (port_status.wPortStatus & USB_PORT_STAT_LOW_SPEED)
- {
- pdev2->flags |= USB_DEV_FLAG_LOW_SPEED;
- }
- else if (port_status.wPortStatus & USB_PORT_STAT_HIGH_SPEED)
- pdev2->flags |= USB_DEV_FLAG_HIGH_SPEED;
-
- pdev2->parent_dev = pdev;
- pdev2->port_idx = (UCHAR) port_idx;
- pdev2->ref_count++;
-
- RtlZeroMemory(purb2, sizeof(URB));
-
- purb2->pdev = pdev2;
- purb2->pendp = &pdev2->default_endp;
- purb2->context = hub_ext;
- purb2->completion = hub_set_address_completion;
-
- InitializeListHead(&purb2->trasac_list);
- purb2->reference = port_idx;
- purb2->pirp = 0;
-
- psetup = (PUSB_CTRL_SETUP_PACKET) purb2->setup_packet;
- psetup->bmRequestType = 0;
- psetup->bRequest = USB_REQ_SET_ADDRESS;
- psetup->wValue = pdev2->dev_addr;
- }
- }
- }
-
- if (pdev2 && purb2)
- {
- //creation success, emit the urb
- //add to dev list
- InsertTailList(&dev_mgr->dev_list, &pdev2->dev_link);
-
- unlock_dev(pdev, TRUE);
- KeReleaseSpinLockFromDpcLevel(&dev_mgr->dev_list_lock);
-
- status = hcd->hcd_submit_urb(hcd, pdev2, purb2->pendp, purb2);
-
- lock_dev(pdev2, TRUE);
- pdev2->ref_count--;
- usb_dbg_print(DBGLVL_MAXIMUM,
- ("hub_check_reset_port_status(): new dev ref_count=0x%x\n", pdev2->ref_count));
- unlock_dev(pdev2, TRUE);
-
- if (status != STATUS_PENDING)
- {
- usb_free_mem(purb2);
- //??? do we need to lock it for SMP?
- //dev_mgr_free_device( dev_mgr, pdev2 ), let dev_mgr_thread to clean it;
- // disable the port
- if (hub_disable_port_request(pdev, (UCHAR) port_idx) != STATUS_PENDING)
- goto LBL_RESET_FAIL;
- }
-
- return TRUE;
- }
- }
- else
- {
- usb_dbg_print(DBGLVL_MAXIMUM, ("hub_check_reset_port_status(): not a correct reset status\n"));
- }
- unlock_dev(pdev, TRUE);
- KeReleaseSpinLockFromDpcLevel(&dev_mgr->dev_list_lock);
-
-LBL_RESET_FAIL:
- //Any event other than reset cause the reset process stall and another
- //pending reset-port requeset is serviced
- hub_reexamine_port_status_queue(pdev, port_idx, TRUE);
- if (hub_remove_reset_event(pdev, port_idx, TRUE))
- hub_start_next_reset_port(dev_mgr, TRUE);
-
- return FALSE;
-}
-
-VOID
-hub_reexamine_port_status_queue(PUSB_DEV hub_dev, ULONG port_idx, BOOLEAN from_dpc)
-{
-
- PHUB2_EXTENSION hub_ext;
- PUSB_DEV_MANAGER dev_mgr;
-
- USE_NON_PENDING_IRQL;
-
- if (hub_dev == NULL || port_idx == 0)
- return;
-
- dev_mgr = dev_mgr_from_dev(hub_dev);
- if (from_dpc)
- KeAcquireSpinLockAtDpcLevel(&dev_mgr->event_list_lock);
- else
- KeAcquireSpinLock(&dev_mgr->event_list_lock, &old_irql);
-
- lock_dev(hub_dev, TRUE);
- if (dev_state(hub_dev) != USB_DEV_STATE_ZOMB)
- {
-
- hub_ext = hub_ext_from_dev(hub_dev);
- if (psq_is_empty(&hub_ext->port_status_queue[port_idx]))
- {
- set_port_state(hub_ext->port_status_queue[port_idx].port_flags, STATE_IDLE);
-
- }
- else
- {
- set_port_state(hub_ext->port_status_queue[port_idx].port_flags, STATE_EXAMINE_STATUS_QUE);
-
- hub_post_esq_event(hub_dev, (UCHAR) port_idx, hub_event_examine_status_que);
- }
- }
- unlock_dev(hub_dev, TRUE);
-
- if (from_dpc)
- KeReleaseSpinLockFromDpcLevel(&dev_mgr->event_list_lock);
- else
- KeReleaseSpinLock(&dev_mgr->event_list_lock, old_irql);
- return;
-}
-
-BOOLEAN
-hub_connect(PDEV_CONNECT_DATA param, DEV_HANDLE dev_handle)
-{
- URB urb, *purb;
- CHAR buf[512];
- DEV_HANDLE endp_handle;
- USB_DEVICE_DESC dev_desc;
- PUSB_CONFIGURATION_DESC pcfg_desc;
- PUSB_INTERFACE_DESC pif_desc;
- PUSB_CTRL_SETUP_PACKET psetup;
- NTSTATUS status;
- LONG i, j, found, cfg_val = 0;
- PUSB_DEV_MANAGER dev_mgr;
- PUSB_DEV pdev;
-
-
- if (param == NULL || dev_handle == 0)
- return FALSE;
-
- dev_mgr = param->dev_mgr;
-
- pcfg_desc = (PUSB_CONFIGURATION_DESC) buf;
- endp_handle = dev_handle | 0xffff;
- UsbBuildGetDescriptorRequest(&urb,
- endp_handle,
- USB_DT_DEVICE, 0, 0, (&dev_desc), (sizeof(USB_DEVICE_DESC)), NULL, 0, 0);
-
- status = usb_submit_urb(dev_mgr, &urb);
- if (status != STATUS_SUCCESS)
- return FALSE;
-
- found = FALSE;
- for(i = 0; i < dev_desc.bNumConfigurations; i++)
- {
- UsbBuildGetDescriptorRequest(&urb, endp_handle, USB_DT_CONFIG, (USHORT) i, 0, buf, 512, NULL, 0, 0);
-
- status = usb_submit_urb(dev_mgr, &urb);
- if (status != STATUS_SUCCESS)
- {
- return FALSE;
- }
-
- status = usb_query_and_lock_dev(dev_mgr, dev_handle, &pdev);
- if (status != STATUS_SUCCESS)
- return FALSE;
-
- pif_desc = (PUSB_INTERFACE_DESC) & buf[sizeof(USB_CONFIGURATION_DESC)];
- for(j = 0; j < pcfg_desc->bNumInterfaces; j++)
- {
- if (pif_desc->bInterfaceClass == USB_CLASS_HUB
- && pif_desc->bInterfaceSubClass == 0 && pif_desc->bNumEndpoints == 1)
- {
- if ((pif_desc->bInterfaceProtocol > 0 && pif_desc->bInterfaceProtocol < 3)
- || (pif_desc->bInterfaceProtocol == 0 && pdev->flags & USB_DEV_FLAG_HIGH_SPEED)
- || (pif_desc->bInterfaceProtocol == 0 && !usb2(pdev->hcd)))
- {
- found = TRUE;
- cfg_val = pcfg_desc->bConfigurationValue;
- break;
- }
- }
- if (usb_skip_if_and_altif((PBYTE *) & pif_desc) == FALSE)
- {
- break;
- }
- }
- usb_unlock_dev(pdev);
-
- if (found)
- break;
-
- if (usb_skip_one_config((PBYTE *) & pcfg_desc) == FALSE)
- {
- break;
- }
-
- }
- if (found)
- {
- purb = usb_alloc_mem(NonPagedPool, sizeof(URB));
- if (purb == NULL)
- return FALSE;
-
- psetup = (PUSB_CTRL_SETUP_PACKET) (purb)->setup_packet;
- urb_init((purb));
-
- purb->endp_handle = endp_handle;
- purb->data_buffer = NULL;
- purb->data_length = 0;
- purb->completion = hub_set_cfg_completion;
- purb->context = dev_mgr;
- purb->reference = (LONG) param->pdriver;
- psetup->bmRequestType = 0;
- psetup->bRequest = USB_REQ_SET_CONFIGURATION;
- psetup->wValue = (USHORT) cfg_val;
- psetup->wIndex = 0;
- psetup->wLength = 0;
-
- status = usb_submit_urb(dev_mgr, purb);
- if (status != STATUS_PENDING)
- {
- usb_free_mem(purb);
- return FALSE;
- }
- return TRUE;
- }
-
- return FALSE;
-}
-
-VOID hub_set_interface_completion(PURB purb, PVOID pcontext);
-
-VOID
-hub_set_cfg_completion(PURB purb, PVOID pcontext)
-{
- PUSB_DEV_MANAGER dev_mgr;
- PUSB_DRIVER pdriver;
- ULONG endp_handle, dev_handle;
- PUSB_CTRL_SETUP_PACKET psetup;
- UCHAR if_idx = 0;
- PUSB_DEV pdev;
- PUSB_INTERFACE pif;
- BOOLEAN high_speed, multiple_tt;
- NTSTATUS status;
- USE_BASIC_NON_PENDING_IRQL;
-
- if (purb == NULL || pcontext == NULL)
- return;
-
- //pdev = NULL;
- dev_mgr = (PUSB_DEV_MANAGER) pcontext;
- endp_handle = purb->endp_handle;
- dev_handle = endp_handle & 0xffff0000;
- pdriver = (PUSB_DRIVER) purb->reference;
- high_speed = FALSE;
- multiple_tt = FALSE;
-
- if (purb->status != STATUS_SUCCESS)
- {
- goto LBL_ERROR;
- }
-
- status = usb_query_and_lock_dev(dev_mgr, purb->endp_handle, &pdev);
- if (status != STATUS_SUCCESS)
- {
- usb_unlock_dev(pdev);
- goto LBL_ERROR;
- }
- lock_dev(pdev, TRUE);
- if (dev_state(pdev) == USB_DEV_STATE_ZOMB)
- {
- unlock_dev(pdev, TRUE);
- usb_unlock_dev(pdev);
- goto LBL_ERROR;
- }
- if (pdev->flags & USB_DEV_FLAG_HIGH_SPEED)
- {
- high_speed = TRUE;
- hub_if_from_dev(pdev, pif);
- if (pif->altif_count)
- {
- multiple_tt = TRUE;
- if_idx = pif - &pdev->usb_config->interf[0];
- }
- }
- unlock_dev(pdev, TRUE);
- usb_unlock_dev(pdev);
-
- if (!high_speed || !multiple_tt)
- {
- hub_set_interface_completion(purb, pcontext);
- return;
- }
-
- psetup = (PUSB_CTRL_SETUP_PACKET) (purb)->setup_packet;
- urb_init((purb));
-
- // set the mult-tt if exist
- purb->endp_handle = endp_handle;
- purb->data_buffer = NULL;
- purb->data_length = 0;
- purb->completion = hub_set_interface_completion;
- purb->context = dev_mgr;
- purb->reference = (LONG) pdriver;
- psetup->bmRequestType = 0;
- psetup->bRequest = USB_REQ_SET_INTERFACE;
- psetup->wValue = (USHORT) 1; // alternate tt
- psetup->wIndex = if_idx; // if index
- psetup->wLength = 0;
-
- status = usb_submit_urb(dev_mgr, purb);
- if (status == STATUS_PENDING)
- return;
-
- LBL_ERROR:
- usb_free_mem(purb);
- purb = NULL;
- return;
-}
-
-void
-hub_set_interface_completion(PURB purb, PVOID pcontext)
-{
- NTSTATUS status;
- PUSB_CTRL_SETUP_PACKET psetup;
- PUSB_DEV_MANAGER dev_mgr;
- PBYTE dev_ext;
- DEV_HANDLE endp_handle;
- PUSB_DRIVER pdriver;
-
- if (purb == NULL || pcontext == NULL)
- return;
-
- //pdev = NULL;
- dev_mgr = (PUSB_DEV_MANAGER) pcontext;
- endp_handle = purb->endp_handle;
- pdriver = (PUSB_DRIVER) purb->reference;
-
- if (purb->status != STATUS_SUCCESS)
- {
- usb_free_mem(purb);
- return;
- }
-
- dev_ext = usb_alloc_mem(NonPagedPool, sizeof(HUB2_EXTENSION));
- if (dev_ext == NULL)
- {
- goto LBL_OUT;
- }
-
- //
- //acquire hub descriptor
- //
- RtlZeroMemory(dev_ext, sizeof(HUB2_EXTENSION));
- urb_init(purb);
-
- purb->data_buffer = (PUCHAR) & ((HUB2_EXTENSION *) dev_ext)->hub_desc;
- purb->endp_handle = endp_handle;
- purb->data_length = sizeof(USB_HUB_DESCRIPTOR);
- purb->completion = hub_get_hub_desc_completion;
- purb->context = (PVOID) dev_mgr;
- purb->reference = (ULONG) dev_ext;
- purb->pirp = (PIRP) pdriver;
-
- psetup = (PUSB_CTRL_SETUP_PACKET) purb->setup_packet;
- psetup->bmRequestType = 0xa0;
- psetup->bRequest = USB_REQ_GET_DESCRIPTOR;
- psetup->wValue = (0x29 << 8);
- psetup->wLength = sizeof(USB_HUB_DESCRIPTOR);
- status = usb_submit_urb(dev_mgr, purb);
-
- if (status != STATUS_PENDING)
- {
- usb_free_mem(dev_ext);
- goto LBL_OUT;
- }
- return;
-
-LBL_OUT:
- //clear the dev_driver fields in the dev.
- usb_free_mem(purb);
- return;
-}
-
-
-VOID
-hub_power_on_port_completion(PURB purb, PVOID pcontext)
-{
- PUSB_DEV_MANAGER dev_mgr;
-
- if (purb == NULL)
- return;
- if (pcontext == NULL)
- goto LBL_OUT;
-
- dev_mgr = (PUSB_DEV_MANAGER) pcontext;
-
- if (purb->status != STATUS_SUCCESS)
- {
- usb_dbg_print(DBGLVL_MAXIMUM,
- ("hub_power_on_port_completion(): port%d power on failed\n", purb->reference));
- }
- else
- {
- usb_dbg_print(DBGLVL_MAXIMUM,
- ("hub_power_on_port_completion(): port%d power on succeed\n", purb->reference));
- }
-
-LBL_OUT:
- usb_free_mem(purb);
- return;
-}
-
-NTSTATUS
-hub_power_on_port(PUSB_DEV pdev, UCHAR port_idx)
-{
- NTSTATUS status;
- PUSB_CTRL_SETUP_PACKET psetup;
- PUSB_DEV_MANAGER dev_mgr;
- PURB purb;
- PHCD hcd;
-
- USE_BASIC_NON_PENDING_IRQL;
- if (pdev == NULL || port_idx == 0)
- return STATUS_INVALID_PARAMETER;
-
- purb = usb_alloc_mem(NonPagedPool, sizeof(URB));
- if (purb == NULL)
- return STATUS_NO_MEMORY;
-
- urb_init(purb);
-
- lock_dev(pdev, FALSE);
- if (dev_state(pdev) == USB_DEV_STATE_ZOMB)
- {
- unlock_dev(pdev, FALSE);
- status = STATUS_DEVICE_DOES_NOT_EXIST;
- goto LBL_OUT;
- }
- dev_mgr = dev_mgr_from_dev(pdev);
- hcd = pdev->hcd;
-
- purb->completion = hub_power_on_port_completion;
- purb->context = (PVOID) dev_mgr;
- purb->reference = (ULONG) port_idx;
- purb->pdev = pdev;
- purb->pendp = &pdev->default_endp;
-
- psetup = (PUSB_CTRL_SETUP_PACKET) purb->setup_packet;
- psetup->bmRequestType = 0x23;
- psetup->bRequest = USB_REQ_SET_FEATURE;
- psetup->wValue = USB_PORT_FEAT_POWER;
- psetup->wIndex = (WORD) port_idx;
- psetup->wLength = 0;
-
- unlock_dev(pdev, FALSE);
-
- status = hcd->hcd_submit_urb(hcd, pdev, purb->pendp, purb);
-
- if (status != STATUS_PENDING)
- {
- goto LBL_OUT;
- }
- return STATUS_PENDING;
-
-LBL_OUT:
- usb_free_mem(purb);
- return status;
-}
-
-void
-hub_get_hub_desc_completion(PURB purb, PVOID pcontext)
-{
- PUSB_DEV_MANAGER dev_mgr;
- PHUB2_EXTENSION hub_ext;
- PUSB_DEV pdev;
- LONG i;
- PUSB_INTERFACE pif = NULL;
- ULONG status;
- LONG port_count;
- PUSB_DRIVER pdriver;
- DEV_HANDLE dev_handle;
-
- USE_BASIC_NON_PENDING_IRQL;
-
- if (purb == NULL)
- {
- return;
- }
-
- dev_mgr = (PUSB_DEV_MANAGER) pcontext;
- hub_ext = (PHUB2_EXTENSION) purb->reference;
- pdriver = (PUSB_DRIVER) purb->pirp;
- dev_handle = purb->endp_handle & 0xffff0000;
-
- if (pcontext == NULL || purb->reference == 0)
- goto LBL_OUT;
-
- if (purb->status != STATUS_SUCCESS)
- {
- goto LBL_OUT;
- }
-
- // obtain the pointer to the dev
- status = usb_query_and_lock_dev(dev_mgr, purb->endp_handle, &pdev);
- if (status != STATUS_SUCCESS)
- {
- usb_unlock_dev(pdev);
- goto LBL_OUT;
- }
- // safe to release the pdev ref since we are in urb completion
- usb_unlock_dev(pdev);
-
- lock_dev(pdev, TRUE);
- if (dev_state(pdev) == USB_DEV_STATE_ZOMB ||
- dev_mgr_set_driver(dev_mgr, dev_handle, pdriver, pdev) == FALSE)
- {
- unlock_dev(pdev, TRUE);
- goto LBL_OUT;
- }
-
- //transit the state to configured
- pdev->flags &= ~USB_DEV_STATE_MASK;
- pdev->flags |= USB_DEV_STATE_CONFIGURED;
-
- pdev->dev_ext = (PBYTE) hub_ext;
- pdev->dev_ext_size = sizeof(HUB2_EXTENSION);
-
- port_count = hub_ext->port_count = hub_ext->hub_desc.bNbrPorts;
- hub_ext->pdev = pdev;
- for(i = 0; i < pdev->usb_config->if_count; i++)
- {
- pif = &pdev->usb_config->interf[i];
- if (pif->pusb_if_desc->bInterfaceClass == USB_CLASS_HUB
- && pif->pusb_if_desc->bInterfaceSubClass == 0
- && pif->pusb_if_desc->bInterfaceProtocol < 3 && pif->pusb_if_desc->bNumEndpoints == 1)
- {
- hub_ext->pif = pif;
- break;
- }
- }
- for(i = 0; i < MAX_HUB_PORTS + 1; i++)
- {
- psq_init((PPORT_STATUS_QUEUE) hub_ext->port_status_queue);
- }
-
- hub_ext->multiple_tt = (pif->pusb_if_desc->bInterfaceProtocol == 2);
-
- unlock_dev(pdev, TRUE);
- usb_free_mem(purb);
-
- hub_start_int_request(pdev);
-
- for(i = 0; i < port_count; i++)
- {
- hub_power_on_port(pdev, (UCHAR) (i + 1));
- }
- return;
-
-LBL_OUT:
- if (purb)
- usb_free_mem(purb);
-
- if (hub_ext)
- usb_free_mem(hub_ext);
- return;
-}
-
-BOOLEAN
-hub_stop(PUSB_DEV_MANAGER dev_mgr, DEV_HANDLE dev_handle)
-{
- UNREFERENCED_PARAMETER(dev_mgr);
- UNREFERENCED_PARAMETER(dev_handle);
- return TRUE;
-}
-
-BOOLEAN
-hub_disconnect(PUSB_DEV_MANAGER dev_mgr, DEV_HANDLE dev_handle)
-{
- PUSB_DEV pdev;
- //special use of usb_query and lock dev
- if (usb_query_and_lock_dev(dev_mgr, dev_handle, &pdev) != STATUS_SUCCESS)
- {
- //will never be success, since the dev is already in zomb state
- //at this point, the dev is valid, ref_count is of none use,
- //no need to lock it
- if (pdev)
- {
- usb_free_mem(pdev->dev_ext);
- }
- }
-
- return TRUE;
-}
-
-static BOOLEAN
-hub_lock_unlock_tt(PUSB_DEV pdev, UCHAR port_idx, UCHAR type, BOOLEAN lock)
-{
- PHUB2_EXTENSION dev_ext;
- PULONG pmap = NULL;
-
- USE_BASIC_NON_PENDING_IRQL;
-
- if (pdev == NULL || port_idx > 127)
- return FALSE;
-
- lock_dev(pdev, FALSE);
- if (dev_state(pdev) == USB_DEV_STATE_ZOMB)
- {
- unlock_dev(pdev, FALSE);
- return FALSE;
- }
-
- dev_ext = hub_ext_from_dev(pdev);
- if (dev_ext == NULL)
- {
- unlock_dev(pdev, FALSE);
- return FALSE;
- }
- if (type == USB_ENDPOINT_XFER_INT || type == USB_ENDPOINT_XFER_ISOC)
- {
- pmap = dev_ext->tt_status_map;
- }
- else if (type == USB_ENDPOINT_XFER_BULK || type == USB_ENDPOINT_XFER_CONTROL)
- {
- pmap = dev_ext->tt_bulk_map;
- }
-
- if (lock)
- {
- if (pmap[port_idx >> 5] & (1 << port_idx))
- {
- unlock_dev(pdev, FALSE);
- return FALSE;
- }
- pmap[port_idx >> 5] |= (1 << port_idx);
- }
- else
- {
- pmap[port_idx >> 5] &= ~(1 << port_idx);
- }
-
- unlock_dev(pdev, FALSE);
- return TRUE;
-}
-
-BOOLEAN
-hub_lock_tt(PUSB_DEV pdev,
- UCHAR port_idx,
- UCHAR type // transfer type
- )
-{
- return hub_lock_unlock_tt(pdev, port_idx, type, TRUE);
-}
-
-BOOLEAN
-hub_unlock_tt(PUSB_DEV pdev, UCHAR port_idx, UCHAR type)
-{
- return hub_lock_unlock_tt(pdev, port_idx, type, FALSE);
-}
-
-VOID
-hub_clear_tt_buffer_completion(PURB purb, PVOID context)
-{
- PUSB_CTRL_SETUP_PACKET psetup;
- PURB_HS_PIPE_CONTENT pipe_content;
- PHUB2_EXTENSION hub_ext;
- PHCD hcd;
-
- if (purb == NULL || context == NULL)
- return;
-
- hub_ext = (PHUB2_EXTENSION) context;
- psetup = (PUSB_CTRL_SETUP_PACKET) purb->setup_packet;
- pipe_content = (PURB_HS_PIPE_CONTENT) & purb->reference;
- hub_unlock_tt(purb->pdev, (UCHAR) psetup->wIndex, (UCHAR) pipe_content->trans_type);
- usb_free_mem(purb);
- purb = NULL;
- hcd = hub_ext->pdev->hcd;
-
- // let those blocked urbs ( sharing the same tt )have chance to be scheduled
- if (hcd && usb2(hcd))
- hcd->hcd_submit_urb(hcd, NULL, NULL, NULL);
-
- return;
-}
-
-// send CLEAR_TT_BUFFER to the hub
-BOOLEAN
-hub_clear_tt_buffer(PUSB_DEV pdev, URB_HS_PIPE_CONTENT pipe_content, UCHAR port_idx)
-{
- PURB purb;
- PUSB_CTRL_SETUP_PACKET psetup;
- PHUB2_EXTENSION hub_ext;
- PHCD hcd;
- NTSTATUS status;
- USE_BASIC_NON_PENDING_IRQL;
-
- if (pdev == NULL)
- return FALSE;
-
- if (pipe_content.speed_high)
- return FALSE;
-
- lock_dev(pdev, FALSE);
- if (dev_state(pdev) == USB_DEV_STATE_ZOMB)
- {
- unlock_dev(pdev, FALSE);
- return FALSE;
- }
-
- hub_ext = hub_ext_from_dev(pdev);
- if (hub_ext == NULL)
- {
- unlock_dev(pdev, FALSE);
- return FALSE;
- }
- purb = usb_alloc_mem(NonPagedPool, sizeof(URB));
-
- if (purb == NULL)
- {
- unlock_dev(pdev, FALSE);
- return FALSE;
- }
-
- RtlZeroMemory(purb, sizeof(URB));
-
- purb->flags = 0;
- purb->status = STATUS_SUCCESS;
- purb->data_buffer = NULL;
- purb->data_length = 0; // ( hub_ext->port_count + 7 ) / 8;
-
- // hub_if_from_dev( pdev, pif );
- purb->pendp = &pdev->default_endp;
- purb->pdev = pdev;
-
- purb->completion = hub_clear_tt_buffer_completion;
- purb->context = hub_ext;
- purb->reference = *((PLONG) & pipe_content);
-
- purb->pirp = NULL;
- hcd = pdev->hcd;
-
- psetup = (PUSB_CTRL_SETUP_PACKET) purb->setup_packet;
- psetup->bmRequestType = 0x23; //host-device class other recepient
- psetup->bRequest = HUB_REQ_CLEAR_TT_BUFFER;
- psetup->wValue = (USHORT) ((pipe_content.endp_addr) | (pipe_content.dev_addr << 4) |
- (pipe_content.trans_type << 10) | (pipe_content.trans_dir << 15));
-
- if (hub_ext->multiple_tt)
- {
- psetup->wIndex = (USHORT) port_idx;
- }
- else
- psetup->wIndex = 1;
-
- psetup->wLength = 0;
- unlock_dev(pdev, FALSE);
-
- status = hcd->hcd_submit_urb(hcd, pdev, purb->pendp, purb);
- if (status != STATUS_PENDING)
- {
- usb_free_mem(purb);
- purb = NULL;
- return FALSE;
- }
- return TRUE;
-}
-
-VOID
-hub_event_clear_tt_buffer(PUSB_DEV pdev, //always null. we do not use this param
- ULONG event,
- ULONG context,
- ULONG param)
-{
- UNREFERENCED_PARAMETER(event);
- hub_clear_tt_buffer(pdev, *((PURB_HS_PIPE_CONTENT) & context), (UCHAR) param);
- return;
-}
-
-VOID
-hub_post_clear_tt_event(PUSB_DEV pdev, BYTE port_idx, ULONG pipe)
-{
- PUSB_DEV_MANAGER dev_mgr;
- PUSB_EVENT pevent;
- USE_NON_PENDING_IRQL;
-
- dev_mgr = dev_mgr_from_dev(pdev);
-
- KeAcquireSpinLock(&dev_mgr->event_list_lock, &old_irql);
- lock_dev(pdev, TRUE);
- if (dev_state(pdev) == USB_DEV_STATE_ZOMB)
- {
- unlock_dev(pdev, TRUE);
- KeReleaseSpinLock(&dev_mgr->event_list_lock, old_irql);
- return;
- }
- pevent = alloc_event(&dev_mgr->event_pool, 1);
- if (pevent == NULL)
- {
- unlock_dev(pdev, TRUE);
- KeReleaseSpinLock(&dev_mgr->event_list_lock, old_irql);
- TRAP();
- return;
- }
-
- pevent->event = USB_EVENT_WAIT_RESET_PORT;
- pevent->pdev = pdev;
- pevent->context = pipe;
- pevent->param = port_idx;
- pevent->flags = USB_EVENT_FLAG_ACTIVE;
- pevent->process_queue = event_list_default_process_queue;
- pevent->process_event = hub_event_clear_tt_buffer;
- pevent->pnext = NULL;
- InsertTailList(&dev_mgr->event_list, &pevent->event_link);
-
- unlock_dev(pdev, TRUE);
- KeReleaseSpinLock(&dev_mgr->event_list_lock, old_irql);
-
- KeSetEvent(&dev_mgr->wake_up_event, 0, FALSE);
- return;
-}
-
-BOOLEAN
-init_irp_list(PIRP_LIST irp_list)
-{
- LONG i;
- KeInitializeSpinLock(&irp_list->irp_list_lock);
- InitializeListHead(&irp_list->irp_busy_list);
- InitializeListHead(&irp_list->irp_free_list);
- irp_list->irp_list_element_array =
- usb_alloc_mem(NonPagedPool, sizeof(IRP_LIST_ELEMENT) * MAX_IRP_LIST_SIZE);
-
- if (irp_list->irp_list_element_array == NULL)
- return FALSE;
-
- RtlZeroMemory(irp_list->irp_list_element_array, sizeof(IRP_LIST_ELEMENT) * MAX_IRP_LIST_SIZE);
- for(i = 0; i < MAX_IRP_LIST_SIZE; i++)
- {
- InsertTailList(&irp_list->irp_free_list, &irp_list->irp_list_element_array[i].irp_link);
- }
- irp_list->irp_free_list_count = MAX_IRP_LIST_SIZE;
- return TRUE;
-}
-
-VOID
-destroy_irp_list(PIRP_LIST irp_list)
-{
- InitializeListHead(&irp_list->irp_busy_list);
- InitializeListHead(&irp_list->irp_free_list);
- usb_free_mem(irp_list->irp_list_element_array);
- irp_list->irp_list_element_array = NULL;
- irp_list->irp_free_list_count = 0;
- return;
-}
-
-BOOLEAN
-add_irp_to_list(PIRP_LIST irp_list, PIRP pirp, PURB purb)
-{
- KIRQL old_irql;
- PIRP_LIST_ELEMENT pile;
-
- if (irp_list == NULL || pirp == NULL || purb == NULL)
- return FALSE;
-
- IoAcquireCancelSpinLock(&old_irql);
- KeAcquireSpinLockAtDpcLevel(&irp_list->irp_list_lock);
-
- if (irp_list->irp_free_list_count == 0)
- {
- KeReleaseSpinLockFromDpcLevel(&irp_list->irp_list_lock);
- IoReleaseCancelSpinLock(old_irql);
- return FALSE;
- }
- pile = (PIRP_LIST_ELEMENT) RemoveHeadList(&irp_list->irp_free_list);
-
- pile->pirp = pirp;
- pile->purb = purb;
-
- irp_list->irp_free_list_count--;
- InsertTailList(&irp_list->irp_busy_list, &pile->irp_link);
- (void)IoSetCancelRoutine(pirp, dev_mgr_cancel_irp);
-
- KeReleaseSpinLockFromDpcLevel(&irp_list->irp_list_lock);
- IoReleaseCancelSpinLock(old_irql);
- return TRUE;
-}
-
-PURB
-remove_irp_from_list(PIRP_LIST irp_list,
- PIRP pirp,
- PUSB_DEV_MANAGER dev_mgr //if dev_mgr is not NULL, the urb needs to be canceled
- )
-{
- PIRP_LIST_ELEMENT pile;
- PLIST_ENTRY pthis, pnext;
- PURB purb;
- DEV_HANDLE endp_handle;
- PUSB_DEV pdev;
- PUSB_ENDPOINT pendp;
- PHCD hcd;
-
- USE_NON_PENDING_IRQL;
-
- if (irp_list == NULL || pirp == NULL)
- return NULL;
-
- KeAcquireSpinLock(&irp_list->irp_list_lock, &old_irql);
-
- if (irp_list->irp_free_list_count == MAX_IRP_LIST_SIZE)
- {
- KeReleaseSpinLock(&irp_list->irp_list_lock, old_irql);
- return NULL;
- }
-
- purb = NULL;
- ListFirst(&irp_list->irp_busy_list, pthis);
- while (pthis)
- {
- pile = struct_ptr(pthis, IRP_LIST_ELEMENT, irp_link);
- if (pile->pirp == pirp)
- {
- purb = pile->purb;
- pile->pirp = NULL;
- pile->purb = NULL;
- RemoveEntryList(pthis);
- InsertTailList(&irp_list->irp_free_list, pthis);
- irp_list->irp_free_list_count++;
- break;
- }
- ListNext(&irp_list->irp_busy_list, pthis, pnext);
- pthis = pnext;
- }
-
- if (purb == NULL)
- {
- // not found
- KeReleaseSpinLock(&irp_list->irp_list_lock, old_irql);
- return NULL;
- }
-
- endp_handle = purb->endp_handle;
- KeReleaseSpinLock(&irp_list->irp_list_lock, old_irql);
-
- if (dev_mgr)
- {
- // indicate we needs to cancel the urb, this condition happens only in cancel routine
- // we should notice that even the hcd_cancel_urb is called, the irp may not be canceled
- // if the urb does not exist in any queue of the host controller driver, indicating
- // it is being processed by dpc. Thus, the dpc will certainly prevent the irp in
- // completion from being canceled at the same time. On the other hand, if the
- // hcd_cancel_urb succeeds, it either directly complete the irp or queue the dpc for
- // irp completion. So, there won't be two simutaneous threads processing the same
- // irp.
-
- if (usb_query_and_lock_dev(dev_mgr, endp_handle, &pdev) != STATUS_SUCCESS)
- return NULL;
-
- lock_dev(pdev, TRUE);
- if (dev_state(pdev) == USB_DEV_STATE_ZOMB)
- {
- unlock_dev(pdev, FALSE);
- usb_unlock_dev(pdev);
- return NULL;
- }
-
- hcd = pdev->hcd;
- endp_from_handle(pdev, endp_handle, pendp);
- unlock_dev(pdev, TRUE);
- hcd->hcd_cancel_urb(hcd, pdev, pendp, purb);
- usb_unlock_dev(pdev);
- return NULL;
- }
- return purb;
-}
-
-BOOLEAN
-irp_list_empty(PIRP_LIST irp_list)
-{
- KIRQL old_irql;
- BOOLEAN ret;
- KeAcquireSpinLock(&irp_list->irp_list_lock, &old_irql);
- ret = (BOOLEAN) (irp_list->irp_free_list_count == MAX_IRP_LIST_SIZE);
- KeReleaseSpinLock(&irp_list->irp_list_lock, old_irql);
- return ret;
-}
-
-BOOLEAN
-irp_list_full(PIRP_LIST irp_list)
-{
- KIRQL old_irql;
- BOOLEAN ret;
- KeAcquireSpinLock(&irp_list->irp_list_lock, &old_irql);
- ret = (BOOLEAN) (irp_list->irp_free_list_count == 0);
- KeReleaseSpinLock(&irp_list->irp_list_lock, old_irql);
- return ret;
-}
diff --git a/reactos/drivers/usb/nt4compat/usbdrv/hub.h b/reactos/drivers/usb/nt4compat/usbdrv/hub.h
deleted file mode 100644
index 940d401bfac..00000000000
--- a/reactos/drivers/usb/nt4compat/usbdrv/hub.h
+++ /dev/null
@@ -1,346 +0,0 @@
-
-#ifndef __HUB_H__
-#define __HUB_H__
-
-/*
- * Hub Class feature numbers
- */
-#define C_HUB_LOCAL_POWER 0
-#define C_HUB_OVER_CURRENT 1
-
-/*
- * Port feature numbers
- */
-#define USB_PORT_FEAT_CONNECTION 0
-#define USB_PORT_FEAT_ENABLE 1
-#define USB_PORT_FEAT_SUSPEND 2
-#define USB_PORT_FEAT_OVER_CURRENT 3
-#define USB_PORT_FEAT_RESET 4
-#define USB_PORT_FEAT_POWER 8
-#define USB_PORT_FEAT_LOWSPEED 9
-#define USB_PORT_FEAT_C_CONNECTION 16
-#define USB_PORT_FEAT_C_ENABLE 17
-#define USB_PORT_FEAT_C_SUSPEND 18
-#define USB_PORT_FEAT_C_OVER_CURRENT 19
-#define USB_PORT_FEAT_C_RESET 20
-
-/* wPortStatus bits */
-#define USB_PORT_STAT_CONNECTION 0x0001
-#define USB_PORT_STAT_ENABLE 0x0002
-#define USB_PORT_STAT_SUSPEND 0x0004
-#define USB_PORT_STAT_OVERCURRENT 0x0008
-#define USB_PORT_STAT_RESET 0x0010
-#define USB_PORT_STAT_POWER 0x0100
-#define USB_PORT_STAT_LOW_SPEED 0x0200
-
-/* usb 2.0 features */
-#define USB_PORT_STAT_HIGH_SPEED 0x0400
-#define USB_PORT_STAT_PORT_TEST 0x0800
-#define USB_PORT_STAT_PORT_INDICATOR 0x1000
-
-/* wPortChange bits */
-#define USB_PORT_STAT_C_CONNECTION 0x0001
-#define USB_PORT_STAT_C_ENABLE 0x0002
-#define USB_PORT_STAT_C_SUSPEND 0x0004
-#define USB_PORT_STAT_C_OVERCURRENT 0x0008
-#define USB_PORT_STAT_C_RESET 0x0010
-
-/* wHubCharacteristics (masks) */
-#define HUB_CHAR_LPSM 0x0003
-#define HUB_CHAR_COMPOUND 0x0004
-#define HUB_CHAR_OCPM 0x0018
-
-/*
- *Hub Status & Hub Change bit masks
- */
-#define HUB_STATUS_LOCAL_POWER 0x0001
-#define HUB_STATUS_OVERCURRENT 0x0002
-
-#define HUB_CHANGE_LOCAL_POWER 0x0001
-#define HUB_CHANGE_OVERCURRENT 0x0002
-
-#define HUB_DESCRIPTOR_MAX_SIZE 39 /* enough for 127 ports on a hub */
-
-#define MAX_HUB_PORTS 8
-#define USB_HUB_INTERVAL 0xff
-
-#define USB_PORT_FLAG_STATE_MASK ( 0xf << 16 )
-#define USB_PORT_FLAG_ENABLE ( 0x1 << 16 )
-#define USB_PORT_FLAG_DISABLE ( 0x2 << 16 )
-#define USB_PORT_FLAG_DISCONNECT ( 0x3 << 16 )
-
-#define USB_PORT_QUE_STATE_MASK 0xff // for detail, refer to document.txt
-#define STATE_IDLE 0x00
-#define STATE_EXAMINE_STATUS_QUE 0x01 // set when post a event to examine the status queue
-#define STATE_WAIT_STABLE 0x02 // set when a new connection comes and about to wait some ms
-#define STATE_WAIT_RESET 0x03 // set when dev stable and about to reset, may pending in the event queue
-#define STATE_WAIT_RESET_COMPLETE 0x04 // set when reset signal is about to assert on the port
-#define STATE_WAIT_ADDRESSED 0x05 // set when reset complete and before address is assigned
-
-#define port_state( port_FLAG ) \
-( port_FLAG & USB_PORT_QUE_STATE_MASK )
-
-#define set_port_state( port_FLAG, stATE ) \
-{ port_FLAG = ( port_FLAG & (~USB_PORT_QUE_STATE_MASK ) ) | ( stATE & USB_PORT_QUE_STATE_MASK ) ;}
-
-#define default_endp_handle( endp_HANDLE ) \
-( ( endp_HANDLE & 0xffff ) == 0xffff )
-
-#define is_if_dev( pdev ) ( pdev->flags & USB_DEV_FLAG_IF_DEV )
-
-#define is_composite_dev( pdev ) \
-( is_if_dev( pdev ) == FALSE \
-&& pdev->pusb_dev_desc->bDeviceClass == 0 \
-&& pdev->pusb_dev_desc->bDeviceSubClass == 0 )
-
-#define dev_handle_from_dev( pdev ) ( pdev->dev_id << 16 )
-#define hub_ext_from_dev( pdEV ) ( ( PHUB2_EXTENSION )pdEV->dev_ext )
-
-#pragma pack( push, hub_align, 1 )
-typedef struct _USB_PORT_STATUS
-{
- USHORT wPortStatus;
- USHORT wPortChange;
-
-} USB_PORT_STATUS, *PUSB_PORT_STATUS;
-
-
-typedef struct _USB_HUB_STATUS
-{
- USHORT wHubStatus;
- USHORT wHubChange;
-
-} USB_HUB_STATUS, *PUSB_HUB_STATUS;
-
-
-typedef struct _USB_HUB_DESCRIPTOR
-{
- BYTE bLength;
- BYTE bDescriptorType;
- BYTE bNbrPorts;
- USHORT wHubCharacteristics;
- BYTE bPwrOn2PwrGood;
- BYTE bHubContrCurrent;
-
- /* DeviceRemovable and PortPwrCtrlMask want to be variable-length
- bitmaps that hold max 256 entries, but for now they're ignored */
- BYTE bitmap[0];
-} USB_HUB_DESCRIPTOR, *PUSB_HUB_DESCRIPTOR;
-#pragma pack( pop, hub_align )
-
-typedef struct _PORT_STATUS_QUEUE
-{
- USB_PORT_STATUS port_status[ 4 ];
- BYTE status_count;
- ULONG port_flags;
-
-} PORT_STATUS_QUEUE, *PPORT_STATUS_QUEUE;
-
-VOID
-psq_init(
-PPORT_STATUS_QUEUE psq
-);
-
-BOOLEAN
-psq_enqueue(
-PPORT_STATUS_QUEUE psq,
-ULONG status
-);
-ULONG
-psq_outqueue(
-PPORT_STATUS_QUEUE psq
-); //return 0xffffffff if no element
-
-BOOLEAN
-psq_push(
-PPORT_STATUS_QUEUE psq,
-ULONG status
-);
-
-#define psq_is_empty( pSQ ) ( ( pSQ )->status_count == 0 )
-#define psq_is_full( pSQ ) ( ( pSQ )->status_count == 4 )
-#define psq_count( psq ) ( ( psq )->status_count )
-#define psq_peek( psq, i ) \
-( ( ( ULONG )i ) < 3 ? ( psq )->port_status[ i ] : ( psq )->port_status[ 3 ] )
-
-#define MAX_DEVS 127
-#define EHCI_MAX_ROOT_PORTS 15
-
-typedef struct _HUB_EXTENSION
-{
-
- LONG port_count;
- PUSB_DEV child_dev[ MAX_HUB_PORTS + 1 ];
-
- PORT_STATUS_QUEUE port_status_queue[ MAX_HUB_PORTS + 1];
- PUSB_DEV pdev;
- PUSB_INTERFACE pif;
- BYTE int_data_buf[ 64 ];
-
- USB_HUB_STATUS hub_status;
- USB_PORT_STATUS port_status; //working data buf for get port feature
-
- USB_PORT_STATUS rh_port1_status; //working buf for get rh port1 feature
- USB_PORT_STATUS rh_port2_status; //working buf for get rh port2 feature
-
- USB_HUB_DESCRIPTOR hub_desc;
-
-} HUB_EXTENSION, *PHUB_EXTENSION;
-
-typedef struct _HUB2_PORT_TT
-{
- ULONG tt_busy : 1;
-
-} HUB2_PORT_TT, *PHUB2_PORT_TT;
-
-typedef struct _HUB2_EXTENSION
-{
-
- LONG port_count;
- PUSB_DEV child_dev[ MAX_HUB_PORTS + 1 ];
-
- PORT_STATUS_QUEUE port_status_queue[ MAX_HUB_PORTS + 1];
-
- PUSB_DEV pdev;
- PUSB_INTERFACE pif;
- BYTE int_data_buf[ 32 ]; // for ports up to 127
-
- USB_HUB_STATUS hub_status;
- USB_PORT_STATUS port_status; //working data buf for get port feature
-
- USB_PORT_STATUS rh_port_status[ EHCI_MAX_ROOT_PORTS + 1 ]; //working buf for get rh ports feature
-
- UCHAR multiple_tt; // boolean
- ULONG tt_status_map[ 4 ]; // bit map to indicate the indexed tt's periodic buffer busy or not
- ULONG tt_bulk_map[ 4 ]; // bit map to indicate the indexed tt's bulk/control buffer busy or not
- USB_HUB_DESCRIPTOR hub_desc;
-
-} HUB2_EXTENSION, *PHUB2_EXTENSION;
-
-
-VOID
-event_list_default_process_queue(
-PLIST_HEAD event_list,
-PUSB_EVENT_POOL event_pool,
-PUSB_EVENT usb_event,
-PUSB_EVENT out_event
-);
-
-VOID
-event_list_default_process_event(
-PUSB_DEV dev,
-ULONG event,
-ULONG context,
-ULONG param
-);
-
-// root hub routines and definitions
-
-#define RH_INTERVAL ( USB_HUB_INTERVAL / DEV_MGR_TIMER_INTERVAL_MS )
-
-BOOLEAN
-rh_driver_destroy(
-PUSB_DEV_MANAGER dev_mgr,
-PUSB_DRIVER pdriver
-);
-
-BOOLEAN
-rh_driver_init(
-PUSB_DEV_MANAGER dev_mgr,
-PUSB_DRIVER pdriver
-);
-
-BOOLEAN
-rh_destroy(
-PUSB_DEV pdev
-);
-
-VOID
-rh_timer_svc(
-PUSB_DEV dev,
-PVOID context
-);
-
-BOOLEAN
-rh_submit_urb(
-PUSB_DEV pdev,
-PURB urb
-);
-
-BOOLEAN
-hub_init(
-PUSB_DEV pdev
-);
-
-BOOLEAN
-hub_destroy(
-PUSB_DEV pdev
-);
-
-BOOLEAN
-hub_lock_tt(
-PUSB_DEV pdev,
-UCHAR port_idx,
-UCHAR type // transfer type
-);
-
-BOOLEAN
-hub_unlock_tt(
-PUSB_DEV pdev,
-UCHAR port_idx,
-UCHAR type
-);
-
-
-VOID
-hub_post_clear_tt_event(
-PUSB_DEV pdev,
-BYTE port_idx,
-ULONG pipe
-);
-
-BOOLEAN
-compdev_driver_init(
-PUSB_DEV_MANAGER dev_mgr,
-PUSB_DRIVER pdriver
-);
-
-BOOLEAN
-compdev_driver_destroy(
-PUSB_DEV_MANAGER dev_mgr,
-PUSB_DRIVER pdriver
-);
-
-BOOLEAN
-gendrv_driver_init(
-PUSB_DEV_MANAGER dev_mgr,
-PUSB_DRIVER pdriver
-);
-
-BOOLEAN
-gendrv_driver_destroy(
-PUSB_DEV_MANAGER dev_mgr,
-PUSB_DRIVER pdriver
-);
-
-BOOLEAN
-gendrv_if_driver_init(
-PUSB_DEV_MANAGER dev_mgr,
-PUSB_DRIVER pdriver
-);
-
-BOOLEAN
-gendrv_if_driver_destroy(
-PUSB_DEV_MANAGER dev_mgr,
-PUSB_DRIVER pdriver
-);
-
-BOOLEAN hub_driver_init(PUSB_DEV_MANAGER dev_mgr, PUSB_DRIVER pdriver);
-BOOLEAN hub_driver_destroy(PUSB_DEV_MANAGER dev_mgr, PUSB_DRIVER pdriver);
-BOOLEAN hub_remove_reset_event(PUSB_DEV pdev, ULONG port_idx, BOOLEAN from_dpc);
-BOOLEAN hub_start_next_reset_port(PUSB_DEV_MANAGER dev_mgr, BOOLEAN from_dpc);
-NTSTATUS hub_start_int_request(PUSB_DEV pdev);
-
-#endif
-
-
diff --git a/reactos/drivers/usb/nt4compat/usbdrv/irplist.h b/reactos/drivers/usb/nt4compat/usbdrv/irplist.h
deleted file mode 100644
index f6dbe064d5e..00000000000
--- a/reactos/drivers/usb/nt4compat/usbdrv/irplist.h
+++ /dev/null
@@ -1,58 +0,0 @@
-#ifndef __IRPLIST_H
-#define __IRPLIST_H
-
-#define MAX_IRP_LIST_SIZE 32
-
-typedef struct _IRP_LIST_ELEMENT
-{
- LIST_ENTRY irp_link;
- PIRP pirp;
- struct _URB *purb;
-
-} IRP_LIST_ELEMENT, *PIRP_LIST_ELEMENT;
-
-typedef struct _IRP_LIST
-{
- KSPIN_LOCK irp_list_lock;
- LIST_HEAD irp_busy_list;
- LONG irp_free_list_count;
- LIST_HEAD irp_free_list;
- PIRP_LIST_ELEMENT irp_list_element_array;
-
-} IRP_LIST, *PIRP_LIST;
-
-BOOLEAN
-init_irp_list(
-PIRP_LIST irp_list
-);
-
-VOID
-destroy_irp_list(
-PIRP_LIST irp_list
-);
-
-BOOLEAN
-add_irp_to_list(
-PIRP_LIST irp_list,
-PIRP pirp,
-PURB purb
-);
-
-PURB
-remove_irp_from_list(
-PIRP_LIST irp_list,
-PIRP pirp,
-struct _USB_DEV_MANAGER *dev_mgr
-);
-
-BOOLEAN
-irp_list_empty(
-PIRP_LIST irp_list
-);
-
-BOOLEAN
-irp_list_full(
-PIRP_LIST irp_list
-);
-
-#endif
diff --git a/reactos/drivers/usb/nt4compat/usbdrv/keyboard.c b/reactos/drivers/usb/nt4compat/usbdrv/keyboard.c
deleted file mode 100644
index cc61daac0c9..00000000000
--- a/reactos/drivers/usb/nt4compat/usbdrv/keyboard.c
+++ /dev/null
@@ -1,581 +0,0 @@
-/*
- * PROJECT: ReactOS USB Drivers
- * COPYRIGHT: GPL - See COPYING in the top level directory
- * FILE: keyboard.c
- * PURPOSE: Generic USB keyboard driver
- * PROGRAMMERS: Aleksey Bragin (aleksey@reactos.org)
- */
-
-#include "usbdriver.h"
-
-NTSTATUS
-AddRegistryEntry(IN PCWSTR PortTypeName,
- IN PUNICODE_STRING DeviceName,
- IN PCWSTR RegistryPath);
-
-BOOLEAN kbd_connect(PDEV_CONNECT_DATA dev_mgr, DEV_HANDLE dev_handle);
-BOOLEAN kbd_disconnect(PUSB_DEV_MANAGER dev_mgr, DEV_HANDLE dev_handle);
-BOOLEAN kbd_stop(PUSB_DEV_MANAGER dev_mgr, DEV_HANDLE dev_handle);
-VOID kbd_irq(PURB purb, PVOID pcontext);
-static NTSTATUS
-KeyboardCreateDevice(IN PDRIVER_OBJECT DriverObject, IN PKEYBOARD_DRVR_EXTENSION DriverExtension);
-void * memscan(void * addr, int c, size_t size);
-
-static UCHAR usb_kbd_keycode[256] =
-{
- 0, 0, 0, 0, 30, 48, 46, 32, 18, 33, 34, 35, 23, 36, 37, 38,
- 50, 49, 24, 25, 16, 19, 31, 20, 22, 47, 17, 45, 21, 44, 2, 3,
- 4, 5, 6, 7, 8, 9, 10, 11, 28, 1, 14, 15, 57, 12, 13, 26,
- 27, 43, 43, 39, 40, 41, 51, 52, 53, 58, 59, 60, 61, 62, 63, 64,
- 65, 66, 67, 68, 87, 88, 99, 70,119,110,102,104,111,107,109,106,
- 105,108,103, 69, 98, 55, 74, 78, 96, 79, 80, 81, 75, 76, 77, 71,
- 72, 73, 82, 83, 86,127,116,117,183,184,185,186,187,188,189,190,
- 191,192,193,194,134,138,130,132,128,129,131,137,133,135,136,113,
- 115,114, 0, 0, 0,121, 0, 89, 93,124, 92, 94, 95, 0, 0, 0,
- 122,123, 90, 91, 85, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 29, 42, 56,125, 97, 54,100,126,164,166,165,163,161,115,114,113,
- 150,158,159,128,136,177,178,176,142,152,173,140
-};
-
-/* This structure starts with the same layout as KEYBOARD_INDICATOR_TRANSLATION */
-typedef struct _LOCAL_KEYBOARD_INDICATOR_TRANSLATION {
- USHORT NumberOfIndicatorKeys;
- INDICATOR_LIST IndicatorList[3];
-} LOCAL_KEYBOARD_INDICATOR_TRANSLATION, *PLOCAL_KEYBOARD_INDICATOR_TRANSLATION;
-
-static LOCAL_KEYBOARD_INDICATOR_TRANSLATION IndicatorTranslation = { 3, {
- {0x3A, KEYBOARD_CAPS_LOCK_ON},
- {0x45, KEYBOARD_NUM_LOCK_ON},
- {0x46, KEYBOARD_SCROLL_LOCK_ON}}};
-
-
-BOOLEAN
-kbd_driver_init(PUSB_DEV_MANAGER dev_mgr, PUSB_DRIVER pdriver)
-{
- PKEYBOARD_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 = 0; // Configuration Value
- pdriver->driver_desc.if_num = 0; // 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 = 1; // Interface Protocol
-
- pdriver->driver_desc.driver_name = "USB Keyboard 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 = 1; // Protocol Info.
-
- pdriver->driver_ext = usb_alloc_mem(NonPagedPool, sizeof(KEYBOARD_DRVR_EXTENSION));
- if (!pdriver->driver_ext) return FALSE;
- pdriver->driver_ext_size = sizeof(KEYBOARD_DRVR_EXTENSION);
-
- RtlZeroMemory(pdriver->driver_ext, sizeof(KEYBOARD_DRVR_EXTENSION));
- pdrvr_ext = (PKEYBOARD_DRVR_EXTENSION) pdriver->driver_ext;
- pdrvr_ext->dev_mgr = dev_mgr;
-
- pdriver->disp_tbl.version = 1;
- pdriver->disp_tbl.dev_connect = kbd_connect;
- pdriver->disp_tbl.dev_disconnect = kbd_disconnect;
- pdriver->disp_tbl.dev_stop = kbd_stop;
- pdriver->disp_tbl.dev_reserved = NULL;
-
- // Create the device
- KeyboardCreateDevice(dev_mgr->usb_driver_obj, pdrvr_ext);
-
- usb_dbg_print(DBGLVL_MAXIMUM, ("kbd_driver_init(): keyboard driver is initialized\n"));
- return TRUE;
-}
-
-BOOLEAN
-kbd_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, ("kbd_driver_destroy(): keyboard driver is destroyed\n"));
- return TRUE;
-}
-
-BOOLEAN
-kbd_connect(PDEV_CONNECT_DATA param, DEV_HANDLE dev_handle)
-{
- PURB purb;
- NTSTATUS status;
- PUSB_DEV_MANAGER dev_mgr;
- PUSB_DRIVER pdrvr;
- PUSB_DEV pdev;
- PKEYBOARD_DRVR_EXTENSION pdev_ext;
- PUSB_ENDPOINT_DESC pendp_desc = NULL;
- ULONG MaxPacketSize;
-
- usb_dbg_print(DBGLVL_MAXIMUM, ("kbd_connect(): entering...\n"));
-
- dev_mgr = param->dev_mgr;
- pdrvr = param->pdriver;
- pdev_ext = (PKEYBOARD_DRVR_EXTENSION)pdrvr->driver_ext;
- pdev_ext->dev_handle = dev_handle;
-
- // Lock USB Device
- status = usb_query_and_lock_dev(dev_mgr, dev_handle, &pdev);
- if (status != STATUS_SUCCESS)
- {
- usb_dbg_print(DBGLVL_MEDIUM, ("kbd_connect(): unable to query&lock device, status=0x%x\n", status));
- return FALSE;
- }
-
- // Get pointer to the endpoint descriptor
- pendp_desc = pdev->usb_config->interf[0].endp[0].pusb_endp_desc;
-
- // Store max packet size
- MaxPacketSize = pendp_desc->wMaxPacketSize;
- if (MaxPacketSize > 8)
- MaxPacketSize = 8;
-
- // Unlock USB Device
- usb_unlock_dev(pdev);
-
- // Send interrupt URB
- purb = usb_alloc_mem(NonPagedPool, sizeof(URB));
- if (purb == NULL)
- return FALSE;
- RtlZeroMemory(purb, sizeof(URB));
-
- RtlZeroMemory(pdev_ext->kbd_old, 8);
-
- // Build a URB for our interrupt transfer
- UsbBuildInterruptOrBulkTransferRequest(purb,
- usb_make_handle((dev_handle >> 16), 0, 0),
- (PUCHAR)&pdev_ext->kbd_data,
- MaxPacketSize, //use max packet size
- kbd_irq,
- pdev_ext->device_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;
-}
-
-VOID
-kbd_irq(PURB purb, PVOID pcontext)
-{
- KEYBOARD_INPUT_DATA KeyboardInputData[20];
- ULONG DataPrepared=0, DataConsumed, i;
- UCHAR ScanCode;
- NTSTATUS status;
- PKEYBOARD_DRVR_EXTENSION pdev_ext;
- PKEYBOARD_DEVICE_EXTENSION DeviceExtension = (PKEYBOARD_DEVICE_EXTENSION)pcontext;
- PUCHAR data, data_old;
- usb_dbg_print(DBGLVL_MAXIMUM, ("kbd_irq(): called\n"));
-
- ASSERT(purb);
-
- if (purb->status != STATUS_SUCCESS)
- {
- usb_dbg_print(DBGLVL_MAXIMUM, ("kbd_irq(): purb->status 0x%08X\n", purb->status));
- return;
- }
-
- pdev_ext = DeviceExtension->DriverExtension;
- data = pdev_ext->kbd_data;
- data_old = pdev_ext->kbd_old;
-
- usb_dbg_print(DBGLVL_MAXIMUM, ("Kbd input: %d %d %d %d %d %d %d %d\n", data[0], data[1], data[2], data[3],
- data[4], data[5], data[6], data[7]));
-
- // Zero initial kbd data array
- RtlZeroMemory(&KeyboardInputData[0], sizeof(KeyboardInputData));
-
- // Scan modifier keys
- for (i=0; i<8; i++)
- {
- ScanCode = usb_kbd_keycode[i + 224];
-
- if (((data[0] >> i) & 1) != ((data_old[0] >> i) & 1))
- {
- usb_dbg_print(DBGLVL_MAXIMUM, ("Scan %d key p/r %d\n", ScanCode, (data[0] >> i) & 1));
-
- KeyboardInputData[DataPrepared].MakeCode = ScanCode;
- if ((data[0] >> i) & 1)
- KeyboardInputData[DataPrepared].Flags |= KEY_MAKE;
- else
- KeyboardInputData[DataPrepared].Flags |= KEY_BREAK;
- DataPrepared++;
- }
- }
-
- // Scan normal keys
- for (i=2; i<8; i++)
- {
- if (data_old[i] > 3 && memscan(data + 2, data_old[i], 6) == data + 8)
- {
- if (usb_kbd_keycode[data_old[i]])
- {
- // key released
- usb_dbg_print(DBGLVL_MAXIMUM, ("Scan %d key released 1\n", usb_kbd_keycode[data_old[i]]));
-
- KeyboardInputData[DataPrepared].MakeCode = usb_kbd_keycode[data_old[i]];
- KeyboardInputData[DataPrepared].Flags |= KEY_BREAK;
- DataPrepared++;
- }
- }
-
- if (data[i] > 3 && memscan(data_old + 2, data[i], 6) == data_old + 8)
- {
- if (usb_kbd_keycode[data[i]])
- {
- // key pressed
- usb_dbg_print(DBGLVL_MAXIMUM, ("Scan %d key pressed 1\n", usb_kbd_keycode[data[i]]));
-
- KeyboardInputData[DataPrepared].MakeCode = usb_kbd_keycode[data[i]];
- KeyboardInputData[DataPrepared].Flags |= KEY_MAKE;
- DataPrepared++;
- }
- }
- }
-
- // Commit the input data somewhere...
- if (DeviceExtension->ConnectData.ClassService && DataPrepared > 0)
- {
- KIRQL OldIrql;
-
- KeRaiseIrql(DISPATCH_LEVEL, &OldIrql);
- (*(PSERVICE_CALLBACK_ROUTINE)DeviceExtension->ConnectData.ClassService)(
- DeviceExtension->ConnectData.ClassDeviceObject,
- &KeyboardInputData[0],
- (&KeyboardInputData[0])+DataPrepared,
- &DataConsumed);
- KeLowerIrql(OldIrql);
- }
-
- // Save old keyboard data
- RtlCopyMemory(pdev_ext->kbd_old, data, 8);
-
- // resubmit the urb
- status = usb_submit_urb(pdev_ext->dev_mgr, purb);
-}
-
-BOOLEAN
-kbd_stop(PUSB_DEV_MANAGER dev_mgr, DEV_HANDLE dev_handle)
-{
- UNREFERENCED_PARAMETER(dev_handle);
- UNREFERENCED_PARAMETER(dev_mgr);
- return TRUE;
-}
-
-BOOLEAN
-kbd_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);
-}
-
-VOID
-kbd_setleds(PKEYBOARD_DEVICE_EXTENSION DeviceExtension)
-{
- PURB Urb;
- PUSB_CTRL_SETUP_PACKET Setup;
- NTSTATUS Status;
-
- // Set LEDs request
- Urb = usb_alloc_mem(NonPagedPool, sizeof(URB));
- if (!Urb) return;
- RtlZeroMemory(Urb, sizeof(URB));
-
- DeviceExtension->DriverExtension->leds_old = 0;
- DeviceExtension->DriverExtension->leds = 7;
-
- // Convert from LedFlags to USB format
- //DeviceExtension->KeyboardIndicators.LedFlags
-
- // Build a URB for setting LEDs
- Setup = (PUSB_CTRL_SETUP_PACKET)Urb->setup_packet;
- urb_init((Urb));
-
- Urb->endp_handle = usb_make_handle((DeviceExtension->DriverExtension->dev_handle >> 16), 0, 0) | 0xffff;
- Urb->data_buffer = &DeviceExtension->DriverExtension->leds;
- Urb->data_length = 1;
- Urb->completion = NULL;
- Urb->context = NULL;
- Urb->reference = 0;
- Setup->bmRequestType = USB_DT_HID;
- Setup->bRequest = USB_REQ_SET_CONFIGURATION;
- Setup->wValue = USB_DT_CONFIG << 8;
- Setup->wIndex = 0;
- Setup->wLength = 1;
-
- // Call USB driver stack
- Status = usb_submit_urb(DeviceExtension->DriverExtension->dev_mgr, Urb);
- if (Status != STATUS_PENDING)
- {
- usb_free_mem(Urb);
- }
-}
-
-// Dispatch routine for our IRPs
-NTSTATUS
-KbdDispatch(PDEVICE_OBJECT DeviceObject, PIRP Irp)
-{
- NTSTATUS Status = STATUS_INVALID_DEVICE_REQUEST;
- PKEYBOARD_DEVICE_EXTENSION DeviceExtension;
-
- DeviceExtension = DeviceObject->DeviceExtension;
-
- usb_dbg_print(DBGLVL_MAXIMUM, ("KbdDispatch(DO %p, code 0x%lx) called\n",
- DeviceObject,
- IoGetCurrentIrpStackLocation(Irp)->Parameters.DeviceIoControl.IoControlCode));
-
- if (DeviceObject == DeviceExtension->Fdo)
- {
- // it's keyboard's IOCTL
- PIO_STACK_LOCATION Stack;
-
- Irp->IoStatus.Information = 0;
- Stack = IoGetCurrentIrpStackLocation(Irp);
-
- switch (Stack->Parameters.DeviceIoControl.IoControlCode)
- {
- case IOCTL_INTERNAL_KEYBOARD_CONNECT:
- usb_dbg_print(DBGLVL_MAXIMUM, ("IOCTL_INTERNAL_KEYBOARD_CONNECT\n"));
- if (Stack->Parameters.DeviceIoControl.InputBufferLength < sizeof(CONNECT_DATA)) {
- usb_dbg_print(DBGLVL_MAXIMUM, ("Keyboard IOCTL_INTERNAL_KEYBOARD_CONNECT "
- "invalid buffer size\n"));
- Status = STATUS_INVALID_PARAMETER;
- break;
- }
-
- RtlCopyMemory(&DeviceExtension->ConnectData,
- Stack->Parameters.DeviceIoControl.Type3InputBuffer,
- sizeof(CONNECT_DATA));
-
- Status = STATUS_SUCCESS;
- break;
- case IOCTL_KEYBOARD_QUERY_ATTRIBUTES:
- usb_dbg_print(DBGLVL_MAXIMUM, ("IOCTL_KEYBOARD_QUERY_ATTRIBUTES\n"));
- if (Stack->Parameters.DeviceIoControl.OutputBufferLength <
- sizeof(KEYBOARD_ATTRIBUTES)) {
- usb_dbg_print(DBGLVL_MAXIMUM, ("Keyboard IOCTL_KEYBOARD_QUERY_ATTRIBUTES: "
- "invalid buffer size\n"));
- Status = STATUS_BUFFER_TOO_SMALL;
- break;
- }
- /*RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer,
- &DevExt->KeyboardAttributes,
- sizeof(KEYBOARD_ATTRIBUTES));*/
-
- Status = STATUS_SUCCESS;
- break;
- case IOCTL_KEYBOARD_QUERY_INDICATORS:
- usb_dbg_print(DBGLVL_MAXIMUM, ("IOCTL_KEYBOARD_QUERY_INDICATORS\n"));
- if (Stack->Parameters.DeviceIoControl.InputBufferLength < sizeof(KEYBOARD_INDICATOR_PARAMETERS))
- {
- Status = STATUS_BUFFER_TOO_SMALL;
- }
- else
- {
- RtlCopyMemory(
- Irp->AssociatedIrp.SystemBuffer,
- &DeviceExtension->KeyboardIndicators,
- sizeof(KEYBOARD_INDICATOR_PARAMETERS));
- Irp->IoStatus.Information = sizeof(KEYBOARD_INDICATOR_PARAMETERS);
- Status = STATUS_SUCCESS;
- }
- break;
- case IOCTL_KEYBOARD_QUERY_TYPEMATIC:
- usb_dbg_print(DBGLVL_MAXIMUM, ("IOCTL_KEYBOARD_QUERY_TYPEMATIC\n"));
- if (Stack->Parameters.DeviceIoControl.OutputBufferLength <
- sizeof(KEYBOARD_TYPEMATIC_PARAMETERS)) {
- usb_dbg_print(DBGLVL_MAXIMUM, ("Keyboard IOCTL_KEYBOARD_QUERY_TYPEMATIC: "
- "invalid buffer size\n"));
- Status = STATUS_BUFFER_TOO_SMALL;
- break;
- }
- /*RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer,
- &DevExt->KeyboardTypematic,
- sizeof(KEYBOARD_TYPEMATIC_PARAMETERS));*/
-
- Status = STATUS_SUCCESS;
- break;
- case IOCTL_KEYBOARD_SET_INDICATORS:
- usb_dbg_print(DBGLVL_MAXIMUM, ("IOCTL_KEYBOARD_SET_INDICATORS\n"));
- if (Stack->Parameters.DeviceIoControl.InputBufferLength <
- sizeof(KEYBOARD_INDICATOR_PARAMETERS)) {
- usb_dbg_print(DBGLVL_MAXIMUM, ("Keyboard IOCTL_KEYBOARD_SET_INDICTATORS: "
- "invalid buffer size\n"));
- Status = STATUS_BUFFER_TOO_SMALL;
- break;
- }
-
- RtlCopyMemory(&DeviceExtension->KeyboardIndicators,
- Irp->AssociatedIrp.SystemBuffer,
- sizeof(KEYBOARD_INDICATOR_PARAMETERS));
-
- //DPRINT("%x\n", DevExt->KeyboardIndicators.LedFlags);
- kbd_setleds(DeviceExtension);
- Status = STATUS_SUCCESS;
- break;
- case IOCTL_KEYBOARD_SET_TYPEMATIC:
- usb_dbg_print(DBGLVL_MAXIMUM, ("IOCTL_KEYBOARD_SET_TYPEMATIC\n"));
- if (Stack->Parameters.DeviceIoControl.InputBufferLength <
- sizeof(KEYBOARD_TYPEMATIC_PARAMETERS)) {
- usb_dbg_print(DBGLVL_MAXIMUM, ("Keyboard IOCTL_KEYBOARD_SET_TYPEMATIC "
- "invalid buffer size\n"));
- Status = STATUS_BUFFER_TOO_SMALL;
- break;
- }
-
- /*RtlCopyMemory(&DevExt->KeyboardTypematic,
- Irp->AssociatedIrp.SystemBuffer,
- sizeof(KEYBOARD_TYPEMATIC_PARAMETERS));*/
-
- Status = STATUS_SUCCESS;
- break;
- case IOCTL_KEYBOARD_QUERY_INDICATOR_TRANSLATION:
- if (Stack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(LOCAL_KEYBOARD_INDICATOR_TRANSLATION))
- {
- Status = STATUS_BUFFER_TOO_SMALL;
- }
- else
- {
- RtlCopyMemory(
- Irp->AssociatedIrp.SystemBuffer,
- &IndicatorTranslation,
- sizeof(LOCAL_KEYBOARD_INDICATOR_TRANSLATION));
- Irp->IoStatus.Information = sizeof(LOCAL_KEYBOARD_INDICATOR_TRANSLATION);
- Status = STATUS_SUCCESS;
- }
- break;
- default:
- Status = STATUS_SUCCESS;//STATUS_INVALID_DEVICE_REQUEST;
- break;
- }
- }
-
- if (Status == STATUS_INVALID_DEVICE_REQUEST)
- {
- usb_dbg_print(DBGLVL_MINIMUM, ("Invalid internal device request!\n"));
- }
-
- Irp->IoStatus.Status = Status;
- if (Status != STATUS_PENDING)
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
- return Status;
-}
-
-static NTSTATUS
-KeyboardCreateDevice(IN PDRIVER_OBJECT DriverObject, IN PKEYBOARD_DRVR_EXTENSION DriverExtension)
-{
- UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Device\\KeyboardPortUSB");
- PKEYBOARD_DEVICE_EXTENSION DeviceExtension;
- PDEVICE_OBJECT Fdo;
- NTSTATUS Status;
-
- Status = AddRegistryEntry(L"KeyboardPort", &DeviceName, L"REGISTRY\\MACHINE\\SYSTEM\\CurrentControlSet\\Services\\usbdriver");
- if (!NT_SUCCESS(Status))
- {
- usb_dbg_print(DBGLVL_MINIMUM, ("AddRegistryEntry() for usb keyboard driver failed with status 0x%08lx\n", Status));
- return Status;
- }
-
- Status = IoCreateDevice(DriverObject,
- sizeof(KEYBOARD_DEVICE_EXTENSION),
- &DeviceName,
- FILE_DEVICE_KEYBOARD,
- FILE_DEVICE_SECURE_OPEN,
- TRUE,
- &Fdo);
-
- if (!NT_SUCCESS(Status))
- {
- usb_dbg_print(DBGLVL_MINIMUM, ("IoCreateDevice() for usb keyboard driver failed with status 0x%08lx\n", Status));
- return Status;
- }
- DeviceExtension = (PKEYBOARD_DEVICE_EXTENSION)Fdo->DeviceExtension;
- RtlZeroMemory(DeviceExtension, sizeof(KEYBOARD_DEVICE_EXTENSION));
-
- DeviceExtension->hdr.dispatch = KbdDispatch;
- DeviceExtension->DriverExtension = DriverExtension;
- DriverExtension->device_ext = DeviceExtension;
-
- DeviceExtension->Fdo = Fdo;
- Fdo->Flags &= ~DO_DEVICE_INITIALIZING;
- usb_dbg_print(DBGLVL_MEDIUM, ("Created keyboard Fdo: %p\n", Fdo));
-
- return STATUS_SUCCESS;
-}
-
-/**
- * memscan - Find a character in an area of memory.
- * @addr: The memory area
- * @c: The byte to search for
- * @size: The size of the area.
- *
- * returns the address of the first occurrence of @c, or 1 byte past
- * the area if @c is not found
- */
-void * memscan(void * addr, int c, size_t size)
-{
- unsigned char * p = (unsigned char *) addr;
-
- while (size) {
- if (*p == c)
- return (void *) p;
- p++;
- size--;
- }
- return (void *) p;
-}
-
diff --git a/reactos/drivers/usb/nt4compat/usbdrv/keyboard.h b/reactos/drivers/usb/nt4compat/usbdrv/keyboard.h
deleted file mode 100644
index fc4105c5696..00000000000
--- a/reactos/drivers/usb/nt4compat/usbdrv/keyboard.h
+++ /dev/null
@@ -1,37 +0,0 @@
-#ifndef __KEYBOARD_H__
-#define __KEYBOARD_H__
-
-#include "kbdmou.h"
-
-typedef struct _KEYBOARD_DRVR_EXTENSION
-{
- PUSB_INTERFACE_DESC pif_desc;
- DEV_HANDLE dev_handle;
-
- PUSB_DEV_MANAGER dev_mgr;
-
- UCHAR kbd_data[8];
- UCHAR kbd_old[8];
-
- UCHAR leds;
- UCHAR leds_old;
-
- struct _KEYBOARD_DEVICE_EXTENSION *device_ext; // back pointer
-} KEYBOARD_DRVR_EXTENSION, *PKEYBOARD_DRVR_EXTENSION;
-
-typedef struct _KEYBOARD_DEVICE_EXTENSION
-{
- DEVEXT_HEADER hdr; // mandatory header
- PKEYBOARD_DRVR_EXTENSION DriverExtension;
- KEYBOARD_INDICATOR_PARAMETERS KeyboardIndicators;
- CONNECT_DATA ConnectData;
- PDEVICE_OBJECT Fdo;
-} KEYBOARD_DEVICE_EXTENSION, *PKEYBOARD_DEVICE_EXTENSION;
-
-BOOLEAN
-kbd_driver_init(PUSB_DEV_MANAGER dev_mgr, PUSB_DRIVER pdriver);
-
-BOOLEAN
-kbd_driver_destroy(PUSB_DEV_MANAGER dev_mgr, PUSB_DRIVER pdriver);
-
-#endif
diff --git a/reactos/drivers/usb/nt4compat/usbdrv/mouse.c b/reactos/drivers/usb/nt4compat/usbdrv/mouse.c
deleted file mode 100644
index 1dc7442dc33..00000000000
--- a/reactos/drivers/usb/nt4compat/usbdrv/mouse.c
+++ /dev/null
@@ -1,417 +0,0 @@
-/*
- * 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"
-
-BOOLEAN mouse_connect(PDEV_CONNECT_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);
-static NTSTATUS MouseCreateDevice(IN PDRIVER_OBJECT DriverObject, IN PMOUSE_DRVR_EXTENSION DriverExtension);
-
-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));
- if (!pdriver->driver_ext) return FALSE;
-
- 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;
-
- // Create the device
- MouseCreateDevice(dev_mgr->usb_driver_obj, pdrvr_ext);
-
- 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(PDEV_CONNECT_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;
- }
-
- // Get pointer to the endpoint descriptor
- pendp_desc = pdev->usb_config->interf[0].endp[0].pusb_endp_desc;
-
- // Store max packet size
- MaxPacketSize = pendp_desc->wMaxPacketSize;
- if (MaxPacketSize > 8)
- MaxPacketSize = 8;
-
- // 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));
-
- // 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->device_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;
-}
-
-VOID
-mouse_irq(PURB purb, PVOID pcontext)
-{
- MOUSE_INPUT_DATA MouseInputData;
- ULONG InputDataConsumed;
- NTSTATUS status;
- PMOUSE_DRVR_EXTENSION pdev_ext;
- PMOUSE_DEVICE_EXTENSION DeviceExtension = (PMOUSE_DEVICE_EXTENSION)pcontext;
- signed char *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;
- }
-
- pdev_ext = DeviceExtension->DriverExtension;
- data = pdev_ext->mouse_data;
-
- 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 (DeviceExtension->ConnectData.ClassService)
- {
- KIRQL OldIrql;
-
- KeRaiseIrql(DISPATCH_LEVEL, &OldIrql);
- (*(PSERVICE_CALLBACK_ROUTINE)DeviceExtension->ConnectData.ClassService)(
- DeviceExtension->ConnectData.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);
-}
-
-// Dispatch routine for our IRPs
-NTSTATUS
-MouseDispatch(PDEVICE_OBJECT DeviceObject, PIRP Irp)
-{
- NTSTATUS Status = STATUS_INVALID_DEVICE_REQUEST;
- PMOUSE_DEVICE_EXTENSION DeviceExtension;
-
- DeviceExtension = DeviceObject->DeviceExtension;
-
- usb_dbg_print(DBGLVL_MAXIMUM, ("MouseDispatch(DO %p, code 0x%lx) called\n",
- DeviceObject,
- IoGetCurrentIrpStackLocation(Irp)->Parameters.DeviceIoControl.IoControlCode));
-
- if (DeviceObject == DeviceExtension->Fdo)
- {
- // it's mouse's IOCTL
- PIO_STACK_LOCATION Stk;
-
- Irp->IoStatus.Information = 0;
- Stk = IoGetCurrentIrpStackLocation(Irp);
-
- switch (Stk->Parameters.DeviceIoControl.IoControlCode)
- {
- case IOCTL_INTERNAL_MOUSE_CONNECT:
- usb_dbg_print(DBGLVL_MAXIMUM, ("IOCTL_INTERNAL_MOUSE_CONNECT\n"));
- if (Stk->Parameters.DeviceIoControl.InputBufferLength < sizeof(CONNECT_DATA)) {
- usb_dbg_print(DBGLVL_MINIMUM, ("IOCTL_INTERNAL_MOUSE_CONNECT: "
- "invalid buffer size\n"));
- Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
- goto intcontfailure2;
- }
-
- RtlCopyMemory(&DeviceExtension->ConnectData,
- Stk->Parameters.DeviceIoControl.Type3InputBuffer,
- sizeof(CONNECT_DATA));
-
- Irp->IoStatus.Status = STATUS_SUCCESS;
- break;
-
- default:
- Irp->IoStatus.Status = STATUS_SUCCESS;//STATUS_INVALID_DEVICE_REQUEST;
- break;
- }
-intcontfailure2:
- Status = Irp->IoStatus.Status;
- }
-
- if (Status == STATUS_INVALID_DEVICE_REQUEST)
- {
- usb_dbg_print(DBGLVL_MINIMUM, ("Invalid internal device request!\n"));
- }
-
- if (Status != STATUS_PENDING)
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
- return Status;
-}
-
-NTSTATUS
-AddRegistryEntry(
- IN PCWSTR PortTypeName,
- IN PUNICODE_STRING DeviceName,
- IN PCWSTR RegistryPath)
-{
- UNICODE_STRING PathU = RTL_CONSTANT_STRING(L"\\REGISTRY\\MACHINE\\HARDWARE\\DEVICEMAP");
- OBJECT_ATTRIBUTES ObjectAttributes;
- HANDLE hDeviceMapKey = (HANDLE)-1;
- HANDLE hPortKey = (HANDLE)-1;
- UNICODE_STRING PortTypeNameU;
- NTSTATUS Status;
-
- InitializeObjectAttributes(&ObjectAttributes, &PathU, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, NULL);
- Status = ZwOpenKey(&hDeviceMapKey, 0, &ObjectAttributes);
- if (!NT_SUCCESS(Status))
- {
- usb_dbg_print(DBGLVL_MINIMUM, ("ZwOpenKey() failed with status 0x%08lx\n", Status));
- goto cleanup;
- }
-
- RtlInitUnicodeString(&PortTypeNameU, PortTypeName);
- InitializeObjectAttributes(&ObjectAttributes, &PortTypeNameU, OBJ_KERNEL_HANDLE, hDeviceMapKey, NULL);
- Status = ZwCreateKey(&hPortKey, KEY_SET_VALUE, &ObjectAttributes, 0, NULL, REG_OPTION_VOLATILE, NULL);
- if (!NT_SUCCESS(Status))
- {
- usb_dbg_print(DBGLVL_MINIMUM, ("ZwCreateKey() failed with status 0x%08lx\n", Status));
- goto cleanup;
- }
-
- Status = ZwSetValueKey(hPortKey, DeviceName, 0, REG_SZ, (PVOID)RegistryPath, (ULONG)(wcslen(RegistryPath) * sizeof(WCHAR) + sizeof(UNICODE_NULL)));
- if (!NT_SUCCESS(Status))
- {
- usb_dbg_print(DBGLVL_MINIMUM, ("ZwSetValueKey() failed with status 0x%08lx\n", Status));
- goto cleanup;
- }
-
- Status = STATUS_SUCCESS;
-
-cleanup:
- if (hDeviceMapKey != (HANDLE)-1)
- ZwClose(hDeviceMapKey);
- if (hPortKey != (HANDLE)-1)
- ZwClose(hPortKey);
- return Status;
-}
-
-static NTSTATUS
-MouseCreateDevice(IN PDRIVER_OBJECT DriverObject, IN PMOUSE_DRVR_EXTENSION DriverExtension)
-{
- UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Device\\PointerPortUSB");
- PMOUSE_DEVICE_EXTENSION DeviceExtension;
- PDEVICE_OBJECT Fdo;
- NTSTATUS Status;
-
- Status = AddRegistryEntry(L"PointerPort", &DeviceName, L"REGISTRY\\MACHINE\\SYSTEM\\CurrentControlSet\\Services\\usbdriver");
- if (!NT_SUCCESS(Status))
- {
- usb_dbg_print(DBGLVL_MINIMUM, ("AddRegistryEntry() for usb mouse driver failed with status 0x%08lx\n", Status));
- return Status;
- }
-
- Status = IoCreateDevice(DriverObject,
- sizeof(MOUSE_DEVICE_EXTENSION),
- &DeviceName,
- FILE_DEVICE_MOUSE,
- FILE_DEVICE_SECURE_OPEN,
- TRUE,
- &Fdo);
-
- if (!NT_SUCCESS(Status))
- {
- usb_dbg_print(DBGLVL_MINIMUM, ("IoCreateDevice() for usb mouse driver failed with status 0x%08lx\n", Status));
- return Status;
- }
- DeviceExtension = (PMOUSE_DEVICE_EXTENSION)Fdo->DeviceExtension;
- RtlZeroMemory(DeviceExtension, sizeof(MOUSE_DEVICE_EXTENSION));
-
- DeviceExtension->hdr.dispatch = MouseDispatch;
- DeviceExtension->DriverExtension = DriverExtension;
- DriverExtension->device_ext = DeviceExtension;
-
- DeviceExtension->Fdo = Fdo;
- Fdo->Flags &= ~DO_DEVICE_INITIALIZING;
- usb_dbg_print(DBGLVL_MEDIUM, ("Created mouse Fdo: %p\n", Fdo));
-
- return STATUS_SUCCESS;
-}
-
diff --git a/reactos/drivers/usb/nt4compat/usbdrv/mouse.h b/reactos/drivers/usb/nt4compat/usbdrv/mouse.h
deleted file mode 100644
index 7fa32bdf680..00000000000
--- a/reactos/drivers/usb/nt4compat/usbdrv/mouse.h
+++ /dev/null
@@ -1,31 +0,0 @@
-#ifndef __MOUSE_H__
-#define __MOUSE_H__
-
-#include "kbdmou.h"
-
-typedef struct _MOUSE_DRVR_EXTENSION
-{
- PUSB_INTERFACE_DESC pif_desc;
-
- PUSB_DEV_MANAGER dev_mgr;
- signed char mouse_data[8];
- UCHAR btn_old;
-
- struct _MOUSE_DEVICE_EXTENSION *device_ext; // back pointer
-} MOUSE_DRVR_EXTENSION, *PMOUSE_DRVR_EXTENSION;
-
-typedef struct _MOUSE_DEVICE_EXTENSION
-{
- DEVEXT_HEADER hdr; // mandatory header
- PMOUSE_DRVR_EXTENSION DriverExtension;
- CONNECT_DATA ConnectData;
- PDEVICE_OBJECT Fdo;
-} MOUSE_DEVICE_EXTENSION, *PMOUSE_DEVICE_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/usbdrv/ohci.c b/reactos/drivers/usb/nt4compat/usbdrv/ohci.c
deleted file mode 100644
index c4b2f213cd1..00000000000
--- a/reactos/drivers/usb/nt4compat/usbdrv/ohci.c
+++ /dev/null
@@ -1,1656 +0,0 @@
-/**
- * ohci.c - USB driver stack project
- *
- * Copyright (c) 2007 Aleksey Bragin
- * based on some code by Zhiming
- *
- * This program/include file is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program/include file is distributed in the hope that it will be
- * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
- * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program (in the main directory of the distribution, the file
- * COPYING); if not, write to the Free Software Foundation,Inc., 59 Temple
- * Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "usbdriver.h"
-#include "ehci.h"
-#include "ohci.h"
-
-PDEVICE_OBJECT ohci_alloc(PDRIVER_OBJECT drvr_obj, PUNICODE_STRING reg_path,
- ULONG bus_addr, PUSB_DEV_MANAGER dev_mgr);
-//BOOLEAN ohci_release(PDEVICE_OBJECT pdev);
-//static VOID ohci_stop(PEHCI_DEV ehci);
-PDEVICE_OBJECT ohci_probe(PDRIVER_OBJECT drvr_obj, PUNICODE_STRING reg_path,
- PUSB_DEV_MANAGER dev_mgr);
-PDEVICE_OBJECT ohci_create_device(PDRIVER_OBJECT drvr_obj, PUSB_DEV_MANAGER dev_mgr);
-//BOOLEAN ohci_delete_device(PDEVICE_OBJECT pdev);
-//VOID ohci_get_capabilities(PEHCI_DEV ehci, PBYTE base);
-//BOOLEAN NTAPI ohci_isr(PKINTERRUPT interrupt, PVOID context);
-//BOOLEAN ohci_start(PHCD hcd);
-VOID ohci_init_hcd_interface(POHCI_DEV ohci);
-BOOLEAN ohci_rh_reset_port(PHCD hcd, UCHAR port_idx);
-VOID ohci_generic_urb_completion(PURB purb, PVOID context);
-
-// shared with EHCI
-NTSTATUS ehci_dispatch_irp(IN PDEVICE_OBJECT DeviceObject, IN PIRP irp);
-PUSB_DEV_MANAGER ehci_get_dev_mgr(PHCD hcd);
-VOID ehci_set_dev_mgr(PHCD hcd, PUSB_DEV_MANAGER dev_mgr);
-VOID ehci_set_id(PHCD hcd, UCHAR id);
-UCHAR ehci_get_id(PHCD hcd);
-UCHAR ehci_alloc_addr(PHCD hcd);
-VOID ehci_free_addr(PHCD hcd, UCHAR addr);
-BOOLEAN NTAPI ehci_cal_cpu_freq(PVOID context);
-
-VOID rh_timer_svc_int_completion(PUSB_DEV pdev, PVOID context);
-VOID rh_timer_svc_reset_port_completion(PUSB_DEV pdev, PVOID context);
-
-extern USB_DEV_MANAGER g_dev_mgr;
-
-/* wrap-aware logic morphed from */
-#define tick_before(t1,t2) ((SHORT)(((SHORT)(t1))-((SHORT)(t2))) < 0)
-
-#define OHCI_READ_PORT_ULONG( pul ) ( *pul )
-#define OHCI_WRITE_PORT_ULONG( pul, src ) \
-{\
- *pul = ( ULONG )src;\
-}
-
-#define OHCI_READ_PORT_UCHAR( pch ) ( *pch )
-#define OHCI_WRITE_PORT_UCHAR( pch, src ) ( *pch = ( UCHAR )src )
-#define OHCI_READ_PORT_USHORT( psh ) ( *psh )
-#define OHCI_WRITE_PORT_USHORT( psh, src ) ( *psh = ( USHORT )src )
-
-/* AMD-756 (D2 rev) reports corrupt register contents in some cases.
- * The erratum (#4) description is incorrect. AMD's workaround waits
- * till some bits (mostly reserved) are clear; ok for all revs.
- */
-ULONG
-FORCEINLINE
-read_roothub(POHCI_DEV hc, PULONG reg, ULONG mask)
-{
- ULONG temp = OHCI_READ_PORT_ULONG(reg);
- if (temp == -1)
- /*disable (hc)*/;
- /*else if (hc->flags & OHCI_QUIRK_AMD756)
- while (temp & mask)
- temp = ohci_readl (hc, &hc->regs->roothub.register); */
- return temp;
-}
-
-static ULONG roothub_a (POHCI_DEV hc)
- { return read_roothub (hc, &hc->regs->roothub.a, 0xfc0fe000); }
-/*
-static inline u32 roothub_b (struct ohci_hcd *hc)
- { return ohci_readl (hc, &hc->regs->roothub.b); }
-static inline u32 roothub_status (struct ohci_hcd *hc)
- { return ohci_readl (hc, &hc->regs->roothub.status); }
-static u32 roothub_portstatus (struct ohci_hcd *hc, int i)
- { return read_roothub (hc, &hc->regs->roothub.portstatus [i], 0xffe0fce0); }
-*/
-
-
-/* For initializing controller (mask in an HCFS mode too) */
-#define OHCI_CONTROL_INIT OHCI_CTRL_CBSR
-#define OHCI_INTR_INIT \
- (OHCI_INTR_MIE | OHCI_INTR_UE | OHCI_INTR_RD | OHCI_INTR_WDH)
-
-/* See usb 7.1.7.5: root hubs must issue at least 50 msec reset signaling,
- * not necessarily continuous ... to guard against resume signaling.
- * The short timeout is safe for non-root hubs, and is backward-compatible
- * with earlier Linux hosts.
- */
-#ifdef CONFIG_USB_SUSPEND
-#define PORT_RESET_MSEC 50
-#else
-#define PORT_RESET_MSEC 10
-#endif
-
-/* this timer value might be vendor-specific ... */
-#define PORT_RESET_HW_MSEC 10
-
-#define DEFAULT_ENDP( enDP ) \
-( enDP->flags & USB_ENDP_FLAG_DEFAULT_ENDP )
-
-#define dev_from_endp( enDP ) \
-( DEFAULT_ENDP( enDP )\
- ? ( ( PUSB_DEV )( enDP )->pusb_if )\
- : ( ( enDP )->pusb_if->pusb_config->pusb_dev ) )
-
-#define endp_state( enDP ) ( ( enDP )->flags & USB_ENDP_FLAG_STAT_MASK )
-
-#define endp_num( enDP ) \
-( DEFAULT_ENDP( enDP )\
- ? 0 \
- : ( ( enDP )->pusb_endp_desc->bEndpointAddress & 0x0f ) )
-
-#define endp_dir( enDP ) \
-( DEFAULT_ENDP( enDP )\
- ? 0L\
- : ( ( enDP )->pusb_endp_desc->bEndpointAddress & USB_DIR_IN ) )
-
-#define dev_set_state( pdEV, staTE ) \
-( pdEV->flags = ( ( pdEV )->flags & ( ~USB_DEV_STATE_MASK ) ) | ( staTE ) )
-
-#define endp_max_packet_size( enDP ) \
-( DEFAULT_ENDP( enDP )\
- ? ( ( ( PUSB_DEV )enDP->pusb_if )->pusb_dev_desc ? \
- ( ( PUSB_DEV )enDP->pusb_if )->pusb_dev_desc->bMaxPacketSize0\
- : 8 )\
- : ( enDP->pusb_endp_desc->wMaxPacketSize & 0x7ff ) )
-
-#define endp_mult_count( endp ) ( ( ( endp->pusb_endp_desc->wMaxPacketSize & 0x1800 ) >> 11 ) + 1 )
-
-#define get_parent_hs_hub( pDEV, parent_HUB, port_IDX ) \
-{\
- parent_HUB = pDEV->parent_dev;\
- port_IDX = pdev->port_idx;\
- while( parent_HUB )\
- {\
- if( ( parent_HUB->flags & USB_DEV_CLASS_MASK ) != USB_DEV_CLASS_HUB )\
- {\
- parent_HUB = NULL;\
- break;\
- }\
- if( ( parent_HUB->flags & USB_DEV_FLAG_HIGH_SPEED ) == 0 )\
- {\
- port_IDX = parent_HUB->port_idx;\
- parent_HUB = parent_HUB->parent_dev;\
- continue;\
- }\
- break;\
- }\
-}
-
-VOID
-ohci_wait_ms(POHCI_DEV ohci, LONG ms)
-{
- LARGE_INTEGER lms;
- if (ms <= 0)
- return;
-
- lms.QuadPart = -10 * ms;
- KeSetTimer(&ohci->reset_timer, lms, NULL);
-
- KeWaitForSingleObject(&ohci->reset_timer, Executive, KernelMode, FALSE, NULL);
-
- return;
-}
-
-PDEVICE_OBJECT ohci_probe(PDRIVER_OBJECT drvr_obj, PUNICODE_STRING reg_path,
- PUSB_DEV_MANAGER dev_mgr)
-{
- LONG bus, i, j, ret = 0;
- PCI_SLOT_NUMBER slot_num;
- PPCI_COMMON_CONFIG pci_config;
- PDEVICE_OBJECT pdev;
- BYTE buffer[sizeof(PCI_COMMON_CONFIG)];
- POHCI_DEVICE_EXTENSION pdev_ext;
-
- slot_num.u.AsULONG = 0;
- pci_config = (PPCI_COMMON_CONFIG) buffer;
- pdev = NULL;
-
- //scan the bus to find ohci controller
- for(bus = 0; bus < 2; bus++) /*enum only bus0 and bus1 */
- {
- for(i = 0; i < PCI_MAX_DEVICES; i++)
- {
- slot_num.u.bits.DeviceNumber = i;
- for(j = 0; j < PCI_MAX_FUNCTIONS; j++)
- {
- slot_num.u.bits.FunctionNumber = j;
-
- ret = HalGetBusData(PCIConfiguration,
- bus, slot_num.u.AsULONG, pci_config, PCI_COMMON_HDR_LENGTH);
-
- /* Don't look further on this device */
- if ((ret == 0) || (ret == 2))
- break;
-
- if (pci_config->BaseClass == 0x0c && pci_config->SubClass == 0x03
- && pci_config->ProgIf == 0x10)
- {
- // we found our usb host controller( OHCI ), create device
- pdev = ohci_alloc(drvr_obj, reg_path, ((bus << 8) | (i << 3) | j), dev_mgr);
-
- if (!pdev)
- continue;
- }
- }
-
- if (ret == 0)
- break;
- }
- }
-
- if (pdev)
- {
- pdev_ext = pdev->DeviceExtension;
- if (pdev_ext)
- {
- // acquire higher irql to eliminate pre-empty
- //KeSynchronizeExecution(pdev_ext->ohci_int, ehci_cal_cpu_freq, NULL);
- }
- }
- return pdev;
-}
-
-BOOLEAN ohci_mem_init (POHCI_DEVICE_EXTENSION dev_ext)
-{
- dev_ext->ohci->td_cache = HalAllocateCommonBuffer(dev_ext->padapter,
- sizeof(OHCI_TD), &dev_ext->ohci->td_logic_addr, FALSE);
-
- if (!dev_ext->ohci->td_cache)
- return FALSE;
-
- dev_ext->ohci->ed_cache = HalAllocateCommonBuffer(dev_ext->padapter,
- sizeof(OHCI_ED), &dev_ext->ohci->ed_logic_addr, FALSE);
-
- if (!dev_ext->ohci->ed_cache)
- {
- HalFreeCommonBuffer(dev_ext->padapter, sizeof(OHCI_TD), dev_ext->ohci->td_logic_addr,
- dev_ext->ohci->td_cache, FALSE);
- return FALSE;
- }
-
- return TRUE;
-}
-
-
-PDEVICE_OBJECT
-ohci_alloc(PDRIVER_OBJECT drvr_obj, PUNICODE_STRING reg_path, ULONG bus_addr, PUSB_DEV_MANAGER dev_mgr)
-{
- LONG frd_num, prd_num;
- PDEVICE_OBJECT pdev = NULL;
- POHCI_DEVICE_EXTENSION pdev_ext;
- ULONG addr_space;
- //ULONG vector;
- LONG bus;
- //KIRQL irql;
- //KAFFINITY affinity;
-
- DEVICE_DESCRIPTION dev_desc;
- CM_PARTIAL_RESOURCE_DESCRIPTOR *pprd;
- PCI_SLOT_NUMBER slot_num;
- NTSTATUS status;
-
- pdev = ohci_create_device(drvr_obj, dev_mgr);
-
- if (pdev == NULL)
- return NULL;
-
- pdev_ext = pdev->DeviceExtension;
-
- pdev_ext->pci_addr = bus_addr;
- bus = (bus_addr >> 8);
-
- slot_num.u.AsULONG = 0;
- slot_num.u.bits.DeviceNumber = ((bus_addr & 0xff) >> 3);
- slot_num.u.bits.FunctionNumber = (bus_addr & 0x07);
-
- //now create adapter object
- RtlZeroMemory(&dev_desc, sizeof(dev_desc));
-
- dev_desc.Version = DEVICE_DESCRIPTION_VERSION;
- dev_desc.Master = TRUE;
- dev_desc.ScatterGather = TRUE;
- dev_desc.Dma32BitAddresses = TRUE;
- dev_desc.BusNumber = bus;
- dev_desc.InterfaceType = PCIBus;
- dev_desc.MaximumLength = EHCI_MAX_SIZE_TRANSFER;
- pdev_ext->map_regs = 2; // we do not use it seriously
- pdev_ext->padapter = HalGetAdapter(&dev_desc, &pdev_ext->map_regs);
-
- DbgPrint("ohci_alloc(): reg_path=0x%x, \n \
- ohci_alloc(): bus=0x%x, bus_addr=0x%x \n \
- ohci_alloc(): slot_num=0x%x \n \
- ", (DWORD) reg_path, (DWORD) bus, (DWORD) bus_addr, (DWORD) slot_num.u.AsULONG);
-
- //let's allocate resources for this device
- DbgPrint("ohci_alloc(): about to assign slot res\n");
- if ((status = HalAssignSlotResources(reg_path, NULL, //no class name yet
- drvr_obj, NULL, //no support of another ehci controller
- PCIBus,
- bus, slot_num.u.AsULONG, &pdev_ext->res_list)) != STATUS_SUCCESS)
- {
- DbgPrint("ohci_alloc(): error assign slot res, 0x%x\n", status);
-#if 0
- release_adapter(pdev_ext->padapter);
- pdev_ext->padapter = NULL;
- ohci_delete_device(pdev);
-#endif
- return NULL;
- }
-
- //parse the resource list
- for(frd_num = 0; frd_num < (LONG) pdev_ext->res_list->Count; frd_num++)
- {
- for(prd_num = 0; prd_num < (LONG) pdev_ext->res_list->List[frd_num].PartialResourceList.Count;
- prd_num++)
- {
- pprd = &pdev_ext->res_list->List[frd_num].PartialResourceList.PartialDescriptors[prd_num];
- if (pprd->Type == CmResourceTypePort)
- {
- RtlCopyMemory(&pdev_ext->res_port, &pprd->u.Port, sizeof(pprd->u.Port));
-
- }
- else if (pprd->Type == CmResourceTypeInterrupt)
- {
- RtlCopyMemory(&pdev_ext->res_interrupt, &pprd->u.Interrupt, sizeof(pprd->u.Interrupt));
- }
- else if (pprd->Type == CmResourceTypeMemory)
- {
- RtlCopyMemory(&pdev_ext->res_memory, &pprd->u.Memory, sizeof(pprd->u.Memory));
- }
- }
- }
-
- //for port, translate them to system address
- addr_space = 0;
- if (HalTranslateBusAddress(PCIBus, bus, pdev_ext->res_port.Start, &addr_space, //io space
- &pdev_ext->ohci->ohci_reg_base) != (BOOLEAN) TRUE)
- {
- DbgPrint("ohci_alloc(): error, can not translate bus address\n");
-#if 0
- release_adapter(pdev_ext->padapter);
- pdev_ext->padapter = NULL;
- ehci_delete_device(pdev);
-#endif
- return NULL;
- }
-
- DbgPrint("ohci_alloc(): address space=0x%x\n, reg_base=0x%x\n",
- addr_space, pdev_ext->ohci->ohci_reg_base.u.LowPart);
-
- if (addr_space == 0)
- {
- //port has been mapped to memory space
- pdev_ext->ohci->port_mapped = TRUE;
- pdev_ext->ohci->port_base = (PBYTE) MmMapIoSpace(pdev_ext->ohci->ohci_reg_base,
- pdev_ext->res_port.Length, FALSE);
-
- //fatal error can not map the registers
- if (pdev_ext->ohci->port_base == NULL)
- {
-#if 0
- release_adapter(pdev_ext->padapter);
- pdev_ext->padapter = NULL;
- ehci_delete_device(pdev);
-#endif
- return NULL;
- }
- }
- else
- {
- //io space
- pdev_ext->ohci->port_mapped = FALSE;
- pdev_ext->ohci->port_base = (PBYTE) pdev_ext->ohci->ohci_reg_base.LowPart;
- }
-
- //before we connect the interrupt, we have to init ohci
- pdev_ext->ohci->pdev_ext = pdev_ext;
- pdev_ext->ohci->regs = (POHCI_REGS)pdev_ext->ohci->port_base;
-
- KeInitializeTimer(&pdev_ext->ohci->reset_timer);
-
- // take it over from SMM/BIOS/whoever has it
- if (OHCI_READ_PORT_ULONG((PULONG)(pdev_ext->ohci->port_base + OHCI_CONTROL)) & OHCI_CTRL_IR)
- {
- ULONG temp;
-
- DbgPrint("USB HC TakeOver from BIOS/SMM\n");
-
- /* this timeout is arbitrary. we make it long, so systems
- * depending on usb keyboards may be usable even if the
- * BIOS/SMM code seems pretty broken.
- */
- temp = 500; /* arbitrary: five seconds */
-
- OHCI_WRITE_PORT_ULONG((PULONG)(pdev_ext->ohci->port_base + OHCI_INTRENABLE), OHCI_INTR_OC);
- OHCI_WRITE_PORT_ULONG((PULONG)(pdev_ext->ohci->port_base + OHCI_CMDSTATUS), OHCI_OCR);
-
- while (OHCI_READ_PORT_ULONG((PULONG)(pdev_ext->ohci->port_base + OHCI_CONTROL)) & OHCI_CTRL_IR)
- {
- ohci_wait_ms(pdev_ext->ohci, 10);
- if (--temp == 0) {
- DbgPrint("USB HC takeover failed!"
- " (BIOS/SMM bug)\n");
- return NULL;
- }
- }
- //ohci_usb_reset (ohci);
- }
-
- /* Disable HC interrupts */
- OHCI_WRITE_PORT_ULONG((PULONG)(pdev_ext->ohci->port_base + OHCI_INTRDISABLE), OHCI_INTR_MIE);
- // flush the writes
- (VOID)OHCI_READ_PORT_ULONG((PULONG)(pdev_ext->ohci->port_base + OHCI_CONTROL));
-
- /* Read the number of ports unless overridden */
- pdev_ext->ohci->num_ports = roothub_a(pdev_ext->ohci) & RH_A_NDP;
-
- DbgPrint("OHCI: %d ports\n", pdev_ext->ohci->num_ports);
-
- pdev_ext->ohci->hcca = HalAllocateCommonBuffer(pdev_ext->padapter,
- sizeof(*pdev_ext->ohci->hcca), &pdev_ext->ohci->hcca_logic_addr, FALSE);
-
- if (!pdev_ext->ohci->hcca)
- {
- DbgPrint("OHCI: HCCA allocation failed!\n");
- return NULL;
- }
-
- if (!ohci_mem_init(pdev_ext))
- {
- DbgPrint("OHCI: Mem init failed!\n");
- return NULL;
- }
-
-#if 0
- if (ehci_init_schedule(pdev_ext->ehci, pdev_ext->padapter) == FALSE)
- {
- release_adapter(pdev_ext->padapter);
- pdev_ext->padapter = NULL;
- ehci_delete_device(pdev);
- return NULL;
- }
-#endif
-
- InitializeListHead(&pdev_ext->ohci->urb_list);
- KeInitializeSpinLock(&pdev_ext->ohci->pending_endp_list_lock);
- InitializeListHead(&pdev_ext->ohci->pending_endp_list);
-
- ohci_dbg_print(DBGLVL_MAXIMUM, ("ohci_alloc(): pending_endp_list=0x%x\n",
- &pdev_ext->ohci->pending_endp_list));
-
- init_pending_endp_pool(&pdev_ext->ohci->pending_endp_pool);
-
-#if 0
- vector = HalGetInterruptVector(PCIBus,
- bus,
- pdev_ext->res_interrupt.level,
- pdev_ext->res_interrupt.vector, &irql, &affinity);
-
- KeInitializeDpc(&pdev_ext->ehci_dpc, ehci_dpc_callback, (PVOID) pdev_ext->ehci);
-
- //connect the interrupt
- DbgPrint("ehci_alloc(): the int=0x%x\n", vector);
- if ((status = IoConnectInterrupt(&pdev_ext->ehci_int, ehci_isr, pdev_ext->ehci, NULL, //&pdev_ext->ehci->frame_list_lock,
- vector, irql, irql, LevelSensitive, TRUE, //share the vector
- affinity, FALSE)) //No float save
- != STATUS_SUCCESS)
- {
- DbgPrint("ehci_alloc(): Failed to connect interrupt, status = 0x%x!\n", status);
- ehci_release(pdev);
- return NULL;
- }
-#endif
-
- return pdev;
-}
-
-PDEVICE_OBJECT
-ohci_create_device(PDRIVER_OBJECT drvr_obj, PUSB_DEV_MANAGER dev_mgr)
-{
- NTSTATUS status;
- PDEVICE_OBJECT pdev;
- POHCI_DEVICE_EXTENSION pdev_ext;
-
- UNICODE_STRING dev_name;
- UNICODE_STRING symb_name;
-
- STRING string, another_string;
- CHAR str_dev_name[64], str_symb_name[64];
- UCHAR hcd_id;
-
- if (drvr_obj == NULL)
- return NULL;
-
- //note: hcd count wont increment till the hcd is registered in dev_mgr
- sprintf(str_dev_name, "%s%d", OHCI_DEVICE_NAME, dev_mgr->hcd_count);
- sprintf(str_symb_name, "%s%d", OHCI_DOS_DEVICE_NAME, dev_mgr->hcd_count);
-
- RtlInitString(&string, str_dev_name);
- RtlAnsiStringToUnicodeString(&dev_name, &string, TRUE);
-
- pdev = NULL;
- status = IoCreateDevice(drvr_obj,
- sizeof(OHCI_DEVICE_EXTENSION) + sizeof(OHCI_DEV),
- &dev_name, FILE_OHCI_DEV_TYPE, 0, FALSE, &pdev);
-
- if (status != STATUS_SUCCESS || pdev == NULL)
- {
- RtlFreeUnicodeString(&dev_name);
- ehci_dbg_print(DBGLVL_MAXIMUM, ("ohci_create_device(): error create device 0x%x\n", status));
- return NULL;
- }
-
- pdev_ext = pdev->DeviceExtension;
- RtlZeroMemory(pdev_ext, sizeof(OHCI_DEVICE_EXTENSION) + sizeof(OHCI_DEV));
-
- pdev_ext->dev_ext_hdr.type = NTDEV_TYPE_HCD;
- pdev_ext->dev_ext_hdr.dispatch = ehci_dispatch_irp;
- pdev_ext->dev_ext_hdr.start_io = NULL; //we do not support startio
- pdev_ext->dev_ext_hdr.dev_mgr = dev_mgr;
-
- pdev_ext->pdev_obj = pdev;
- pdev_ext->pdrvr_obj = drvr_obj;
-
- pdev_ext->ohci = (POHCI_DEV) & (pdev_ext[1]);
-
- RtlInitString(&another_string, str_symb_name);
- RtlAnsiStringToUnicodeString(&symb_name, &another_string, TRUE);
- //RtlInitUnicodeString( &symb_name, DOS_DEVICE_NAME );
-
- IoCreateSymbolicLink(&symb_name, &dev_name);
-
- ehci_dbg_print(DBGLVL_MAXIMUM,
- ("ohci_create_device(): dev=0x%x\n, pdev_ext= 0x%x, ehci=0x%x, dev_mgr=0x%x\n", pdev,
- pdev_ext, pdev_ext->ohci, dev_mgr));
-
- RtlFreeUnicodeString(&dev_name);
- RtlFreeUnicodeString(&symb_name);
-
- //register with dev_mgr though it is not initilized
- ohci_init_hcd_interface(pdev_ext->ohci);
- hcd_id = dev_mgr_register_hcd(dev_mgr, &pdev_ext->ohci->hcd_interf);
-
- pdev_ext->ohci->hcd_interf.hcd_set_id(&pdev_ext->ohci->hcd_interf, hcd_id);
- pdev_ext->ohci->hcd_interf.hcd_set_dev_mgr(&pdev_ext->ohci->hcd_interf, dev_mgr);
-
- return pdev;
-}
-
-BOOLEAN
-ohci_start(PHCD hcd)
-{
- ULONG temp, mask;
- //PBYTE base;
- //PEHCI_USBCMD_CONTENT usbcmd;
- POHCI_DEV ohci;
- ULONG hc_control;
-
- if (hcd == NULL)
- return FALSE;
-
- ohci = struct_ptr(hcd, OHCI_DEV, hcd_interf);
-
- /* Reset USB nearly "by the book". RemoteWakeupConnected
- * saved if boot firmware (BIOS/SMM/...) told us it's connected
- * (for OHCI integrated on mainboard, it normally is)
- */
- hc_control = OHCI_READ_PORT_ULONG((PULONG)&ohci->regs->control);
- DbgPrint("OHCI: resetting from state %x, control = 0x%x\n",
- (hc_control & OHCI_CTRL_HCFS),
- hc_control);
-
- //if (hc_control & OHCI_CTRL_RWC
- // && !(ohci->flags & OHCI_QUIRK_AMD756))
- // ohci_to_hcd(ohci)->can_wakeup = 1;
-
- switch (hc_control & OHCI_CTRL_HCFS) {
- case OHCI_USB_OPER:
- temp = 0;
- break;
- case OHCI_USB_SUSPEND:
- case OHCI_USB_RESUME:
- hc_control &= OHCI_CTRL_RWC;
- hc_control |= OHCI_USB_RESUME;
- temp = 10 /* msec wait */;
- break;
- // case OHCI_USB_RESET:
- default:
- hc_control &= OHCI_CTRL_RWC;
- hc_control |= OHCI_USB_RESET;
- temp = 50 /* msec wait */;
- break;
- }
- OHCI_WRITE_PORT_ULONG((PULONG)&ohci->regs->control, hc_control);
-
- // flush the writes
- (VOID)OHCI_READ_PORT_ULONG((PULONG)&ohci->regs->control);
-
- ohci_wait_ms(ohci, temp);
- temp = roothub_a (ohci);
- if (!(temp & RH_A_NPS)) {
- /* power down each port */
- for (temp = 0; temp < ohci->num_ports; temp++)
- {
- OHCI_WRITE_PORT_ULONG((PULONG)&ohci->regs->roothub.portstatus [temp], RH_PS_LSDA);
- }
- }
- // flush those writes
- (VOID)OHCI_READ_PORT_ULONG((PULONG)&ohci->regs->control);
- RtlZeroMemory(ohci->hcca, sizeof(OHCI_HCCA));
-
- /* 2msec timelimit here means no irqs/preempt */
- //spin_lock_irq (&ohci->lock);
-
-//retry:
- /* HC Reset requires max 10 us delay */
- OHCI_WRITE_PORT_ULONG((PULONG)&ohci->regs->cmdstatus, OHCI_HCR);
- temp = 30; /* ... allow extra time */
- while ((OHCI_READ_PORT_ULONG ((PULONG)&ohci->regs->cmdstatus) & OHCI_HCR) != 0) {
- if (--temp == 0) {
- //spin_unlock_irq (&ohci->lock);
- //ohci_err (ohci, "USB HC reset timed out!\n");
- DbgPrint("OHCI: USB HC reset timed out!\n");
- return FALSE;
- }
- KeStallExecutionProcessor(1);
- }
-
- /* now we're in the SUSPEND state ... must go OPERATIONAL
- * within 2msec else HC enters RESUME
- *
- * ... but some hardware won't init fmInterval "by the book"
- * (SiS, OPTi ...), so reset again instead. SiS doesn't need
- * this if we write fmInterval after we're OPERATIONAL.
- * Unclear about ALi, ServerWorks, and others ... this could
- * easily be a longstanding bug in chip init on Linux.
- */
-#if 0
- if (ohci->flags & OHCI_QUIRK_INITRESET) {
- ohci_writel (ohci, ohci->hc_control, &ohci->regs->control);
- // flush those writes
- (void) ohci_readl (ohci, &ohci->regs->control);
- }
-#endif
- /* Tell the controller where the control and bulk lists are
- * The lists are empty now. */
- OHCI_WRITE_PORT_ULONG((PULONG)&ohci->regs->ed_controlhead, 0);
- OHCI_WRITE_PORT_ULONG((PULONG)&ohci->regs->ed_bulkhead, 0);
-
- /* a reset clears this */
- OHCI_WRITE_PORT_ULONG((PULONG)&ohci->regs->hcca, (ULONG)ohci->hcca_logic_addr.LowPart);
-
- //periodic_reinit (ohci);
-
- /* start controller operations */
- hc_control &= OHCI_CTRL_RWC;
- hc_control |= OHCI_CONTROL_INIT | OHCI_USB_OPER;
- OHCI_WRITE_PORT_ULONG((PULONG)&ohci->regs->control, hc_control);
- //ohci_to_hcd(ohci)->state = HC_STATE_RUNNING;
-
- /* wake on ConnectStatusChange, matching external hubs */
- OHCI_WRITE_PORT_ULONG((PULONG)&ohci->regs->roothub.status, RH_HS_DRWE);
-
- /* Choose the interrupts we care about now, others later on demand */
- mask = OHCI_INTR_INIT;
- //OHCI_WRITE_PORT_ULONG((PULONG)&ohci->regs->intrstatus, mask);
- //OHCI_WRITE_PORT_ULONG((PULONG)&ohci->regs->intrenable, mask);
-
- /* handle root hub init quirks ... */
- temp = roothub_a(ohci);
- temp &= ~(RH_A_PSM | RH_A_OCPM);
- OHCI_WRITE_PORT_ULONG((PULONG)&ohci->regs->roothub.status, RH_HS_LPSC);
- OHCI_WRITE_PORT_ULONG((PULONG)&ohci->regs->roothub.b, (temp & RH_A_NPS) ? 0 : RH_B_PPCM);
- // flush those writes
- (VOID)OHCI_READ_PORT_ULONG((PULONG)&ohci->regs->control);
-
- //spin_unlock_irq (&ohci->lock);
-
- // POTPGT delay is bits 24-31, in 2 ms units.
- ohci_wait_ms(ohci, (temp >> 23) & 0x1fe);
- //ohci_to_hcd(ohci)->state = HC_STATE_RUNNING;
-
-
- // Debug code follows!
- /*(VOID)ohci_rh_reset_port(hcd, 1);
- (VOID)ohci_rh_reset_port(hcd, 2);
- (VOID)ohci_rh_reset_port(hcd, 3);
- (VOID)ohci_rh_reset_port(hcd, 4);*/
- // Debug code ends!
-
-
- return TRUE;
-}
-
-static VOID NTAPI
-ohci_cancel_pending_endp_urb(IN PVOID Parameter)
-{
- PLIST_ENTRY abort_list;
- PUSB_DEV pdev;
- PURB purb;
- USE_BASIC_NON_PENDING_IRQL;
-
- abort_list = (PLIST_ENTRY) Parameter;
-
- if (abort_list == NULL)
- return;
-
- while (IsListEmpty(abort_list) == FALSE)
- {
- //these devs are protected by purb's ref-count
- purb = (PURB) RemoveHeadList(abort_list);
- pdev = purb->pdev;
- // purb->status is set when they are added to abort_list
-
- ohci_generic_urb_completion(purb, purb->context);
-
- lock_dev(pdev, FALSE);
- pdev->ref_count--;
- unlock_dev(pdev, FALSE);
- }
- usb_free_mem(abort_list);
- return;
-}
-
-static NTSTATUS
-ohci_internal_submit_bulk(POHCI_DEV ohci, PURB purb)
-{
- return STATUS_SUCCESS;
-}
-
-static NTSTATUS
-ohci_internal_submit_ctrl(POHCI_DEV ohci, PURB purb)
-{
- return STATUS_SUCCESS;
-}
-
-static NTSTATUS
-ohci_internal_submit_int(POHCI_DEV ohci, PURB purb)
-{
- return STATUS_SUCCESS;
-}
-
-static NTSTATUS
-ohci_internal_submit_iso(POHCI_DEV ohci, PURB purb)
-{
- return STATUS_SUCCESS;
-}
-
-
-static BOOLEAN
-ohci_process_pending_endp(POHCI_DEV ehci)
-{
- PUSB_DEV pdev;
- LIST_ENTRY temp_list, abort_list;
- PLIST_ENTRY pthis;
- PURB purb;
- PUSB_ENDPOINT pendp;
- NTSTATUS can_submit = STATUS_SUCCESS;
- PWORK_QUEUE_ITEM pwork_item;
- PLIST_ENTRY cancel_list;
- PUSB_DEV pparent = NULL;
- UCHAR port_idx = 0;
- BOOLEAN tt_needed;
- UCHAR hub_addr = 0;
- USE_BASIC_IRQL;
-
- if (ehci == NULL)
- return FALSE;
-
- InitializeListHead(&temp_list);
- InitializeListHead(&abort_list);
-
- purb = NULL;
- ohci_dbg_print(DBGLVL_MEDIUM, ("ohci_process_pending_endp(): entering..., ehci=0x%x\n", ehci));
-
- lock_pending_endp_list(&ehci->pending_endp_list_lock);
- while (IsListEmpty(&ehci->pending_endp_list) == FALSE)
- {
-
- ehci_dbg_print(DBGLVL_MAXIMUM, ("ohci_process_pending_endp(): pending_endp_list=0x%x\n",
- &ehci->pending_endp_list));
-
- tt_needed = FALSE;
- pthis = RemoveHeadList(&ehci->pending_endp_list);
- pendp = ((PUHCI_PENDING_ENDP) pthis)->pendp;
- pdev = dev_from_endp(pendp);
- lock_dev(pdev, TRUE);
-
- if (dev_state(pdev) == USB_DEV_STATE_ZOMB)
- {
- unlock_dev(pdev, TRUE);
- free_pending_endp(&ehci->pending_endp_pool, struct_ptr(pthis, UHCI_PENDING_ENDP, endp_link));
- //delegate to ehci_remove_device for remiving the purb queue on the endpoint
- continue;
- }
- if ((pdev->flags & USB_DEV_FLAG_HIGH_SPEED) == 0)
- {
- // prepare split transaction
- unlock_dev(pdev, TRUE);
-
- // pparent won't be removed when pending_endp_list_lock is acquired.
- get_parent_hs_hub(pdev, pparent, port_idx);
-
- if (pparent == NULL)
- {
- TRAP();
- ehci_dbg_print(DBGLVL_MEDIUM,
- ("ohci_process_pending_endp(): full/low speed device with no parent!!!\n"));
- free_pending_endp(&ehci->pending_endp_pool, struct_ptr(pthis, UHCI_PENDING_ENDP, endp_link));
- continue;
- }
-
- if (hub_lock_tt(pparent, port_idx, (UCHAR) endp_type(pendp)) == FALSE)
- {
- lock_dev(pdev, TRUE);
- if (dev_state(pdev) != USB_DEV_STATE_ZOMB)
- {
- // reinsert the pending-endp to the list
- InsertTailList(&temp_list, pthis);
- unlock_dev(pdev, TRUE);
- }
- else
- {
- // delegate to ehci_remove_device for purb removal
- unlock_dev(pdev, TRUE);
- free_pending_endp(&ehci->pending_endp_pool,
- struct_ptr(pthis, UHCI_PENDING_ENDP, endp_link));
- }
- continue;
- }
-
- // backup the hub address for future use
- hub_addr = pparent->dev_addr;
-
- lock_dev(pdev, TRUE);
- if (dev_state(pdev) == USB_DEV_STATE_ZOMB)
- {
- unlock_dev(pdev, TRUE);
- free_pending_endp(&ehci->pending_endp_pool, struct_ptr(pthis, UHCI_PENDING_ENDP, endp_link));
- hub_unlock_tt(pparent, port_idx, (UCHAR) endp_type(pendp));
- continue;
- }
- tt_needed = TRUE;
- // go on processing
- }
-
- if (endp_state(pendp) == USB_ENDP_FLAG_STALL)
- {
- while (IsListEmpty(&pendp->urb_list) == FALSE)
- {
- purb = (PURB) RemoveHeadList(&pendp->urb_list);
- purb->status = USB_STATUS_ENDPOINT_HALTED;
- InsertTailList(&abort_list, (LIST_ENTRY *) purb);
- }
- InitializeListHead(&pendp->urb_list);
- unlock_dev(pdev, TRUE);
- free_pending_endp(&ehci->pending_endp_pool, struct_ptr(pthis, UHCI_PENDING_ENDP, endp_link));
- if (tt_needed)
- hub_unlock_tt(pparent, port_idx, (UCHAR) endp_type(pendp));
- continue;
- }
-
- if (IsListEmpty(&pendp->urb_list) == FALSE)
- {
- purb = (PURB) RemoveHeadList(&pendp->urb_list);
- ASSERT(purb);
- }
- else
- {
- InitializeListHead(&pendp->urb_list);
- unlock_dev(pdev, TRUE);
- free_pending_endp(&ehci->pending_endp_pool, struct_ptr(pthis, UHCI_PENDING_ENDP, endp_link));
- if (tt_needed)
- hub_unlock_tt(pparent, port_idx, (UCHAR) endp_type(pendp));
- continue;
- }
-
- if (tt_needed)
- {
- ((PURB_HS_CONTEXT_CONTENT) & purb->hs_context)->hub_addr = hub_addr;
- ((PURB_HS_CONTEXT_CONTENT) & purb->hs_context)->port_idx = port_idx;
- }
-
- // if can_submit is STATUS_SUCCESS, the purb is inserted into the schedule
- switch (endp_type(pendp))
- {
- case USB_ENDPOINT_XFER_BULK:
- {
- can_submit = ohci_internal_submit_bulk(ehci, purb);
- break;
- }
- case USB_ENDPOINT_XFER_CONTROL:
- {
- can_submit = ohci_internal_submit_ctrl(ehci, purb);
- break;
- }
- case USB_ENDPOINT_XFER_INT:
- {
- can_submit = ohci_internal_submit_int(ehci, purb);
- break;
- }
- case USB_ENDPOINT_XFER_ISOC:
- {
- can_submit = ohci_internal_submit_iso(ehci, purb);
- break;
- }
- }
-
- if (can_submit == STATUS_NO_MORE_ENTRIES)
- {
- //no enough bandwidth or tds
- InsertHeadList(&pendp->urb_list, &purb->urb_link);
- InsertTailList(&temp_list, pthis);
- }
- else
- {
- // otherwise error or success
- free_pending_endp(&ehci->pending_endp_pool, struct_ptr(pthis, UHCI_PENDING_ENDP, endp_link));
-
- if (can_submit != STATUS_SUCCESS)
- {
- //abort these URBs
- InsertTailList(&abort_list, (LIST_ENTRY *) purb);
- purb->status = can_submit;
- }
- }
- unlock_dev(pdev, TRUE);
- if (can_submit != STATUS_SUCCESS && tt_needed)
- {
- hub_unlock_tt(pparent, port_idx, (UCHAR) endp_type(pendp));
- }
- }
-
- if (IsListEmpty(&temp_list) == FALSE)
- {
- //re-append them to the pending_endp_list
- ListFirst(&temp_list, pthis);
- RemoveEntryList(&temp_list);
- MergeList(&ehci->pending_endp_list, pthis);
- }
- unlock_pending_endp_list(&ehci->pending_endp_list_lock);
-
- if (IsListEmpty(&abort_list) == FALSE)
- {
- PLIST_ENTRY pthis;
- cancel_list = (PLIST_ENTRY) usb_alloc_mem(NonPagedPool, sizeof(WORK_QUEUE_ITEM) + sizeof(LIST_ENTRY));
- ASSERT(cancel_list);
-
- ListFirst(&abort_list, pthis);
- RemoveEntryList(&abort_list);
- InsertTailList(pthis, cancel_list);
-
- pwork_item = (PWORK_QUEUE_ITEM) & cancel_list[1];
-
- // we do not need to worry the ehci_cancel_pending_endp_urb running when the
- // driver is unloading since purb-reference count will prevent the dev_mgr to
- // quit till all the reference count to the dev drop to zero.
- ExInitializeWorkItem(pwork_item, ohci_cancel_pending_endp_urb, (PVOID) cancel_list);
- ExQueueWorkItem(pwork_item, DelayedWorkQueue);
- }
- return TRUE;
-}
-
-NTSTATUS
-ohci_rh_submit_urb(PUSB_DEV pdev, PURB purb)
-{
- PUSB_DEV_MANAGER dev_mgr;
- PTIMER_SVC ptimer;
- PUSB_CTRL_SETUP_PACKET psetup;
- POHCI_DEV ohci;
- NTSTATUS status;
- PHUB2_EXTENSION hub_ext;
- PUSB_PORT_STATUS ps, psret;
- UCHAR port_count;
- ULONG i;
-
- USE_NON_PENDING_IRQL;
- if (pdev == NULL || purb == NULL)
- return STATUS_INVALID_PARAMETER;
-
- dev_mgr = dev_mgr_from_dev(pdev);
-
- KeAcquireSpinLock(&dev_mgr->timer_svc_list_lock, &old_irql);
- lock_dev(pdev, FALSE);
- if (dev_state(pdev) == USB_DEV_STATE_ZOMB)
- {
- unlock_dev(pdev, FALSE);
- KeReleaseSpinLock(&dev_mgr->timer_svc_list_lock, old_irql);
- return STATUS_DEVICE_DOES_NOT_EXIST;
- }
-
- ohci = ohci_from_hcd(pdev->hcd);
- psetup = (PUSB_CTRL_SETUP_PACKET) purb->setup_packet;
-
- hub_ext = ((PHUB2_EXTENSION) pdev->dev_ext);
- port_count = ohci->num_ports;
-
- switch (endp_type(purb->pendp))
- {
- case USB_ENDPOINT_XFER_CONTROL:
- {
- if (psetup->bmRequestType == 0xa3 && psetup->bRequest == USB_REQ_GET_STATUS)
- {
- //get-port-status
- if (psetup->wIndex == 0 || psetup->wIndex > port_count || psetup->wLength < 4)
- {
- purb->status = STATUS_INVALID_PARAMETER;
- break;
- }
-
- ps = &hub_ext->rh_port_status[psetup->wIndex];
- psret = (PUSB_PORT_STATUS) purb->data_buffer;
-
- status =
- OHCI_READ_PORT_ULONG((PULONG)&ohci->regs->roothub.portstatus[psetup->wIndex-1]);
-
- ps->wPortStatus = 0;
-
- if (status & RH_PS_CCS)
- {
- ps->wPortStatus |= USB_PORT_STAT_CONNECTION;
- }
- if (status & RH_PS_PES)
- {
- ps->wPortStatus |= USB_PORT_STAT_ENABLE;
- //ps->wPortStatus |= USB_PORT_STAT_HIGH_SPEED; // ehci spec
- }
- if (status & RH_PS_PRS)
- {
- ps->wPortStatus |= USB_PORT_STAT_RESET;
- }
- if (status & RH_PS_PSS)
- {
- ps->wPortStatus |= USB_PORT_STAT_SUSPEND;
- }
- if (status & RH_PS_LSDA)
- {
- ps->wPortStatus |= USB_PORT_STAT_LOW_SPEED;
- }
-
- //always power on
- ps->wPortStatus |= USB_PORT_STAT_POWER;
-
- //now set change field
- if ((status & RH_PS_CSC) && !(ps->wPortStatus & USB_PORT_STAT_LOW_SPEED))
- {
- ps->wPortChange |= USB_PORT_STAT_C_CONNECTION;
- }
- if ((status & RH_PS_PESC) && !(ps->wPortStatus & USB_PORT_STAT_LOW_SPEED))
- {
- ps->wPortChange |= USB_PORT_STAT_C_ENABLE;
- }
-
- //don't touch other fields, might be filled by
- //other function
-
- usb_dbg_print(DBGLVL_MAXIMUM,
- ("ohci_rh_submit_urb(): get port status, wPortStatus=0x%x, wPortChange=0x%x, address=0x%x\n",
- ps->wPortStatus, ps->wPortChange, ps));
-
- psret->wPortChange = ps->wPortChange;
- psret->wPortStatus = ps->wPortStatus;
-
- purb->status = STATUS_SUCCESS;
-
- break;
- }
- else if (psetup->bmRequestType == 0x23 && psetup->bRequest == USB_REQ_CLEAR_FEATURE)
- {
- //clear-port-feature
- if (psetup->wIndex == 0 || psetup->wIndex > port_count)
- {
- purb->status = STATUS_INVALID_PARAMETER;
- break;
- }
-
- i = psetup->wIndex - 1;
- ps = &hub_ext->rh_port_status[psetup->wIndex];
-
- purb->status = STATUS_SUCCESS;
- switch (psetup->wValue)
- {
- case USB_PORT_FEAT_C_CONNECTION:
- {
- OHCI_WRITE_PORT_ULONG((PULONG)&ohci->regs->roothub.portstatus[i], RH_PS_CSC);
- status = OHCI_READ_PORT_ULONG((PULONG)&ohci->regs->roothub.portstatus[i]);
- usb_dbg_print(DBGLVL_MAXIMUM,
- ("ohci_rh_submit_urb(): clear csc, port%d=0x%x\n", psetup->wIndex, status));
- ps->wPortChange &= ~USB_PORT_STAT_C_CONNECTION;
- break;
- }
- case USB_PORT_FEAT_C_ENABLE:
- {
- OHCI_WRITE_PORT_ULONG((PULONG)&ohci->regs->roothub.portstatus[i], RH_PS_PESC);
- status = OHCI_READ_PORT_ULONG((PULONG)&ohci->regs->roothub.portstatus[i]);
- usb_dbg_print(DBGLVL_MAXIMUM,
- ("ohci_rh_submit_urb(): clear pec, port%d=0x%x\n", psetup->wIndex, status));
- ps->wPortChange &= ~USB_PORT_STAT_C_ENABLE;
- break;
- }
- case USB_PORT_FEAT_C_RESET:
- {
- ps->wPortChange &= ~USB_PORT_STAT_C_RESET;
- //the reset signal is down in rh_timer_svc_reset_port_completion
- // enable or not is set by host controller
- // status = EHCI_READ_PORT_ULONG( ( PUSHORT ) ( ehci->port_base + i ) );
- usb_dbg_print(DBGLVL_MAXIMUM,
- ("ohci_rh_submit_urb(): clear pr, enable pe, port%d=0x%x\n",
- psetup->wIndex, 0));
- break;
- }
- case USB_PORT_FEAT_ENABLE:
- {
- ps->wPortStatus &= ~USB_PORT_STAT_ENABLE;
- OHCI_WRITE_PORT_ULONG((PULONG)&ohci->regs->roothub.portstatus[i], RH_PS_PES);
- status = OHCI_READ_PORT_ULONG((PULONG)&ohci->regs->roothub.portstatus[i]);
- usb_dbg_print(DBGLVL_MAXIMUM,
- ("ohci_rh_submit_urb(): clear pe, port%d=0x%x\n", psetup->wIndex, status));
- break;
- }
- default:
- purb->status = STATUS_UNSUCCESSFUL;
- }
-
- break;
- }
- else if (psetup->bmRequestType == 0xd3 && psetup->bRequest == HUB_REQ_GET_STATE)
- {
- // get bus state
- if (psetup->wIndex == 0 || psetup->wIndex > port_count || psetup->wLength == 0)
- {
- purb->status = STATUS_INVALID_PARAMETER;
- break;
- }
-#if 0
- i = EHCI_PORTSC + 4 * (psetup->wIndex - 1); // USBPORTSC1;
- status = EHCI_READ_PORT_ULONG((PULONG) (ehci->port_base + i));
- purb->data_buffer[0] = (status & USBPORTSC_LS);
-
- // reverse the order
- purb->data_buffer[0] ^= 0x3;
-#endif
- purb->status = STATUS_SUCCESS;
- break;
- }
- else if (psetup->bmRequestType == 0x23 && psetup->bRequest == USB_REQ_SET_FEATURE)
- {
- //reset port
- if (psetup->wValue != USB_PORT_FEAT_RESET)
- {
- purb->status = STATUS_INVALID_PARAMETER;
- ehci_dbg_print(DBGLVL_MAXIMUM,
- ("ohci_rh_submit_urb(): set feature with wValue=0x%x\n", psetup->wValue));
- break;
- }
-
- ptimer = alloc_timer_svc(&dev_mgr->timer_svc_pool, 1);
- if (!ptimer)
- {
- purb->status = STATUS_NO_MEMORY;
- break;
- }
-
- ptimer->threshold = 0; // within [ 50ms, 60ms ], one tick is 10 ms
- ptimer->context = (ULONG) purb;
- ptimer->pdev = pdev;
- ptimer->func = rh_timer_svc_reset_port_completion;
-
- //start the timer
- pdev->ref_count += 2; //one for timer and one for purb
-
- status =
- OHCI_READ_PORT_ULONG((PULONG)&ohci->regs->roothub.portstatus[psetup->wIndex-1]);
-
- usb_dbg_print(DBGLVL_MAXIMUM,
- ("ohci_rh_submit_urb(): reset port, port%d=0x%x\n", psetup->wIndex, status));
- InsertTailList(&dev_mgr->timer_svc_list, &ptimer->timer_svc_link);
- purb->status = STATUS_PENDING;
- }
- else
- {
- purb->status = STATUS_INVALID_PARAMETER;
- }
- break;
- }
- case USB_ENDPOINT_XFER_INT:
- {
- ptimer = alloc_timer_svc(&dev_mgr->timer_svc_pool, 1);
- if (!ptimer)
- {
- purb->status = STATUS_NO_MEMORY;
- break;
- }
-
- ptimer->threshold = RH_INTERVAL;
- ptimer->context = (ULONG) purb;
- ptimer->pdev = pdev;
- ptimer->func = rh_timer_svc_int_completion;
-
- //start the timer
- InsertTailList(&dev_mgr->timer_svc_list, &ptimer->timer_svc_link);
-
- //usb_dbg_print(DBGLVL_MAXIMUM,
- // ("ehci_rh_submit_urb(): current rh's ref_count=0x%x\n", pdev->ref_count));
- pdev->ref_count += 2; //one for timer and one for purb
-
- purb->status = STATUS_PENDING;
- break;
- }
- case USB_ENDPOINT_XFER_BULK:
- case USB_ENDPOINT_XFER_ISOC:
- default:
- {
- purb->status = STATUS_INVALID_PARAMETER;
- break;
- }
- }
- unlock_dev(pdev, FALSE);
- KeReleaseSpinLock(&dev_mgr->timer_svc_list_lock, old_irql);
- return purb->status;
-}
-
-NTSTATUS
-ohci_submit_urb(POHCI_DEV ehci, PUSB_DEV pdev, PUSB_ENDPOINT pendp, PURB purb)
-{
- int i;
- PUHCI_PENDING_ENDP pending_endp;
- NTSTATUS status;
- USE_BASIC_IRQL;
-
- if (ehci == NULL)
- return STATUS_INVALID_PARAMETER;
-
- if (pdev == NULL || pendp == NULL || purb == NULL)
- {
- // give a chance to those pending urb, especially for clearing hub tt
- ohci_process_pending_endp(ehci);
- return STATUS_INVALID_PARAMETER;
- }
-
- lock_pending_endp_list(&ehci->pending_endp_list_lock);
- lock_dev(pdev, TRUE);
-
- if (dev_state(pdev) == USB_DEV_STATE_ZOMB)
- {
- status = purb->status = STATUS_DEVICE_DOES_NOT_EXIST;
- goto LBL_OUT;
- }
-
- if (dev_class(pdev) == USB_DEV_CLASS_ROOT_HUB)
- {
- unlock_dev(pdev, TRUE);
- unlock_pending_endp_list(&ehci->pending_endp_list_lock);
- status = ohci_rh_submit_urb(pdev, purb);
- return status;
- }
-
- if (pendp)
- purb->pendp = pendp;
- else
- purb->pendp = &pdev->default_endp;
-
- if (dev_from_endp(purb->pendp) != pdev)
- {
- status = purb->status = STATUS_INVALID_PARAMETER;
- goto LBL_OUT;
- }
-
- if (endp_state(purb->pendp) == USB_ENDP_FLAG_STALL)
- {
- status = purb->status = USB_STATUS_ENDPOINT_HALTED;
- goto LBL_OUT;
- }
-
- if ((pdev->flags & USB_DEV_FLAG_HIGH_SPEED) == 0)
- {
- // wait one ms
- usb_wait_ms_dpc(1);
- }
-
- purb->pdev = pdev;
- purb->rest_bytes = purb->data_length;
-
- if (endp_type(purb->pendp) == USB_ENDPOINT_XFER_BULK)
- purb->bytes_to_transfer = (purb->data_length > EHCI_MAX_SIZE_TRANSFER ? EHCI_MAX_SIZE_TRANSFER : purb->data_length); //multiple transfer for large data block
- else
- purb->bytes_to_transfer = purb->data_length;
-
- ehci_dbg_print(DBGLVL_MEDIUM, ("ohci_submit_urb(): bytes_to_transfer=0x%x\n", purb->bytes_to_transfer));
-
- purb->bytes_transfered = 0;
- InitializeListHead(&purb->trasac_list);
- purb->last_finished_td = &purb->trasac_list;
- purb->flags &= ~(URB_FLAG_STATE_MASK | URB_FLAG_IN_SCHEDULE | URB_FLAG_FORCE_CANCEL);
- purb->flags |= URB_FLAG_STATE_PENDING;
-
-
- i = IsListEmpty(&pendp->urb_list);
- InsertTailList(&pendp->urb_list, &purb->urb_link);
-
- pdev->ref_count++; //for purb reference
-
- if (i == FALSE)
- {
- //there is purb pending, simply queue it and return
- status = purb->status = STATUS_PENDING;
- goto LBL_OUT;
- }
- else if (usb_endp_busy_count(purb->pendp) && endp_type(purb->pendp) != USB_ENDPOINT_XFER_ISOC)
- {
- //
- //No purb waiting but purb overlap not allowed,
- //so leave it in queue and return, will be scheduled
- //later
- //
- status = purb->status = STATUS_PENDING;
- goto LBL_OUT;
- }
-
- pending_endp = alloc_pending_endp(&ehci->pending_endp_pool, 1);
- if (pending_endp == NULL)
- {
- //panic
- status = purb->status = STATUS_UNSUCCESSFUL;
- goto LBL_OUT2;
- }
-
- pending_endp->pendp = purb->pendp;
- InsertTailList(&ehci->pending_endp_list, &pending_endp->endp_link);
-
- unlock_dev(pdev, TRUE);
- unlock_pending_endp_list(&ehci->pending_endp_list_lock);
-
- ohci_process_pending_endp(ehci);
- return STATUS_PENDING;
-
- LBL_OUT2:
- pdev->ref_count--;
- RemoveEntryList(&purb->urb_link);
-
- LBL_OUT:
- unlock_dev(pdev, TRUE);
- unlock_pending_endp_list(&ehci->pending_endp_list_lock);
- ohci_process_pending_endp(ehci);
- return status;
-}
-
-ULONG
-ohci_get_type(PHCD hcd)
-{
- return HCD_TYPE_OHCI; // ( hcd->flags & HCD_TYPE_MASK );
-}
-
-NTSTATUS
-ohci_submit_urb2(PHCD hcd, PUSB_DEV pdev, PUSB_ENDPOINT pendp, PURB purb)
-{
- return ohci_submit_urb(ohci_from_hcd(hcd), pdev, pendp, purb);
-}
-
-PUSB_DEV
-ohci_get_root_hub(PHCD hcd)
-{
- return ohci_from_hcd(hcd)->root_hub;
-}
-
-VOID
-ohci_set_root_hub(PHCD hcd, PUSB_DEV root_hub)
-{
- if (hcd == NULL || root_hub == NULL)
- return;
- ohci_from_hcd(hcd)->root_hub = root_hub;
- return;
-}
-
-BOOLEAN
-ohci_remove_device2(PHCD hcd, PUSB_DEV pdev)
-{
- if (hcd == NULL || pdev == NULL)
- return FALSE;
-
- return FALSE;
- //return ehci_remove_device(ehci_from_hcd(hcd), pdev);
-}
-
-BOOLEAN
-ohci_hcd_release(PHCD hcd)
-{
- POHCI_DEV ohci;
- POHCI_DEVICE_EXTENSION pdev_ext;
-
- if (hcd == NULL)
- return FALSE;
-
- ohci = ohci_from_hcd(hcd);
- pdev_ext = ohci->pdev_ext;
- return FALSE;//ehci_release(pdev_ext->pdev_obj);
-}
-
-NTSTATUS
-ohci_cancel_urb2(PHCD hcd, PUSB_DEV pdev, PUSB_ENDPOINT pendp, PURB purb)
-{
- POHCI_DEV ohci;
- if (hcd == NULL)
- return STATUS_INVALID_PARAMETER;
-
- ohci = ohci_from_hcd(hcd);
- DbgPrint("ohci_cancel_urb2 called, but not implemented!\n");
- return STATUS_UNSUCCESSFUL;//ehci_cancel_urb(ehci, pdev, pendp, purb);
-}
-
-VOID
-ohci_generic_urb_completion(PURB purb, PVOID context)
-{
- PUSB_DEV pdev;
- BOOLEAN is_ctrl = FALSE;
- USE_NON_PENDING_IRQL;
-
- old_irql = KeGetCurrentIrql();
- if (old_irql > DISPATCH_LEVEL)
- TRAP();
-
- if (old_irql < DISPATCH_LEVEL)
- KeRaiseIrql(DISPATCH_LEVEL, &old_irql);
-
- if (purb == NULL)
- goto LBL_LOWER_IRQL;
-
- pdev = purb->pdev;
-
- if (pdev == NULL)
- goto LBL_LOWER_IRQL;
-
- lock_dev(pdev, TRUE);
-
- if (dev_state(pdev) == USB_DEV_STATE_ZOMB)
- {
- // no need to do following statistics
- unlock_dev(pdev, TRUE);
- goto LBL_CLIENT_PROCESS;
- }
- if (usb_error(purb->status))
- {
- pdev->error_count++;
- }
-
- if (purb->pendp == &pdev->default_endp)
- {
- if (usb_halted(purb->status))
- {
- pdev->time_out_count++;
- if (pdev->time_out_count > 3)
- {
- dev_set_state(pdev, USB_DEV_STATE_ZOMB);
- ohci_dbg_print(DBGLVL_MAXIMUM,
- ("ohci_generic_urb_completion(): contiguous error 3 times, dev 0x%x is deactivated\n",
- pdev));
- }
- }
- else
- pdev->time_out_count = 0;
-
- }
-
- if (endp_type(purb->pendp) == USB_ENDPOINT_XFER_CONTROL)
- is_ctrl = TRUE;
-
- unlock_dev(pdev, TRUE);
-
- LBL_CLIENT_PROCESS:
- if (!is_ctrl)
- {
- if (purb->completion)
- purb->completion(purb, context);
- }
- else
- {
- if (purb->ctrl_req_context.ctrl_stack_count == 0)
- {
- if (purb->completion)
- purb->completion(purb, context);
- }
- else
- {
- // pstack = &purb->ctrl_req_stack[ purb->ctrl_req_context.ctrl_cur_stack ];
- // if( pstack->urb_completion )
- // pstack->urb_completion( purb, pstack->context );
- usb_call_ctrl_completion(purb);
- }
- }
-
- LBL_LOWER_IRQL:
- if (old_irql < DISPATCH_LEVEL)
- KeLowerIrql(old_irql);
-
- return;
-}
-
-BOOLEAN
-ohci_rh_reset_port(PHCD hcd, UCHAR port_idx)
-{
- POHCI_DEV ohci;
- ULONG status, temp;
- PULONG PortStatus;
- USHORT Now, ResetDone;
-
- if (hcd == NULL)
- return FALSE;
-
- ohci = ohci_from_hcd(hcd);
-
- if (port_idx < 1 || port_idx > ohci->num_ports)
- return FALSE;
-
- port_idx--;
-
- PortStatus = &ohci->regs->roothub.portstatus[port_idx];
-
- Now = OHCI_READ_PORT_ULONG((PULONG)&ohci->regs->fmnumber);
- ResetDone = Now + PORT_RESET_MSEC;
-
- /* build a "continuous enough" reset signal, with up to
- * 3msec gap between pulses. scheduler HZ==100 must work;
- * this might need to be deadline-scheduled.
- */
- do {
- /* spin until any current reset finishes */
- for (;;) {
- temp = OHCI_READ_PORT_ULONG(PortStatus);
- if (!(temp & RH_PS_PRS))
- break;
- usb_wait_us_dpc(500);
- }
-
- if (!(temp & RH_PS_CCS))
- break;
- if (temp & RH_PS_PRSC)
- {
- OHCI_WRITE_PORT_ULONG(PortStatus, RH_PS_PRSC);
- }
-
- /* start the next reset, sleep till it's probably done */
- OHCI_WRITE_PORT_ULONG(PortStatus, RH_PS_PRS);
- usb_wait_ms_dpc(PORT_RESET_HW_MSEC);
- Now = OHCI_READ_PORT_ULONG((PULONG)&ohci->regs->fmnumber);
- } while (tick_before(Now, ResetDone));
-
- status = OHCI_READ_PORT_ULONG((PULONG)(&ohci->regs->roothub.portstatus[port_idx]));
- usb_dbg_print(DBGLVL_MAXIMUM, ("ohci_rh_reset_port(): status after written=0x%x\n", status));
- return TRUE;
-}
-
-BOOLEAN
-ohci_rh_get_dev_change(PHCD hcd, PBYTE buf) //must have the rh dev_lock acquired
-{
- POHCI_DEV ohci;
- LONG i;
- ULONG status;
-
- if (hcd == NULL)
- return FALSE;
-
- ohci = ohci_from_hcd(hcd);
-
- for(i = 0; i < ohci->num_ports; i++)
- {
- status = OHCI_READ_PORT_ULONG((PULONG)(&ohci->regs->roothub.portstatus[i]));
-
- if (status != 0)
- {
- ohci_dbg_print(DBGLVL_MAXIMUM, ("ohci_rh_get_dev_change(): erh port%d status=0x%x\n", i, status));
- }
-
- if (status & (RH_PS_PESC | RH_PS_CSC | RH_PS_OCIC))
- {
- buf[(i + 1) >> 3] |= (1 << ((i + 1) & 7));
- }
- }
- return TRUE;
-}
-
-
-NTSTATUS
-ohci_hcd_dispatch(PHCD hcd, LONG disp_code, PVOID param)
-{
- POHCI_DEV ohci;
-
- if (hcd == NULL)
- return STATUS_INVALID_PARAMETER;
- ohci = ohci_from_hcd(hcd);
-
- switch (disp_code)
- {
- case HCD_DISP_READ_PORT_COUNT:
- {
- if (param == NULL)
- return STATUS_INVALID_PARAMETER;
- *((PUCHAR) param) = ohci->num_ports;
- return STATUS_SUCCESS;
- }
- case HCD_DISP_READ_RH_DEV_CHANGE:
- {
- if (ohci_rh_get_dev_change(hcd, param) == FALSE)
- return STATUS_INVALID_PARAMETER;
- return STATUS_SUCCESS;
- }
- }
-
- return STATUS_NOT_IMPLEMENTED;
-}
-
-VOID
-ohci_init_hcd_interface(POHCI_DEV ohci)
-{
- ohci->hcd_interf.hcd_set_dev_mgr = ehci_set_dev_mgr;
- ohci->hcd_interf.hcd_get_dev_mgr = ehci_get_dev_mgr;
- ohci->hcd_interf.hcd_get_type = ohci_get_type;
- ohci->hcd_interf.hcd_set_id = ehci_set_id;
- ohci->hcd_interf.hcd_get_id = ehci_get_id;
- ohci->hcd_interf.hcd_alloc_addr = ehci_alloc_addr;
- ohci->hcd_interf.hcd_free_addr = ehci_free_addr;
- ohci->hcd_interf.hcd_submit_urb = ohci_submit_urb2;
- ohci->hcd_interf.hcd_generic_urb_completion = ohci_generic_urb_completion;
- ohci->hcd_interf.hcd_get_root_hub = ohci_get_root_hub;
- ohci->hcd_interf.hcd_set_root_hub = ohci_set_root_hub;
- ohci->hcd_interf.hcd_remove_device = ohci_remove_device2;
- ohci->hcd_interf.hcd_rh_reset_port = ohci_rh_reset_port;
- ohci->hcd_interf.hcd_release = ohci_hcd_release;
- ohci->hcd_interf.hcd_cancel_urb = ohci_cancel_urb2;
- ohci->hcd_interf.hcd_start = ohci_start;
- ohci->hcd_interf.hcd_dispatch = ohci_hcd_dispatch;
-
- ohci->hcd_interf.flags = HCD_TYPE_OHCI; //hcd types | hcd id
-}
-
diff --git a/reactos/drivers/usb/nt4compat/usbdrv/ohci.h b/reactos/drivers/usb/nt4compat/usbdrv/ohci.h
deleted file mode 100644
index a7bd6362723..00000000000
--- a/reactos/drivers/usb/nt4compat/usbdrv/ohci.h
+++ /dev/null
@@ -1,358 +0,0 @@
-/*
- * Copyright (c) 2007 by Aleksey Bragin
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#ifndef __OHCI_H__
-#define __OHCI_H__
-
-#define OHCI_DEVICE_NAME "\\Device\\OHCI"
-#define OHCI_DOS_DEVICE_NAME "\\DosDevices\\OHCI"
-
-/* Host Controller Operational Registers */
-
-#define OHCI_REVISION 0x0
-#define OHCI_CONTROL 0x4
-#define OHCI_CMDSTATUS 0x8
-#define OHCI_INTRSTATUS 0xc
-#define OHCI_INTRENABLE 0x10
-#define OHCI_INTRDISABLE 0x14
-
-/* OHCI CONTROL AND STATUS REGISTER MASKS */
-
-/*
- * HcControl (control) register masks
- */
-#define OHCI_CTRL_CBSR (3 << 0) /* control/bulk service ratio */
-#define OHCI_CTRL_PLE (1 << 2) /* periodic list enable */
-#define OHCI_CTRL_IE (1 << 3) /* isochronous enable */
-#define OHCI_CTRL_CLE (1 << 4) /* control list enable */
-#define OHCI_CTRL_BLE (1 << 5) /* bulk list enable */
-#define OHCI_CTRL_HCFS (3 << 6) /* host controller functional state */
-#define OHCI_CTRL_IR (1 << 8) /* interrupt routing */
-#define OHCI_CTRL_RWC (1 << 9) /* remote wakeup connected */
-#define OHCI_CTRL_RWE (1 << 10) /* remote wakeup enable */
-
-/* pre-shifted values for HCFS */
-# define OHCI_USB_RESET (0 << 6)
-# define OHCI_USB_RESUME (1 << 6)
-# define OHCI_USB_OPER (2 << 6)
-# define OHCI_USB_SUSPEND (3 << 6)
-
-/*
- * HcCommandStatus (cmdstatus) register masks
- */
-#define OHCI_HCR (1 << 0) /* host controller reset */
-#define OHCI_CLF (1 << 1) /* control list filled */
-#define OHCI_BLF (1 << 2) /* bulk list filled */
-#define OHCI_OCR (1 << 3) /* ownership change request */
-#define OHCI_SOC (3 << 16) /* scheduling overrun count */
-
-/*
- * masks used with interrupt registers:
- * HcInterruptStatus (intrstatus)
- * HcInterruptEnable (intrenable)
- * HcInterruptDisable (intrdisable)
- */
-#define OHCI_INTR_SO (1 << 0) /* scheduling overrun */
-#define OHCI_INTR_WDH (1 << 1) /* writeback of done_head */
-#define OHCI_INTR_SF (1 << 2) /* start frame */
-#define OHCI_INTR_RD (1 << 3) /* resume detect */
-#define OHCI_INTR_UE (1 << 4) /* unrecoverable error */
-#define OHCI_INTR_FNO (1 << 5) /* frame number overflow */
-#define OHCI_INTR_RHSC (1 << 6) /* root hub status change */
-#define OHCI_INTR_OC (1 << 30) /* ownership change */
-#define OHCI_INTR_MIE (1 << 31) /* master interrupt enable */
-
-
-/* OHCI ROOT HUB REGISTER MASKS */
-
-/* roothub.portstatus [i] bits */
-#define RH_PS_CCS 0x00000001 /* current connect status */
-#define RH_PS_PES 0x00000002 /* port enable status*/
-#define RH_PS_PSS 0x00000004 /* port suspend status */
-#define RH_PS_POCI 0x00000008 /* port over current indicator */
-#define RH_PS_PRS 0x00000010 /* port reset status */
-#define RH_PS_PPS 0x00000100 /* port power status */
-#define RH_PS_LSDA 0x00000200 /* low speed device attached */
-#define RH_PS_CSC 0x00010000 /* connect status change */
-#define RH_PS_PESC 0x00020000 /* port enable status change */
-#define RH_PS_PSSC 0x00040000 /* port suspend status change */
-#define RH_PS_OCIC 0x00080000 /* over current indicator change */
-#define RH_PS_PRSC 0x00100000 /* port reset status change */
-
-/* roothub.status bits */
-#define RH_HS_LPS 0x00000001 /* local power status */
-#define RH_HS_OCI 0x00000002 /* over current indicator */
-#define RH_HS_DRWE 0x00008000 /* device remote wakeup enable */
-#define RH_HS_LPSC 0x00010000 /* local power status change */
-#define RH_HS_OCIC 0x00020000 /* over current indicator change */
-#define RH_HS_CRWE 0x80000000 /* clear remote wakeup enable */
-
-/* roothub.b masks */
-#define RH_B_DR 0x0000ffff /* device removable flags */
-#define RH_B_PPCM 0xffff0000 /* port power control mask */
-
-/* roothub.a masks */
-#define RH_A_NDP (0xff << 0) /* number of downstream ports */
-#define RH_A_PSM (1 << 8) /* power switching mode */
-#define RH_A_NPS (1 << 9) /* no power switching */
-#define RH_A_DT (1 << 10) /* device type (mbz) */
-#define RH_A_OCPM (1 << 11) /* over current protection mode */
-#define RH_A_NOCP (1 << 12) /* no over current protection */
-#define RH_A_POTPGT (0xff << 24) /* power on to power good time */
-
-/*
- * OHCI Endpoint Descriptor (ED) ... holds TD queue
- * See OHCI spec, section 4.2
- *
- * This is a "Queue Head" for those transfers, which is why
- * both EHCI and UHCI call similar structures a "QH".
- */
-typedef struct _OHCI_ED {
- /* first fields are hardware-specified */
- ULONG hwINFO; /* endpoint config bitmap */
- /* info bits defined by hcd */
-#define ED_DEQUEUE (1 << 27)
- /* info bits defined by the hardware */
-#define ED_ISO (1 << 15)
-#define ED_SKIP (1 << 14)
-#define ED_LOWSPEED (1 << 13)
-#define ED_OUT (0x01 << 11)
-#define ED_IN (0x02 << 11)
- ULONG hwTailP; /* tail of TD list */
- ULONG hwHeadP; /* head of TD list (hc r/w) */
-#define ED_C (0x02) /* toggle carry */
-#define ED_H (0x01) /* halted */
- ULONG hwNextED; /* next ED in list */
-
- /* rest are purely for the driver's use */
-#if 0
- dma_addr_t dma; /* addr of ED */
- struct _OHCI_TD *dummy; /* next TD to activate */
-
- /* host's view of schedule */
- struct _OHCI_ED *ed_next; /* on schedule or rm_list */
- struct _OHCI_ED *ed_prev; /* for non-interrupt EDs */
- struct list_head td_list; /* "shadow list" of our TDs */
-
- /* create --> IDLE --> OPER --> ... --> IDLE --> destroy
- * usually: OPER --> UNLINK --> (IDLE | OPER) --> ...
- */
- UCHAR state; /* ED_{IDLE,UNLINK,OPER} */
-#define ED_IDLE 0x00 /* NOT linked to HC */
-#define ED_UNLINK 0x01 /* being unlinked from hc */
-#define ED_OPER 0x02 /* IS linked to hc */
-
- UCHAR type; /* PIPE_{BULK,...} */
-
- /* periodic scheduling params (for intr and iso) */
- UCHAR branch;
- USHORT interval;
- USHORT load;
- USHORT last_iso; /* iso only */
-
- /* HC may see EDs on rm_list until next frame (frame_no == tick) */
- USHORT tick;
-#endif
-} OHCI_ED, *POHCI_ED;
-
-#define ED_MASK ((u32)~0x0f) /* strip hw status in low addr bits */
-
-
-/*
- * OHCI Transfer Descriptor (TD) ... one per transfer segment
- * See OHCI spec, sections 4.3.1 (general = control/bulk/interrupt)
- * and 4.3.2 (iso)
- */
-typedef struct _OHCI_TD {
- /* first fields are hardware-specified */
- ULONG hwINFO; /* transfer info bitmask */
-
- /* hwINFO bits for both general and iso tds: */
-#define TD_CC 0xf0000000 /* condition code */
-#define TD_CC_GET(td_p) ((td_p >>28) & 0x0f)
-//#define TD_CC_SET(td_p, cc) (td_p) = ((td_p) & 0x0fffffff) | (((cc) & 0x0f) << 28)
-#define TD_DI 0x00E00000 /* frames before interrupt */
-#define TD_DI_SET(X) (((X) & 0x07)<< 21)
- /* these two bits are available for definition/use by HCDs in both
- * general and iso tds ... others are available for only one type
- */
-#define TD_DONE 0x00020000 /* retired to donelist */
-#define TD_ISO 0x00010000 /* copy of ED_ISO */
-
- /* hwINFO bits for general tds: */
-#define TD_EC 0x0C000000 /* error count */
-#define TD_T 0x03000000 /* data toggle state */
-#define TD_T_DATA0 0x02000000 /* DATA0 */
-#define TD_T_DATA1 0x03000000 /* DATA1 */
-#define TD_T_TOGGLE 0x00000000 /* uses ED_C */
-#define TD_DP 0x00180000 /* direction/pid */
-#define TD_DP_SETUP 0x00000000 /* SETUP pid */
-#define TD_DP_IN 0x00100000 /* IN pid */
-#define TD_DP_OUT 0x00080000 /* OUT pid */
- /* 0x00180000 rsvd */
-#define TD_R 0x00040000 /* round: short packets OK? */
-
- /* (no hwINFO #defines yet for iso tds) */
-
- ULONG hwCBP; /* Current Buffer Pointer (or 0) */
- ULONG hwNextTD; /* Next TD Pointer */
- ULONG hwBE; /* Memory Buffer End Pointer */
-
- /* PSW is only for ISO. Only 1 PSW entry is used, but on
- * big-endian PPC hardware that's the second entry.
- */
-#define MAXPSW 2
- USHORT hwPSW [MAXPSW];
-
- /* rest are purely for the driver's use */
-#if 0
- UCHAR index;
- struct ed *ed;
- struct td *td_hash; /* dma-->td hashtable */
- struct td *next_dl_td;
- struct urb *urb;
-
- dma_addr_t td_dma; /* addr of this TD */
- dma_addr_t data_dma; /* addr of data it points to */
-
- struct list_head td_list; /* "shadow list", TDs on same ED */
-#endif
-} OHCI_TD, *POHCI_TD;
-
-/*
- * The HCCA (Host Controller Communications Area) is a 256 byte
- * structure defined section 4.4.1 of the OHCI spec. The HC is
- * told the base address of it. It must be 256-byte aligned.
- */
-typedef struct _OHCI_HCCA
-{
-#define NUM_INTS 32
- ULONG int_table [NUM_INTS]; /* periodic schedule */
-
- /*
- * OHCI defines u16 frame_no, followed by u16 zero pad.
- * Since some processors can't do 16 bit bus accesses,
- * portable access must be a 32 bits wide.
- */
- ULONG frame_no; /* current frame number */
- ULONG done_head; /* info returned for an interrupt */
- UCHAR reserved_for_hc [116];
- UCHAR what [4]; /* spec only identifies 252 bytes :) */
-} OHCI_HCCA, *POHCI_HCCA;
-
-/*
- * This is the structure of the OHCI controller's memory mapped I/O region.
- * You must use readl() and writel() (in ) to access these fields!!
- * Layout is in section 7 (and appendix B) of the spec.
- */
-typedef struct _OHCI_REGS
-{
- /* control and status registers (section 7.1) */
- ULONG revision;
- ULONG control;
- ULONG cmdstatus;
- ULONG intrstatus;
- ULONG intrenable;
- ULONG intrdisable;
-
- /* memory pointers (section 7.2) */
- ULONG hcca;
- ULONG ed_periodcurrent;
- ULONG ed_controlhead;
- ULONG ed_controlcurrent;
- ULONG ed_bulkhead;
- ULONG ed_bulkcurrent;
- ULONG donehead;
-
- /* frame counters (section 7.3) */
- ULONG fminterval;
- ULONG fmremaining;
- ULONG fmnumber;
- ULONG periodicstart;
- ULONG lsthresh;
-
- /* Root hub ports (section 7.4) */
- struct ohci_roothub_regs {
- ULONG a;
- ULONG b;
- ULONG status;
-#define MAX_ROOT_PORTS 15 /* maximum OHCI root hub ports (RH_A_NDP) */
- ULONG portstatus [MAX_ROOT_PORTS];
- } roothub;
-
- /* and optional "legacy support" registers (appendix B) at 0x0100 */
-} OHCI_REGS, *POHCI_REGS;
-
-typedef struct _OHCI_DEV
-{
- HCD hcd_interf;
-
- PHYSICAL_ADDRESS ohci_reg_base; // io space
- BOOLEAN port_mapped;
- PBYTE port_base; // note: added by ehci_caps.length, operational regs base addr, not the actural base
- struct _OHCI_REGS *regs;
- struct _OHCI_HCCA *hcca;
- PVOID td_cache;
- PVOID ed_cache;
-
- PHYSICAL_ADDRESS hcca_logic_addr;
- PHYSICAL_ADDRESS td_logic_addr;
- PHYSICAL_ADDRESS ed_logic_addr;
-
- USHORT num_ports;
-
- LIST_HEAD urb_list; // active urb-list
-
- //
- //for iso and int bandwidth claim, bandwidth schedule
- //
- KSPIN_LOCK pending_endp_list_lock; //lock to access the following two
- LIST_HEAD pending_endp_list;
- UHCI_PENDING_ENDP_POOL pending_endp_pool;
-
- KTIMER reset_timer; //used to reset the host controller
- struct _OHCI_DEVICE_EXTENSION *pdev_ext;
- PUSB_DEV root_hub; //root hub
-} OHCI_DEV, *POHCI_DEV;
-
-typedef struct _OHCI_DEVICE_EXTENSION
-{
- DEVEXT_HEADER dev_ext_hdr;
- PDEVICE_OBJECT pdev_obj;
- PDRIVER_OBJECT pdrvr_obj;
- POHCI_DEV ohci;
-
- //device resources
- PADAPTER_OBJECT padapter;
- ULONG map_regs;
- PCM_RESOURCE_LIST res_list;
- ULONG pci_addr; // bus number | slot number | funciton number
- UHCI_INTERRUPT res_interrupt;
- union
- {
- UHCI_PORT res_port;
- EHCI_MEMORY res_memory;
- };
-
- PKINTERRUPT ohci_int;
- KDPC ohci_dpc;
-} OHCI_DEVICE_EXTENSION, *POHCI_DEVICE_EXTENSION;
-
-#define ohci_from_hcd( hCD ) ( struct_ptr( ( hCD ), OHCI_DEV, hcd_interf ) )
-
-#endif /* __OHCI_H__ */
diff --git a/reactos/drivers/usb/nt4compat/usbdrv/roothub.c b/reactos/drivers/usb/nt4compat/usbdrv/roothub.c
deleted file mode 100644
index d76b2da0df1..00000000000
--- a/reactos/drivers/usb/nt4compat/usbdrv/roothub.c
+++ /dev/null
@@ -1,433 +0,0 @@
-/**
- * roothub.c - USB driver stack project for Windows NT 4.0
- *
- * Copyright (c) 2002-2004 Zhiming mypublic99@yahoo.com
- *
- * This program/include file is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program/include file is distributed in the hope that it will be
- * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
- * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program (in the main directory of the distribution, the file
- * COPYING); if not, write to the Free Software Foundation,Inc., 59 Temple
- * Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "usbdriver.h"
-
-//----------------------------------------------------------
-
-BOOLEAN
-rh_driver_destroy(PUSB_DEV_MANAGER dev_mgr, PUSB_DRIVER pdriver)
-{
- LONG i;
- PHCD hcd;
-
- if (dev_mgr == NULL)
- return FALSE;
-
- for(i = 0; i < dev_mgr->hcd_count; i++)
- {
- hcd = dev_mgr->hcd_array[i];
- // if( hcd->hcd_get_type( hcd ) != HCD_TYPE_UHCI )
- // continue;
- rh_destroy(hcd->hcd_get_root_hub(hcd));
- }
- return TRUE;
-}
-
-BOOLEAN
-rh_driver_init(PUSB_DEV_MANAGER dev_mgr, PUSB_DRIVER pdriver)
-{
-
- PUSB_DEV rh;
- PUSB_CONFIGURATION_DESC pconfig_desc;
- PUSB_INTERFACE_DESC pif_desc;
- PUSB_ENDPOINT_DESC pendp_desc;
- PUSB_CONFIGURATION pconfig;
- PUSB_INTERFACE pif;
- PUSB_ENDPOINT pendp;
- PHUB2_EXTENSION phub_ext;
- NTSTATUS status;
- PHCD hcd;
- LONG i;
-
- if (dev_mgr == NULL || pdriver == NULL)
- return FALSE;
-
- //init driver structure, no PNP table functions
- pdriver->driver_desc.flags = USB_DRIVER_FLAG_DEV_CAPABLE;
- pdriver->driver_desc.vendor_id = 0xffff; // USB Vendor ID
- pdriver->driver_desc.product_id = 0xffff; // USB Product ID.
- pdriver->driver_desc.release_num = 0xffff; // Release Number of Device
-
- pdriver->driver_desc.config_val = 0; // Configuration Value
- pdriver->driver_desc.if_num = 0; // Interface Number
- pdriver->driver_desc.if_class = USB_CLASS_HUB; // Interface Class
- pdriver->driver_desc.if_sub_class = 0; // Interface SubClass
- pdriver->driver_desc.if_protocol = 0; // Interface Protocol
-
- pdriver->driver_desc.driver_name = "USB root hub"; // Driver name for Name Registry
- pdriver->driver_desc.dev_class = USB_CLASS_HUB;
- pdriver->driver_desc.dev_sub_class = 0; // Device Subclass
- pdriver->driver_desc.dev_protocol = 0; // Protocol Info.
-
- //pdriver->driver_init = rh_driver_init; // initialized in dev_mgr_init_driver
- //pdriver->driver_destroy = rh_driver_destroy;
- pdriver->disp_tbl.version = 1; // other fields of the dispatch table is not used since rh needs no pnp
-
- pdriver->driver_ext = 0;
- pdriver->driver_ext_size = 0;
-
- for(i = 0; i < dev_mgr->hcd_count; i++)
- {
- hcd = dev_mgr->hcd_array[i];
- //if( hcd->hcd_get_type( hcd ) != HCD_TYPE_UHCI )
- // continue;
-
- if ((rh = dev_mgr_alloc_device(dev_mgr, hcd)) == NULL)
- return FALSE;
-
- rh->parent_dev = NULL;
- rh->port_idx = 0;
- rh->hcd = hcd;
- rh->flags = USB_DEV_CLASS_ROOT_HUB | USB_DEV_STATE_CONFIGURED;
-
- if (usb2(hcd))
- rh->flags |= USB_DEV_FLAG_HIGH_SPEED;
-
- rh->dev_driver = pdriver;
-
- rh->desc_buf_size = sizeof(USB_DEVICE_DESC)
- + sizeof(USB_CONFIGURATION_DESC)
- + sizeof(USB_INTERFACE_DESC)
- + sizeof(USB_ENDPOINT_DESC) + sizeof(USB_CONFIGURATION) + sizeof(HUB2_EXTENSION);
-
- rh->desc_buf = usb_alloc_mem(NonPagedPool, rh->desc_buf_size);
-
- if (rh->desc_buf == NULL)
- {
- return FALSE;
- }
- else
- RtlZeroMemory(rh->desc_buf, rh->desc_buf_size);
-
- rh->pusb_dev_desc = (PUSB_DEVICE_DESC) rh->desc_buf;
-
- rh->pusb_dev_desc->bLength = sizeof(USB_DEVICE_DESC);
- rh->pusb_dev_desc->bDescriptorType = USB_DT_DEVICE;
- rh->pusb_dev_desc->bcdUSB = 0x110;
- if (usb2(hcd))
- rh->pusb_dev_desc->bcdUSB = 0x200;
- rh->pusb_dev_desc->bDeviceClass = USB_CLASS_HUB;
- rh->pusb_dev_desc->bDeviceSubClass = 0;
- rh->pusb_dev_desc->bDeviceProtocol = 0;
- rh->pusb_dev_desc->bMaxPacketSize0 = 8;
- if (usb2(hcd))
- {
- rh->pusb_dev_desc->bDeviceProtocol = 1;
- rh->pusb_dev_desc->bMaxPacketSize0 = 64;
- }
- rh->pusb_dev_desc->idVendor = 0;
- rh->pusb_dev_desc->idProduct = 0;
- rh->pusb_dev_desc->bcdDevice = 0x100;
- rh->pusb_dev_desc->iManufacturer = 0;
- rh->pusb_dev_desc->iProduct = 0;
- rh->pusb_dev_desc->iSerialNumber = 0;
- rh->pusb_dev_desc->bNumConfigurations = 1;
-
- pconfig_desc = (PUSB_CONFIGURATION_DESC) & rh->desc_buf[sizeof(USB_DEVICE_DESC)];
- pif_desc = (PUSB_INTERFACE_DESC) & pconfig_desc[1];
- pendp_desc = (PUSB_ENDPOINT_DESC) & pif_desc[1];
-
- pconfig_desc->bLength = sizeof(USB_CONFIGURATION_DESC);
- pconfig_desc->bDescriptorType = USB_DT_CONFIG;
-
- pconfig_desc->wTotalLength = sizeof(USB_CONFIGURATION_DESC)
- + sizeof(USB_INTERFACE_DESC) + sizeof(USB_ENDPOINT_DESC);
-
- pconfig_desc->bNumInterfaces = 1;
- pconfig_desc->bConfigurationValue = 1;
- pconfig_desc->iConfiguration = 0;
- pconfig_desc->bmAttributes = 0Xe0; //self-powered and support remoke wakeup
- pconfig_desc->MaxPower = 0;
-
- pif_desc->bLength = sizeof(USB_INTERFACE_DESC);
- pif_desc->bDescriptorType = USB_DT_INTERFACE;
- pif_desc->bInterfaceNumber = 0;
- pif_desc->bAlternateSetting = 0;
- pif_desc->bNumEndpoints = 1;
- pif_desc->bInterfaceClass = USB_CLASS_HUB;
- pif_desc->bInterfaceSubClass = 0;
- pif_desc->bInterfaceProtocol = 0;
- pif_desc->iInterface = 0;
-
- pendp_desc->bLength = sizeof(USB_ENDPOINT_DESC);
- pendp_desc->bDescriptorType = USB_DT_ENDPOINT;
- pendp_desc->bEndpointAddress = 0x81;
- pendp_desc->bmAttributes = 0x03;
- pendp_desc->wMaxPacketSize = 8;
- pendp_desc->bInterval = USB_HUB_INTERVAL;
- if (usb2(hcd))
- pendp_desc->bInterval = 0x0c;
-
- pconfig = rh->usb_config = (PUSB_CONFIGURATION) & pendp_desc[1];
- rh->active_config_idx = 0;
- pconfig->pusb_config_desc = pconfig_desc;
- pconfig->if_count = 1;
- pconfig->pusb_dev = rh;
- pif = &pconfig->interf[0];
-
- pif->endp_count = 1;
- pendp = &pif->endp[0];
- pif->pusb_config = pconfig;
- pif->pusb_if_desc = pif_desc;
-
- pif->if_ext_size = 0;
- pif->if_ext = NULL;
-
- phub_ext = (PHUB2_EXTENSION) & pconfig[1];
- phub_ext->port_count = 2;
-
- if (usb2(hcd))
- {
- // port count is configurable in usb2
- hcd->hcd_dispatch(hcd, HCD_DISP_READ_PORT_COUNT, &phub_ext->port_count);
- }
-
- {
- int j;
- for(j = 0; j < phub_ext->port_count; j++)
- {
- psq_init(&phub_ext->port_status_queue[j]);
- phub_ext->child_dev[j] = NULL;
- usb_dbg_print(DBGLVL_MAXIMUM, ("rh_driver_init(): port[ %d ].flag=0x%x\n",
- j, phub_ext->port_status_queue[j].port_flags));
- }
- }
-
- phub_ext->pif = pif;
- phub_ext->hub_desc.bLength = sizeof(USB_HUB_DESCRIPTOR);
- phub_ext->hub_desc.bDescriptorType = USB_DT_HUB;
- phub_ext->hub_desc.bNbrPorts = (UCHAR) phub_ext->port_count;
- phub_ext->hub_desc.wHubCharacteristics = 0;
- phub_ext->hub_desc.bPwrOn2PwrGood = 0;
- phub_ext->hub_desc.bHubContrCurrent = 50;
-
- rh->dev_ext = (PBYTE) phub_ext;
- rh->dev_ext_size = sizeof(HUB2_EXTENSION);
-
- rh->default_endp.flags = USB_ENDP_FLAG_DEFAULT_ENDP;
- InitializeListHead(&rh->default_endp.urb_list);
- rh->default_endp.pusb_if = (PUSB_INTERFACE) rh;
- rh->default_endp.pusb_endp_desc = NULL; //???
- rh->time_out_count = 0;
- rh->error_count = 0;
-
- InitializeListHead(&pendp->urb_list);
- pendp->flags = 0;
- pendp->pusb_endp_desc = pendp_desc;
- pendp->pusb_if = pif;
-
- //add to device list
- InsertTailList(&dev_mgr->dev_list, &rh->dev_link);
- hcd->hcd_set_root_hub(hcd, rh);
- status = hub_start_int_request(rh);
- pdriver->driver_ext = 0;
- }
- return TRUE;
-}
-
-//to be the reverse of what init does, we assume that the timer is now killed
-//int is disconnected and the hub thread will not process event anymore
-BOOLEAN
-rh_destroy(PUSB_DEV pdev)
-{
- PUSB_DEV rh;
- PUSB_DEV_MANAGER dev_mgr;
-
- if (pdev == NULL)
- return FALSE;
-
- dev_mgr = dev_mgr_from_dev(pdev);
-
- //???
- rh = pdev->hcd->hcd_get_root_hub(pdev->hcd);
- if (rh == pdev)
- {
- //free all the buf
- dev_mgr_free_device(dev_mgr, rh);
- //dev_mgr->root_hub = NULL;
- }
-
- return TRUE;
-}
-
-VOID
-rh_timer_svc_int_completion(PUSB_DEV pdev, PVOID context)
-{
- PURB purb;
- PHCD hcd;
- USE_BASIC_NON_PENDING_IRQL;
-
- if (pdev == NULL || context == NULL)
- return;
-
- purb = (PURB) context;
-
- lock_dev(pdev, TRUE);
-
- if (dev_state(pdev) == USB_DEV_STATE_ZOMB)
- {
- pdev->ref_count -= 2; // one for timer_svc and one for urb, for those rh requests
- unlock_dev(pdev, TRUE);
- usb_free_mem(purb);
- usb_dbg_print(DBGLVL_MAXIMUM, ("rh_timer_svc_int_completion(): the dev is zomb, 0x%x\n", pdev));
- return;
- }
-
- hcd = pdev->hcd;
- if (purb->data_length < 1)
- {
- purb->status = STATUS_INVALID_PARAMETER;
- unlock_dev(pdev, TRUE);
- goto LBL_OUT;
- }
-
- pdev->hcd->hcd_dispatch(pdev->hcd, HCD_DISP_READ_RH_DEV_CHANGE, purb->data_buffer);
- purb->status = STATUS_SUCCESS;
- unlock_dev(pdev, TRUE);
-
- LBL_OUT:
- hcd->hcd_generic_urb_completion(purb, purb->context);
-
- lock_dev(pdev, TRUE);
- pdev->ref_count -= 2;
- // one for timer_svc and one for urb, for those rh requests
- // that completed immediately, the ref_count of the dev for
- // that urb won't increment and for normal hub request
- // completion, hcd_generic_urb_completion will be called
- // by the xhci_dpc_callback, and the ref_count for the urb
- // is maintained there. So only rh's timer-svc cares refcount
- // when hcd_generic_urb_completion is called.
- usb_dbg_print(DBGLVL_ULTRA, ("rh_timer_svc_int_completion(): rh's ref_count=0x%x\n", pdev->ref_count));
- unlock_dev(pdev, TRUE);
- usb_dbg_print(DBGLVL_ULTRA, ("rh_timer_svc_int_completion(): exitiing...\n"));
- return;
-}
-
-VOID
-rh_timer_svc_reset_port_completion(PUSB_DEV pdev, PVOID context)
-{
- PURB purb;
- ULONG i;
- PHUB2_EXTENSION hub_ext;
- PLIST_ENTRY pthis, pnext;
- PUSB_DEV_MANAGER dev_mgr;
- PUSB_CTRL_SETUP_PACKET psetup;
-
- USE_BASIC_NON_PENDING_IRQL;
-
- if (pdev == NULL || context == NULL)
- return;
-
- dev_mgr = dev_mgr_from_dev(pdev); //readonly and hold ref_count
-
- //block the rh polling
- KeAcquireSpinLockAtDpcLevel(&dev_mgr->timer_svc_list_lock);
- if (IsListEmpty(&dev_mgr->timer_svc_list) == FALSE)
- {
- ListFirst(&dev_mgr->timer_svc_list, pthis);
- while (pthis)
- {
- if (((PTIMER_SVC) pthis)->pdev == pdev && ((PTIMER_SVC) pthis)->threshold == RH_INTERVAL)
- {
- ((PTIMER_SVC) pthis)->threshold = RH_INTERVAL + 0x800000;
- break;
- }
-
- ListNext(&dev_mgr->timer_svc_list, pthis, pnext);
- pthis = pnext;
- }
- }
- KeReleaseSpinLockFromDpcLevel(&dev_mgr->timer_svc_list_lock);
-
- purb = (PURB) context;
- psetup = (PUSB_CTRL_SETUP_PACKET) purb->setup_packet;
-
- lock_dev(pdev, TRUE);
- if (dev_state(pdev) == USB_DEV_STATE_ZOMB)
- {
- //purb->status = STATUS_ERROR;
- //pdev->hcd->hcd_generic_urb_completion( purb, purb->context );
-
- pdev->ref_count -= 2;
- unlock_dev(pdev, TRUE);
- usb_free_mem(purb);
- return;
- }
-
- i = pdev->hcd->hcd_rh_reset_port(pdev->hcd, (UCHAR) psetup->wIndex);
-
- hub_ext = hub_ext_from_dev(pdev);
-
- {
- USHORT temp;
- PUCHAR pbuf;
- if (psetup->wIndex < 16)
- {
- temp = 1 << psetup->wIndex;
- pbuf = (PUCHAR) & temp;
- if (temp > 128)
- pbuf++;
- hub_ext->int_data_buf[psetup->wIndex / 8] |= *pbuf;
- if (i == TRUE)
- hub_ext->rh_port_status[psetup->wIndex].wPortChange |= USB_PORT_STAT_C_RESET;
- else // notify that is not a high speed device, will lost definitely
- hub_ext->rh_port_status[psetup->wIndex].wPortChange |= USB_PORT_STAT_C_CONNECTION;
- }
- }
-
- //???how to construct port status map
- // decrease the timer_svc ref-count
- pdev->ref_count--;
- unlock_dev(pdev, TRUE);
-
- purb->status = STATUS_SUCCESS;
- //we delegate the completion to the rh_timer_svc_int_completion.
- //this function is equivalent to hub_start_reset_port_completion
-
- usb_free_mem(purb);
-
- //expire the rh polling timer
- KeAcquireSpinLockAtDpcLevel(&dev_mgr->timer_svc_list_lock);
- if (IsListEmpty(&dev_mgr->timer_svc_list) == FALSE)
- {
- ListFirst(&dev_mgr->timer_svc_list, pthis);
- while (pthis)
- {
- if (((PTIMER_SVC) pthis)->pdev == pdev &&
- ((PTIMER_SVC) pthis)->threshold == RH_INTERVAL + 0x800000)
- {
- ((PTIMER_SVC) pthis)->counter = RH_INTERVAL;
- ((PTIMER_SVC) pthis)->threshold = RH_INTERVAL;
- break;
- }
-
- ListNext(&dev_mgr->timer_svc_list, pthis, pnext);
- pthis = pnext;
- }
- }
- KeReleaseSpinLockFromDpcLevel(&dev_mgr->timer_svc_list_lock);
-
- lock_dev(pdev, TRUE);
- pdev->ref_count--;
- unlock_dev(pdev, TRUE);
- return;
-}
diff --git a/reactos/drivers/usb/nt4compat/usbdrv/td.c b/reactos/drivers/usb/nt4compat/usbdrv/td.c
deleted file mode 100644
index 1f1bfe00e28..00000000000
--- a/reactos/drivers/usb/nt4compat/usbdrv/td.c
+++ /dev/null
@@ -1,603 +0,0 @@
-/**
- * td.c - USB driver stack project for Windows NT 4.0
- *
- * Copyright (c) 2002-2004 Zhiming mypublic99@yahoo.com
- *
- * This program/include file is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program/include file is distributed in the hope that it will be
- * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
- * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program (in the main directory of the distribution, the file
- * COPYING); if not, write to the Free Software Foundation,Inc., 59 Temple
- * Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "usbdriver.h"
-
-#define UHCI_MIN_TD_POOLS 4
-
-BOOLEAN free_td_to_pool(PUHCI_TD_POOL ptd_pool, PUHCI_TD ptd); //add tds till pnext == NULL
-
-
-PUHCI_QH alloc_qh(PUHCI_QH_POOL pqh_pool); //null if failed
-
-BOOLEAN
-init_td_pool(PUHCI_TD_POOL ptd_pool)
-{
- int i, pages;
- PTD_EXTENSION ptde;
-
- if (ptd_pool == NULL)
- return FALSE;
-
- if (ptd_pool->padapter == NULL)
- return FALSE;
-
- pages = sizeof(UHCI_TD) * UHCI_MAX_POOL_TDS / PAGE_SIZE;
- RtlZeroMemory(ptd_pool->td_array, sizeof(ptd_pool->td_array));
- RtlZeroMemory(ptd_pool->logic_addr, sizeof(ptd_pool->logic_addr));
-
- for(i = 0; i < pages; i++)
- {
- ptd_pool->td_array[i] =
- HalAllocateCommonBuffer(ptd_pool->padapter, PAGE_SIZE, &ptd_pool->logic_addr[i], FALSE);
- if (ptd_pool->td_array[i] == NULL)
- goto failed;
- }
-
- ptd_pool->tde_array = (PTD_EXTENSION) usb_alloc_mem(NonPagedPool,
- sizeof(TD_EXTENSION) * UHCI_MAX_POOL_TDS);
-
- if (ptd_pool->tde_array == NULL)
- goto failed;
-
- for(i = 0; i < pages; i++)
- {
- RtlZeroMemory(ptd_pool->td_array[i], PAGE_SIZE);
- }
-
- RtlZeroMemory(ptd_pool->tde_array, sizeof(TD_EXTENSION) * UHCI_MAX_POOL_TDS);
-
- ptde = ptd_pool->tde_array;
- ptd_pool->free_count = 0;
- ptd_pool->total_count = UHCI_MAX_POOL_TDS;
- InitializeListHead(&ptd_pool->free_que);
-
- for(i = 0; i < UHCI_MAX_POOL_TDS; i++)
- {
- //link tde and the td one by one, fixed since this init
- ptd_pool->td_array[i >> 7][i & 0x7f].ptde = &ptde[i];
- ptde[i].ptd = &ptd_pool->td_array[i >> 7][i & 0x7f];
- ptde[i].flags = UHCI_ITEM_FLAG_TD;
- ptd_pool->td_array[i >> 7][i & 0x7f].phy_addr =
- ptd_pool->logic_addr[i >> 7].LowPart + (i & 0x7f) * sizeof(UHCI_TD);
- ptd_pool->td_array[i >> 7][i & 0x7f].pool = ptd_pool;
- ptd_pool->td_array[i >> 7][i & 0x7f].purb = NULL;
- free_td_to_pool(ptd_pool, &ptd_pool->td_array[i >> 7][i & 0x7f]);
-
- }
- return TRUE;
-
-failed:
- for(i = 0; i < pages; i++)
- {
- if (ptd_pool->td_array[i])
- {
- HalFreeCommonBuffer(ptd_pool->padapter,
- PAGE_SIZE, ptd_pool->logic_addr[i], ptd_pool->td_array[i], FALSE);
- ptd_pool->td_array[i] = NULL;
- ptd_pool->logic_addr[i].QuadPart = 0;
- }
- }
-
- if (ptd_pool->tde_array)
- usb_free_mem(ptd_pool->tde_array);
-
- uhci_dbg_print(DBGLVL_MAXIMUM, ("init_td_pool(): failed to init the td pool\n"));
- TRAP();
-
- ptd_pool->free_count = ptd_pool->total_count = 0;
- return FALSE;
-}
-
-//add tds till pnext == NULL
-BOOLEAN
-free_td_to_pool(PUHCI_TD_POOL ptd_pool, PUHCI_TD ptd)
-{
- if (ptd_pool == NULL || ptd == NULL)
- {
- return FALSE;
- }
-
- ptd->link = ptd->status = ptd->info = ptd->buffer = 0;
- ptd->purb = NULL;
- ptd_pool->free_count++;
-
- InsertTailList(&ptd_pool->free_que, &ptd->ptde->vert_link);
-
- return TRUE;
-
-}
-
-// qh routines
-
-//null if failed
-PUHCI_TD
-alloc_td_from_pool(PUHCI_TD_POOL ptd_pool)
-{
- PTD_EXTENSION ptde;
- PLIST_ENTRY temp;
-
- if (ptd_pool == NULL)
- return FALSE;
-
- if (IsListEmpty(&ptd_pool->free_que))
- return FALSE;
-
- temp = RemoveHeadList(&ptd_pool->free_que);
-
- if (temp == NULL)
- return FALSE;
-
- ptde = struct_ptr(temp, TD_EXTENSION, vert_link);
-
- ptd_pool->free_count--;
-
- InitializeListHead(&ptde->vert_link);
- InitializeListHead(&ptde->hori_link);
-
- return ptde->ptd;
-
-}
-
-//test whether the pool is all free
-BOOLEAN
-is_pool_free(PUHCI_TD_POOL pool)
-{
- if (pool == NULL)
- return FALSE;
-
- if (pool->free_count == pool->total_count)
- return TRUE;
-
- return FALSE;
-}
-
-BOOLEAN
-is_pool_empty(PUHCI_TD_POOL pool)
-{
- if (pool == NULL)
- return FALSE;
-
- return (BOOLEAN) (pool->free_count == 0);
-}
-
-BOOLEAN
-destroy_td_pool(PUHCI_TD_POOL ptd_pool)
-{
- int i, pages;
- PADAPTER_OBJECT padapter; //we need this garbage for allocation
-
- padapter = ptd_pool->padapter;
-
- pages = sizeof(UHCI_TD) * UHCI_MAX_POOL_TDS / PAGE_SIZE;
- if (ptd_pool && ptd_pool->padapter)
- {
- usb_free_mem(ptd_pool->tde_array);
- ptd_pool->tde_array = NULL;
- for(i = 0; i < pages; i++)
- {
- if (ptd_pool->td_array[i])
- {
- HalFreeCommonBuffer(ptd_pool->padapter,
- PAGE_SIZE, ptd_pool->logic_addr[i], ptd_pool->td_array[i], FALSE);
- ptd_pool->td_array[i] = NULL;
- ptd_pool->logic_addr[i].QuadPart = 0;
- }
- }
- RtlZeroMemory(ptd_pool, sizeof(UHCI_TD_POOL));
- ptd_pool->padapter = padapter;
- ptd_pool->free_count = ptd_pool->total_count = 0;
- }
- else
- return FALSE;
-
- return TRUE;
-}
-
-BOOLEAN
-init_td_pool_list(PUHCI_TD_POOL_LIST pool_list, PADAPTER_OBJECT padapter)
-{
- int i;
- RtlZeroMemory(pool_list, sizeof(UHCI_TD_POOL_LIST));
- InitializeListHead(&pool_list->busy_pools);
- InitializeListHead(&pool_list->free_pools);
-
- pool_list->free_count = UHCI_MAX_TD_POOLS;
- pool_list->free_tds = 0;
-
- for(i = 0; i < UHCI_MAX_TD_POOLS; i++)
- {
- pool_list->pool_array[i].padapter = padapter;
- InsertTailList(&pool_list->free_pools, &pool_list->pool_array[i].pool_link);
- }
-
- KeInitializeSpinLock(&pool_list->pool_lock);
- return expand_pool_list(pool_list, UHCI_MIN_TD_POOLS);
-}
-
-BOOLEAN
-destroy_td_pool_list(PUHCI_TD_POOL_LIST pool_list)
-{
- PUHCI_TD_POOL pool;
- while (IsListEmpty(&pool_list->busy_pools) == FALSE)
- {
- pool = (PUHCI_TD_POOL) RemoveHeadList(&pool_list->busy_pools);
- destroy_td_pool(pool);
- }
-
- RtlZeroMemory(pool_list, sizeof(UHCI_TD_POOL_LIST));
- return TRUE;
-}
-
-BOOLEAN
-expand_pool_list(PUHCI_TD_POOL_LIST pool_list, LONG pool_count) //private
-{
- PUHCI_TD_POOL pool;
- int i;
-
- if (IsListEmpty(&pool_list->free_pools) == TRUE)
- return FALSE;
-
- if (pool_list->free_count < pool_count)
- return FALSE;
-
- for(i = 0; i < pool_count; i++)
- {
- pool = (PUHCI_TD_POOL) RemoveHeadList(&pool_list->free_pools);
-
- if (init_td_pool(pool) == FALSE)
- {
- //reverse the allocation
- InsertHeadList(&pool_list->free_pools, &pool->pool_link);
- // collect_garbage( pool_list );
- return FALSE;
- }
-
- InsertTailList(&pool_list->busy_pools, &pool->pool_link);
- pool_list->free_tds += UHCI_MAX_POOL_TDS;
- pool_list->free_count--;
- }
- return TRUE;
-}
-
-BOOLEAN
-collect_garbage(PUHCI_TD_POOL_LIST pool_list)
-{
- PLIST_ENTRY prev, next;
-
- // no garbage
- if (pool_list->free_count >= UHCI_MAX_TD_POOLS - UHCI_MIN_TD_POOLS)
- return TRUE;
-
- ListFirstPrev(&pool_list->busy_pools, prev);
- ListNext(&pool_list->busy_pools, prev, next);
-
- while (next && next != &pool_list->busy_pools)
- {
- if (is_pool_free((PUHCI_TD_POOL) next))
- {
- RemoveEntryList(next);
- destroy_td_pool((PUHCI_TD_POOL) next);
- InsertTailList(&pool_list->free_pools, next);
- pool_list->free_count++;
- pool_list->free_tds -= UHCI_MAX_POOL_TDS;
- ListNext(&pool_list->busy_pools, prev, next);
- if (pool_list->free_count >= UHCI_MAX_TD_POOLS - UHCI_MIN_TD_POOLS)
- break;
- }
- else
- {
- prev = next;
- ListNext(&pool_list->busy_pools, prev, next);
- }
- }
- return TRUE;
-
-}
-
-//private
-LONG
-get_num_free_tds(PUHCI_TD_POOL_LIST pool_list)
-{
- return pool_list->free_tds;
-}
-
-//private
-LONG
-get_max_free_tds(PUHCI_TD_POOL_LIST pool_list)
-{
- return pool_list->free_tds + pool_list->free_count * UHCI_MAX_POOL_TDS;
-}
-
-//add tds till pnext == NULL
-BOOLEAN
-free_td(PUHCI_TD_POOL_LIST pool_list, PUHCI_TD ptd)
-{
- if (pool_list == NULL || ptd == NULL)
- return FALSE;
-
- if (free_td_to_pool(ptd->pool, ptd) == FALSE)
- return FALSE;
-
- pool_list->free_tds++;
-
- if (is_pool_free(ptd->pool))
- {
- collect_garbage(pool_list);
- }
- return TRUE;
-}
-
-//null if failed
-PUHCI_TD
-alloc_td(PUHCI_TD_POOL_LIST pool_list)
-{
- PLIST_ENTRY prev, next;
- PUHCI_TD new_td;
-
- if (pool_list == NULL)
- return NULL;
-
- if (pool_list->free_tds == 0)
- {
- if (expand_pool_list(pool_list, 1) == FALSE)
- return NULL;
- }
-
- ListFirst(&pool_list->busy_pools, prev);
-
- while (prev && prev != &pool_list->busy_pools)
- {
- if (is_pool_empty((PUHCI_TD_POOL) prev) == FALSE)
- {
- new_td = alloc_td_from_pool((PUHCI_TD_POOL) prev);
-
- if (new_td == NULL)
- TRAP();
-
- pool_list->free_tds--;
-
- return new_td;
- }
-
- ListNext(&pool_list->busy_pools, prev, next);
- prev = next;
- }
-
- return NULL;
-}
-
-PUHCI_TD
-alloc_tds(PUHCI_TD_POOL_LIST pool_list, LONG count)
-{
- //return value is a list of tds, vert_link chain.
-
- LONG i;
- PUHCI_TD ptd, pnext;
-
- if (pool_list == NULL || count <= 0)
- return NULL;
-
- if (count >= get_max_free_tds(pool_list))
- return NULL;
-
- ptd = alloc_td(pool_list);
- if (!ptd) return NULL;
-
- for(i = 1; i < count; i++)
- {
- pnext = alloc_td(pool_list);
-
- if (pnext)
- {
- InsertTailList(&ptd->ptde->vert_link, &pnext->ptde->vert_link);
- }
- else
- TRAP();
- }
-
- uhci_dbg_print(DBGLVL_MEDIUM, ("alloc_tds(): td pool-list free_tds=0x%x, free pools=0x%x\n",
- pool_list->free_tds, pool_list->free_count));
-
- return ptd;
-
-}
-
-VOID
-free_tds(PUHCI_TD_POOL_LIST pool_list, PUHCI_TD ptd)
-{
- PUHCI_TD ptofree;
- PLIST_ENTRY pthis;
-
- if (pool_list == NULL || ptd == NULL)
- return;
-
- while (IsListEmpty(&ptd->ptde->vert_link) == FALSE)
- {
- pthis = RemoveHeadList(&ptd->ptde->vert_link);
- ptofree = ((PTD_EXTENSION) pthis)->ptd;
- free_td(pool_list, ptofree);
- }
-
- free_td(pool_list, ptd);
- return;
-}
-
-
-
-BOOLEAN
-can_transfer(PUHCI_TD_POOL_LIST pool_list, LONG td_count)
-{
- if (td_count > get_max_free_tds(pool_list))
- return FALSE;
-
- return TRUE;
-}
-
-VOID
-lock_td_pool(PUHCI_TD_POOL_LIST pool_list, BOOLEAN at_dpc)
-{
- //if( !at_dpc )
- // KeAcquireSpinLock( &pool_list->pool_lock );
- //else
- // KeAcquireSpinLockAtDpcLevel( &pool_list->pool_lock );
-}
-
-VOID
-unlock_td_pool(PUHCI_TD_POOL_LIST pool_list, BOOLEAN at_dpc)
-{
- //if( !at_dpc )
- // KeReleaseSpinLock( &pool_list->pool_lock );
- //else
- // KeReleaseSpinLockFromDpcLevel( &pool_list->pool_lock );
-}
-
-BOOLEAN
-init_qh_pool(PUHCI_QH_POOL pqh_pool, PADAPTER_OBJECT padapter)
-{
- PQH_EXTENSION pqhe;
- LONG i;
-
- if (pqh_pool == NULL || padapter == NULL)
- return FALSE;
-
- pqh_pool->padapter = padapter;
-
- pqh_pool->qhe_array = (PQH_EXTENSION) usb_alloc_mem(NonPagedPool,
- sizeof(QH_EXTENSION) * UHCI_MAX_POOL_QHS);
-
- if (pqh_pool->qhe_array == NULL)
- return FALSE;
-
- pqh_pool->qh_array =
- (PUHCI_QH) HalAllocateCommonBuffer(padapter,
- sizeof(UHCI_QH) * UHCI_MAX_POOL_QHS, &pqh_pool->logic_addr, FALSE);
-
- if (pqh_pool->qh_array == NULL)
- {
- usb_free_mem(pqh_pool->qhe_array);
- pqh_pool->qhe_array = NULL;
- return FALSE;
- }
-
- pqhe = pqh_pool->qhe_array;
-
- pqh_pool->free_count = 0;
- pqh_pool->total_count = UHCI_MAX_POOL_TDS;
-
- KeInitializeSpinLock(&pqh_pool->pool_lock);
- InitializeListHead(&pqh_pool->free_que);
-
-
- for(i = 0; i < UHCI_MAX_POOL_QHS; i++)
- {
- pqh_pool->qh_array[i].pqhe = &pqhe[i];
- pqhe[i].pqh = &pqh_pool->qh_array[i];
-
- pqh_pool->qh_array[i].phy_addr = (pqh_pool->logic_addr.LowPart + (sizeof(UHCI_QH) * i)) | UHCI_PTR_QH;
- //pqh_pool->qh_array[i].reserved = 0;
-
- //always breadth first
- pqhe[i].flags = UHCI_ITEM_FLAG_QH;
-
- free_qh(pqh_pool, &pqh_pool->qh_array[i]);
-
- }
- return TRUE;
-
-}
-
-//add qhs till pnext == NULL
-BOOLEAN
-free_qh(PUHCI_QH_POOL pqh_pool, PUHCI_QH pqh)
-{
- if (pqh_pool == NULL || pqh == NULL)
- return FALSE;
-
- pqh->link = pqh->element = 0;
- pqh->pqhe->purb = NULL;
- InsertTailList(&pqh_pool->free_que, &pqh->pqhe->vert_link);
- pqh_pool->free_count++;
-
- return TRUE;
-}
-
-//null if failed
-PUHCI_QH
-alloc_qh(PUHCI_QH_POOL pqh_pool)
-{
- PQH_EXTENSION pqhe;
-
- if (pqh_pool == NULL)
- return FALSE;
-
- if (IsListEmpty(&pqh_pool->free_que))
- return FALSE;
-
- pqhe = (PQH_EXTENSION) RemoveHeadList(&pqh_pool->free_que);
-
- if (pqhe)
- {
- InitializeListHead(&pqhe->hori_link);
- InitializeListHead(&pqhe->vert_link);
- return pqhe->pqh;
- }
- return NULL;
-
-}
-
-BOOLEAN
-destroy_qh_pool(PUHCI_QH_POOL pqh_pool)
-{
- if (pqh_pool)
- {
- usb_free_mem(pqh_pool->qhe_array);
-
- HalFreeCommonBuffer(pqh_pool->padapter,
- sizeof(UHCI_QH) * UHCI_MAX_POOL_QHS,
- pqh_pool->logic_addr, pqh_pool->qh_array, FALSE);
-
- RtlZeroMemory(pqh_pool, sizeof(UHCI_QH_POOL));
-
- }
- else
- return FALSE;
-
- return TRUE;
-}
-
-VOID
-lock_qh_pool(PUHCI_QH_POOL pool, BOOLEAN at_dpc)
-{
- //if( !at_dpc )
- // KeAcquireSpinLock( &pool->pool_lock );
- //else
- // KeAcquireSpinLockAtDpcLevel( &pool->pool_lock );
-}
-
-VOID
-unlock_qh_pool(PUHCI_QH_POOL pool, BOOLEAN at_dpc)
-{
- //if( !at_dpc )
- // KeReleaseSpinLock( &pool->pool_lock );
- //else
- // KeReleaseSpinLockFromDpcLevel( &pool->pool_lock );
-}
diff --git a/reactos/drivers/usb/nt4compat/usbdrv/td.h b/reactos/drivers/usb/nt4compat/usbdrv/td.h
deleted file mode 100644
index ec2afa8ac8a..00000000000
--- a/reactos/drivers/usb/nt4compat/usbdrv/td.h
+++ /dev/null
@@ -1,1049 +0,0 @@
-/*
- * NOTE!!!: part of the code is pasted from linux/driver/usb/uhci.h
- */
-
-#ifndef __UHCI_H__
-#define __UHCI_H__
-
-#define LIST_HEAD LIST_ENTRY
-#define PLIST_HEAD PLIST_ENTRY
-#define BYTE UCHAR
-#define PBYTE PUCHAR
-#define WORD USHORT
-#define DWORD ULONG
-
-#ifndef LOWORD
-#define LOWORD(l) ( (WORD) ( ( l ) & 0xffff ) )
-#endif
-#ifndef HIWORD
-#define HIWORD(l) ( (WORD) ( ( l ) >> 16 ) )
-#endif
-
-#define PCI_MAX_FUNCTIONS 8
-
-
-#define UHCI_MAX_POOL_TDS 1024 //8 pages of 4k
-#define UHCI_MAX_POOL_QHS 256 //1 page of 4k
-#define UHCI_MAX_ANT_TDS 0x20e82
-
-#define UHCI_MAX_TD_POOLS 8
-#define UHCI_MAX_TDS_PER_TRANSFER UHCI_MAX_POOL_TDS
-
-#define UHCI_FULL_SPEED_BANDWIDHT ( 12 * 1000 * 1000 )
-#define UHCI_LOW_SPEED_BANDWIDHT ( 15 * 100 * 1000 )
-/*
- * Universal Host Controller Interface data structures and defines
- */
-
-/* Command register */
-#define USBCMD 0
-#define USBCMD_RS 0x0001 /* Run/Stop */
-#define USBCMD_HCRESET 0x0002 /* Host reset */
-#define USBCMD_GRESET 0x0004 /* Global reset */
-#define USBCMD_EGSM 0x0008 /* Global Suspend Mode */
-#define USBCMD_FGR 0x0010 /* Force Global Resume */
-#define USBCMD_SWDBG 0x0020 /* SW Debug mode */
-#define USBCMD_CF 0x0040 /* Config Flag (sw only) */
-#define USBCMD_MAXP 0x0080 /* Max Packet (0 = 32, 1 = 64) */
-
-/* Status register */
-#define USBSTS 2
-#define USBSTS_USBINT 0x0001 /* Interrupt due to IOC */
-#define USBSTS_ERROR 0x0002 /* Interrupt due to error */
-#define USBSTS_RD 0x0004 /* Resume Detect */
-#define USBSTS_HSE 0x0008 /* Host System Error - basically PCI problems */
-#define USBSTS_HCPE 0x0010 /* Host Controller Process Error - the scripts were buggy */
-#define USBSTS_HCH 0x0020 /* HC Halted */
-
-/* Interrupt enable register */
-#define USBINTR 4
-#define USBINTR_TIMEOUT 0x0001 /* Timeout/CRC error enable */
-#define USBINTR_RESUME 0x0002 /* Resume interrupt enable */
-#define USBINTR_IOC 0x0004 /* Interrupt On Complete enable */
-#define USBINTR_SP 0x0008 /* Short packet interrupt enable */
-
-#define USBFRNUM 6
-#define USBFLBASEADD 8
-#define USBSOF 12
-
-/* USB port status and control registers */
-#define USBPORTSC1 16
-#define USBPORTSC2 18
-#define USBPORTSC_CCS 0x0001 /* Current Connect Status ("device present") */
-#define USBPORTSC_CSC 0x0002 /* Connect Status Change */
-#define USBPORTSC_PE 0x0004 /* Port Enable */
-#define USBPORTSC_PEC 0x0008 /* Port Enable Change */
-#define USBPORTSC_LS 0x0020 /* Line Status */
-#define USBPORTSC_RD 0x0040 /* Resume Detect */
-#define USBPORTSC_LSDA 0x0100 /* Low Speed Device Attached */
-#define USBPORTSC_PR 0x0200 /* Port Reset */
-#define USBPORTSC_SUSP 0x1000 /* Suspend */
-
-/* Legacy support register */
-#define USBLEGSUP 0xc0
-#define USBLEGSUP_DEFAULT 0x2000 /* only PIRQ enable set */
-#define USBLEGSUP_RWC 0x8f00 /* the R/WC bits */
-#define USBLEGSUP_RO 0x5040 /* R/O and reserved bits */
-
-
-#define UHCI_NULL_DATA_SIZE 0x7FF /* for UHCI controller TD */
-
-#define UHCI_PTR_BITS 0x000F
-#define UHCI_PTR_TERM 0x0001
-#define UHCI_PTR_QH 0x0002
-#define UHCI_PTR_DEPTH 0x0004
-
-#define UHCI_MAX_FRAMES 1024 /* in the frame list [array] */
-#define UHCI_MAX_SOF_NUMBER 2047 /* in an SOF packet */
-#define CAN_SCHEDULE_FRAMES 1000 /* how far future frames can be scheduled */
-
-
-//from linux's uhci.h
-#define UHCI_MAX_SKELTDS 10
-#define skel_int1_td skel_td[0]
-#define skel_int2_td skel_td[1]
-#define skel_int4_td skel_td[2]
-#define skel_int8_td skel_td[3]
-#define skel_int16_td skel_td[4]
-#define skel_int32_td skel_td[5]
-#define skel_int64_td skel_td[6]
-#define skel_int128_td skel_td[7]
-#define skel_int256_td skel_td[8]
-#define skel_term_td skel_td[9] /* To work around PIIX UHCI bug */
-
-#define UHCI_MAX_SKELQHS 4
-#define skel_ls_control_qh skel_qh[0]
-#define skel_hs_control_qh skel_qh[1]
-#define skel_bulk_qh skel_qh[2]
-#define skel_term_qh skel_qh[3]
-
-
-
-struct URB;
-
-/*
- * for TD :
- */
-#define TD_CTRL_SPD (1 << 29) /* Short Packet Detect */
-#define TD_CTRL_C_ERR_MASK (3 << 27) /* Error Counter bits */
-#define TD_CTRL_C_ERR_SHIFT 27
-#define TD_CTRL_LS (1 << 26) /* Low Speed Device */
-#define TD_CTRL_IOS (1 << 25) /* Isochronous Select */
-#define TD_CTRL_IOC (1 << 24) /* Interrupt on Complete */
-#define TD_CTRL_ACTIVE (1 << 23) /* TD Active */
-#define TD_CTRL_STALLED (1 << 22) /* TD Stalled */
-#define TD_CTRL_DBUFERR (1 << 21) /* Data Buffer Error */
-#define TD_CTRL_BABBLE (1 << 20) /* Babble Detected */
-#define TD_CTRL_NAK (1 << 19) /* NAK Received */
-#define TD_CTRL_CRCTIMEO (1 << 18) /* CRC/Time Out Error */
-#define TD_CTRL_BITSTUFF (1 << 17) /* Bit Stuff Error */
-#define TD_CTRL_ACTLEN_MASK 0x7FF /* actual length, encoded as n - 1 */
-
-#define TD_CTRL_ANY_ERROR (TD_CTRL_STALLED | TD_CTRL_DBUFERR | \
- TD_CTRL_BABBLE | TD_CTRL_CRCTIMEO | TD_CTRL_BITSTUFF)
-
-#define uhci_status_bits(ctrl_sts) (ctrl_sts & 0xFE0000)
-#define uhci_actual_length(ctrl_sts) ((ctrl_sts + 1) & TD_CTRL_ACTLEN_MASK) /* 1-based */
-
-/*
- * for TD : (a.k.a. Token)
- */
-#define TD_TOKEN_TOGGLE 19
-#define TD_PID 0xFF
-
-#define uhci_maxlen(token) ((token) >> 21)
-#define uhci_expected_length(info) (((info >> 21) + 1) & TD_CTRL_ACTLEN_MASK) /* 1-based */
-#define uhci_toggle(token) (((token) >> TD_TOKEN_TOGGLE) & 1)
-#define uhci_endpoint(token) (((token) >> 15) & 0xf)
-#define uhci_devaddr(token) (((token) >> 8) & 0x7f)
-#define uhci_devep(token) (((token) >> 8) & 0x7ff)
-#define uhci_packetid(token) ((token) & 0xff)
-#define uhci_packetout(token) (uhci_packetid(token) != USB_PID_IN)
-#define uhci_packetin(token) (uhci_packetid(token) == USB_PID_IN)
-
-/*
- * The documentation says "4 dwords for hardware, 4 dwords for software".
- *
- * That's silly, the hardware doesn't care. The hardware only cares that
- * the hardware words are 16-byte aligned, and we can have any amount of
- * sw space after the TD entry as far as I can tell.
- *
- * But let's just go with the documentation, at least for 32-bit machines.
- * On 64-bit machines we probably want to take advantage of the fact that
- * hw doesn't really care about the size of the sw-only area.
- *
- * Alas, not anymore, we have more than 4 dwords for software, woops.
- * Everything still works tho, surprise! -jerdfelt
- */
-
-#define UHCI_ITEM_FLAG_TYPE 0x3
-#define UHCI_ITEM_FLAG_TD 0x0
-#define UHCI_ITEM_FLAG_QH 0x1
-
-#ifndef offsetof
-#define offsetof( s, m ) ( ( ULONG )( &( ( s* )0 )->m ) )
-#endif
-
-#define struct_ptr( meMBER_ptr, stRUCT_name, meMBER_name ) \
-( ( stRUCT_name* ) ( ( (CHAR*)( meMBER_ptr ) ) - offsetof( stRUCT_name, meMBER_name ) ) )
-
-#define dev_state( pdEV ) ( ( pdEV )->flags & USB_DEV_STATE_MASK )
-
-#define dev_class( pdev ) ( pdev->flags & USB_DEV_CLASS_MASK )
-
-#define uhci_from_hcd( hCD ) ( struct_ptr( ( hCD ), UHCI_DEV, hcd_interf ) )
-#define uhci_from_dev( dEV ) ( struct_ptr( ( dEV->hcd ), UHCI_DEV, hcd_interf ) )
-
-typedef struct _TD_EXTENSION
-{
- LIST_ENTRY vert_link; // urb will use this to link qh and tds
- LIST_ENTRY hori_link;
- ULONG flags;
- struct _UHCI_TD *ptd; //link to is companion td, constant since initialized
-
-} TD_EXTENSION, *PTD_EXTENSION;
-
-typedef struct _UHCI_TD
-{
- /* Hardware fields */
- ULONG link;
- ULONG status;
- ULONG info;
- ULONG buffer;
-
- /* Software fields */
- ULONG phy_addr;
- PTD_EXTENSION ptde;
- struct _URB *purb;
- struct _UHCI_TD_POOL *pool; //pool this td belongs to
-
-} UHCI_TD, *PUHCI_TD;
-
-typedef struct _UHCI_TD_POOL
-{
-
- LIST_ENTRY pool_link; //link to next and prev td pool
- PUHCI_TD td_array[ sizeof( UHCI_TD ) * UHCI_MAX_POOL_TDS / PAGE_SIZE ]; //would be allcated in common buffer
- PHYSICAL_ADDRESS logic_addr[ sizeof( UHCI_TD ) * UHCI_MAX_POOL_TDS / PAGE_SIZE ]; //logical addr of the array
-
- PTD_EXTENSION tde_array;
- LIST_ENTRY free_que; //list of free tds
- LONG free_count; //free tds in this pool
- LONG total_count; //total count of the tds
- PADAPTER_OBJECT padapter;
-
-} UHCI_TD_POOL, *PUHCI_TD_POOL;
-
-BOOLEAN
-init_td_pool(
-PUHCI_TD_POOL pool
-);
-
-BOOLEAN
-free_td_to_pool(
-PUHCI_TD_POOL pool,
-PUHCI_TD ptd
-); //add tds till pnext == NULL
-
-PUHCI_TD
-alloc_td_from_pool(
-PUHCI_TD_POOL ptd_pool
-); //null if failed]
-
-BOOLEAN
-is_pool_free(
-PUHCI_TD_POOL pool
-); //test whether the pool is all free
-
-BOOLEAN
-is_pool_full(
-PUHCI_TD_POOL pool
-);
-
-BOOLEAN
-destroy_td_pool(
-PUHCI_TD_POOL pool
-);
-
-typedef struct _UHCI_TD_POOL_LIST
-{
- LIST_ENTRY busy_pools;
- KSPIN_LOCK pool_lock;
- LONG free_tds; //free tds in all the pool
- LONG free_count; //free pool count
- LIST_ENTRY free_pools;
- UHCI_TD_POOL pool_array[UHCI_MAX_TD_POOLS]; //max transfer is 640k
-
-} UHCI_TD_POOL_LIST, *PUHCI_TD_POOL_LIST;
-
-BOOLEAN
-init_td_pool_list(
-PUHCI_TD_POOL_LIST pool_list,
-PADAPTER_OBJECT padapter
-);
-
-BOOLEAN
-destroy_td_pool_list(
-PUHCI_TD_POOL_LIST pool_list
-);
-
-BOOLEAN
-expand_pool_list(
-PUHCI_TD_POOL_LIST pool_list,
-LONG pool_count
-); //private
-
-BOOLEAN
-collect_garbage(
-PUHCI_TD_POOL_LIST pool_list
-);
-
-LONG
-get_free_tds(
-PUHCI_TD_POOL_LIST pool_list
-); //private
-
-LONG
-get_max_free_tds(
-PUHCI_TD_POOL_LIST pool_list
-); //private
-
-BOOLEAN
-can_transfer(
-PUHCI_TD_POOL_LIST pool_list,
-LONG td_count);
-
-BOOLEAN
-free_td(
-PUHCI_TD_POOL_LIST pool_list,
-PUHCI_TD ptd
-); //add tds till pnext == NULL
-
-PUHCI_TD
-alloc_td(
-PUHCI_TD_POOL_LIST pool_list
-); //null if failed
-
-VOID
-lock_td_pool(
-PUHCI_TD_POOL_LIST pool_list,
-BOOLEAN at_dpc
-);
-
-VOID
-unlock_td_pool(
-PUHCI_TD_POOL_LIST pool_list,
-BOOLEAN at_dpc
-);
-
-typedef struct _UHCI_QH
-{
- /* Hardware fields */
- ULONG link; // Next queue
- ULONG element; // Queue element pointer
-
- /* Software fields */
- ULONG phy_addr; //constant since initialized
- struct _QH_EXTENSION *pqhe;
-
-} UHCI_QH, *PUHCI_QH;
-
-typedef struct _QH_EXTENSION
-{
-
- LIST_ENTRY vert_link;
- LIST_ENTRY hori_link;
- ULONG flags;
- PUHCI_QH pqh; //constant since initialized
- struct _URB *purb;
-
-} QH_EXTENSION, *PQH_EXTENSION;
-
-typedef struct _UHCI_QH_POOL
-{
-
- PUHCI_QH qh_array;
- PHYSICAL_ADDRESS logic_addr; //logical addr of the array
-
- PQH_EXTENSION qhe_array;
- LIST_ENTRY free_que;
- LONG free_count;
- LONG total_count;
- KSPIN_LOCK pool_lock;
- PADAPTER_OBJECT padapter; //we need this garbage for allocation
-
-} UHCI_QH_POOL, *PUHCI_QH_POOL;
-
-
-BOOLEAN
-init_qh_pool(
-PUHCI_QH_POOL pool,
-PADAPTER_OBJECT padapter
-);
-
-BOOLEAN
-free_qh(
-PUHCI_QH_POOL pool,
-PUHCI_QH ptd
-); //add qhs till pnext == NULL
-
-PUHCI_QH
-alloc_qh(
-PUHCI_QH_POOL pool
-); //null if failed
-
-BOOLEAN
-destroy_qh_pool(
-PUHCI_QH_POOL pool
-);
-
-VOID
-lock_qh_pool(
-PUHCI_QH_POOL pool,
-BOOLEAN at_dpc
-);
-
-VOID
-unlock_qh_pool(
-PUHCI_QH_POOL pool,
-BOOLEAN at_dpc
-);
-
-/*
- * Search tree for determining where fits in the
- * skelqh[] skeleton.
- *
- * An interrupt request should be placed into the slowest skelqh[]
- * which meets the interval/period/frequency requirement.
- * An interrupt request is allowed to be faster than but not slower.
- *
- * For a given , this function returns the appropriate/matching
- * skelqh[] index value.
- *
- * NOTE: For UHCI, we don't really need int256_qh since the maximum interval
- * is 255 ms. However, we do need an int1_qh since 1 is a valid interval
- * and we should meet that frequency when requested to do so.
- * This will require some change(s) to the UHCI skeleton.
- */
-#if 0
-static int __interval_to_skel(int interval)
-{
- if (interval < 16) {
- if (interval < 4) {
- if (interval < 2)
- return 0; /* int1 for 0-1 ms */
- return 1; /* int2 for 2-3 ms */
- }
- if (interval < 8)
- return 2; /* int4 for 4-7 ms */
- return 3; /* int8 for 8-15 ms */
- }
- if (interval < 64) {
- if (interval < 32)
- return 4; /* int16 for 16-31 ms */
- return 5; /* int32 for 32-63 ms */
- }
- if (interval < 128)
- return 6; /* int64 for 64-127 ms */
- return 7; /* int128 for 128-255 ms (Max.) */
-}
-#endif
-
-#define USB_ENDP_FLAG_BUSY_MASK 0x0000ff00
-#define USB_ENDP_FLAG_STAT_MASK 0xff
-#define USB_ENDP_FLAG_STALL 0x01
-#define USB_ENDP_FLAG_DATATOGGLE 0x80000000
-#define USB_ENDP_FLAG_DEFAULT_ENDP 0x40000000
-
-#define usb_endp_busy_count( peNDP ) \
-( ( ( peNDP )->flags & USB_ENDP_FLAG_BUSY_MASK ) >> 8 )
-
-#define usb_endp_busy_count_inc( peNDP ) \
-( peNDP->flags = ( ( ( ( usb_endp_busy_count( peNDP ) + 1 ) << 8 ) & USB_ENDP_FLAG_BUSY_MASK ) | \
-( ( peNDP )->flags & ~USB_ENDP_FLAG_BUSY_MASK ) ) )
-
-#define usb_endp_busy_count_dec( peNDP ) \
-( peNDP->flags = ( ( ( ( usb_endp_busy_count( peNDP ) - 1 ) << 8 ) & USB_ENDP_FLAG_BUSY_MASK )| \
-( ( peNDP )->flags & ~USB_ENDP_FLAG_BUSY_MASK ) ) )
-
-typedef struct _USB_ENDPOINT
-{
- ULONG flags; //toggle | busy-count | stall | default-endp; busy count( usually 1 when busy, may be greater if iso endp )
- LIST_ENTRY urb_list; //pending urb queue
-
- struct _USB_INTERFACE *pusb_if;
- struct _USB_ENDPOINT_DESC *pusb_endp_desc;
-
-} USB_ENDPOINT, *PUSB_ENDPOINT;
-
-#define MAX_ENDPS_PER_IF 10
-
-typedef struct _USB_INTERFACE
-{
- UCHAR endp_count;
- USB_ENDPOINT endp[MAX_ENDPS_PER_IF];
-
-
- struct _USB_CONFIGURATION *pusb_config;
- PUSB_INTERFACE_DESC pusb_if_desc;
-
- struct _USB_DRIVER *pif_drv; //for hub_dev use
- PVOID if_ext;
- LONG if_ext_size;
- UCHAR altif_count;
- LIST_ENTRY altif_list;
-
-
-} USB_INTERFACE, *PUSB_INTERFACE;
-
-#define MAX_INTERFACES_PER_CONFIG 4
-#define MAX_CONFIGS_PER_DEV 4
-
-typedef struct _USB_CONFIGURATION
-{
- //only for active configuration
- struct _USB_CONFIGURATION_DESC *pusb_config_desc;
- UCHAR if_count;
- USB_INTERFACE interf[MAX_INTERFACES_PER_CONFIG];
- struct _USB_DEV *pusb_dev;
-
-} USB_CONFIGURATION, *PUSB_CONFIGURATION;
-
-#define USE_IRQL \
-KIRQL _pending_endp_lock_old_irql=0, _pending_endp_list_lock_old_irql=0, _dev_lock_old_irql=0, old_irql=0;
-
-#define USE_BASIC_IRQL \
-KIRQL _pending_endp_list_lock_old_irql=0, _dev_lock_old_irql=0;
-
-#define USE_NON_PENDING_IRQL \
-KIRQL _dev_lock_old_irql=0, old_irql=0;
-
-#define USE_BASIC_NON_PENDING_IRQL \
-KIRQL _dev_lock_old_irql=0;
-
-
-#define USB_DEV_STATE_MASK ( 0xff << 8 )
-#define USB_DEV_STATE_POWERED ( 0x01 << 8 )
-#define USB_DEV_STATE_RESET ( 0x02 << 8 )
-#define USB_DEV_STATE_ADDRESSED ( 0x03 << 8 )
-#define USB_DEV_STATE_FIRST_CONFIG ( 0x04 << 8 )
-#define USB_DEV_STATE_RECONFIG ( 0x05 << 8 )
-#define USB_DEV_STATE_CONFIGURED ( 0x06 << 8 )
-#define USB_DEV_STATE_SUSPENDED ( 0x07 << 8 )
-#define USB_DEV_STATE_BEFORE_ZOMB ( 0x08 << 8 )
-#define USB_DEV_STATE_ZOMB ( 0x09 << 8 )
-
-#define USB_DEV_CLASS_MASK ( 0xff << 16 )
-#define USB_DEV_CLASS_HUB ( USB_CLASS_HUB << 16 )
-#define USB_DEV_CLASS_MASSSTOR ( USB_CLASS_MASS_STORAGE << 16 )
-#define USB_DEV_CLASS_ROOT_HUB ( ( USB_CLASS_VENDOR_SPEC - 2 ) << 16 )
-#define USB_DEV_CLASS_SCANNER ( ( USB_DEV_CLASS_ROOT_HUB - 1 ) << 16 )
-
-#define USB_DEV_FLAG_HIGH_SPEED 0x20 // high speed dev for usb2.0
-#define USB_DEV_FLAG_LOW_SPEED 0x40 // note: this bit is shared in urb->pipe
-#define USB_DEV_FLAG_IF_DEV 0x01 // this dev is a virtual dev, that is a interface
-
-#define lock_dev( pdev, at_dpc ) \
-{\
- KIRQL cur_irql;\
- cur_irql = KeGetCurrentIrql();\
- if( cur_irql == DISPATCH_LEVEL )\
- {\
- KeAcquireSpinLockAtDpcLevel( &pdev->dev_lock );\
- _dev_lock_old_irql = DISPATCH_LEVEL;\
- }\
- else if( cur_irql < DISPATCH_LEVEL )\
- KeAcquireSpinLock( &pdev->dev_lock, &_dev_lock_old_irql );\
- else\
- TRAP();\
-}
-
-#define unlock_dev( pdev, from_dpc ) \
-{\
- if( _dev_lock_old_irql == DISPATCH_LEVEL )\
- KeReleaseSpinLockFromDpcLevel( &pdev->dev_lock );\
- else if( _dev_lock_old_irql < DISPATCH_LEVEL )\
- KeReleaseSpinLock( &pdev->dev_lock, _dev_lock_old_irql );\
- else\
- TRAP();\
-}
-
-typedef struct _USB_DEV
-{
- LIST_ENTRY dev_link; //for dev-list
-
- KSPIN_LOCK dev_lock;
- PDEVICE_OBJECT dev_obj;
- ULONG flags; //class | cur_state | low speed
- LONG ref_count; //client count
-
- UCHAR dev_addr; //usb addr
- ULONG dev_id; //will be used to compose dev handle
-
- struct _USB_DEV *parent_dev;
- UCHAR port_idx; //parent hub's port idx, to which the dev attached
-
- struct _HCD *hcd; //point to the hcd the dev belongs to
-
- USB_ENDPOINT default_endp; //control endp. its interfac pointer is to the first interface
-
- LONG desc_buf_size;
- PUCHAR desc_buf;
- struct _USB_DEVICE_DESC *pusb_dev_desc;
-
- UCHAR active_config_idx;
- PUSB_CONFIGURATION usb_config; //the active configuration
-
- struct _USB_DRIVER *dev_driver;
- PVOID dev_ext;
- LONG dev_ext_size;
-
- LONG time_out_count; //default pipe error counter, three time-outs will cause the dev not function
- LONG error_count; //usb transfer error counter for statics only
-
-} USB_DEV, *PUSB_DEV;
-
-// pending endpoint pool definitions
-
-#define UHCI_MAX_PENDING_ENDPS 32
-
-typedef struct _UHCI_PENDING_ENDP
-{
- LIST_ENTRY endp_link;
- PUSB_ENDPOINT pendp;
-
-} UHCI_PENDING_ENDP, *PUHCI_PENDING_ENDP;
-
-typedef struct _UHCI_PENDING_ENDP_POOL
-{
- PUHCI_PENDING_ENDP pending_endp_array;
- LIST_ENTRY free_que;
- LONG free_count;
- LONG total_count;
- KSPIN_LOCK pool_lock;
-
-} UHCI_PENDING_ENDP_POOL, *PUHCI_PENDING_ENDP_POOL;
-
-BOOLEAN
-init_pending_endp_pool(
-PUHCI_PENDING_ENDP_POOL pool
-);
-
-BOOLEAN
-free_pending_endp(
-PUHCI_PENDING_ENDP_POOL pool,
-PUHCI_PENDING_ENDP pending_endp
-);
-
-PUHCI_PENDING_ENDP
-alloc_pending_endp(
-PUHCI_PENDING_ENDP_POOL pool,
-LONG count
-);
-
-BOOLEAN
-destroy_pending_endp_pool(
-PUHCI_PENDING_ENDP_POOL pool
-);
-
-// pool type is PUHCI_PENDING_ENDP_POOL
-#define lock_pending_endp_pool( pool ) \
-{\
- KeAcquireSpinLock( &pool->pool_lock, &_pending_endp_lock_old_irql );\
-}
-
-#define unlock_pending_endp_pool( pool ) \
-{\
- KeReleaseSpinLock( &pool->pool_lock, &_pending_endp_lock_old_irql );\
-}
-
-
-// end of pending endpoint pool
-typedef struct _FRAME_LIST_CPU_ENTRY
-{
- LIST_ENTRY td_link;
-
-} FRAME_LIST_CPU_ENTRY, *PFRAME_LIST_CPU_ENTRY;
-
-#define uhci_public_res_lock pending_endp_list_lock
-#define uhci_status( _uhci_ ) ( READ_PORT_USHORT( ( PUSHORT )( ( _uhci_ )->port_base + USBSTS ) ) )
-
-typedef struct _UHCI
-{
- PHYSICAL_ADDRESS uhci_reg_base; // io space
- BOOLEAN port_mapped;
- PBYTE port_base;
-
- PHYSICAL_ADDRESS io_buf_logic_addr;
- PBYTE io_buf;
-
- PHYSICAL_ADDRESS frame_list_logic_addr;
-
- KSPIN_LOCK frame_list_lock; //run at DIRQL
- PULONG frame_list;
- PFRAME_LIST_CPU_ENTRY frame_list_cpu;
- LIST_HEAD urb_list; //active urb-list
- PUHCI_TD skel_td[UHCI_MAX_SKELTDS];
- PUHCI_QH skel_qh[UHCI_MAX_SKELQHS]; //skeltons
-
-
-
- UHCI_TD_POOL_LIST td_pool;
- UHCI_QH_POOL qh_pool;
-
-
- //for iso and int bandwidth claim, bandwidth schedule
- KSPIN_LOCK pending_endp_list_lock; //lock to access the following two
- LIST_HEAD pending_endp_list;
- UHCI_PENDING_ENDP_POOL pending_endp_pool;
- PLONG frame_bw;
- LONG fsbr_cnt; //used to record number of fsbr users
-
- KTIMER reset_timer; //used to reset the host controller
-
- //struct _USB_DEV_MANAGER dev_mgr; //it is in hcd_interf
- struct _DEVICE_EXTENSION *pdev_ext;
-
- PUSB_DEV root_hub; //root hub
- HCD hcd_interf;
-
-} UHCI_DEV, *PUHCI_DEV;
-
-#define lock_pending_endp_list( list_lock ) \
-{\
- KeAcquireSpinLock( list_lock, &_pending_endp_list_lock_old_irql );\
-}
-
-#define unlock_pending_endp_list( list_lock ) \
-{\
- KeReleaseSpinLock( list_lock, _pending_endp_list_lock_old_irql );\
-}
-typedef struct _UHCI_INTERRUPT
-{
- ULONG level;
- ULONG vector;
- ULONG affinity;
-
-} UHCI_INTERRUPT, *PUHCI_INTERRUPT;
-
-typedef struct _UHCI_PORT
-{
- PHYSICAL_ADDRESS Start;
- ULONG Length;
-
-} UHCI_PORT, *PUHCI_PORT;
-
-typedef NTSTATUS ( *PDISPATCH_ROUTINE )( PDEVICE_OBJECT dev_obj, PIRP irp );
-
-#define NTDEV_TYPE_HCD 1
-#define NTDEV_TYPE_CLIENT_DEV 2
-
-typedef struct _DEVEXT_HEADER
-{
- ULONG type;
- PDISPATCH_ROUTINE dispatch;
- PDRIVER_STARTIO start_io;
-
- struct _USB_DEV_MANAGER *dev_mgr; //mainly for use by cancel irp
-
-} DEVEXT_HEADER, *PDEVEXT_HEADER;
-
-typedef struct _DEVICE_EXTENSION
-{
- //struct _USB_DEV_MANAGER *pdev_mgr;
- DEVEXT_HEADER dev_ext_hdr;
- PDEVICE_OBJECT pdev_obj;
- PDRIVER_OBJECT pdrvr_obj;
- PUHCI_DEV uhci;
-
- //device resources
- PADAPTER_OBJECT padapter;
- ULONG map_regs;
- PCM_RESOURCE_LIST res_list;
- ULONG pci_addr; // bus number | slot number | funciton number
- UHCI_INTERRUPT res_interrupt;
- UHCI_PORT res_port;
-
- PKINTERRUPT uhci_int;
- KDPC uhci_dpc;
-
-} DEVICE_EXTENSION, *PDEVICE_EXTENSION;
-
-//helper macro
-#define ListFirst( heAD, firST) \
-{\
- if( IsListEmpty( ( heAD ) ) )\
- firST = NULL;\
- else\
- firST = ( heAD )->Flink;\
-}
-
-#define ListNext( heAD, curreNT, neXT) \
-{\
- if( IsListEmpty( ( heAD ) ) == FALSE )\
- {\
- neXT = (curreNT)->Flink;\
- if( neXT == heAD )\
- neXT = NULL;\
- }\
- else\
- neXT = NULL;\
-}
-
-#define ListPrev( heAD, curreNT, prEV) \
-{\
- if( IsListEmpty( ( heAD ) ) == FALSE )\
- {\
- prEV = (curreNT)->Blink;\
- if( prEV == heAD )\
- prEV = NULL;\
- else\
- prEV = NULL;\
-}
-
-#define ListFirstPrev( heAD, firST) \
-{\
- if( IsListEmpty( ( heAD ) ) )\
- firST = NULL;\
- else\
- firST = ( heAD )->Blink;\
-}
-
-#define MergeList( liST1, liST2 )\
-{\
- PLIST_ENTRY taIL1, taIL2;\
- if( IsListEmpty( liST2 ) == TRUE )\
- {\
- InsertTailList( liST1, liST2 );\
- }\
- else if( IsListEmpty( liST1 ) == TRUE )\
- {\
- InsertTailList( liST2, liST1 );\
- }\
- else\
- {\
- ListFirstPrev( liST1, taIL1 );\
- ListFirstPrev( liST2, taIL2 );\
-\
- taIL1->Flink = ( liST2 );\
- ( liST2 )->Blink = taIL1;\
-\
- taIL2->Flink = ( liST1 );\
- ( liST1 )->Blink = taIL2;\
- }\
-}
-
-PUHCI_TD
-alloc_tds(
-PUHCI_TD_POOL_LIST pool_list,
-LONG count
-);
-
-VOID
-free_tds(
-PUHCI_TD_POOL_LIST pool_list,
-PUHCI_TD ptd
-);
-
-BOOLEAN
-uhci_init(
-PUHCI_DEV uhci,
-PADAPTER_OBJECT padapter
-);
-
-BOOLEAN
-uhci_destroy(
-PUHCI_DEV uhci
-);
-
-// funcitons exported to dev-manager
-BOOLEAN
-uhci_add_device(
-PUHCI_DEV uhci,
-PUSB_DEV dev
-);
-
-BOOLEAN
-uhci_remove_device(
-PUHCI_DEV uhci,
-PUSB_DEV dev
-);
-
-//helpers
-VOID NTAPI
-uhci_dpc_callback(
-PKDPC dpc,
-PVOID context,
-PVOID sysarg1,
-PVOID sysarg2
-);
-
-#if 0
-static VOID
-uhci_flush_adapter_buf()
-{
-#ifdef _X86
- __asm invd;
-#endif
-}
-#endif
-
-NTSTATUS
-uhci_submit_urb(
-PUHCI_DEV uhci,
-PUSB_DEV pdev,
-PUSB_ENDPOINT pendp,
-struct _URB *urb
-);
-
-//must have dev_lock acquired
-NTSTATUS
-uhci_internal_submit_bulk(
-PUHCI_DEV uhci,
-struct _URB *urb
-);
-
-NTSTATUS
-uhci_internal_submit_iso(
-PUHCI_DEV uhci,
-struct _URB *urb
-);
-
-NTSTATUS
-uhci_internal_submit_ctrl(
-PUHCI_DEV uhci,
-struct _URB *urb
-);
-
-NTSTATUS
-uhci_internal_submit_int(
-PUHCI_DEV uhci,
-struct _URB *urb
-);
-
-BOOLEAN
-uhci_remove_bulk_from_schedule(
-PUHCI_DEV uhci,
-struct _URB *urb
-);
-
-#define uhci_remove_ctrl_from_schedule uhci_remove_bulk_from_schedule
-
-BOOLEAN
-uhci_remove_iso_from_schedule(
-PUHCI_DEV uhci,
-struct _URB *urb
-);
-
-BOOLEAN
-uhci_remove_int_from_schedule(
-PUHCI_DEV uhci,
-struct _URB *urb
-);
-
-BOOLEAN
-uhci_remove_urb_from_schedule(
-PUHCI_DEV uhci,
-struct _URB *urb
-);
-
-BOOLEAN
-uhci_is_xfer_finished( //will set urb error code here
-struct _URB *urb
-);
-
-NTSTATUS
-uhci_set_error_code(
-struct _URB *urb,
-ULONG raw_status
-);
-
-BOOLEAN
-uhci_insert_tds_qh(
-PUHCI_QH pqh,
-PUHCI_TD td_chain
-);
-
-BOOLEAN
-uhci_insert_qh_urb(
-struct _URB *urb,
-PUHCI_QH qh_chain
-);
-
-BOOLEAN
-uhci_insert_urb_schedule(
-PUHCI_DEV uhci,
-struct _URB *urb
-);
-
-BOOLEAN
-uhci_claim_bandwidth(
-PUHCI_DEV uhci,
-struct _URB *urb,
-BOOLEAN claim_bw
-);
-
-BOOLEAN
-uhci_process_pending_endp(
-PUHCI_DEV uhci
-);
-
-NTSTATUS
-uhci_cancel_urb(
-PUHCI_DEV uhci,
-PUSB_DEV pdev,
-PUSB_ENDPOINT endp,
-struct _URB *urb
-);
-
-VOID
-uhci_generic_urb_completion(
-struct _URB *urb,
-PVOID context
-);
-
-// the following are NT driver definitions
-
-// NT device name
-#define UHCI_DEVICE_NAME "\\Device\\UHCI"
-
-// File system device name. When you execute a CreateFile call to open the
-// device, use "\\.\GpdDev", or, given C's conversion of \\ to \, use
-// "\\\\.\\GpdDev"
-
-#define DOS_DEVICE_NAME "\\DosDevices\\UHCI"
-
-
-#define CLR_RH_PORTSTAT( port_idx, x ) \
-{\
- PUSHORT addr; \
- addr = ( PUSHORT )( uhci->port_base + port_idx ); \
- status = READ_PORT_USHORT( addr ); \
- status = ( status & 0xfff5 ) & ~( x ); \
- WRITE_PORT_USHORT( addr, ( USHORT )status ); \
-}
-
-#define SET_RH_PORTSTAT( port_idx, x ) \
-{\
- PUSHORT addr; \
- addr = ( PUSHORT )( uhci->port_base + port_idx ); \
- status = READ_PORT_USHORT( addr ); \
- status = ( status & 0xfff5 ) | ( x ); \
- WRITE_PORT_USHORT( addr, ( USHORT )status ); \
-}
-
-//this is for dispatch routine
-#define EXIT_DISPATCH( nTstatUs, iRp)\
-{\
- if( nTstatUs != STATUS_PENDING)\
- {\
- iRp->IoStatus.Status = nTstatUs;\
- IoCompleteRequest( iRp, IO_NO_INCREMENT);\
- return nTstatUs;\
- }\
- IoMarkIrpPending( iRp);\
- return nTstatUs;\
-}
-
-#endif
-
diff --git a/reactos/drivers/usb/nt4compat/usbdrv/uhci.c b/reactos/drivers/usb/nt4compat/usbdrv/uhci.c
deleted file mode 100644
index 857498c4e00..00000000000
--- a/reactos/drivers/usb/nt4compat/usbdrv/uhci.c
+++ /dev/null
@@ -1,3897 +0,0 @@
-/**
- * uhci.c - USB driver stack project for Windows NT 4.0
- *
- * Copyright (c) 2002-2004 Zhiming mypublic99@yahoo.com
- *
- * This program/include file is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program/include file is distributed in the hope that it will be
- * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
- * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program (in the main directory of the distribution, the file
- * COPYING); if not, write to the Free Software Foundation,Inc., 59 Temple
- * Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "usbdriver.h"
-
-//----------------------------------------------------------
-// uhci routines
-//#define DEMO
-
-#ifdef INCLUDE_EHCI
-
-#define rh_port1_status rh_port_status[ 1 ]
-#define rh_port2_status rh_port_status[ 2 ]
-
-extern PDEVICE_OBJECT ehci_probe(PDRIVER_OBJECT drvr_obj, PUNICODE_STRING reg_path, PUSB_DEV_MANAGER dev_mgr);
-
-#endif
-
-#define DEFAULT_ENDP( enDP ) \
-( enDP->flags & USB_ENDP_FLAG_DEFAULT_ENDP )
-
-#define dev_from_endp( enDP ) \
-( DEFAULT_ENDP( enDP )\
- ? ( ( PUSB_DEV )( enDP )->pusb_if )\
- : ( ( enDP )->pusb_if->pusb_config->pusb_dev ) )
-
-#define endp_state( enDP ) ( ( enDP )->flags & USB_ENDP_FLAG_STAT_MASK )
-
-#define endp_num( enDP ) \
-( DEFAULT_ENDP( enDP )\
- ? 0 \
- : ( ( enDP )->pusb_endp_desc->bEndpointAddress & 0x0f ) )
-
-#define endp_dir( enDP ) \
-( DEFAULT_ENDP( enDP )\
- ? 0L\
- : ( ( enDP )->pusb_endp_desc->bEndpointAddress & USB_DIR_IN ) )
-
-#define dev_set_state( pdEV, staTE ) \
-( pdEV->flags = ( ( pdEV )->flags & ( ~USB_DEV_STATE_MASK ) ) | ( staTE ) )
-
-#define endp_max_packet_size( enDP ) \
-( DEFAULT_ENDP( enDP )\
- ? ( ( ( PUSB_DEV )enDP->pusb_if )->pusb_dev_desc ? \
- ( ( PUSB_DEV )enDP->pusb_if )->pusb_dev_desc->bMaxPacketSize0\
- : 8 )\
- : enDP->pusb_endp_desc->wMaxPacketSize )
-
-
-#define release_adapter( padapTER ) HalPutDmaAdapter(padapTER)
-
-#define get_int_idx( _urb, _idx ) \
-{\
- UCHAR interVAL;\
- interVAL = ( UCHAR )( ( _urb )->pipe >> 24 );\
- for( _idx = 1; _idx < 9; _idx++ )\
- {\
- interVAL >>= 1;\
- if( !interVAL )\
- break;\
- }\
- _idx --;\
-}
-
-#define uhci_insert_urb_to_schedule( uHCI, pURB, rET ) \
-{\
- SYNC_PARAM sync_param;\
- sync_param.uhci = uHCI;\
- sync_param.context = pURB;\
-\
- rET = KeSynchronizeExecution( uHCI->pdev_ext->uhci_int, uhci_sync_insert_urb_schedule, &sync_param );\
-}
-
-//declarations
-typedef struct
-{
- PUHCI_DEV uhci;
- PVOID context;
- ULONG ret;
-} SYNC_PARAM, *PSYNC_PARAM;
-
-PDEVICE_OBJECT
-uhci_alloc(PDRIVER_OBJECT drvr_obj, PUNICODE_STRING reg_path, ULONG bus_addr, PUSB_DEV_MANAGER dev_mgr);
-
-BOOLEAN uhci_init_schedule(PUHCI_DEV uhci, PADAPTER_OBJECT padapter);
-
-BOOLEAN uhci_release(PDEVICE_OBJECT pdev, PUSB_DEV_MANAGER dev_mgr);
-
-static VOID uhci_stop(PUHCI_DEV uhci);
-
-BOOLEAN uhci_destroy_schedule(PUHCI_DEV uhci);
-
-BOOLEAN NTAPI uhci_sync_insert_urb_schedule(PVOID context);
-
-VOID uhci_init_hcd_interface(PUHCI_DEV uhci);
-
-NTSTATUS uhci_rh_submit_urb(PUSB_DEV rh, PURB purb);
-
-NTSTATUS uhci_dispatch_irp(IN PDEVICE_OBJECT DeviceObject, IN PIRP irp);
-
-extern VOID rh_timer_svc_reset_port_completion(PUSB_DEV dev, PVOID context);
-
-extern VOID rh_timer_svc_int_completion(PUSB_DEV dev, PVOID context);
-
-ULONG debug_level = DBGLVL_MINIMUM;//DBGLVL_MAXIMUM;
-PDRIVER_OBJECT usb_driver_obj = NULL;
-extern USB_DEV_MANAGER g_dev_mgr;
-
-//pending endpoint pool funcs
-VOID
-uhci_wait_ms(PUHCI_DEV uhci, LONG ms)
-{
- LARGE_INTEGER lms;
- if (ms <= 0)
- return;
-
- lms.QuadPart = -10 * ms;
- KeSetTimer(&uhci->reset_timer, lms, NULL);
-
- KeWaitForSingleObject(&uhci->reset_timer, Executive, KernelMode, FALSE, NULL);
-
- return;
-}
-
-BOOLEAN
-init_pending_endp_pool(PUHCI_PENDING_ENDP_POOL pool)
-{
- int i;
- if (pool == NULL)
- return FALSE;
-
- pool->pending_endp_array =
- usb_alloc_mem(NonPagedPool, sizeof(UHCI_PENDING_ENDP) * UHCI_MAX_PENDING_ENDPS);
- InitializeListHead(&pool->free_que);
- pool->free_count = 0;
- pool->total_count = UHCI_MAX_PENDING_ENDPS;
- KeInitializeSpinLock(&pool->pool_lock);
-
- for(i = 0; i < MAX_TIMER_SVCS; i++)
- {
- free_pending_endp(pool, &pool->pending_endp_array[i]);
- }
-
- return TRUE;
-
-}
-
-BOOLEAN
-free_pending_endp(PUHCI_PENDING_ENDP_POOL pool, PUHCI_PENDING_ENDP pending_endp)
-{
- if (pool == NULL || pending_endp == NULL)
- {
- return FALSE;
- }
-
- RtlZeroMemory(pending_endp, sizeof(UHCI_PENDING_ENDP));
- InsertTailList(&pool->free_que, &pending_endp->endp_link);
- pool->free_count++;
-
- return TRUE;
-}
-
-PUHCI_PENDING_ENDP
-alloc_pending_endp(PUHCI_PENDING_ENDP_POOL pool, LONG count)
-{
- PUHCI_PENDING_ENDP new_endp;
- if (pool == NULL || count != 1)
- return NULL;
-
- if (pool->free_count <= 0)
- return NULL;
-
- new_endp = (PUHCI_PENDING_ENDP) RemoveHeadList(&pool->free_que);
- pool->free_count--;
- return new_endp;
-}
-
-BOOLEAN
-destroy_pending_endp_pool(PUHCI_PENDING_ENDP_POOL pool)
-{
- if (pool == NULL)
- return FALSE;
-
- InitializeListHead(&pool->free_que);
- pool->free_count = pool->total_count = 0;
- usb_free_mem(pool->pending_endp_array);
- pool->pending_endp_array = NULL;
-
- return TRUE;
-
-}
-
-
-//end of pending endpoint pool funcs
-
-static void
-uhci_fill_td(PUHCI_TD td, ULONG status, ULONG info, ULONG buffer)
-{
- td->status = status;
- td->info = info;
- td->buffer = buffer;
-}
-
-BOOLEAN
-uhci_insert_td_fl(PUHCI_TD prev_td, PUHCI_TD ptd)
-{
- PLIST_ENTRY temp_entry;
-
- if (prev_td == NULL || ptd == NULL)
- return FALSE;
-
- temp_entry = &prev_td->ptde->hori_link;
-
- ptd->link = (struct_ptr(temp_entry, TD_EXTENSION, hori_link))->ptd->phy_addr;
- prev_td->link = ptd->phy_addr;
-
- InsertHeadList(&prev_td->ptde->hori_link, &ptd->ptde->hori_link);
- return TRUE;
-}
-
-BOOLEAN
-uhci_remove_td_fl(PUHCI_TD ptd)
-{
- PUHCI_TD prev_td;
-
- if (ptd == NULL)
- return FALSE;
-
- prev_td = (struct_ptr(ptd->ptde->hori_link.Blink, TD_EXTENSION, hori_link))->ptd;
- prev_td->link = ptd->link;
- ptd->link = UHCI_PTR_TERM;
-
- RemoveEntryList(&ptd->ptde->hori_link);
-
- return FALSE;
-}
-
-BOOLEAN
-uhci_insert_qh_fl(PVOID prev_item, PUHCI_QH pqh)
-{
- //only horizontal link allowed
- PUHCI_QH pprev_qh;
- PUHCI_TD pprev_td;
- PLIST_ENTRY temp_entry;
-
- if (prev_item == NULL || pqh == NULL)
- return FALSE;
-
- if ((((PUHCI_TD) prev_item)->ptde->flags & UHCI_ITEM_FLAG_TYPE) == UHCI_ITEM_FLAG_QH)
- {
- pprev_qh = (PUHCI_QH) prev_item;
- temp_entry = pprev_qh->pqhe->hori_link.Flink;
- pqh->link = (struct_ptr(temp_entry, TD_EXTENSION, hori_link))->ptd->phy_addr;
- pprev_qh->link = pqh->phy_addr;
-
- InsertHeadList(&pprev_qh->pqhe->hori_link, &pqh->pqhe->hori_link);
- }
- else
- {
- pprev_td = ((PUHCI_TD) prev_item);
-
- temp_entry = pprev_td->ptde->hori_link.Flink;
- pprev_td->link = pqh->phy_addr;
- pqh->link = (struct_ptr(temp_entry, TD_EXTENSION, hori_link))->ptd->phy_addr;
-
- InsertHeadList(&pprev_td->ptde->hori_link, &pqh->pqhe->hori_link);
- }
-
- return FALSE;
-}
-
-BOOLEAN
-uhci_remove_qh_fl(PUHCI_QH pqh)
-{
- PVOID prev_item;
- PUHCI_QH pprevqh;
- PUHCI_TD pprevtd;
-
- if (pqh == NULL)
- return FALSE;
-
- prev_item = (struct_ptr(pqh->pqhe->hori_link.Blink, TD_EXTENSION, hori_link))->ptd;
-
- if ((((PUHCI_TD) prev_item)->ptde->flags & UHCI_ITEM_FLAG_TYPE) == UHCI_ITEM_FLAG_QH)
- {
- pprevqh = (PUHCI_QH) prev_item;
- pprevqh->link = pqh->link;
- }
- else
- {
- pprevtd = ((PUHCI_TD) prev_item);
- pprevtd->link = pqh->link;
- }
-
- RemoveEntryList(&pqh->pqhe->hori_link);
-
- pqh->link = UHCI_PTR_TERM;
- pqh->pqhe->hori_link.Flink = pqh->pqhe->hori_link.Blink = NULL;
-
- return TRUE;
-}
-
-BOOLEAN
-uhci_init_frame_list(PUHCI_DEV uhci, PADAPTER_OBJECT padapter)
-{
- int i;
- if (uhci == NULL || padapter == NULL)
- return FALSE;
-
- //note: frame_list_lock will be connected to interrupt
- KeInitializeSpinLock(&uhci->frame_list_lock);
-
- uhci->io_buf = HalAllocateCommonBuffer(padapter, 4096, &uhci->io_buf_logic_addr, FALSE);
-
- if (uhci->io_buf == NULL)
- return FALSE;
-
- uhci->frame_list =
- HalAllocateCommonBuffer(padapter,
- sizeof(ULONG) * UHCI_MAX_FRAMES, &uhci->frame_list_logic_addr, FALSE);
-
- if (uhci->frame_list == NULL)
- return FALSE;
-
- RtlZeroMemory(uhci->frame_list, sizeof(ULONG) * UHCI_MAX_FRAMES);
-
- uhci->frame_list_cpu = usb_alloc_mem(NonPagedPool, sizeof(FRAME_LIST_CPU_ENTRY) * UHCI_MAX_FRAMES);
-
- if (uhci->frame_list_cpu == NULL)
- return FALSE;
-
- for(i = 0; i < UHCI_MAX_FRAMES; i++)
- InitializeListHead(&uhci->frame_list_cpu[i].td_link);
-
- uhci->frame_bw = usb_alloc_mem(NonPagedPool, sizeof(LONG) * UHCI_MAX_FRAMES);
-
- if (uhci->frame_bw == NULL)
- return FALSE;
-
- for(i = 0; i < UHCI_MAX_FRAMES; i++)
- {
- uhci->frame_bw[i] = FRAME_TIME_MAX_USECS_ALLOC;
- }
- uhci->fsbr_cnt = 0;
-
- return TRUE;
-
-}
-
-BOOLEAN
-uhci_destroy_frame_list(PUHCI_DEV uhci)
-{
- if (uhci == NULL)
- return FALSE;
-
- if (uhci->frame_list)
- HalFreeCommonBuffer(uhci->pdev_ext->padapter,
- sizeof(ULONG) * UHCI_MAX_FRAMES,
- uhci->frame_list_logic_addr, uhci->frame_list, FALSE);
-
- uhci->frame_list = NULL;
- uhci->frame_list_logic_addr.LowPart = 0;
- uhci->frame_list_logic_addr.HighPart = 0;
-
- if (uhci->frame_list_cpu)
- usb_free_mem(uhci->frame_list_cpu);
-
- uhci->frame_list_cpu = NULL;
-
- if (uhci->frame_bw)
- usb_free_mem(uhci->frame_bw);
-
- uhci->frame_bw = NULL;
-
- return TRUE;
-}
-
-PDEVICE_OBJECT
-uhci_create_device(PDRIVER_OBJECT drvr_obj, PUSB_DEV_MANAGER dev_mgr)
-{
- NTSTATUS status;
- PDEVICE_OBJECT pdev;
- PDEVICE_EXTENSION pdev_ext;
-
- UNICODE_STRING dev_name;
- UNICODE_STRING symb_name;
-
- STRING string, another_string;
- CHAR str_dev_name[64], str_symb_name[64];
- UCHAR hcd_id;
-
- if (drvr_obj == NULL)
- return NULL;
-
- ASSERT(dev_mgr != NULL);
-
- //note: hcd count wont increment till the hcd is registered in dev_mgr
- sprintf(str_dev_name, "%s%d", UHCI_DEVICE_NAME, dev_mgr->hcd_count);
- sprintf(str_symb_name, "%s%d", DOS_DEVICE_NAME, dev_mgr->hcd_count);
-
- RtlInitString(&string, str_dev_name);
- RtlAnsiStringToUnicodeString(&dev_name, &string, TRUE);
-
- pdev = NULL;
- status = IoCreateDevice(drvr_obj,
- sizeof(DEVICE_EXTENSION) + sizeof(UHCI_DEV),
- &dev_name, FILE_UHCI_DEV_TYPE, 0, FALSE, &pdev);
-
- if (status != STATUS_SUCCESS || pdev == NULL)
- {
- RtlFreeUnicodeString(&dev_name);
- return NULL;
- }
-
- pdev_ext = pdev->DeviceExtension;
- RtlZeroMemory(pdev_ext, sizeof(DEVICE_EXTENSION) + sizeof(UHCI_DEV));
-
- pdev_ext->dev_ext_hdr.type = NTDEV_TYPE_HCD;
- pdev_ext->dev_ext_hdr.dispatch = uhci_dispatch_irp;
- pdev_ext->dev_ext_hdr.start_io = NULL; //we do not support startio
- pdev_ext->dev_ext_hdr.dev_mgr = dev_mgr;
-
- pdev_ext->pdev_obj = pdev;
- pdev_ext->pdrvr_obj = drvr_obj;
-
- pdev_ext->uhci = (PUHCI_DEV) & (pdev_ext[1]);
-
- RtlInitString(&another_string, str_symb_name);
- RtlAnsiStringToUnicodeString(&symb_name, &another_string, TRUE);
-
- IoCreateSymbolicLink(&symb_name, &dev_name);
-
- uhci_dbg_print(DBGLVL_MAXIMUM,
- ("uhci_create_device(): dev=0x%x\n, pdev_ext= 0x%x, uhci=0x%x, dev_mgr=0x%x\n", pdev,
- pdev_ext, pdev_ext->uhci, dev_mgr));
-
- RtlFreeUnicodeString(&dev_name);
- RtlFreeUnicodeString(&symb_name);
-
- //register with dev_mgr though it is not initilized
- uhci_init_hcd_interface(pdev_ext->uhci);
- hcd_id = dev_mgr_register_hcd(dev_mgr, &pdev_ext->uhci->hcd_interf);
-
- pdev_ext->uhci->hcd_interf.hcd_set_id(&pdev_ext->uhci->hcd_interf, hcd_id);
- pdev_ext->uhci->hcd_interf.hcd_set_dev_mgr(&pdev_ext->uhci->hcd_interf, dev_mgr);
- return pdev;
-}
-
-BOOLEAN
-uhci_delete_device(PDEVICE_OBJECT pdev, PUSB_DEV_MANAGER dev_mgr)
-{
- STRING string;
- UNICODE_STRING symb_name;
- PDEVICE_EXTENSION pdev_ext;
- CHAR str_symb_name[64];
-
-
- if (pdev == NULL)
- return FALSE;
-
- pdev_ext = pdev->DeviceExtension;
-
- sprintf(str_symb_name,
- "%s%d", DOS_DEVICE_NAME, pdev_ext->uhci->hcd_interf.hcd_get_id(&pdev_ext->uhci->hcd_interf));
- RtlInitString(&string, str_symb_name);
- RtlAnsiStringToUnicodeString(&symb_name, &string, TRUE);
- IoDeleteSymbolicLink(&symb_name);
- RtlFreeUnicodeString(&symb_name);
-
- dev_mgr_deregister_hcd(dev_mgr, pdev_ext->uhci->hcd_interf.hcd_get_id(&pdev_ext->uhci->hcd_interf));
-
- if (pdev_ext->res_list)
- ExFreePool(pdev_ext->res_list); // not allocated by usb_alloc_mem
-
- IoDeleteDevice(pdev);
- uhci_dbg_print(DBGLVL_MAXIMUM, ("uhci_delete_device(): device deleted\n"));
- return TRUE;
-}
-
-// we can not use endp here for it is within the dev scope, and
-// we can not acquire the dev-lock, fortunately we saved some
-// info in urb->pipe in uhci_internal_submit_XXX.
-BOOLEAN NTAPI
-uhci_isr(PKINTERRUPT interrupt, PVOID context)
-{
- PUHCI_DEV uhci;
- USHORT status;
- PLIST_ENTRY pthis, pnext;
- PURB purb;
-
- UNREFERENCED_PARAMETER(interrupt);
- UNREFERENCED_PARAMETER(context);
-
- uhci_dbg_print(DBGLVL_ULTRA, ("uhci_isr(): context=0x%x\n", context));
-
- /*
- * Read the interrupt status, and write it back to clear the
- * interrupt cause
- */
- uhci = (PUHCI_DEV) context;
- if (uhci == NULL)
- return FALSE;
-
- status = READ_PORT_USHORT((PUSHORT) (uhci->port_base + USBSTS));
- if (!status) /* shared interrupt, not mine */
- return FALSE;
-
- if (status != 1)
- {
- uhci_dbg_print(DBGLVL_MAXIMUM, ("uhci_isr(): current uhci status=0x%x\n", status));
- }
- else
- {
- uhci_dbg_print(DBGLVL_MAXIMUM, ("uhci_isr(): congratulations, no error occurs\n"));
- }
-
- /* clear it */
- WRITE_PORT_USHORT((PUSHORT) (uhci->port_base + USBSTS), status);
-
- if (status & ~(USBSTS_USBINT | USBSTS_ERROR | USBSTS_RD))
- {
- if (status & USBSTS_HSE)
- {
- DbgPrint("uhci_isr(): host system error, PCI problems?\n");
- //for( ; ; );
- }
- if (status & USBSTS_HCPE)
- {
- DbgPrint("uhci_isr(): host controller process error. something bad happened\n");
- //for( ; ; );
- //for( ; ; );
- }
- if ((status & USBSTS_HCH)) //&& !uhci->is_suspended
- {
- DbgPrint("uhci_isr(): host controller halted. very bad\n");
- /* FIXME: Reset the controller, fix the offending TD */
- }
- }
-
- // don't no how to handle it yet
- //if (status & USBSTS_RD)
- //{
- //uhci_wakeup(uhci);
- //}*/
-
- //let's remove those force-cancel urbs from the schedule first
- ListFirst(&uhci->urb_list, pthis);
- while (pthis)
- {
- purb = (PURB) pthis;
- if (purb->flags & URB_FLAG_FORCE_CANCEL)
- {
- uhci_remove_urb_from_schedule(uhci, purb);
- }
- ListNext(&uhci->urb_list, pthis, pnext);
- pthis = pnext;
- }
-
- //clear the interrupt if the urb is force canceled
- uhci->skel_term_td->status &= ~TD_CTRL_IOC;
-
- //next we need to find if anything fininshed
- ListFirst(&uhci->urb_list, pthis);
- while (pthis)
- {
- purb = (PURB) pthis;
- if (purb->flags & URB_FLAG_IN_SCHEDULE)
- {
- if (uhci_is_xfer_finished(purb))
- uhci_remove_urb_from_schedule(uhci, purb);
- }
- ListNext(&uhci->urb_list, pthis, pnext);
- pthis = pnext;
- }
-
- KeInsertQueueDpc(&uhci->pdev_ext->uhci_dpc, uhci, 0);
- return TRUE;
-}
-
-BOOLEAN NTAPI
-uhci_cal_cpu_freq(PVOID context)
-{
- UNREFERENCED_PARAMETER(context);
-
- usb_cal_cpu_freq();
- return TRUE;
-}
-
-PDEVICE_OBJECT
-uhci_probe(PDRIVER_OBJECT drvr_obj, PUNICODE_STRING reg_path, PUSB_DEV_MANAGER dev_mgr)
-{
- LONG bus, i, j, ret = 0;
- PCI_SLOT_NUMBER slot_num;
- PPCI_COMMON_CONFIG pci_config;
- PDEVICE_OBJECT pdev;
- BYTE buffer[sizeof(PCI_COMMON_CONFIG)];
- LONG count;
- PDEVICE_EXTENSION pdev_ext;
-
- slot_num.u.AsULONG = 0;
- pci_config = (PPCI_COMMON_CONFIG) buffer;
- count = 0;
- pdev = NULL;
-
- //scan the PCI buses to find uhci controller
- for (bus = 0; bus <= PCI_MAX_BRIDGE_NUMBER; bus++)
- {
- for(i = 0; i <= PCI_MAX_DEVICES; i++)
- {
- slot_num.u.bits.DeviceNumber = i;
- for(j = 0; j <= PCI_MAX_FUNCTION; j++)
- {
- slot_num.u.bits.FunctionNumber = j;
-
- ret = HalGetBusData(PCIConfiguration,
- bus, slot_num.u.AsULONG, pci_config, PCI_COMMON_HDR_LENGTH);
-
- if (ret == 0) /*no this bus */
- break;
-
- if (ret == 2) /*no device on the slot */
- break;
-
- if (pci_config->BaseClass == 0x0c && pci_config->SubClass == 0x03 &&
- pci_config->ProgIf == 0x00)
- {
- // well, we find our usb host controller, create device
- pdev = uhci_alloc(drvr_obj, reg_path, ((bus << 8) | (i << 3) | j), dev_mgr);
- if (pdev)
-#ifdef _MULTI_UHCI
- count++;
-#else
- goto LBL_LOOPOUT;
-#endif
- }
- }
- if (ret == 0)
- break;
- }
- }
-
-#ifndef _MULTI_UHCI
-LBL_LOOPOUT:
-#endif
- DbgPrint("Found %d UHCI controllers\n", count);
-
- if (pdev)
- {
- pdev_ext = pdev->DeviceExtension;
- if (pdev_ext)
- {
- // acquire higher irql to eliminate pre-empty
- KeSynchronizeExecution(pdev_ext->uhci_int, uhci_cal_cpu_freq, NULL);
- }
- }
- return pdev;
-}
-
-PDEVICE_OBJECT
-uhci_alloc(PDRIVER_OBJECT drvr_obj, PUNICODE_STRING reg_path, ULONG bus_addr, PUSB_DEV_MANAGER dev_mgr)
-{
- LONG frd_num, prd_num;
- PDEVICE_OBJECT pdev;
- PDEVICE_EXTENSION pdev_ext;
- ULONG vector, addr_space;
- LONG bus;
- KIRQL irql;
- KAFFINITY affinity;
-
- DEVICE_DESCRIPTION dev_desc;
- CM_PARTIAL_RESOURCE_DESCRIPTOR *pprd;
- PCI_SLOT_NUMBER slot_num;
- NTSTATUS status;
-
-
- pdev = uhci_create_device(drvr_obj, dev_mgr);
- if (pdev == NULL)
- return pdev;
- pdev_ext = pdev->DeviceExtension;
-
- pdev_ext->pci_addr = bus_addr;
- bus = (bus_addr >> 8);
-
- slot_num.u.AsULONG = 0;
- slot_num.u.bits.DeviceNumber = ((bus_addr & 0xff) >> 3);
- slot_num.u.bits.FunctionNumber = (bus_addr & 0x07);
-
- //now create adapter object
- RtlZeroMemory(&dev_desc, sizeof(dev_desc));
-
- dev_desc.Version = DEVICE_DESCRIPTION_VERSION;
- dev_desc.Master = TRUE;
- dev_desc.ScatterGather = TRUE;
- dev_desc.Dma32BitAddresses = TRUE;
- dev_desc.BusNumber = bus;
- dev_desc.InterfaceType = PCIBus;
- dev_desc.MaximumLength =
- UHCI_MAX_POOL_TDS * sizeof(UHCI_TD) * UHCI_MAX_TD_POOLS
- + sizeof(UHCI_QH) * UHCI_MAX_POOL_QHS + sizeof(ULONG) * UHCI_MAX_FRAMES;
-
- pdev_ext->map_regs = 2; // UHCI_MAX_TD_POOLS +
- //+ BYTES_TO_PAGES( ( UHCI_MAX_POOL_TDS * 64 ) * UHCI_MAX_TD_POOLS ) ;
-
- pdev_ext->padapter = HalGetAdapter(&dev_desc, &pdev_ext->map_regs);
-
- uhci_dbg_print(DBGLVL_MAXIMUM, ("uhci_alloc(): padapter=0x%x\n", pdev_ext->padapter));
- if (pdev_ext->padapter == NULL)
- {
- //fatal error
- uhci_delete_device(pdev, dev_mgr);
- return NULL;
- }
-
- DbgPrint("uhci_alloc(): reg_path=%p, \n \
- uhci_alloc(): PCIBus=0x%x, bus=0x%x, bus_addr=0x%x \n \
- uhci_alloc(): slot_num=0x%x, &res_list=%p \n", reg_path, (DWORD) PCIBus, (DWORD) bus,
- (DWORD) bus_addr, (DWORD) slot_num.u.AsULONG, & pdev_ext->res_list);
-
- //let's allocate resources for this device
- DbgPrint("uhci_alloc(): about to assign slot res\n");
- if ((status = HalAssignSlotResources(reg_path, NULL, //no class name yet
- drvr_obj, NULL, //no support of another uhci controller
- PCIBus,
- bus, slot_num.u.AsULONG, &pdev_ext->res_list)) != STATUS_SUCCESS)
- {
- DbgPrint("uhci_alloc(): error assign slot res, 0x%x\n", status);
- release_adapter(pdev_ext->padapter);
- pdev_ext->padapter = NULL;
- uhci_delete_device(pdev, dev_mgr);
- return NULL;
- }
-
- //parse the resource list
- for(frd_num = 0; frd_num < (LONG) pdev_ext->res_list->Count; frd_num++)
- {
- for(prd_num = 0; prd_num < (LONG) pdev_ext->res_list->List[frd_num].PartialResourceList.Count;
- prd_num++)
- {
- pprd = &pdev_ext->res_list->List[frd_num].PartialResourceList.PartialDescriptors[prd_num];
- if (pprd->Type == CmResourceTypePort)
- {
- RtlCopyMemory(&pdev_ext->res_port, &pprd->u.Port, sizeof(pprd->u.Port));
- }
- else if (pprd->Type == CmResourceTypeInterrupt)
- {
- RtlCopyMemory(&pdev_ext->res_interrupt, &pprd->u.Interrupt, sizeof(pprd->u.Interrupt));
- }
- }
- }
-
- //for port, translate them to system address
- addr_space = 1;
- if (HalTranslateBusAddress(PCIBus, bus, pdev_ext->res_port.Start, &addr_space, //io space
- &pdev_ext->uhci->uhci_reg_base) != (BOOLEAN) TRUE)
- {
- DbgPrint("uhci_alloc(): error, can not translate bus address\n");
- release_adapter(pdev_ext->padapter);
- pdev_ext->padapter = NULL;
- uhci_delete_device(pdev, dev_mgr);
- return NULL;
- }
-
- DbgPrint("uhci_alloc(): address space=0x%x\n, reg_base=0x%x\n",
- addr_space, pdev_ext->uhci->uhci_reg_base.u.LowPart);
-
- if (addr_space == 0)
- {
- //port has been mapped to memory space
- pdev_ext->uhci->port_mapped = TRUE;
- pdev_ext->uhci->port_base = (PBYTE) MmMapIoSpace(pdev_ext->uhci->uhci_reg_base,
- pdev_ext->res_port.Length, FALSE);
-
- //fatal error can not map the registers
- if (pdev_ext->uhci->port_base == NULL)
- {
- release_adapter(pdev_ext->padapter);
- pdev_ext->padapter = NULL;
- uhci_delete_device(pdev, dev_mgr);
- return NULL;
- }
- }
- else
- {
- //io space
- pdev_ext->uhci->port_mapped = FALSE;
- pdev_ext->uhci->port_base = (PBYTE) pdev_ext->uhci->uhci_reg_base.LowPart;
- }
-
- //before we connect the interrupt, we have to init uhci
- pdev_ext->uhci->fsbr_cnt = 0;
- pdev_ext->uhci->pdev_ext = pdev_ext;
-
- if (uhci_init_schedule(pdev_ext->uhci, pdev_ext->padapter) == FALSE)
- {
- release_adapter(pdev_ext->padapter);
- pdev_ext->padapter = NULL;
- uhci_delete_device(pdev, dev_mgr);
- return NULL;
- }
-
- InitializeListHead(&pdev_ext->uhci->urb_list);
- KeInitializeSpinLock(&pdev_ext->uhci->pending_endp_list_lock);
- InitializeListHead(&pdev_ext->uhci->pending_endp_list);
-
- uhci_dbg_print(DBGLVL_MAXIMUM, ("uhci_alloc(): pending_endp_list=0x%x\n",
- &pdev_ext->uhci->pending_endp_list));
-
- init_pending_endp_pool(&pdev_ext->uhci->pending_endp_pool);
- KeInitializeTimer(&pdev_ext->uhci->reset_timer);
-
- vector = HalGetInterruptVector(PCIBus,
- bus,
- pdev_ext->res_interrupt.level,
- pdev_ext->res_interrupt.vector,
- &irql,
- &affinity);
-
- KeInitializeDpc(&pdev_ext->uhci_dpc, uhci_dpc_callback, (PVOID) pdev_ext->uhci);
-
- //connect the interrupt
- DbgPrint("uhci_alloc(): the int=0x%x\n", vector);
- if (IoConnectInterrupt(&pdev_ext->uhci_int,
- uhci_isr,
- pdev_ext->uhci,
- NULL, //&pdev_ext->uhci->frame_list_lock,
- vector,
- irql,
- irql,
- LevelSensitive,
- TRUE, //share the vector
- affinity,
- FALSE) //No float save
- != STATUS_SUCCESS)
- {
- uhci_release(pdev, dev_mgr);
- return NULL;
- }
-
- return pdev;
-}
-
-BOOLEAN
-uhci_release(PDEVICE_OBJECT pdev, PUSB_DEV_MANAGER dev_mgr)
-{
- PDEVICE_EXTENSION pdev_ext;
- PUHCI_DEV uhci;
-
- if (pdev == NULL)
- return FALSE;
-
- pdev_ext = pdev->DeviceExtension;
-
- if (pdev_ext == NULL)
- return FALSE;
-
- uhci = pdev_ext->uhci;
- if (uhci == NULL)
- return FALSE;
-
- uhci_stop(uhci);
- //pdev_ext->uhci->conn_count = 0;
- pdev_ext->uhci->fsbr_cnt = 0;
-
- if (pdev_ext->uhci_int)
- {
- IoDisconnectInterrupt(pdev_ext->uhci_int);
- pdev_ext->uhci_int = NULL;
- }
- else
- TRAP();
- destroy_pending_endp_pool(&pdev_ext->uhci->pending_endp_pool);
- //pdev_ext->uhci->pending_endp_pool = NULL;
-
- uhci_destroy_schedule(uhci);
-
- release_adapter(pdev_ext->padapter);
- pdev_ext->padapter = NULL;
-
- uhci_delete_device(pdev, dev_mgr);
-
- return FALSE;
-
-}
-
-// send cmds to start the uhc
-// shamelessly copied from linux's uhci.c (reset_hc(), configure_hc() routines)
-BOOLEAN
-uhci_start(PHCD hcd)
-{
- PUHCI_DEV uhci;
- PBYTE io_addr;
- USHORT pirq;
- PCI_SLOT_NUMBER SlotNum;
- int timeout = 10000;
-
- uhci = uhci_from_hcd(hcd);
- io_addr = uhci->port_base;
-
- /*
- * Reset the HC - this will force us to get a
- * new notification of any already connected
- * ports due to the virtual disconnect that it
- * implies.
- */
- WRITE_PORT_USHORT((PUSHORT) (io_addr + USBCMD), USBCMD_HCRESET);
- while (READ_PORT_USHORT((PUSHORT) (io_addr + USBCMD)) & USBCMD_HCRESET)
- {
- if (!--timeout)
- {
- break;
- }
- }
-
- /* Turn on all interrupts */
- WRITE_PORT_USHORT((PUSHORT) (io_addr + USBINTR),
- USBINTR_TIMEOUT | USBINTR_RESUME | USBINTR_IOC | USBINTR_SP);
-
- /* Start at frame 0 */
- WRITE_PORT_USHORT((PUSHORT) (io_addr + USBFRNUM), 0);
- WRITE_PORT_ULONG((PULONG) (io_addr + USBFLBASEADD), uhci->frame_list_logic_addr.LowPart);
-
- /* Run and mark it configured with a 64-byte max packet */
- WRITE_PORT_USHORT((PUSHORT) (io_addr + USBCMD), USBCMD_RS | USBCMD_CF | USBCMD_MAXP);
-
- DbgPrint("uhci_start(): current uhci status=0x%x\n", uhci_status(uhci));
-
- /* Enable PIRQ */
- pirq = USBLEGSUP_DEFAULT;
- SlotNum.u.AsULONG = 0;
- SlotNum.u.bits.DeviceNumber = ((uhci->pdev_ext->pci_addr & 0xff) >> 3);
- SlotNum.u.bits.FunctionNumber = (uhci->pdev_ext->pci_addr & 0x07);
-
- DbgPrint("uhci_start(): set bus %d data at slot 0x%x\n", (uhci->pdev_ext->pci_addr >> 8),
- SlotNum.u.AsULONG);
-
- HalSetBusDataByOffset(PCIConfiguration, (uhci->pdev_ext->pci_addr >> 8), SlotNum.u.AsULONG,
- &pirq, USBLEGSUP, sizeof(pirq));
-
- return TRUE;
-}
-
-VOID
-uhci_stop(PUHCI_DEV uhci)
-{
- PBYTE io_addr = uhci->port_base;
- // turn off all the interrupt
- WRITE_PORT_USHORT((PUSHORT) (io_addr + USBINTR), 0);
- WRITE_PORT_USHORT((PUSHORT) (io_addr + USBCMD), 0);
-}
-
-static VOID
-uhci_reset(PUHCI_DEV uhci)
-{
- PBYTE io_addr = uhci->port_base;
-
- uhci_stop(uhci);
- /* Global reset for 50ms */
- WRITE_PORT_USHORT((PUSHORT) (io_addr + USBCMD), USBCMD_GRESET);
- //uhci_wait_ms( uhci, 50 );
- usb_wait_ms_dpc(50);
-
- WRITE_PORT_USHORT((PUSHORT) (io_addr + USBCMD), 0);
- //uhci_wait_ms( uhci, 10 );
- usb_wait_ms_dpc(10);
-}
-
-VOID
-uhci_suspend(PUHCI_DEV uhci)
-{
- PBYTE io_addr = uhci->port_base;
-
- //uhci->is_suspended = 1;
- WRITE_PORT_USHORT((PUSHORT) (io_addr + USBCMD), USBCMD_EGSM);
-
-}
-
-VOID
-uhci_wakeup(PUHCI_DEV uhci)
-{
- PBYTE io_addr;
- unsigned int status;
-
- io_addr = uhci->port_base;
-
- WRITE_PORT_USHORT((PUSHORT) (io_addr + USBCMD), 0);
-
- /* wait for EOP to be sent */
- status = READ_PORT_USHORT((PUSHORT) (io_addr + USBCMD));
- while (status & USBCMD_FGR)
- status = READ_PORT_USHORT((PUSHORT) (io_addr + USBCMD));
-
- //uhci->is_suspended = 0;
-
- /* Run and mark it configured with a 64-byte max packet */
- WRITE_PORT_USHORT((PUSHORT) (io_addr + USBCMD), USBCMD_RS | USBCMD_CF | USBCMD_MAXP);
-
-}
-
-BOOLEAN
-uhci_init_schedule(PUHCI_DEV uhci, PADAPTER_OBJECT padapter)
-{
- int i, irq;
-
- uhci_dbg_print(DBGLVL_MAXIMUM, ("uhci_init_schedule(): entering..., uhci=0x%x\n", uhci));
- if (uhci == NULL || padapter == NULL)
- return FALSE;
-
- if (init_td_pool_list(&uhci->td_pool, padapter) == FALSE)
- {
- return FALSE;
- }
- if (init_qh_pool(&uhci->qh_pool, padapter) == FALSE)
- {
- return FALSE;
- }
-
- //since uhci is not started we can freely access all resources.
- for(i = 0; i < UHCI_MAX_SKELTDS; i++)
- {
- uhci->skel_td[i] = alloc_td(&uhci->td_pool);
- uhci_fill_td(uhci->skel_td[i], 0, (UHCI_NULL_DATA_SIZE << 21) | (0x7f << 8) | USB_PID_IN, 0);
-
- if (i > 0)
- {
- uhci->skel_td[i]->link = uhci->skel_td[i - 1]->phy_addr;
- }
- }
-
- /*for( i = UHCI_MAX_SKELTDS - 3; i >= 0; i-- )
- {
- InsertTailList( &uhci->skel_int256_td->ptde->hori_link,
- &uhci->skel_td[ i ]->ptde->hori_link );
- } */
-
- for(i = 0; i < UHCI_MAX_SKELQHS; i++)
- {
- uhci->skel_qh[i] = alloc_qh(&uhci->qh_pool);
- if (i > 0)
- {
- uhci->skel_qh[i - 1]->link = uhci->skel_qh[i]->phy_addr;
- }
-
- uhci->skel_qh[i]->element = UHCI_PTR_TERM;
- }
-
- uhci->skel_int1_td->link = uhci->skel_ls_control_qh->phy_addr;
-
- // Hack for PIIX
- uhci_fill_td(uhci->skel_term_td, 0, (UHCI_NULL_DATA_SIZE << 21) | (0x7f << 8) | USB_PID_IN, 0);
- uhci->skel_term_td->link = uhci->skel_term_td->phy_addr;
-
- uhci->skel_term_qh->link = UHCI_PTR_TERM;
- uhci->skel_term_qh->element = uhci->skel_term_td->phy_addr;
-
- InsertTailList(&uhci->skel_term_qh->pqhe->vert_link, &uhci->skel_term_td->ptde->vert_link);
-
- /*for( i = 0; i < UHCI_MAX_SKELQHS; i++ )
- {
- InsertTailList( &uhci->skel_int256_td->ptde->hori_link,
- &uhci->skel_qh[ i ]->pqhe->hori_link );
- } */
-
- if (uhci_init_frame_list(uhci, uhci->pdev_ext->padapter) == FALSE)
- uhci_destroy_frame_list(uhci);
-
- //well all have been chained, now scatter the int tds to frame-list
- //shamelessly pasted from linux's uhci.c :-)
- for(i = 0; i < UHCI_MAX_FRAMES; i++)
- {
- irq = 0;
- if (i & 1)
- {
- irq++;
- if (i & 2)
- {
- irq++;
- if (i & 4)
- {
- irq++;
- if (i & 8)
- {
- irq++;
- if (i & 16)
- {
- irq++;
- if (i & 32)
- {
- irq++;
- if (i & 64)
- irq++;
- }
- }
- }
- }
- }
- }
-
- /* Only place we don't use the frame list routines */
- uhci->frame_list[i] = uhci->skel_td[irq]->phy_addr;
- }
- return TRUE;
-}
-
-BOOLEAN
-uhci_destroy_schedule(PUHCI_DEV uhci)
-{
- BOOLEAN ret;
-
- ret = uhci_destroy_frame_list(uhci);
- ret = destroy_qh_pool(&uhci->qh_pool);
- ret = destroy_td_pool_list(&uhci->td_pool);
-
- return ret;
-
-}
-
-VOID NTAPI
-uhci_cancel_pending_endp_urb(IN PVOID Parameter)
-{
- PLIST_ENTRY abort_list;
- PUSB_DEV pdev;
- PURB purb;
- USE_BASIC_NON_PENDING_IRQL;
-
- abort_list = (PLIST_ENTRY) Parameter;
-
- if (abort_list == NULL)
- return;
-
- while (IsListEmpty(abort_list) == FALSE)
- {
- //these devs are protected by urb's ref-count
- purb = (PURB) RemoveHeadList(abort_list);
- pdev = purb->pdev;
- // purb->status is set when they are added to abort_list
-
- uhci_generic_urb_completion(purb, purb->context);
-
- lock_dev(pdev, FALSE);
- pdev->ref_count--;
- unlock_dev(pdev, FALSE);
- }
- usb_free_mem(abort_list);
- return;
-}
-
-BOOLEAN
-uhci_process_pending_endp(PUHCI_DEV uhci)
-{
- PUSB_DEV pdev;
- LIST_ENTRY temp_list, abort_list;
- PLIST_ENTRY pthis;
- PURB purb;
- PUSB_ENDPOINT pendp;
- NTSTATUS can_submit = STATUS_UNSUCCESSFUL;
- PWORK_QUEUE_ITEM pwork_item;
- PLIST_ENTRY cancel_list;
- USE_BASIC_IRQL;
-
- if (uhci == NULL)
- return FALSE;
-
- InitializeListHead(&temp_list);
- InitializeListHead(&abort_list);
-
- purb = NULL;
- uhci_dbg_print(DBGLVL_MEDIUM, ("uhci_process_pending_endp(): entering..., uhci=0x%x\n", uhci));
-
- lock_pending_endp_list(&uhci->pending_endp_list_lock);
- while (IsListEmpty(&uhci->pending_endp_list) == FALSE)
- {
-
- uhci_dbg_print(DBGLVL_MAXIMUM, ("uhci_process_pending_endp(): pending_endp_list=0x%x\n",
- &uhci->pending_endp_list));
-
- pthis = RemoveHeadList(&uhci->pending_endp_list);
- pendp = ((PUHCI_PENDING_ENDP) pthis)->pendp;
- pdev = dev_from_endp(pendp);
-
- lock_dev(pdev, TRUE);
-
- if (dev_state(pdev) == USB_DEV_STATE_ZOMB)
- {
- unlock_dev(pdev, TRUE);
- free_pending_endp(&uhci->pending_endp_pool, struct_ptr(pthis, UHCI_PENDING_ENDP, endp_link));
- //delegate to uhci_remove_device for removing the urb queue on the endpoint
- continue;
- }
-
- if (endp_state(pendp) == USB_ENDP_FLAG_STALL)
- {
- while (IsListEmpty(&pendp->urb_list) == FALSE)
- {
- purb = (PURB) RemoveHeadList(&pendp->urb_list);
- purb->status = USB_STATUS_ENDPOINT_HALTED;
- InsertTailList(&abort_list, (LIST_ENTRY *) purb);
- }
- InitializeListHead(&pendp->urb_list);
- unlock_dev(pdev, TRUE);
- free_pending_endp(&uhci->pending_endp_pool, struct_ptr(pthis, UHCI_PENDING_ENDP, endp_link));
- continue;
- }
-
-
- if (IsListEmpty(&pendp->urb_list) == FALSE)
- {
- purb = (PURB) RemoveHeadList(&pendp->urb_list);
- ASSERT(purb);
- }
- else
- {
- InitializeListHead(&pendp->urb_list);
- unlock_dev(pdev, TRUE);
- free_pending_endp(&uhci->pending_endp_pool, struct_ptr(pthis, UHCI_PENDING_ENDP, endp_link));
- continue;
- }
-
- // 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:
- {
-#ifdef DEMO
- can_submit = STATUS_UNSUCCESSFUL;
-#else
- can_submit = uhci_internal_submit_bulk(uhci, purb);
-#endif
- break;
- }
- case USB_ENDPOINT_XFER_CONTROL:
- {
- can_submit = uhci_internal_submit_ctrl(uhci, purb);
- break;
- }
- case USB_ENDPOINT_XFER_INT:
- {
- can_submit = uhci_internal_submit_int(uhci, purb);
- break;
- }
- case USB_ENDPOINT_XFER_ISOC:
- {
- can_submit = uhci_internal_submit_iso(uhci, purb);
- break;
- }
- }
-
- if (can_submit == STATUS_NO_MORE_ENTRIES)
- {
- //no enough bandwidth or tds
- InsertHeadList(&pendp->urb_list, &purb->urb_link);
- InsertTailList(&temp_list, pthis);
- }
- else
- {
- // other error or success
- free_pending_endp(&uhci->pending_endp_pool, struct_ptr(pthis, UHCI_PENDING_ENDP, endp_link));
-
- if (can_submit != STATUS_SUCCESS)
- {
- //abort these URBs
- InsertTailList(&abort_list, (LIST_ENTRY *) purb);
- uhci_dbg_print(DBGLVL_MEDIUM, ("uhci_process_pending_endp(): unable to submit urb 0x%x, "
- "with status=0x%x\n", purb, can_submit));
- purb->status = can_submit;
- }
-
- }
- unlock_dev(pdev, TRUE);
- }
-
- if (IsListEmpty(&temp_list) == FALSE)
- {
- //re-append them to the pending_endp_list
- ListFirst(&temp_list, pthis);
- RemoveEntryList(&temp_list);
- MergeList(&uhci->pending_endp_list, pthis);
- }
- unlock_pending_endp_list(&uhci->pending_endp_list_lock);
-
- if (IsListEmpty(&abort_list) == FALSE)
- {
- PLIST_ENTRY pthis;
- cancel_list = (PLIST_ENTRY) usb_alloc_mem(NonPagedPool, sizeof(WORK_QUEUE_ITEM) + sizeof(LIST_ENTRY));
- ASSERT(cancel_list);
-
- ListFirst(&abort_list, pthis);
- RemoveEntryList(&abort_list);
- InsertTailList(pthis, cancel_list);
-
- pwork_item = (PWORK_QUEUE_ITEM) (cancel_list + 1);
-
- // we do not need to worry the uhci_cancel_pending_endp_urb running when the
- // driver is unloading since it will prevent the dev_mgr to quit till all the
- // reference count to the dev drop to zero.
- ExInitializeWorkItem(pwork_item, uhci_cancel_pending_endp_urb, (PVOID) cancel_list);
- ExQueueWorkItem(pwork_item, DelayedWorkQueue);
- }
- return TRUE;
-}
-
-NTSTATUS
-uhci_submit_urb(PUHCI_DEV uhci, PUSB_DEV pdev, PUSB_ENDPOINT pendp, PURB purb)
-{
- int i;
- PUHCI_PENDING_ENDP pending_endp;
- NTSTATUS status;
- USE_BASIC_IRQL;
-
- if (uhci == NULL || pdev == NULL || pendp == NULL || purb == NULL)
- {
- uhci_dbg_print(DBGLVL_MEDIUM,
- ("uhci_submit_urb(): uhci=0x%x, pdev=0x%x, pendp=0x%x, purb=0x%x "
- "called with invalid param!\n", uhci, pdev, pendp, purb));
- return STATUS_INVALID_PARAMETER;
- }
-
- lock_pending_endp_list(&uhci->pending_endp_list_lock);
- lock_dev(pdev, TRUE);
-
- if (dev_state(pdev) == USB_DEV_STATE_ZOMB)
- {
- status = purb->status = STATUS_DEVICE_DOES_NOT_EXIST;
- goto LBL_OUT;
- }
-
- if (dev_class(pdev) == USB_DEV_CLASS_ROOT_HUB)
- {
- unlock_dev(pdev, TRUE);
- unlock_pending_endp_list(&uhci->pending_endp_list_lock);
- status = uhci_rh_submit_urb(pdev, purb);
- return status;
- }
-
- if (pendp)
- purb->pendp = pendp;
- else
- purb->pendp = &pdev->default_endp;
-
- if (dev_from_endp(purb->pendp) != pdev)
- {
- uhci_dbg_print(DBGLVL_MEDIUM,
- ("uhci_submit_urb(): dev_from_endp=0x%x\n, pdev=0x%x, pendp=0x%x "
- "devices mismatch!\n", dev_from_endp(purb->pendp), pdev, pendp));
-
- status = purb->status = STATUS_INVALID_PARAMETER;
- goto LBL_OUT;
- }
-
- if (endp_state(purb->pendp) == USB_ENDP_FLAG_STALL)
- {
- status = purb->status = USB_STATUS_ENDPOINT_HALTED;
- goto LBL_OUT;
- }
-
- purb->pdev = pdev;
- purb->rest_bytes = purb->data_length;
-
- if (endp_type(purb->pendp) == USB_ENDPOINT_XFER_BULK)
- purb->bytes_to_transfer = (purb->data_length > purb->pendp->pusb_endp_desc->wMaxPacketSize * UHCI_MAX_TDS_PER_TRANSFER ? purb->pendp->pusb_endp_desc->wMaxPacketSize * UHCI_MAX_TDS_PER_TRANSFER : purb->data_length); //multiple transfer for large data block
- else
- purb->bytes_to_transfer = purb->data_length;
-
- uhci_dbg_print(DBGLVL_MEDIUM, ("uhci_submit_urb(): bytes_to_transfer=0x%x\n", purb->bytes_to_transfer));
-
- purb->bytes_transfered = 0;
- InitializeListHead(&purb->trasac_list);
- purb->last_finished_td = &purb->trasac_list;
- purb->flags &= ~(URB_FLAG_STATE_MASK | URB_FLAG_IN_SCHEDULE | URB_FLAG_FORCE_CANCEL);
- purb->flags |= URB_FLAG_STATE_PENDING;
-
-
- i = IsListEmpty(&pendp->urb_list);
- InsertTailList(&pendp->urb_list, &purb->urb_link);
-
- pdev->ref_count++; //for urb reference
-
- if (i == FALSE)
- {
- //there is urb pending, simply queue it and return
- status = purb->status = STATUS_PENDING;
- goto LBL_OUT;
- }
- else if (usb_endp_busy_count(purb->pendp) && endp_type(purb->pendp) != USB_ENDPOINT_XFER_ISOC)
- {
- //
- //No urb waiting but urb overlap not allowed,
- //so leave it in queue and return, will be scheduled
- //later
- //
- status = purb->status = STATUS_PENDING;
- goto LBL_OUT;
- }
-
- pending_endp = alloc_pending_endp(&uhci->pending_endp_pool, 1);
- if (pending_endp == NULL)
- {
- //panic
- status = purb->status = STATUS_UNSUCCESSFUL;
- goto LBL_OUT2;
- }
-
- pending_endp->pendp = purb->pendp;
- InsertTailList(&uhci->pending_endp_list, &pending_endp->endp_link );
-
- unlock_dev(pdev, TRUE);
- unlock_pending_endp_list(&uhci->pending_endp_list_lock);
-
- uhci_process_pending_endp(uhci);
- return STATUS_PENDING;
-
-LBL_OUT2:
- pdev->ref_count--;
- RemoveEntryList(&purb->urb_link);
-
-LBL_OUT:
- unlock_dev(pdev, TRUE);
- unlock_pending_endp_list(&uhci->pending_endp_list_lock);
- return status;
-}
-
-NTSTATUS
-uhci_set_error_code(PURB urb, ULONG raw_status)
-{
- if ((raw_status & TD_CTRL_ANY_ERROR) == 0)
- {
- //test if the urb is canceled
- if (urb->flags & URB_FLAG_FORCE_CANCEL)
- urb->status = STATUS_CANCELLED;
- else
- urb->status = STATUS_SUCCESS;
- }
-
- else if (raw_status & TD_CTRL_BABBLE)
- urb->status = USB_STATUS_DATA_OVERRUN;
-
- else if (raw_status & TD_CTRL_STALLED)
- urb->status = USB_STATUS_STALL_PID;
-
- else if (raw_status & TD_CTRL_DBUFERR)
- urb->status = USB_STATUS_BUFFER_OVERRUN;
-
- else if (raw_status & TD_CTRL_CRCTIMEO)
- urb->status = USB_STATUS_CRC;
-
- else if (raw_status & TD_CTRL_BITSTUFF)
- urb->status = USB_STATUS_BTSTUFF;
-
- else
- urb->status = STATUS_UNSUCCESSFUL;
-
- return urb->status;
-}
-
-BOOLEAN NTAPI
-uhci_sync_remove_urb_finished(PVOID context)
-{
- PUHCI_DEV uhci;
- PLIST_ENTRY pthis, pnext, ptemp;
- PURB purb;
- PSYNC_PARAM pparam;
-
- pparam = (PSYNC_PARAM) context;
- uhci = pparam->uhci;
- ptemp = (PLIST_ENTRY) pparam->context;
-
- if (uhci == NULL)
- {
- return (UCHAR) (pparam->ret = FALSE);
- }
-
- ListFirst(&uhci->urb_list, pthis);
- while (pthis)
- {
- //remove urbs not in the schedule
- ListNext(&uhci->urb_list, pthis, pnext);
- purb = (PURB) pthis;
-
- if ((purb->flags & URB_FLAG_IN_SCHEDULE) == 0)
- {
- //finished or canceled( not apply for split bulk ).
- purb->flags &= ~URB_FLAG_STATE_MASK;
- purb->flags |= URB_FLAG_STATE_FINISHED;
- RemoveEntryList(pthis);
- InsertTailList(ptemp, pthis);
- }
- pthis = pnext;
- }
- pparam->ret = TRUE;
- return (UCHAR) TRUE;
-}
-
-BOOLEAN
-uhci_drop_fsbr(PUHCI_DEV uhci)
-{
- if (uhci == NULL)
- return (UCHAR) FALSE;
-
- uhci->fsbr_cnt--;
-
- if (uhci->fsbr_cnt <= 0)
- {
- uhci->skel_term_qh->link = UHCI_PTR_TERM;
- uhci->fsbr_cnt = 0;
- }
-
- return (UCHAR) TRUE;
-}
-
-VOID NTAPI
-uhci_dpc_callback(PKDPC dpc, PVOID context, PVOID sysarg1, PVOID sysarg2)
-{
- PUHCI_DEV uhci;
-
- LIST_HEAD temp_list;
- PLIST_ENTRY pthis, pnext;
- PURB purb;
- PQH_EXTENSION pqhe;
- PUHCI_PENDING_ENDP pending_endp;
- PUSB_DEV pdev;
- PUSB_ENDPOINT pendp;
-
- BOOLEAN finished;
- LONG i, j;
- ULONG uhci_status, urb_status, toggle = 0;
-
- SYNC_PARAM sync_param;
- USE_BASIC_NON_PENDING_IRQL;
-
- UNREFERENCED_PARAMETER(dpc);
- UNREFERENCED_PARAMETER(sysarg2);
-
- uhci = (PUHCI_DEV) context;
- if (uhci == NULL)
- return;
-
- uhci_status = (ULONG) sysarg1;
-
- InitializeListHead(&temp_list);
-
- sync_param.uhci = uhci;
- sync_param.context = (PVOID) & temp_list;
-
- uhci_dbg_print(DBGLVL_MAXIMUM, ("uhci_dpc_callback(): entering..., uhci=0x%x\n", uhci));
- //remove finished urb from uhci's urb-list
- KeSynchronizeExecution(uhci->pdev_ext->uhci_int, uhci_sync_remove_urb_finished, &sync_param);
-
- //release resources( tds, and qhs ) the urb occupied
- while (IsListEmpty(&temp_list) == FALSE)
- {
- //not in any public queue, if do not access into dev, no race
- //condition will occur
- purb = (PURB) RemoveHeadList(&temp_list);
- urb_status = purb->status;
-
- //the only place we do not use this lock on non-pending-endp-list data ops
- KeAcquireSpinLockAtDpcLevel(&uhci->pending_endp_list_lock);
- while (IsListEmpty(&purb->trasac_list) == FALSE)
- {
- pthis = RemoveHeadList(&purb->trasac_list);
-
- if ((((PTD_EXTENSION) pthis)->flags & UHCI_ITEM_FLAG_TYPE) == UHCI_ITEM_FLAG_QH)
- {
- pqhe = (PQH_EXTENSION) pthis;
- lock_qh_pool(&uhci->qh_pool, TRUE);
- free_qh(&uhci->qh_pool, pqhe->pqh);
- unlock_qh_pool(&uhci->qh_pool, TRUE);
- }
- else
- {
- //must be a td chain
- InsertHeadList(&purb->trasac_list, pthis);
- for(i = 0, purb->bytes_transfered = 0; i < purb->td_count; i++)
- {
- PUHCI_TD ptd;
- // accumulate data transfered in tds
- ptd = ((PTD_EXTENSION) pthis)->ptd;
- if ((ptd->status & TD_CTRL_ACTIVE) == 0 && (ptd->status & TD_CTRL_ANY_ERROR) == 0)
- {
- j = ptd->status & 0x7ff;
- purb->bytes_transfered += ((j == 0x7ff) ? 0 : (j + 1));
-
- }
- ListNext(&purb->trasac_list, pthis, pnext);
- pthis = pnext;
- }
-
- if (urb_status & TD_CTRL_ANY_ERROR)
- {
- if (purb->last_finished_td != NULL && purb->last_finished_td != &purb->trasac_list)
- toggle = (((PTD_EXTENSION) purb->last_finished_td)->ptd->info & (1 << 19));
- }
- //trick, remove trasac_list
- ListFirst(&purb->trasac_list, pthis);
- RemoveEntryList(&purb->trasac_list);
- lock_td_pool(&uhci->td_pool, TRUE);
- free_tds(&uhci->td_pool, ((PTD_EXTENSION) pthis)->ptd);
- unlock_td_pool(&uhci->td_pool, TRUE);
- //termination condition
- InitializeListHead(&purb->trasac_list);
- purb->last_finished_td = NULL;
- }
- }
-
- if (endp_type(purb->pendp) == USB_ENDPOINT_XFER_ISOC
- || endp_type(purb->pendp) == USB_ENDPOINT_XFER_INT)
- uhci_claim_bandwidth(uhci, purb, FALSE); //release band-width
-
- KeReleaseSpinLockFromDpcLevel(&uhci->pending_endp_list_lock);
-
- uhci_set_error_code(purb, urb_status);
-
- finished = TRUE;
-
- //since the ref_count for the urb is not released, we can safely have one
- //pointer to dev
- pdev = dev_from_endp(purb->pendp);
- pendp = purb->pendp;
-
- if (purb->status == USB_STATUS_BABBLE_DETECTED)
- {
- usb_dbg_print(DBGLVL_MEDIUM,
- ("uhci_dpc_callback(): alert!!!, babble detected, severe error, reset the whole bus\n"));
- uhci_reset(uhci);
- uhci_start(&uhci->hcd_interf);
- }
-
- //this will let the new request in uhci_generic_urb_completion to this endp
- //be processed rather than queued in the pending_endp_list
- lock_dev(pdev, TRUE);
- usb_endp_busy_count_dec(pendp);
- unlock_dev(pdev, TRUE);
-
- if (usb_success(purb->status) == FALSE)
- {
- // set error code and complete the urb and purb is invalid from this point
- uhci_generic_urb_completion(purb, purb->context);
- }
- else
- {
- if ((purb->pipe & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_BULK)
- {
- purb->rest_bytes -= purb->bytes_transfered;
- if (purb->rest_bytes)
- {
- finished = FALSE;
- }
- else
- {
- uhci_generic_urb_completion(purb, purb->context);
- }
- }
- else
- {
- uhci_generic_urb_completion(purb, purb->context);
- //purb is now invalid
- }
- }
-
- KeAcquireSpinLockAtDpcLevel(&uhci->pending_endp_list_lock);
- lock_dev(pdev, TRUE);
-
- if (finished)
- pdev->ref_count--;
-
- if (urb_status & TD_CTRL_ANY_ERROR && endp_type(pendp) != USB_ENDPOINT_XFER_CONTROL)
- {
- pendp->flags &= ~USB_ENDP_FLAG_STAT_MASK;
- pendp->flags |= USB_ENDP_FLAG_STALL;
- }
-
- if (dev_state(pdev) == USB_DEV_STATE_ZOMB)
- {
- unlock_dev(pdev, TRUE);
- KeReleaseSpinLockFromDpcLevel(&uhci->pending_endp_list_lock);
- if (finished == FALSE)
- {
-
- purb->status = STATUS_DEVICE_DOES_NOT_EXIST;
- uhci_generic_urb_completion(purb, purb->context);
-
- lock_dev(pdev, TRUE);
- pdev->ref_count--;
- unlock_dev(pdev, TRUE);
- }
- continue;
- }
-
- if (finished && IsListEmpty(&pendp->urb_list) == TRUE)
- {
- unlock_dev(pdev, TRUE);
- KeReleaseSpinLockFromDpcLevel(&uhci->pending_endp_list_lock);
- continue;
- }
- else if (finished == TRUE)
- {
- //has urb in the endp's urb-list
- if (usb_endp_busy_count(pendp) > 0)
- {
- //the urbs still have chance to be sheduled but not this time
- unlock_dev(pdev, TRUE);
- KeReleaseSpinLockFromDpcLevel(&uhci->pending_endp_list_lock);
- continue;
- }
- }
-
- if (finished == FALSE)
- {
- //a split bulk transfer
- purb->bytes_transfered = 0;
- purb->bytes_to_transfer =
- UHCI_MAX_TDS_PER_TRANSFER * purb->pendp->pusb_endp_desc->wMaxPacketSize
- > purb->rest_bytes
- ? purb->rest_bytes : UHCI_MAX_TDS_PER_TRANSFER * purb->pendp->pusb_endp_desc->wMaxPacketSize;
-
- //the urb is not finished
- purb->flags &= ~URB_FLAG_STATE_MASK;
- purb->flags |= URB_FLAG_STATE_PENDING;
-
- InsertHeadList(&pendp->urb_list, &purb->urb_link);
- }
-
- pending_endp = alloc_pending_endp(&uhci->pending_endp_pool, 1);
- if (!pending_endp)
- {
- unlock_dev(pdev, TRUE);
- KeReleaseSpinLockFromDpcLevel(&uhci->pending_endp_list_lock);
- return;
- }
-
- pending_endp->pendp = pendp;
- InsertTailList(&uhci->pending_endp_list, &pending_endp->endp_link);
-
- unlock_dev(pdev, TRUE);
- KeReleaseSpinLockFromDpcLevel(&uhci->pending_endp_list_lock);
- }
-
- //ah...exhausted, let's find some in the pending_endp_list to rock
- uhci_process_pending_endp(uhci);
- return;
-}
-
-BOOLEAN
-uhci_add_device(PUHCI_DEV uhci, PUSB_DEV dev)
-{
- if (dev == NULL || uhci == NULL)
- return FALSE;
-
- return TRUE;
-}
-
-BOOLEAN NTAPI
-uhci_sync_cancel_urbs_dev(PVOID context)
-{
- //cancel all the urbs on one dev
- PUHCI_DEV uhci;
- PUSB_DEV pdev, dest_dev;
- PSYNC_PARAM sync_param;
- PLIST_ENTRY pthis, pnext;
- LONG count;
-
- sync_param = (PSYNC_PARAM) context;
- dest_dev = (PUSB_DEV) sync_param->context;
- uhci = sync_param->uhci;
-
- if (uhci == NULL || dest_dev == NULL)
- {
- return (UCHAR) (sync_param->ret = FALSE);
- }
- count = 0;
- ListFirst(&uhci->urb_list, pthis);
- while (pthis)
- {
- pdev = dev_from_endp(((PURB) pthis)->pendp);
- if (pdev == dest_dev)
- {
- ((PURB) pthis)->flags |= URB_FLAG_FORCE_CANCEL;
- }
- ListNext(&uhci->urb_list, pthis, pnext);
- pthis = pnext;
- count++;
- }
- if (count)
- uhci->skel_term_td->status |= TD_CTRL_IOC;
-
- return (UCHAR) (sync_param->ret = TRUE);
-}
-
-BOOLEAN
-uhci_remove_device(PUHCI_DEV uhci, PUSB_DEV dev)
-{
- PUHCI_PENDING_ENDP ppending_endp;
- PLIST_ENTRY pthis, pnext;
- PURB purb;
- LIST_HEAD temp_list;
- int i, j, k;
- SYNC_PARAM sync_param;
-
- USE_BASIC_IRQL;
-
- if (uhci == NULL || dev == NULL)
- return FALSE;
-
- InitializeListHead(&temp_list);
-
- //free pending endp that has urb queued from pending endp list
- lock_pending_endp_list(&uhci->pending_endp_list_lock);
-
- ListFirst(&uhci->pending_endp_list, pthis);
-
- while (pthis)
- {
- ppending_endp = (PUHCI_PENDING_ENDP) pthis;
- ListNext(&uhci->pending_endp_list, pthis, pnext);
- if (dev_from_endp(ppending_endp->pendp) == dev)
- {
- RemoveEntryList(pthis);
- free_pending_endp(&uhci->pending_endp_pool, struct_ptr(pthis, UHCI_PENDING_ENDP, endp_link));
- }
- pthis = pnext;
- }
- unlock_pending_endp_list(&uhci->pending_endp_list_lock);
-
- //cancel all the urbs in the urb-list
- sync_param.uhci = uhci;
- sync_param.context = (PVOID) dev;
-
- KeSynchronizeExecution(uhci->pdev_ext->uhci_int, uhci_sync_cancel_urbs_dev, &sync_param);
-
- //cancel all the urb in the endp's urb-list
- k = 0;
- lock_dev(dev, FALSE);
- if (dev->usb_config)
- {
- //only for configed dev
- for(i = 0; i < dev->usb_config->if_count; i++)
- {
- for(j = 0; j < dev->usb_config->interf[i].endp_count; j++)
- {
- ListFirst(&dev->usb_config->interf[i].endp[j].urb_list, pthis);
- while (pthis)
- {
- ListNext(&dev->usb_config->interf[i].endp[j].urb_list, pthis, pnext);
-
- RemoveEntryList(pthis);
- InsertHeadList(&temp_list, pthis);
- pthis = pnext;
- k++;
- }
-
- }
- }
- }
- ListFirst(&dev->default_endp.urb_list, pthis);
-
- while (pthis)
- {
- ListNext(&dev->default_endp.urb_list, pthis, pnext);
-
- RemoveEntryList(pthis);
- InsertHeadList(&temp_list, pthis);
- pthis = pnext;
- k++;
- }
- unlock_dev(dev, FALSE);
-
- if (IsListEmpty(&temp_list) == FALSE)
- {
- for(i = 0; i < k; i++)
- {
- //complete those urbs with error
- pthis = RemoveHeadList(&temp_list);
- purb = (PURB) pthis;
- purb->status = STATUS_DEVICE_DOES_NOT_EXIST;
- {
- uhci_generic_urb_completion(purb, purb->context);
- }
- }
- }
-
- lock_dev(dev, FALSE) dev->ref_count -= k;
- unlock_dev(dev, FALSE);
-
- return TRUE;
-}
-
-
-//
-// assume that the urb has its rest_bytes and bytes_to_transfer set
-// and bytes_transfered is zeroed.
-// dev_lock must be acquired outside
-// urb comes from dev's endpoint urb-list. it is already removed from
-// the endpoint urb-list.
-//
-NTSTATUS
-uhci_internal_submit_bulk(PUHCI_DEV uhci, PURB urb)
-{
-
- LONG max_packet_size, td_count, offset, bytes_to_transfer, data_load;
- PBYTE start_addr;
- PUHCI_TD ptd;
- PUHCI_QH pqh;
- LIST_ENTRY td_list, *pthis, *pnext;
- BOOLEAN old_toggle, toggle, ret;
- UCHAR pid;
-
- if (uhci == NULL || urb == NULL)
- return STATUS_INVALID_PARAMETER;
-
- max_packet_size = endp_max_packet_size(urb->pendp);
- if (urb->bytes_to_transfer == 0)
- {
- return STATUS_INVALID_PARAMETER;
- }
-
- td_count = (urb->bytes_to_transfer + max_packet_size - 1) / max_packet_size;
-
- lock_td_pool(&uhci->td_pool, TRUE);
- if (can_transfer(&uhci->td_pool, td_count) == FALSE)
- {
- unlock_td_pool(&uhci->td_pool, TRUE);
- return STATUS_NO_MORE_ENTRIES;
- }
-
- ptd = alloc_tds(&uhci->td_pool, td_count);
- unlock_td_pool(&uhci->td_pool, TRUE);
-
- if (ptd == NULL)
- {
- return STATUS_UNSUCCESSFUL;
- }
-
- InitializeListHead(&td_list);
- InsertTailList(&ptd->ptde->vert_link, &td_list);
-
- ListFirst(&td_list, pthis);
- ListNext(&td_list, pthis, pnext);
-
- start_addr = &urb->data_buffer[urb->data_length - urb->rest_bytes];
- offset = 0;
-
- old_toggle = toggle = urb->pendp->flags & USB_ENDP_FLAG_DATATOGGLE ? TRUE : FALSE;
- bytes_to_transfer = urb->bytes_to_transfer;
-
- urb->pipe = ((max_packet_size - 1) << 21)
- | ((ULONG) endp_num(urb->pendp) << 15)
- | (dev_from_endp(urb->pendp)->dev_addr << 8)
- | ((ULONG) endp_dir(urb->pendp)) | USB_ENDPOINT_XFER_BULK;
-
- pid = (((ULONG) urb->pendp->pusb_endp_desc->bEndpointAddress & USB_DIR_IN) ? USB_PID_IN : USB_PID_OUT);
- while (pthis)
- {
- ptd = ((PTD_EXTENSION) pthis)->ptd;
-
- data_load = max_packet_size < bytes_to_transfer ? max_packet_size : bytes_to_transfer;
- ptd->purb = urb;
- uhci_fill_td(ptd,
- (3 << TD_CTRL_C_ERR_SHIFT)
- | (TD_CTRL_ACTIVE),
- ((data_load - 1) << 21)
- | (toggle << 19)
- | ((ULONG) endp_num(urb->pendp) << 15)
- | (dev_from_endp(urb->pendp)->dev_addr << 8)
- | pid, MmGetPhysicalAddress(start_addr + offset).LowPart);
-
- bytes_to_transfer -= data_load;
- offset += data_load;
-
- if (pnext)
- {
- ptd->link = ((PTD_EXTENSION) pnext)->ptd->phy_addr;
- }
- else
- {
- //Last one, enable ioc and short packet detect if necessary
- ptd->link = UHCI_PTR_TERM;
- ptd->status |= TD_CTRL_IOC;
- if (bytes_to_transfer < max_packet_size && (pid == USB_PID_IN))
- {
- //ptd->status |= TD_CTRL_SPD;
- }
- }
-
- pthis = pnext;
- toggle ^= 1;
- if (pthis)
- ListNext(&td_list, pthis, pnext);
-
- }
-
- ListFirst(&td_list, pthis);
- RemoveEntryList(&td_list);
-
- lock_qh_pool(&uhci->qh_pool, TRUE);
- pqh = alloc_qh(&uhci->qh_pool);
- unlock_qh_pool(&uhci->qh_pool, TRUE);
-
- if (pqh == NULL)
- {
- lock_td_pool(&uhci->td_pool, TRUE);
-
- if (pthis)
- free_tds(&uhci->td_pool, ((PTD_EXTENSION) pthis)->ptd);
-
- unlock_td_pool(&uhci->td_pool, TRUE);
- return STATUS_NO_MORE_ENTRIES;
-
- }
-
- urb->td_count = td_count;
-
- uhci_insert_tds_qh(pqh, ((PTD_EXTENSION) pthis)->ptd);
- uhci_insert_qh_urb(urb, pqh);
- urb->pendp->flags =
- (urb->pendp->flags & ~USB_ENDP_FLAG_DATATOGGLE) | (toggle ? USB_ENDP_FLAG_DATATOGGLE : 0);
- usb_endp_busy_count_inc(urb->pendp);
- uhci_insert_urb_to_schedule(uhci, urb, ret);
-
- if (ret == FALSE)
- {
- // undo all we have done
- RemoveEntryList(&pqh->pqhe->vert_link); //remove qh from td_chain
- RemoveEntryList(&urb->trasac_list);
-
- lock_td_pool(&uhci->td_pool, TRUE);
- if (pthis)
- free_tds(&uhci->td_pool, ((PTD_EXTENSION) pthis)->ptd);
- unlock_td_pool(&uhci->td_pool, TRUE);
-
- lock_qh_pool(&uhci->qh_pool, TRUE);
- if (pqh)
- free_qh(&uhci->qh_pool, pqh);
- unlock_qh_pool(&uhci->qh_pool, TRUE);
-
- InitializeListHead(&urb->trasac_list);
- usb_endp_busy_count_dec(urb->pendp);
- urb->pendp->flags =
- (urb->pendp->flags & ~USB_ENDP_FLAG_DATATOGGLE) | (old_toggle ? USB_ENDP_FLAG_DATATOGGLE : 0);
- return STATUS_UNSUCCESSFUL;
- }
- return STATUS_SUCCESS;
-}
-
-NTSTATUS
-uhci_internal_submit_ctrl(PUHCI_DEV uhci, PURB urb)
-{
- LIST_ENTRY td_list, *pthis, *pnext;
- LONG i, td_count;
- LONG toggle;
- LONG max_packet_size, bytes_to_transfer, bytes_rest, start_idx;
- PUHCI_TD ptd;
- PUHCI_QH pqh;
- ULONG dev_addr;
- PUSB_DEV pdev;
- BOOLEAN ret;
-
- if (uhci == NULL || urb == NULL)
- return STATUS_INVALID_PARAMETER;
-
- toggle = 0;
- bytes_rest = urb->rest_bytes;
- bytes_to_transfer = urb->bytes_to_transfer;
- max_packet_size = endp_max_packet_size(urb->pendp);
- start_idx = urb->data_length - urb->rest_bytes;
- td_count = 2 + (urb->bytes_to_transfer + max_packet_size - 1) / max_packet_size;
-
- lock_td_pool(&uhci->td_pool, TRUE);
-
- if (can_transfer(&uhci->td_pool, td_count) == FALSE)
- {
- unlock_td_pool(&uhci->td_pool, TRUE);
- return STATUS_NO_MORE_ENTRIES;
- }
-
- ptd = alloc_tds(&uhci->td_pool, td_count);
- unlock_td_pool(&uhci->td_pool, TRUE);
-
- if (ptd == NULL)
- {
- return STATUS_UNSUCCESSFUL;
- }
-
- InsertTailList(&ptd->ptde->vert_link, &td_list);
-
- ListFirst(&td_list, pthis);
- ListNext(&td_list, pthis, pnext);
-
- ptd = ((PTD_EXTENSION) pthis)->ptd;
-
- pdev = dev_from_endp(urb->pendp);
- dev_addr = pdev->dev_addr;
-
- if (dev_state(pdev) <= USB_DEV_STATE_RESET)
- dev_addr = 0;
-
- usb_dbg_print(DBGLVL_MAXIMUM, ("uhci_internal_submit_ctrl(): dev_addr =0x%x\n", dev_addr));
-
- RtlCopyMemory(uhci->io_buf, urb->setup_packet, 8);
-
- if ((urb->setup_packet[0] & USB_DIR_IN) == 0) //out
- RtlCopyMemory(&uhci->io_buf[8], urb->data_buffer, bytes_to_transfer);
- else
- RtlZeroMemory(&uhci->io_buf[8], bytes_to_transfer);
-
- uhci_fill_td(ptd,
- (3 << TD_CTRL_C_ERR_SHIFT) | (TD_CTRL_ACTIVE),
- (7 << 21) | (((ULONG) endp_num(urb->pendp)) << 15) | (dev_addr << 8) | (USB_PID_SETUP),
- //uhci->io_buf_logic_addr.LowPart);
- MmGetPhysicalAddress(urb->setup_packet).LowPart);
-
- ptd->link = ((PTD_EXTENSION) pnext)->ptd->phy_addr;
- pthis = pnext;
- ListNext(&td_list, pthis, pnext);
-
- urb->pipe = ((max_packet_size - 1) << 21)
- | ((ULONG) endp_num(urb->pendp) << 15)
- | (dev_addr << 8) | (pdev->flags & USB_DEV_FLAG_LOW_SPEED) | USB_ENDPOINT_XFER_CONTROL;
-
- for(i = 0, toggle = 1; ((i < td_count - 2) && pthis); i++, toggle ^= 1)
- {
- //construct tds for DATA packets of data stage.
- ptd = ((PTD_EXTENSION) pthis)->ptd;
- uhci_fill_td(ptd,
- (3 << TD_CTRL_C_ERR_SHIFT)
- | (TD_CTRL_ACTIVE),
- ((bytes_to_transfer >
- max_packet_size ? max_packet_size - 1 : bytes_to_transfer -
- 1) << 21) | (toggle << 19) | (((ULONG) endp_num(urb->
- pendp)) << 15) | (dev_addr << 8) |
- ((urb->setup_packet[0] & USB_DIR_IN) ? USB_PID_IN : USB_PID_OUT),
- //uhci->io_buf_logic_addr.LowPart + 8 + i * max_packet_size );
- MmGetPhysicalAddress(&urb->data_buffer[start_idx + i * max_packet_size]).LowPart);
-
- if (pnext)
- ptd->link = ((PTD_EXTENSION) pnext)->ptd->phy_addr;
-
- if (i < td_count - 3)
- {
- bytes_to_transfer -= max_packet_size;
- }
- else
- {
- if (bytes_to_transfer > 0)
- {
- if (bytes_to_transfer < max_packet_size && (urb->setup_packet[0] & USB_DIR_IN))
- ptd->status |= TD_CTRL_SPD;
- }
- }
- pthis = pnext;
-
- if (pthis)
- ListNext(&td_list, pthis, pnext);
- }
-
- if (pnext)
- ptd->link = ((PTD_EXTENSION) pnext)->ptd->phy_addr;
-
- ListFirstPrev(&td_list, pthis);
- ptd = ((PTD_EXTENSION) pthis)->ptd;
-
- //the last is an IN transaction
- uhci_fill_td(ptd,
- (3 << TD_CTRL_C_ERR_SHIFT)
- | (TD_CTRL_ACTIVE | TD_CTRL_IOC),
- (UHCI_NULL_DATA_SIZE << 21)
- | (1 << 19)
- | (((ULONG) endp_num(urb->pendp)) << 15)
- | (dev_addr << 8)
- | ((td_count > 2)
- ? ((urb->setup_packet[0] & USB_DIR_IN) ? USB_PID_OUT : USB_PID_IN) : USB_PID_IN), 0);
-
- ptd->link = UHCI_PTR_TERM;
-
- ListFirst(&td_list, pthis);
- RemoveEntryList(&td_list);
-
- lock_qh_pool(&uhci->qh_pool, TRUE);
- pqh = alloc_qh(&uhci->qh_pool);
- unlock_qh_pool(&uhci->qh_pool, TRUE);
-
- if (pqh == NULL)
- {
- lock_td_pool(&uhci->td_pool, TRUE);
- if (pthis)
- free_tds(&uhci->td_pool, ((PTD_EXTENSION) pthis)->ptd);
- unlock_td_pool(&uhci->td_pool, TRUE);
-
- return STATUS_NO_MORE_ENTRIES;
- }
-
- urb->td_count = td_count;
-
- uhci_insert_tds_qh(pqh, ((PTD_EXTENSION) pthis)->ptd);
- uhci_insert_qh_urb(urb, pqh);
-
- usb_endp_busy_count_inc(urb->pendp);
- uhci_insert_urb_to_schedule(uhci, urb, ret);
- if (ret == FALSE)
- {
- RemoveEntryList(&pqh->pqhe->vert_link);
- RemoveEntryList(&urb->trasac_list);
-
- lock_td_pool(&uhci->td_pool, TRUE);
- if (pthis)
- free_tds(&uhci->td_pool, ((PTD_EXTENSION) pthis)->ptd);
- unlock_td_pool(&uhci->td_pool, TRUE);
-
- lock_qh_pool(&uhci->qh_pool, TRUE);
- if (pqh)
- free_qh(&uhci->qh_pool, pqh);
- unlock_qh_pool(&uhci->qh_pool, TRUE);
-
- InitializeListHead(&urb->trasac_list);
- usb_endp_busy_count_dec(urb->pendp);
- return STATUS_UNSUCCESSFUL;
- }
-
- return STATUS_SUCCESS;
-}
-
-NTSTATUS
-uhci_internal_submit_int(PUHCI_DEV uhci, PURB urb)
-{
- LONG i;
- LONG toggle = 0;
- LONG max_packet_size;
- PUHCI_TD ptd;
- BOOLEAN ret;
-
- if (uhci == NULL || urb == NULL)
- {
- uhci_dbg_print(DBGLVL_MEDIUM,
- ("uhci_internal_submit_int(): uhci=0x%x, urb=0x%x "
- "returning STATUS_INVALID_PARAMETER!\n", uhci, urb));
- return STATUS_INVALID_PARAMETER;
- }
-
- toggle = (urb->pendp->flags & USB_ENDP_FLAG_DATATOGGLE) ? TRUE : FALSE;
- max_packet_size = endp_max_packet_size(urb->pendp);
-
- if (max_packet_size < urb->data_length || max_packet_size == 0 || max_packet_size > 64)
- {
- uhci_dbg_print(DBGLVL_MEDIUM,
- ("uhci_internal_submit_int(): max_packet_size=%d, urb->data_length=%d "
- "returning STATUS_INVALID_PARAMETER!\n", max_packet_size, urb->data_length));
- return STATUS_INVALID_PARAMETER;
- }
-
- lock_td_pool(&uhci->td_pool, TRUE);
- ptd = alloc_td(&uhci->td_pool);
- unlock_td_pool(&uhci->td_pool, TRUE);
-
- if (ptd == NULL)
- return STATUS_NO_MORE_ENTRIES;
-
- for(i = 1; i <= 7; i++)
- {
- if (((ULONG) max_packet_size) >> i)
- continue;
- else
- break;
- }
-
- i--;
- i &= 7;
-
- urb->pipe = (((ULONG) urb->pendp->pusb_endp_desc->bInterval) << 24)
- | (i << 21)
- | (toggle << 19)
- | ((ULONG) endp_num(urb->pendp) << 15)
- | (((ULONG) dev_from_endp(urb->pendp)->dev_addr) << 8)
- | USB_DIR_IN | (dev_from_endp(urb->pendp)->flags & USB_DEV_FLAG_LOW_SPEED) | USB_ENDPOINT_XFER_INT;
-
- uhci_fill_td(ptd,
- (3 << TD_CTRL_C_ERR_SHIFT)
- | (TD_CTRL_ACTIVE)
- | ((urb->data_length < max_packet_size ? TD_CTRL_SPD : 0))
- | (TD_CTRL_IOC),
- (((ULONG) max_packet_size - 1) << 21)
- | (toggle << 19)
- | ((ULONG) endp_num(urb->pendp) << 15)
- | (((ULONG) dev_from_endp(urb->pendp)->dev_addr & 0x7f) << 8)
- | USB_PID_IN, MmGetPhysicalAddress(urb->data_buffer).LowPart);
-
- toggle ^= 1;
- urb->td_count = 1;
-
- InitializeListHead(&urb->trasac_list);
- InsertTailList(&urb->trasac_list, &ptd->ptde->vert_link);
-
- //indirectly guarded by pending_endp_list_lock
- if (uhci_claim_bandwidth(uhci, urb, TRUE) == FALSE)
- {
- InitializeListHead(&urb->trasac_list);
-
- lock_td_pool(&uhci->td_pool, TRUE);
- free_td(&uhci->td_pool, ptd);
- unlock_td_pool(&uhci->td_pool, TRUE);
-
- return STATUS_NO_MORE_ENTRIES;
- }
-
- urb->pendp->flags = (urb->pendp->flags & ~USB_ENDP_FLAG_DATATOGGLE) | (toggle << 31);
- usb_endp_busy_count_inc(urb->pendp);
-
- uhci_insert_urb_to_schedule(uhci, urb, ret);
-
- if (ret == FALSE)
- {
- lock_td_pool(&uhci->td_pool, TRUE);
- if (ptd)
- free_td(&uhci->td_pool, ptd);
- unlock_td_pool(&uhci->td_pool, TRUE);
-
- InitializeListHead(&urb->trasac_list);
- usb_endp_busy_count_dec(urb->pendp);
- urb->pendp->flags = (urb->pendp->flags & ~USB_ENDP_FLAG_DATATOGGLE) | ((toggle ^ 1) << 31);
- uhci_claim_bandwidth(uhci, urb, FALSE);
- return STATUS_UNSUCCESSFUL;
- }
-
- return STATUS_SUCCESS;
-}
-
-
-NTSTATUS
-uhci_internal_submit_iso(PUHCI_DEV uhci, PURB urb)
-{
- PUHCI_TD ptd;
- LIST_ENTRY td_list, *pthis, *pnext;
- int i;
- BOOLEAN toggle = FALSE, ret;
-
- if (uhci == NULL || urb == NULL)
- return STATUS_INVALID_PARAMETER;
-
- if (urb->iso_frame_count == 0)
- return STATUS_INVALID_PARAMETER;
-
- lock_td_pool(&uhci->td_pool, TRUE);
-
- if (can_transfer(&uhci->td_pool, urb->iso_frame_count) == FALSE)
- {
- unlock_td_pool(&uhci->td_pool, TRUE);
- return STATUS_NO_MORE_ENTRIES;
- }
-
- ptd = alloc_tds(&uhci->td_pool, urb->iso_frame_count);
- unlock_td_pool(&uhci->td_pool, TRUE);
-
- if (ptd == NULL)
- {
- return STATUS_UNSUCCESSFUL;
- }
-
- InsertTailList(&ptd->ptde->vert_link, &td_list);
- ListFirst(&td_list, pthis);
-
- urb->td_count = urb->iso_frame_count;
-
- urb->pipe = (((ULONG) urb->iso_packet_desc[0].length) << 21)
- | ((ULONG) endp_num(urb->pendp) << 15)
- | (((ULONG) dev_from_endp(urb->pendp)->dev_addr) << 8)
- | ((ULONG) endp_dir(urb->pendp)) | USB_ENDPOINT_XFER_ISOC;
-
-
- for(i = 0; i < urb->iso_frame_count && pthis; i++)
- {
- ptd = ((PTD_EXTENSION) pthis)->ptd;
- uhci_fill_td(ptd,
- (3 << TD_CTRL_C_ERR_SHIFT)
- | (TD_CTRL_ACTIVE)
- | (TD_CTRL_IOS),
- (((ULONG) urb->iso_packet_desc[i].length - 1) << 21)
- | (0 << 19)
- | ((ULONG) endp_num(urb->pendp) << 15)
- | (((ULONG) dev_from_endp(urb->pendp)->dev_addr) << 8)
- | ((urb->pendp->pusb_endp_desc->bEndpointAddress & USB_DIR_IN)
- ? USB_PID_OUT : USB_PID_IN),
- MmGetPhysicalAddress(&urb->data_buffer[urb->iso_packet_desc[i].offset]).LowPart);
-
- toggle ^= 1;
- ListNext(&td_list, pthis, pnext);
- pthis = pnext;
- }
-
- ptd->status |= TD_CTRL_IOC; //need interrupt
-
- ListFirst(&td_list, pthis);
- RemoveEntryList(&td_list);
-
- InsertTailList(pthis, &urb->trasac_list);
-
- //indirectly guarded by pending_endp_list_lock
- if (uhci_claim_bandwidth(uhci, urb, TRUE) == FALSE)
- {
- //bad news: we can not allocate the enough bandwidth for the urb
- RemoveEntryList(&urb->trasac_list);
- InitializeListHead(&urb->trasac_list);
-
- lock_td_pool(&uhci->td_pool, TRUE);
- free_tds(&uhci->td_pool, ((PTD_EXTENSION) pthis)->ptd);
- unlock_td_pool(&uhci->td_pool, TRUE);
- return STATUS_NO_MORE_ENTRIES;
-
- }
-
- usb_endp_busy_count_inc(urb->pendp);
- uhci_insert_urb_to_schedule(uhci, urb, ret);
- if (ret == FALSE)
- {
- usb_endp_busy_count_dec(urb->pendp);
- RemoveEntryList(&urb->trasac_list);
-
- lock_td_pool(&uhci->td_pool, TRUE);
- free_tds(&uhci->td_pool, ((PTD_EXTENSION) pthis)->ptd);
- unlock_td_pool(&uhci->td_pool, TRUE);
- uhci_claim_bandwidth(uhci, urb, FALSE);
- return STATUS_UNSUCCESSFUL;
- }
-
- return STATUS_SUCCESS;
-}
-
-// runs in uhci_isr
-BOOLEAN
-uhci_is_xfer_finished(PURB urb)
-{
- PLIST_ENTRY pthis, pnext;
- PUHCI_TD ptd;
- BOOLEAN ret = TRUE;
- PTD_EXTENSION ptde;
-
- if (urb->last_finished_td == NULL)
- {
- urb->last_finished_td = &urb->trasac_list;
- }
-
- if (&urb->trasac_list == urb->last_finished_td)
- ListFirst(&urb->trasac_list, pthis)
- else
- ListNext(&urb->trasac_list, urb->last_finished_td, pthis);
-
- while (pthis)
- {
- if ((((PTD_EXTENSION) pthis)->flags & UHCI_ITEM_FLAG_TYPE) != UHCI_ITEM_FLAG_TD)
- {
- ListNext(&urb->trasac_list, pthis, pnext);
- pthis = pnext;
- continue;
- }
- else
- {
- ptde = (PTD_EXTENSION) pthis;
- ptd = ptde->ptd;
- ASSERT(ptd != NULL);
-
- if (ptd->status & TD_CTRL_ACTIVE)
- {
- //still active
- ret = FALSE;
- break;
- }
- //let's see whether error occured
- if ((ptd->status & TD_CTRL_ANY_ERROR) == 0)
- {
- urb->last_finished_td = pthis;
- ListNext(&urb->trasac_list, pthis, pnext);
- pthis = pnext;
- continue;
- }
- else
- {
- urb->status = ptd->status;
- pthis = NULL;
- continue;
- }
- }
-
- }
-
- if (pthis == NULL)
- ret = TRUE;
-
- return ret;
-}
-
-// executed in isr, and have frame_list_lock acquired, so
-// never try to acquire any spin-lock
-// remove the bulk urb from schedule, and mark it not in
-// the schedule
-BOOLEAN
-uhci_remove_urb_from_schedule(PUHCI_DEV uhci, PURB urb)
-{
- BOOLEAN ret = FALSE;
- {
- switch (urb->pipe & USB_ENDPOINT_XFERTYPE_MASK)
- {
- case USB_ENDPOINT_XFER_BULK:
- {
- ret = uhci_remove_bulk_from_schedule(uhci, urb);
- break;
- }
- case USB_ENDPOINT_XFER_CONTROL:
- {
- ret = uhci_remove_ctrl_from_schedule(uhci, urb);
- break;
- }
- case USB_ENDPOINT_XFER_INT:
- {
- ret = uhci_remove_int_from_schedule(uhci, urb);
- break;
- }
- case USB_ENDPOINT_XFER_ISOC:
- {
- ret = uhci_remove_iso_from_schedule(uhci, urb);
- break;
- }
- }
- }
- return ret;
-}
-
-// executed in isr, and have frame_list_lock acquired, so
-// never try to acquire any spin-lock
-// remove the bulk urb from schedule, and mark it not in
-// the schedule
-BOOLEAN
-uhci_remove_bulk_from_schedule(PUHCI_DEV uhci, PURB urb)
-{
-
- PUHCI_QH pqh, pnext_qh, pprev_qh;
- PLIST_ENTRY pthis, pnext, pprev;
- LONG i;
-
- if (uhci == NULL || urb == NULL)
- return FALSE;
-
- ListFirst(&urb->trasac_list, pthis);
- pqh = ((PQH_EXTENSION) pthis)->pqh;
-
- ListFirst(&pqh->pqhe->hori_link, pnext);
- ListFirstPrev(&pqh->pqhe->hori_link, pprev);
-
- if (pprev == NULL || pnext == NULL)
- return FALSE;
-
- pnext_qh = struct_ptr(pnext, QH_EXTENSION, hori_link)->pqh;
- pprev_qh = struct_ptr(pprev, QH_EXTENSION, hori_link)->pqh;
-
- if (pprev != pnext)
- {
- //not the last one
- pprev_qh->link = pnext_qh->phy_addr;
- }
- else
- {
- //only two qhs in the list
- for(i = 0; i < UHCI_MAX_SKELQHS; i++)
- {
- if (pprev_qh == uhci->skel_qh[i])
- {
- break;
- }
- }
- ASSERT(i < UHCI_MAX_SKELQHS - 1);
- pprev_qh->link = uhci->skel_qh[i + 1]->phy_addr;
- }
- RemoveEntryList(&pqh->pqhe->hori_link);
-
- urb->flags &= ~URB_FLAG_IN_SCHEDULE;
-
- if ((urb->pipe & USB_DEV_FLAG_LOW_SPEED) == 0)
- uhci_drop_fsbr(uhci);
-
- return TRUE;
-}
-
-BOOLEAN
-uhci_remove_iso_from_schedule(PUHCI_DEV uhci, PURB urb)
-{
- PUHCI_TD ptd, pprev_td;
- PLIST_ENTRY pthis, pnext, pprev;
- int i, idx;
-
- if (uhci == NULL || urb == NULL)
- return FALSE;
-
- ListFirst(&urb->trasac_list, pthis);
-
- for(i = 0; i < urb->iso_frame_count && pthis; i++)
- {
- ptd = ((PTD_EXTENSION) pthis)->ptd;
- idx = (urb->iso_start_frame + i) & (UHCI_MAX_FRAMES - 1);
-
- ListFirstPrev(&ptd->ptde->hori_link, pprev);
-
- if (pprev == NULL)
- return FALSE;
-
- if (pprev == &uhci->frame_list_cpu[idx].td_link)
- {
- uhci->frame_list[idx] = ptd->link;
- }
- else
- {
- pprev_td = struct_ptr(pprev, TD_EXTENSION, hori_link)->ptd;
- pprev_td->link = ptd->link;
- }
-
- RemoveEntryList(&ptd->ptde->hori_link);
- ListNext(&urb->trasac_list, pthis, pnext);
- pthis = pnext;
- }
-
- urb->flags &= ~URB_FLAG_IN_SCHEDULE;
- return TRUE;
-}
-
-BOOLEAN
-uhci_remove_int_from_schedule(PUHCI_DEV uhci, PURB urb)
-{
- PUHCI_TD ptd, pnext_td, pprev_td;
- PLIST_ENTRY pthis, pnext, pprev;
- LONG i;
-
- if (uhci == NULL || urb == NULL)
- return FALSE;
-
- ListFirst(&urb->trasac_list, pthis);
- ptd = ((PTD_EXTENSION) pthis)->ptd;
- ListFirst(&ptd->ptde->hori_link, pnext);
- ListFirstPrev(&ptd->ptde->hori_link, pprev);
-
- if (pprev == NULL || pnext == NULL)
- return FALSE;
-
- pnext_td = struct_ptr(pnext, TD_EXTENSION, hori_link)->ptd;
- pprev_td = struct_ptr(pprev, TD_EXTENSION, hori_link)->ptd;
-
- if (pprev_td != pnext_td)
- pprev_td->link = pnext_td->phy_addr;
- else
- {
- //the last one
- for(i = UHCI_MAX_SKELTDS - 2; i >= 0; i--)
- {
- //UHCI_MAX_SKELTDS -1 skel tds for int transfer
- if (pprev_td == uhci->skel_td[i])
- break;
- }
-
- ASSERT(i >= 0);
- if (i == 0)
- {
- pprev_td->link = uhci->skel_qh[0]->phy_addr;
- }
- else
- {
- pprev_td->link = uhci->skel_td[i - 1]->phy_addr;
- }
- }
- RemoveEntryList(&ptd->ptde->hori_link);
-
- urb->flags &= ~URB_FLAG_IN_SCHEDULE;
- return TRUE;
-}
-
-BOOLEAN
-uhci_insert_tds_qh(PUHCI_QH pqh, PUHCI_TD td_chain)
-{
- if (pqh == NULL || td_chain == NULL)
- return FALSE;
-
- InsertTailList(&td_chain->ptde->vert_link, &pqh->pqhe->vert_link);
- pqh->element = td_chain->phy_addr;
- return TRUE;
-}
-
-BOOLEAN
-uhci_insert_qh_urb(PURB urb, PUHCI_QH qh_chain)
-{
- if (urb == NULL || qh_chain == NULL)
- return FALSE;
-
- InsertTailList(&qh_chain->pqhe->vert_link, &urb->trasac_list);
- qh_chain->pqhe->purb = urb;
- return TRUE;
-}
-
-// must have dev_lock and frame_list_lock acquired
-BOOLEAN
-uhci_insert_urb_schedule(PUHCI_DEV uhci, PURB urb)
-{
- PUHCI_QH pqh, pskel_qh, pnext_qh;
- PUHCI_TD ptd, plast_td;
- PLIST_ENTRY pthis, pnext;
- int i;
-
- if (uhci == NULL || urb == NULL)
- return FALSE;
-
- ListFirst(&urb->trasac_list, pthis);
- if (pthis == NULL)
- return FALSE;
-
- InsertTailList(&uhci->urb_list, &urb->urb_link);
-
- urb->flags &= ~URB_FLAG_STATE_MASK;
- urb->flags |= URB_FLAG_STATE_IN_PROCESS | URB_FLAG_IN_SCHEDULE;
-
-
- switch (endp_type(urb->pendp))
- {
- case USB_ENDPOINT_XFER_CONTROL:
- {
- pqh = ((PQH_EXTENSION) pthis)->pqh;
-
- if ((dev_from_endp(urb->pendp)->flags & USB_DEV_FLAG_LOW_SPEED) == 0)
- {
- pskel_qh = uhci->skel_hs_control_qh;
- pnext_qh = uhci->skel_bulk_qh;
- }
- else
- {
- pskel_qh = uhci->skel_ls_control_qh;
- pnext_qh = uhci->skel_hs_control_qh;
- }
-
- ListFirstPrev(&pskel_qh->pqhe->hori_link, pthis);
-
- if (pthis == NULL)
- pthis = &pskel_qh->pqhe->hori_link;
-
- InsertTailList(&pskel_qh->pqhe->hori_link, &pqh->pqhe->hori_link);
- pqh->link = pnext_qh->phy_addr;
- struct_ptr(pthis, QH_EXTENSION, hori_link)->pqh->link = pqh->phy_addr;
-
- //full speed band reclaimation
- if ((urb->pipe & USB_DEV_FLAG_LOW_SPEED) == 0)
- {
- uhci->fsbr_cnt++;
- if (uhci->fsbr_cnt == 1)
- {
- uhci->skel_term_qh->link = uhci->skel_hs_control_qh->phy_addr;
- }
- }
- return TRUE;
- }
- case USB_ENDPOINT_XFER_BULK:
- {
- pqh = ((PQH_EXTENSION) pthis)->pqh;
-
- ListFirstPrev(&uhci->skel_bulk_qh->pqhe->hori_link, pthis);
-
- if (pthis == NULL)
- pthis = &uhci->skel_bulk_qh->pqhe->hori_link;
-
- InsertTailList(&uhci->skel_bulk_qh->pqhe->hori_link, &pqh->pqhe->hori_link);
-
- pqh->link = uhci->skel_term_qh->phy_addr;
- struct_ptr(pthis, QH_EXTENSION, hori_link)->pqh->link = pqh->phy_addr;
-
- //full speed band reclaimation
- uhci->fsbr_cnt++;
- if (uhci->fsbr_cnt == 1)
- {
- uhci->skel_term_qh->link = uhci->skel_hs_control_qh->phy_addr;
- }
-
- return TRUE;
- }
- case USB_ENDPOINT_XFER_INT:
- {
- //bandwidth claim is done outside
- ptd = ((PTD_EXTENSION) pthis)->ptd;
-
- get_int_idx(urb, i);
-
- ListFirstPrev(&uhci->skel_td[i]->ptde->hori_link, pthis);
- if (pthis == NULL)
- pthis = &uhci->skel_td[i]->ptde->hori_link;
-
- InsertTailList(&uhci->skel_td[i]->ptde->hori_link, &ptd->ptde->hori_link);
-
- if (i > 0)
- {
- ptd->link = uhci->skel_td[i - 1]->phy_addr;
- }
- else if (i == 0)
- {
- ptd->link = uhci->skel_qh[0]->phy_addr;
- }
- //finally link the previous td to this td
- struct_ptr(pthis, TD_EXTENSION, hori_link)->ptd->link = ptd->phy_addr;
- return TRUE;
- }
- case USB_ENDPOINT_XFER_ISOC:
- {
-
- for(i = 0; i < urb->iso_frame_count; i++)
- {
- ptd = ((PTD_EXTENSION) pthis)->ptd;
- InsertTailList(&uhci->frame_list_cpu[(urb->iso_start_frame + i) & 0x3ff].td_link,
- &ptd->ptde->hori_link);
-
- if (IsListEmpty(&uhci->frame_list_cpu[(urb->iso_start_frame + i) & 0x3ff].td_link) == TRUE)
- {
- ptd->link = uhci->frame_list[(urb->iso_start_frame + i) & 0x3ff];
- uhci->frame_list[i] = ptd->phy_addr;
- }
- else
- {
- ListFirstPrev(&uhci->frame_list_cpu[(urb->iso_start_frame + i) & 0x3ff].td_link, pnext);
- plast_td = struct_ptr(pnext, TD_EXTENSION, hori_link)->ptd;
- ptd->link = plast_td->link;
- plast_td->link = ptd->phy_addr;
- }
-
- ListNext(&urb->trasac_list, pthis, pnext);
- pthis = pnext;
- }
- return TRUE;
-
- }
- }
- return FALSE;
-}
-
-//this function used as the KeSynchronizeExecution param to delegate control to uhci_insert_urb_schedule
-BOOLEAN NTAPI
-uhci_sync_insert_urb_schedule(PVOID context)
-{
- PSYNC_PARAM sync_param;
- PUHCI_DEV uhci;
- PURB purb;
-
- sync_param = (PSYNC_PARAM) context;
- if (sync_param == NULL)
- return FALSE;
-
- uhci = sync_param->uhci;
- purb = (PURB) sync_param->context;
-
- if (uhci == NULL || purb == NULL)
- return (UCHAR) (sync_param->ret = FALSE);
-
- return (UCHAR) (sync_param->ret = uhci_insert_urb_schedule(uhci, purb));
-}
-
-// be sure pending_endp_list_lock acquired
-BOOLEAN
-uhci_claim_bandwidth(PUHCI_DEV uhci,
- PURB urb,
- BOOLEAN claim_bw //true to claim bandwidth, false to free bandwidth
- )
-{
-
- UCHAR type;
- BOOLEAN ls, can_alloc;
- LONG bus_time, us;
- LONG i, idx, j, start_frame, interval;
-
- if (urb == NULL)
- return FALSE;
-
- can_alloc = TRUE;
-
- type = (UCHAR) (urb->pipe & USB_ENDPOINT_XFERTYPE_MASK);
- if (type == USB_ENDPOINT_XFER_BULK || type == USB_ENDPOINT_XFER_CONTROL)
- {
- return FALSE;
- }
-
- ls = (urb->pipe & USB_DEV_FLAG_LOW_SPEED) ? TRUE : FALSE;
-
- if (type == USB_ENDPOINT_XFER_INT)
- {
- start_frame = 0;
- i = urb->data_length;
- bus_time = usb_calc_bus_time(ls, FALSE, FALSE, i);
- us = ns_to_us(bus_time);
-
- i = (urb->pipe >> 24); //polling interval
-
- for(interval = 0, j = 0; j < 8; j++)
- {
- if (i & (1 << j))
- {
- interval = j;
- }
- }
-
- interval = 1 << interval;
- start_frame = interval - 1;
-
- if (claim_bw)
- {
-
- for(idx = 0; idx < UHCI_MAX_FRAMES; idx += interval)
- {
- if (uhci->frame_bw[idx] < us)
- {
- can_alloc = FALSE;
- break;
- }
- }
-
- if (!can_alloc)
- {
- return FALSE;
- }
-
- for(idx = start_frame; idx < UHCI_MAX_FRAMES; idx += interval)
- {
- uhci->frame_bw[idx] -= us;
- }
- }
- else
- {
- for(idx = start_frame; idx < UHCI_MAX_FRAMES; idx += interval)
- {
- uhci->frame_bw[idx] += us;
- }
- }
-
- }
- else if (type == USB_ENDPOINT_XFER_ISOC)
- {
- if (claim_bw)
- {
- for(i = 0; i < urb->iso_frame_count; i++)
- {
- bus_time = usb_calc_bus_time(FALSE,
- (urb->pipe & USB_DIR_IN)
- ? TRUE : FALSE, TRUE, urb->iso_packet_desc[i].length);
-
- urb->iso_packet_desc[i].bus_time = ns_to_us(bus_time);
- }
-
- for(i = 0; i < urb->iso_frame_count; i++)
- {
- if (uhci->frame_bw[(urb->iso_start_frame + i) & 0x3ff] < urb->iso_packet_desc[i].bus_time)
- {
- can_alloc = FALSE;
- break;
- }
- }
-
- if (!can_alloc)
- {
- return FALSE;
- }
-
- for(i = 0; i < urb->iso_frame_count; i++)
- {
- uhci->frame_bw[(urb->iso_start_frame + i) & 0x3ff] -= urb->iso_packet_desc[i].bus_time;
- }
- }
- else
- {
- for(i = 0; i < urb->iso_frame_count; i++)
- {
- uhci->frame_bw[(urb->iso_start_frame + i) & 0x3ff] += urb->iso_packet_desc[i].bus_time;
- }
- }
-
- }
-
- return TRUE;
-}
-
-
-//cancel a single urb
-BOOLEAN NTAPI
-uhci_sync_cancel_urb(PVOID context)
-{
- PUHCI_DEV uhci;
- PSYNC_PARAM sync_param;
- PURB purb2, dest_urb;
- PLIST_ENTRY pthis, pnext;
- BOOLEAN found = FALSE;
-
- if (context == NULL)
- return FALSE;
-
- sync_param = (PSYNC_PARAM) context;
- uhci = sync_param->uhci;
- dest_urb = (PURB) sync_param->context;
-
- if (uhci == NULL || dest_urb == NULL)
- return (UCHAR) (sync_param->ret = FALSE);
-
- ListFirst(&uhci->urb_list, pthis);
- while (pthis)
- {
- purb2 = (PURB) pthis;
- if (purb2 == dest_urb)
- {
- found = TRUE;
- purb2->flags |= URB_FLAG_FORCE_CANCEL;
- break;
- }
- ListNext(&uhci->urb_list, pthis, pnext);
- pthis = pnext;
- }
- if (found)
- uhci->skel_term_td->status |= TD_CTRL_IOC;
-
- return (UCHAR) (sync_param->ret = found);
-}
-
-//note any fields of the purb can not be referenced unless it is found in some queue
-NTSTATUS
-uhci_cancel_urb(PUHCI_DEV uhci, PUSB_DEV pdev, PUSB_ENDPOINT pendp, PURB purb)
-{
- PLIST_ENTRY pthis, pnext;
- BOOLEAN found;
- PURB purb2;
-
- SYNC_PARAM sync_param;
-
- USE_BASIC_NON_PENDING_IRQL;
-
- if (uhci == NULL || purb == NULL || pdev == NULL || pendp == NULL)
- return STATUS_INVALID_PARAMETER;
-
- lock_dev(pdev, FALSE);
-
- if (dev_state(pdev) == USB_DEV_STATE_ZOMB)
- {
- unlock_dev(pdev, FALSE);
- //delegate to remove device for this job
- return STATUS_DEVICE_DOES_NOT_EXIST;
- }
-
- if (dev_from_endp(pendp) != pdev)
- {
- unlock_dev(pdev, FALSE);
- return STATUS_INVALID_PARAMETER;
- }
-
- if (endp_state(pendp) == USB_ENDP_FLAG_STALL)
- {
- //it will be canceled in uhci_process_pending_endp
- unlock_dev(pdev, FALSE);
- return USB_STATUS_ENDPOINT_HALTED;
- }
-
- found = FALSE;
- ListFirst(&pendp->urb_list, pthis);
- while (pthis)
- {
- purb2 = (PURB) pthis;
- if (purb2 == purb)
- {
- found = TRUE;
- RemoveEntryList(pthis);
- InitializeListHead(pthis);
- break;
- }
- ListNext(&pendp->urb_list, pthis, pnext);
- pthis = pnext;
- }
- unlock_dev(pdev, FALSE);
-
- if (found)
- {
- purb->status = STATUS_CANCELLED;
-
- uhci_generic_urb_completion(purb, purb->context);
-
- lock_dev(pdev, FALSE);
- pdev->ref_count--;
- unlock_dev(pdev, FALSE);
- return STATUS_SUCCESS;
- }
-
- // search the urb in the urb-list and try to cancel
- sync_param.uhci = uhci;
- sync_param.context = purb;
-
- KeSynchronizeExecution(uhci->pdev_ext->uhci_int, uhci_sync_cancel_urb, &sync_param);
-
- found = (BOOLEAN) sync_param.ret;
-
- if (found)
- return USB_STATUS_CANCELING;
-
- return STATUS_INVALID_PARAMETER;
-}
-
-VOID
-uhci_generic_urb_completion(PURB purb, PVOID context)
-{
- PUSB_DEV pdev;
- USE_NON_PENDING_IRQL;
-
- old_irql = KeGetCurrentIrql();
- if (old_irql > DISPATCH_LEVEL)
- TRAP();
-
- if (old_irql < DISPATCH_LEVEL)
- KeRaiseIrql(DISPATCH_LEVEL, &old_irql);
-
- if (purb == NULL)
- return;
-
- pdev = purb->pdev;
-
- if (pdev == NULL)
- return;
-
- lock_dev(pdev, TRUE);
-
- if (dev_state(pdev) == USB_DEV_STATE_ZOMB)
- {
- unlock_dev(pdev, TRUE);
- goto LBL_CLIENT_PROCESS;
- }
- if (usb_error(purb->status))
- {
- pdev->error_count++;
- }
-
- if (purb->pendp == &pdev->default_endp)
- {
- if (usb_halted(purb->status))
- {
- pdev->time_out_count++;
- if (pdev->time_out_count > 3)
- {
- dev_set_state(pdev, USB_DEV_STATE_ZOMB);
- uhci_dbg_print(DBGLVL_MAXIMUM,
- ("uhci_generic_urb_completion(): contiguous error 3 times, dev 0x%x is deactivated\n",
- pdev));
- }
- }
- else
- pdev->time_out_count = 0;
-
- }
- unlock_dev(pdev, TRUE);
-
- LBL_CLIENT_PROCESS:
- if (purb->completion)
- purb->completion(purb, context);
-
- if (old_irql < DISPATCH_LEVEL)
- KeLowerIrql(old_irql);
-
- return;
-}
-
-
-NTSTATUS
-uhci_rh_submit_urb(PUSB_DEV pdev, PURB purb)
-{
- PUSB_DEV_MANAGER dev_mgr;
- PTIMER_SVC ptimer;
- PUSB_CTRL_SETUP_PACKET psetup;
- PUHCI_DEV uhci;
- NTSTATUS status;
- USHORT port_status;
-#ifndef INCLUDE_EHCI
- PHUB_EXTENSION hub_ext;
-#else
- PHUB2_EXTENSION hub_ext;
-#endif
- PUSB_PORT_STATUS ps, psret;
- LONG i;
- USE_NON_PENDING_IRQL;
-
- if (pdev == NULL || purb == NULL)
- return STATUS_INVALID_PARAMETER;
-
- dev_mgr = dev_mgr_from_dev(pdev);
-
- KeAcquireSpinLock(&dev_mgr->timer_svc_list_lock, &old_irql);
- lock_dev(pdev, FALSE);
- if (dev_state(pdev) == USB_DEV_STATE_ZOMB)
- {
- unlock_dev(pdev, FALSE);
- KeReleaseSpinLock(&dev_mgr->timer_svc_list_lock, old_irql);
- return STATUS_DEVICE_DOES_NOT_EXIST;
- }
-
- uhci = uhci_from_hcd(pdev->hcd);
- psetup = (PUSB_CTRL_SETUP_PACKET) purb->setup_packet;
-
-#ifndef INCLUDE_EHCI
- hub_ext = ((PHUB_EXTENSION) pdev->dev_ext);
-#else
- hub_ext = ((PHUB2_EXTENSION) pdev->dev_ext);
-#endif
-
- switch (endp_type(purb->pendp))
- {
- case USB_ENDPOINT_XFER_CONTROL:
- {
- if (psetup->bmRequestType == 0xa3 && psetup->bRequest == USB_REQ_GET_STATUS)
- {
- //get-port-status
- if (psetup->wIndex == 0 || psetup->wIndex > 2 || psetup->wLength < 4)
- {
- purb->status = STATUS_INVALID_PARAMETER;
- break;
- }
- if (psetup->wIndex == 1)
- {
- status = READ_PORT_USHORT((PUSHORT) (uhci->port_base + USBPORTSC1));
- ps = &hub_ext->rh_port1_status;
- }
- else
- {
- status = READ_PORT_USHORT((PUSHORT) (uhci->port_base + USBPORTSC2));
- ps = &hub_ext->rh_port2_status;
- }
-
- psret = (PUSB_PORT_STATUS) purb->data_buffer;
- ps->wPortStatus = 0;
-
- if (status & USBPORTSC_CCS)
- {
- ps->wPortStatus |= USB_PORT_STAT_CONNECTION;
- }
- if (status & USBPORTSC_PE)
- {
- ps->wPortStatus |= USB_PORT_STAT_ENABLE;
- }
- if (status & USBPORTSC_PR)
- {
- ps->wPortStatus |= USB_PORT_STAT_RESET;
- }
- if (status & USBPORTSC_SUSP)
- {
- ps->wPortStatus |= USB_PORT_STAT_SUSPEND;
- }
- if (status & USBPORTSC_LSDA)
- {
- ps->wPortStatus |= USB_PORT_STAT_LOW_SPEED;
- }
-
- //always power on
- ps->wPortStatus |= USB_PORT_STAT_POWER;
-
- //now set change field
- if (status & USBPORTSC_CSC)
- {
- ps->wPortChange |= USB_PORT_STAT_C_CONNECTION;
- }
- if (status & USBPORTSC_PEC)
- {
- ps->wPortChange |= USB_PORT_STAT_C_ENABLE;
- }
-
- //don't touch other fields, will be filled by
- //other function
-
- usb_dbg_print(DBGLVL_MAXIMUM,
- ("uhci_rh_submit_urb(): get port status, wPortStatus=0x%x, wPortChange=0x%x, address=0x%x\n",
- ps->wPortStatus, ps->wPortChange, ps));
-
- psret->wPortChange = ps->wPortChange;
- psret->wPortStatus = ps->wPortStatus;
-
- purb->status = STATUS_SUCCESS;
-
- break;
- }
- else if (psetup->bmRequestType == 0x23 && psetup->bRequest == USB_REQ_CLEAR_FEATURE)
- {
- //clear-port-feature
- if (psetup->wIndex == 0 || psetup->wIndex > 2)
- {
- purb->status = STATUS_INVALID_PARAMETER;
- break;
- }
- if (psetup->wIndex == 1)
- {
- i = USBPORTSC1;
- ps = &hub_ext->rh_port1_status;
- }
- else
- {
- i = USBPORTSC2;
- ps = &hub_ext->rh_port2_status;
- }
-
- purb->status = STATUS_SUCCESS;
- switch (psetup->wValue)
- {
- case USB_PORT_FEAT_C_CONNECTION:
- {
- ps->wPortChange &= ~USB_PORT_STAT_C_CONNECTION;
- SET_RH_PORTSTAT(i, USBPORTSC_CSC);
- status = READ_PORT_USHORT((PUSHORT) (uhci->port_base + i));
- usb_dbg_print(DBGLVL_MAXIMUM,
- ("uhci_rh_submit_urb(): clear csc, port%d=0x%x\n", psetup->wIndex,
- status));
- break;
- }
- case USB_PORT_FEAT_C_ENABLE:
- {
- ps->wPortChange &= ~USB_PORT_STAT_C_ENABLE;
- SET_RH_PORTSTAT(i, USBPORTSC_PEC);
- status = READ_PORT_USHORT((PUSHORT) (uhci->port_base + i));
- usb_dbg_print(DBGLVL_MAXIMUM,
- ("uhci_rh_submit_urb(): clear pec, port%d=0x%x\n", psetup->wIndex,
- status));
- break;
- }
- case USB_PORT_FEAT_C_RESET:
- {
- ps->wPortChange &= ~USB_PORT_STAT_C_RESET;
- //the reset signal is down in rh_timer_svc_reset_port_completion
- //so enable the port here
- status = READ_PORT_USHORT((PUSHORT)(uhci->port_base + i));
- usb_dbg_print(DBGLVL_MAXIMUM,
- ("uhci_rh_submit_urb(): clear pr, enable pe, port%d=0x%x\n",
- psetup->wIndex, status));
- break;
- }
- case USB_PORT_FEAT_ENABLE:
- {
- ps->wPortStatus &= ~USB_PORT_STAT_ENABLE;
- CLR_RH_PORTSTAT(i, USBPORTSC_PE);
- status = READ_PORT_USHORT((PUSHORT)(uhci->port_base + i));
- usb_dbg_print(DBGLVL_MAXIMUM,
- ("uhci_rh_submit_urb(): clear pe, port%d=0x%x\n", psetup->wIndex,
- status));
- break;
- }
- default:
- purb->status = STATUS_UNSUCCESSFUL;
- }
- break;
- }
- else if (psetup->bmRequestType == 0xd3 && psetup->bRequest == HUB_REQ_GET_STATE)
- {
- // get bus state
- if (psetup->wIndex == 0 || psetup->wIndex > 2 || psetup->wLength == 0)
- {
- purb->status = STATUS_INVALID_PARAMETER;
- break;
- }
-
- if (psetup->wIndex == 1)
- {
- i = USBPORTSC1;
- }
- else
- {
- i = USBPORTSC2;
- }
- port_status = READ_PORT_USHORT((PUSHORT)(uhci->port_base + i));
- purb->data_buffer[0] = (port_status & USBPORTSC_LS);
-
- // reverse the order
- purb->data_buffer[0] ^= 0x3;
- purb->status = STATUS_SUCCESS;
- break;
- }
- else if (psetup->bmRequestType == 0x23 && psetup->bRequest == USB_REQ_SET_FEATURE)
- {
- //reset port
- if (psetup->wValue != USB_PORT_FEAT_RESET)
- {
- purb->status = STATUS_INVALID_PARAMETER;
- uhci_dbg_print(DBGLVL_MAXIMUM,
- ("uhci_rh_submit_urb(): set feature with wValue=0x%x\n", psetup->wValue));
- break;
- }
- if (psetup->wIndex == 1)
- {
- i = USBPORTSC1;
- }
- else
- {
- i = USBPORTSC2;
- }
-
- ptimer = alloc_timer_svc(&dev_mgr->timer_svc_pool, 1);
- if (!ptimer)
- {
- purb->status = STATUS_NO_MEMORY;
- break;
- }
-
- ptimer->threshold = 0; // within [ 50ms, 60ms ], one tick is 10 ms
- ptimer->context = (ULONG) purb;
- ptimer->pdev = pdev;
- ptimer->func = rh_timer_svc_reset_port_completion;
-
- //start the timer
- pdev->ref_count += 2; //one for timer and one for urb
-
- status = READ_PORT_USHORT((PUSHORT) (uhci->port_base + i));
- usb_dbg_print(DBGLVL_MAXIMUM,
- ("uhci_rh_submit_urb(): reset port, port%d=0x%x\n", psetup->wIndex, status));
- InsertTailList(&dev_mgr->timer_svc_list, &ptimer->timer_svc_link);
- purb->status = STATUS_PENDING;
- }
- else
- {
- purb->status = STATUS_INVALID_PARAMETER;
- }
- break;
- }
- case USB_ENDPOINT_XFER_INT:
- {
- ptimer = alloc_timer_svc(&dev_mgr->timer_svc_pool, 1);
- if (!ptimer)
- {
- purb->status = STATUS_NO_MEMORY;
- break;
- }
-
- ptimer->threshold = RH_INTERVAL;
- ptimer->context = (ULONG) purb;
- ptimer->pdev = pdev;
- ptimer->func = rh_timer_svc_int_completion;
-
- //start the timer
- InsertTailList(&dev_mgr->timer_svc_list, &ptimer->timer_svc_link);
-
- usb_dbg_print(DBGLVL_ULTRA,
- ("uhci_rh_submit_urb(): current rh's ref_count=0x%x\n", pdev->ref_count));
- pdev->ref_count += 2; //one for timer and one for urb
-
- purb->status = STATUS_PENDING;
- break;
- }
- case USB_ENDPOINT_XFER_BULK:
- case USB_ENDPOINT_XFER_ISOC:
- default:
- {
- purb->status = STATUS_INVALID_PARAMETER;
- break;
- }
- }
- unlock_dev(pdev, FALSE);
- KeReleaseSpinLock(&dev_mgr->timer_svc_list_lock, old_irql);
- return purb->status;
-}
-
-//must have rh dev_lock acquired
-BOOLEAN
-uhci_rh_reset_port(PHCD hcd, UCHAR port_idx)
-{
- LONG i;
- PUHCI_DEV uhci;
- ULONG status;
-
- if (port_idx != 1 && port_idx != 2)
- return FALSE;
-
- if (hcd == NULL)
- return FALSE;
-
- if (port_idx == 1)
- {
- i = USBPORTSC1;
- }
- else
- {
- i = USBPORTSC2;
- }
-
- uhci = uhci_from_hcd(hcd);
- //assert the reset signal,(implicitly disable the port)
- SET_RH_PORTSTAT(i, USBPORTSC_PR);
- usb_wait_ms_dpc(50);
- //clear the reset signal, delay port enable till clearing port feature
- CLR_RH_PORTSTAT(i, USBPORTSC_PR);
- usb_wait_us_dpc(10);
- SET_RH_PORTSTAT(i, USBPORTSC_PE);
- //recovery time 10ms
- usb_wait_ms_dpc(10);
- SET_RH_PORTSTAT(i, 0x0a);
-
- status = READ_PORT_USHORT((PUSHORT) (uhci->port_base + i));
- usb_dbg_print(DBGLVL_MAXIMUM, ("uhci_rh_reset_port(): status after written=0x%x\n", status));
-
- return TRUE;
-}
-
-NTSTATUS
-uhci_dispatch_irp(IN PDEVICE_OBJECT DeviceObject, IN PIRP irp)
-{
- PDEVICE_EXTENSION pdev_ext;
- PUSB_DEV_MANAGER dev_mgr;
- PUHCI_DEV uhci;
-
- pdev_ext = DeviceObject->DeviceExtension;
- uhci = pdev_ext->uhci;
-
- dev_mgr = uhci->hcd_interf.hcd_get_dev_mgr(&uhci->hcd_interf);
- return dev_mgr_dispatch(dev_mgr, irp);
-}
-
-VOID NTAPI
-uhci_unload(IN PDRIVER_OBJECT DriverObject)
-{
- PDEVICE_OBJECT pdev;
- PDEVICE_EXTENSION pdev_ext;
- PUSB_DEV_MANAGER dev_mgr;
-
- pdev = DriverObject->DeviceObject;
-
- if (pdev == NULL)
- return;
-
- pdev_ext = pdev->DeviceExtension;
- if (pdev_ext == NULL)
- return;
-
- dev_mgr = &g_dev_mgr;
- if (dev_mgr == NULL)
- return;
- //
- // set the termination flag
- //
- dev_mgr->term_flag = TRUE;
-
- //
- // wake up the thread if it is
- //
- KeSetEvent(&dev_mgr->wake_up_event, 0, FALSE);
- KeWaitForSingleObject(dev_mgr->pthread, Executive, KernelMode, TRUE, NULL);
- ObDereferenceObject(dev_mgr->pthread);
- dev_mgr->pthread = NULL;
- // for( i = 0; i < dev_mgr->hcd_count; i++ )
- // dev_mgr->hcd_array[ i ]->hcd_release( dev_mgr->hcd_array[ i ]);
- dev_mgr_release_hcd(dev_mgr);
-
- return;
-}
-
-//the following are for hcd interface methods
-VOID
-uhci_set_dev_mgr(struct _HCD * hcd, PUSB_DEV_MANAGER dev_mgr)
-{
- hcd->dev_mgr = dev_mgr;
-}
-
-PUSB_DEV_MANAGER
-uhci_get_dev_mgr(struct _HCD *hcd)
-{
- return hcd->dev_mgr;
-}
-
-ULONG
-uhci_get_type(struct _HCD * hcd)
-{
- return (hcd->flags & HCD_TYPE_MASK);
-}
-
-VOID
-uhci_set_id(struct _HCD * hcd, UCHAR id)
-{
- hcd->flags &= ~HCD_ID_MASK;
- hcd->flags |= (HCD_ID_MASK & id);
-}
-
-UCHAR
-uhci_get_id(struct _HCD *hcd)
-{
- return (UCHAR) (hcd->flags & HCD_ID_MASK);
-}
-
-
-UCHAR
-uhci_alloc_addr(struct _HCD * hcd)
-{
- LONG i;
- if (hcd == NULL)
- return 0;
-
- for(i = 1; i < MAX_DEVS; i++)
- {
- if (hcd->dev_addr_map[i >> 3] & (1 << (i & 7)))
- {
- continue;
- }
- else
- {
- break;
- }
- }
-
- if (i >= MAX_DEVS)
- return 0xff;
-
- hcd->dev_addr_map[i >> 3] |= (1 << (i & 7));
- hcd->conn_count++;
- return (BYTE) i;
-}
-
-VOID
-uhci_free_addr(struct _HCD * hcd, UCHAR addr)
-{
- if (addr & 0x80)
- return;
-
- if (hcd == NULL)
- return;
-
- hcd->dev_addr_map[addr >> 3] &= ~(1 << (addr & 7));
- return;
-
-}
-
-NTSTATUS
-uhci_submit_urb2(struct _HCD * hcd, PUSB_DEV pdev, PUSB_ENDPOINT pendp, PURB purb)
-{
- return uhci_submit_urb(uhci_from_hcd(hcd), pdev, pendp, purb);
-}
-
-PUSB_DEV
-uhci_get_root_hub(struct _HCD * hcd)
-{
- return uhci_from_hcd(hcd)->root_hub;
-}
-
-VOID
-uhci_set_root_hub(struct _HCD * hcd, PUSB_DEV root_hub)
-{
- if (hcd == NULL || root_hub == NULL)
- return;
- uhci_from_hcd(hcd)->root_hub = root_hub;
- return;
-}
-
-BOOLEAN
-uhci_remove_device2(struct _HCD * hcd, PUSB_DEV pdev)
-{
- if (hcd == NULL || pdev == NULL)
- return FALSE;
-
- return uhci_remove_device(uhci_from_hcd(hcd), pdev);
-}
-
-BOOLEAN
-uhci_hcd_release(struct _HCD * hcd)
-{
- PUHCI_DEV uhci;
- PDEVICE_EXTENSION pdev_ext;
-
- if (hcd == NULL)
- return FALSE;
-
-
- uhci = uhci_from_hcd(hcd);
- pdev_ext = uhci->pdev_ext;
-
- return uhci_release(pdev_ext->pdev_obj, hcd->dev_mgr);
-}
-
-NTSTATUS
-uhci_cancel_urb2(struct _HCD * hcd, PUSB_DEV pdev, PUSB_ENDPOINT pendp, PURB purb)
-{
- PUHCI_DEV uhci;
- if (hcd == NULL)
- return STATUS_INVALID_PARAMETER;
-
- uhci = uhci_from_hcd(hcd);
- return uhci_cancel_urb(uhci, pdev, pendp, purb);
-}
-
-BOOLEAN
-uhci_rh_get_dev_change(PHCD hcd, PBYTE buf)
-{
- PUHCI_DEV uhci;
- ULONG status;
-
- if (hcd == NULL || buf == NULL)
- return FALSE;
-
- uhci = uhci_from_hcd(hcd);
- status = READ_PORT_USHORT((PUSHORT) (uhci->port_base + USBPORTSC1));
- usb_dbg_print(DBGLVL_ULTRA, ("uhci_rh_get_dev_change(): rh port1 status=0x%x\n", status));
-
- if ((status & USBPORTSC_PEC) || (status & USBPORTSC_CSC))
- {
- buf[0] |= (1 << 1);
- }
-
- status = READ_PORT_USHORT((PUSHORT) (uhci->port_base + USBPORTSC2));
- usb_dbg_print(DBGLVL_ULTRA, ("uhci_rh_get_dev_change(): rh port2 status=0x%x\n", status));
-
- if ((status & USBPORTSC_PEC) || (status & USBPORTSC_CSC))
- {
- buf[0] |= (1 << 2);
- }
- return TRUE;
-}
-
-NTSTATUS
-uhci_dispatch(PHCD hcd, LONG disp_code, PVOID param) // locking depends on type of code
-{
- if (hcd == NULL)
- return FALSE;
-
- switch (disp_code)
- {
- case HCD_DISP_READ_PORT_COUNT:
- {
- if (param == NULL)
- return STATUS_INVALID_PARAMETER;
- *((PUCHAR) param) = 2;
- return STATUS_SUCCESS;
- }
- case HCD_DISP_READ_RH_DEV_CHANGE:
- {
- if (uhci_rh_get_dev_change(hcd, param) == FALSE)
- return STATUS_INVALID_PARAMETER;
- return STATUS_SUCCESS;
- }
- }
-
- return STATUS_NOT_IMPLEMENTED;
-}
-
-VOID
-uhci_init_hcd_interface(PUHCI_DEV uhci)
-{
- uhci->hcd_interf.hcd_set_dev_mgr = uhci_set_dev_mgr;
- uhci->hcd_interf.hcd_get_dev_mgr = uhci_get_dev_mgr;
- uhci->hcd_interf.hcd_get_type = uhci_get_type;
- uhci->hcd_interf.hcd_set_id = uhci_set_id;
- uhci->hcd_interf.hcd_get_id = uhci_get_id;
- uhci->hcd_interf.hcd_alloc_addr = uhci_alloc_addr;
- uhci->hcd_interf.hcd_free_addr = uhci_free_addr;
- uhci->hcd_interf.hcd_submit_urb = uhci_submit_urb2;
- uhci->hcd_interf.hcd_generic_urb_completion = uhci_generic_urb_completion;
- uhci->hcd_interf.hcd_get_root_hub = uhci_get_root_hub;
- uhci->hcd_interf.hcd_set_root_hub = uhci_set_root_hub;
- uhci->hcd_interf.hcd_remove_device = uhci_remove_device2;
- uhci->hcd_interf.hcd_rh_reset_port = uhci_rh_reset_port;
- uhci->hcd_interf.hcd_release = uhci_hcd_release;
- uhci->hcd_interf.hcd_cancel_urb = uhci_cancel_urb2;
- uhci->hcd_interf.hcd_start = uhci_start;
- uhci->hcd_interf.hcd_dispatch = uhci_dispatch;
-
- uhci->hcd_interf.flags = HCD_TYPE_UHCI; //hcd types | hcd id
-}
-
-NTSTATUS NTAPI
-generic_dispatch_irp(IN PDEVICE_OBJECT dev_obj, IN PIRP irp)
-{
- PDEVEXT_HEADER dev_ext;
-
- dev_ext = (PDEVEXT_HEADER) dev_obj->DeviceExtension;
-
- if (dev_ext && dev_ext->dispatch)
- return dev_ext->dispatch(dev_obj, irp);
-
- irp->IoStatus.Information = 0;
-
- EXIT_DISPATCH(STATUS_UNSUCCESSFUL, irp);
-}
-
-
-VOID NTAPI
-generic_start_io(IN PDEVICE_OBJECT dev_obj, IN PIRP irp)
-{
- PDEVEXT_HEADER dev_ext;
-
- KIRQL old_irql;
-
- IoAcquireCancelSpinLock(&old_irql);
- if (irp != dev_obj->CurrentIrp || irp->Cancel)
- {
- IoReleaseCancelSpinLock(old_irql);
- return;
- }
- else
- {
- (void)IoSetCancelRoutine(irp, NULL);
- IoReleaseCancelSpinLock(old_irql);
- }
-
- dev_ext = (PDEVEXT_HEADER) dev_obj->DeviceExtension;
-
- if (dev_ext && dev_ext->start_io)
- {
- dev_ext->start_io(dev_obj, irp);
- return;
- }
-
- irp->IoStatus.Information = 0;
- irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
-
- IoStartNextPacket(dev_obj, FALSE);
- IoCompleteRequest(irp, IO_NO_INCREMENT);
-}
-
-NTSTATUS
-NTAPI
-DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
-{
- NTSTATUS ntStatus = STATUS_SUCCESS;
-
-#if DBG
- // should be done before any debug output is done.
- // read our debug verbosity level from the registry
- //NetacOD_GetRegistryDword( NetacOD_REGISTRY_PARAMETERS_PATH, //absolute registry path
- // L"DebugLevel", // REG_DWORD ValueName
- // &gDebugLevel ); // Value receiver
-
- // debug_level = DBGLVL_MAXIMUM;
-#endif
-
- uhci_dbg_print_cond(DBGLVL_MINIMUM, DEBUG_UHCI,
- ("Entering DriverEntry(), RegistryPath=\n %ws\n", RegistryPath->Buffer));
-
- // Remember our driver object, for when we create our child PDO
- usb_driver_obj = DriverObject;
-
- //
- // Create dispatch points for create, close, unload
- DriverObject->MajorFunction[IRP_MJ_CREATE] = generic_dispatch_irp;
- DriverObject->MajorFunction[IRP_MJ_CLOSE] = generic_dispatch_irp;
- DriverObject->DriverUnload = uhci_unload;
-
- // User mode DeviceIoControl() calls will be routed here
- DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = generic_dispatch_irp;
- DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = generic_dispatch_irp;
-
- // User mode ReadFile()/WriteFile() calls will be routed here
- DriverObject->MajorFunction[IRP_MJ_WRITE] = generic_dispatch_irp;
- DriverObject->MajorFunction[IRP_MJ_READ] = generic_dispatch_irp;
-
- DriverObject->MajorFunction[IRP_MJ_SHUTDOWN] = generic_dispatch_irp;
- DriverObject->MajorFunction[IRP_MJ_SCSI] = generic_dispatch_irp;
- DriverObject->MajorFunction[IRP_MJ_FLUSH_BUFFERS] = generic_dispatch_irp;
-
- DriverObject->DriverStartIo = generic_start_io;
- // routines for handling system PNP and power management requests
- //DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = generic_dispatch_irp;
-
- // The Functional Device Object (FDO) will not be created for PNP devices until
- // this routine is called upon device plug-in.
- RtlZeroMemory(&g_dev_mgr, sizeof(USB_DEV_MANAGER));
- g_dev_mgr.usb_driver_obj = DriverObject;
-
-#ifdef INCLUDE_EHCI
- ehci_probe(DriverObject, RegistryPath, &g_dev_mgr);
-#endif
-
- uhci_probe(DriverObject, RegistryPath, &g_dev_mgr);
-
- if (dev_mgr_strobe(&g_dev_mgr) == FALSE)
- {
-
- dev_mgr_release_hcd(&g_dev_mgr);
- return STATUS_UNSUCCESSFUL;
- }
-
- dev_mgr_start_hcd(&g_dev_mgr);
-
- /* Wait till all drivers are initialized */
- ntStatus = KeWaitForSingleObject(&g_dev_mgr.drivers_inited, Executive, KernelMode, TRUE, NULL);
-
- uhci_dbg_print_cond(DBGLVL_DEFAULT, DEBUG_UHCI, ("DriverEntry(): exiting... (%x)\n", ntStatus));
- return STATUS_SUCCESS;
-}
-
-//note: the initialization will be in the following order
-// uhci_probe
-// dev_mgr_strobe
-// uhci_start
-
-// to kill dev_mgr_thread:
-// dev_mgr->term_flag = TRUE;
-// KeSetEvent( &dev_mgr->wake_up_event );
-// this piece of code must run at passive-level
diff --git a/reactos/drivers/usb/nt4compat/usbdrv/uhciver.h b/reactos/drivers/usb/nt4compat/usbdrv/uhciver.h
deleted file mode 100644
index 4ea9e812556..00000000000
--- a/reactos/drivers/usb/nt4compat/usbdrv/uhciver.h
+++ /dev/null
@@ -1,13 +0,0 @@
-#ifndef __UHCIVER_H__
-#define __UHCIVER_H__
-
-//#define _MULTI_UHCI
-//#define _TIANSHENG_DRIVER
-
-#ifdef _MULTI_UHCI
-#define UHCI_VER_STR "m564.a\0"
-#else
-#define UHCI_VER_STR "0564.d\0"
-#endif
-
-#endif
diff --git a/reactos/drivers/usb/nt4compat/usbdrv/umss.c b/reactos/drivers/usb/nt4compat/usbdrv/umss.c
deleted file mode 100644
index 6014606620c..00000000000
--- a/reactos/drivers/usb/nt4compat/usbdrv/umss.c
+++ /dev/null
@@ -1,2230 +0,0 @@
-/**
- * umss.c - USB driver stack project for Windows NT 4.0
- *
- * Copyright (c) 2002-2004 Zhiming mypublic99@yahoo.com
- *
- * This program/include file is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program/include file is distributed in the hope that it will be
- * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
- * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program (in the main directory of the distribution, the file
- * COPYING); if not, write to the Free Software Foundation,Inc., 59 Temple
- * Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "usbdriver.h"
-
-#include
-#include
-#include
-
-#define UMSS_EXIT_DISPATCH( dev_OBJ, staTUS, iRp ) \
-{\
- iRp->IoStatus.Status = staTUS;\
- if( staTUS != STATUS_PENDING)\
- {\
- IoCompleteRequest( iRp, IO_NO_INCREMENT);\
- return staTUS;\
- }\
- IoMarkIrpPending( iRp );\
- IoStartPacket( dev_OBJ, iRp, NULL, NULL ); \
- return STATUS_PENDING;\
-}
-
-#define UMSS_COMPLETE_START_IO( dev_OBJ, staTUS, iRP ) \
-{\
- iRP->IoStatus.Status = staTUS;\
- if( staTUS != STATUS_PENDING )\
- {\
- IoStartNextPacket( dev_OBJ, FALSE );\
- IoCompleteRequest( iRP, IO_NO_INCREMENT );\
- }\
- return;\
-}
-
-extern VOID gendrv_startio(IN PDEVICE_OBJECT dev_obj, IN PIRP irp);
-
-NTSYSAPI NTSTATUS NTAPI ZwLoadDriver(IN PUNICODE_STRING DriverServiceName);
-
-NTSYSAPI
-NTSTATUS
-NTAPI
-ObOpenObjectByName(IN POBJECT_ATTRIBUTES ObjectAttributes,
- IN POBJECT_TYPE ObjectType OPTIONAL,
- IN KPROCESSOR_MODE AccessMode,
- IN OUT PACCESS_STATE AccessState OPTIONAL,
- IN ACCESS_MASK DesiredAccess OPTIONAL,
- IN OUT PVOID ParseContext OPTIONAL, OUT PHANDLE Handle);
-
-VOID NTAPI umss_start_io(IN PDEVICE_OBJECT dev_obj, IN PIRP irp);
-NTSTATUS umss_port_dispatch_routine(PDEVICE_OBJECT pdev_obj, PIRP irp);
-BOOLEAN umss_connect(PDEV_CONNECT_DATA dev_mgr, DEV_HANDLE dev_handle);
-BOOLEAN umss_disconnect(PUSB_DEV_MANAGER dev_mgr, DEV_HANDLE dev_handle);
-BOOLEAN umss_stop(PUSB_DEV_MANAGER dev_mgr, DEV_HANDLE dev_handle);
-NTSTATUS umss_dispatch_routine(PDEVICE_OBJECT pdev_obj, PIRP irp);
-VOID umss_set_cfg_completion(PURB purb, PVOID pcontext);
-VOID NTAPI umss_start_create_device(IN PVOID Parameter);
-BOOLEAN umss_delete_device(PUSB_DEV_MANAGER dev_mgr, PUSB_DRIVER pdrvr, PDEVICE_OBJECT dev_obj, BOOLEAN is_if);
-BOOLEAN umss_stop(PUSB_DEV_MANAGER dev_mgr, DEV_HANDLE dev_handle);
-NTSTATUS umss_process_srb(PDEVICE_OBJECT dev_obj, PIRP irp);
-VOID umss_load_class_driver(PVOID context);
-BOOLEAN umss_tsc_to_sff(PIO_PACKET io_packet);
-VOID umss_fix_sff_result(PIO_PACKET io_packet, SCSI_REQUEST_BLOCK * srb);
-
-PDEVICE_OBJECT
-umss_create_port_device(PUSB_DEV_MANAGER dev_mgr, PUSB_DRIVER pdriver)
-{
-
- // currently a port device is a connection point
- // and upper driver use this to register itself
- // with umss driver for future notification of
- // pnp event. 2004-03-22 23:12:41
- CHAR dev_name[64];
- STRING string;
- NTSTATUS status;
- PDEVICE_OBJECT pdev;
- UNICODE_STRING name_string, symb_link;
- PUMSS_PORT_DEV_EXT pdev_ext;
-
- sprintf(dev_name, "\\Device\\usbPort_%d", (int)0);
-
- RtlInitString(&string, dev_name);
- RtlAnsiStringToUnicodeString(&name_string, &string, TRUE);
- pdev = NULL;
-
- status = IoCreateDevice(dev_mgr->usb_driver_obj,
- sizeof(UMSS_PORT_DEV_EXT), &name_string, FILE_USB_DEV_TYPE, 0, TRUE, &pdev);
-
- if (status == STATUS_SUCCESS)
- {
- //
- // We do buffered io
- //
- pdev->Flags |= DO_BUFFERED_IO;
-
- pdev->Flags &= ~DO_DEVICE_INITIALIZING;
- pdev->StackSize = 2; //one for fdo, one for file device obj
-
- pdev_ext = (PUMSS_PORT_DEV_EXT) pdev->DeviceExtension;
-
- pdev_ext->dev_ext_hdr.type = NTDEV_TYPE_CLIENT_DEV;
- pdev_ext->dev_ext_hdr.dispatch = umss_port_dispatch_routine;
- pdev_ext->dev_ext_hdr.start_io = NULL;
- pdev_ext->dev_ext_hdr.dev_mgr = dev_mgr;
- pdev_ext->pdriver = pdriver;
-
- sprintf(dev_name, "\\DosDevices\\usbPort%d", (int)0);
-
- RtlInitString(&string, dev_name);
- RtlAnsiStringToUnicodeString(&symb_link, &string, TRUE);
- IoCreateSymbolicLink(&symb_link, &name_string);
- RtlFreeUnicodeString(&symb_link);
-
- }
-
- RtlFreeUnicodeString(&name_string);
- return pdev;
-}
-
-BOOLEAN
-umss_delete_port_device(PDEVICE_OBJECT dev_obj)
-{
- CHAR dev_name[64];
- STRING string;
- UNICODE_STRING symb_link;
-
- if (dev_obj == NULL)
- return FALSE;
-
- // remove the symbolic link
- sprintf(dev_name, "\\DosDevices\\usbPort%d", (int)0);
- RtlInitString(&string, dev_name);
- RtlAnsiStringToUnicodeString(&symb_link, &string, TRUE);
- IoDeleteSymbolicLink(&symb_link);
- RtlFreeUnicodeString(&symb_link);
-
- if (dev_obj->ReferenceCount == 0)
- {
- IoDeleteDevice(dev_obj);
- usb_dbg_print(DBGLVL_MAXIMUM, ("umss_delete_port_device(): port device object is removed\n"));
- }
- return TRUE;
-}
-
-// FIXME!!! there can not be sent IOCTL_SUBMIT_URB_XXX while
-// the IOCTL_SUBMIT_CDB_XXX are active. may confuse the device.
-// not resolved yet.
-// 2004-03-22 23:12:26
-NTSTATUS
-umss_port_dispatch_routine(PDEVICE_OBJECT pdev_obj, PIRP irp)
-{
- ULONG ctrl_code;
- NTSTATUS status;
- PIO_STACK_LOCATION irp_stack;
- PUMSS_PORT_DEV_EXT pdev_ext;
- PUMSS_DRVR_EXTENSION pdrvr_ext;
-
- if (pdev_obj == NULL || irp == NULL)
- return STATUS_INVALID_PARAMETER;
-
- status = STATUS_SUCCESS;
- irp_stack = IoGetCurrentIrpStackLocation(irp);
- ctrl_code = irp_stack->Parameters.DeviceIoControl.IoControlCode;
-
- pdev_ext = (PUMSS_PORT_DEV_EXT) pdev_obj->DeviceExtension;
-
- switch (irp_stack->MajorFunction)
- {
- case IRP_MJ_INTERNAL_DEVICE_CONTROL:
- {
- switch (ctrl_code)
- {
- case IOCTL_REGISTER_DRIVER:
- {
- PCLASS_DRV_REG_INFO pcdri;
- if (irp_stack->Parameters.DeviceIoControl.InputBufferLength < sizeof(CLASS_DRV_REG_INFO))
- {
- EXIT_DISPATCH(STATUS_INVALID_PARAMETER, irp);
- }
-
- pcdri = irp->AssociatedIrp.SystemBuffer;
- if (pcdri->fdo_driver == NULL || pcdri->add_device == NULL || pcdri->pnp_dispatch == NULL)
- {
- EXIT_DISPATCH(STATUS_INVALID_PARAMETER, irp);
- }
- pdrvr_ext = (PUMSS_DRVR_EXTENSION) pdev_ext->pdriver->driver_ext;
- pdrvr_ext->class_driver_info.fdo_driver = pcdri->fdo_driver;
- pdrvr_ext->class_driver_info.add_device = pcdri->add_device;
- pdrvr_ext->class_driver_info.pnp_dispatch = pcdri->pnp_dispatch;
- EXIT_DISPATCH(STATUS_SUCCESS, irp);
- }
- case IOCTL_REVOKE_DRIVER:
- {
- pdrvr_ext = (PUMSS_DRVR_EXTENSION) pdev_ext->pdriver->driver_ext;
- pdrvr_ext->class_driver_info.fdo_driver = NULL;
- pdrvr_ext->class_driver_info.add_device = NULL;
- pdrvr_ext->class_driver_info.pnp_dispatch = NULL;
- EXIT_DISPATCH(STATUS_SUCCESS, irp);
- }
- }
- break;
- }
- case IRP_MJ_CREATE:
- case IRP_MJ_CLOSE:
- {
- EXIT_DISPATCH(STATUS_SUCCESS, irp);
- }
- }
- EXIT_DISPATCH(STATUS_INVALID_DEVICE_REQUEST, irp);
-}
-
-BOOLEAN
-umss_driver_init(PUSB_DEV_MANAGER dev_mgr, PUSB_DRIVER pdriver)
-{
- PUMSS_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_DEV_CAPABLE;
- pdriver->driver_desc.vendor_id = 0x0dd8; // USB Vendor ID
- pdriver->driver_desc.product_id = 0x0003; // 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_MASS_STORAGE; // Interface Class
- pdriver->driver_desc.if_sub_class = 0; // Interface SubClass
- pdriver->driver_desc.if_protocol = 0; // Interface Protocol
-
- pdriver->driver_desc.driver_name = "USB Mass Storage driver"; // Driver name for Name Registry
- pdriver->driver_desc.dev_class = USB_CLASS_MASS_STORAGE;
- pdriver->driver_desc.dev_sub_class = 0; // Device Subclass
- pdriver->driver_desc.dev_protocol = 0; // Protocol Info.
-
- pdriver->driver_ext = usb_alloc_mem(NonPagedPool, sizeof(UMSS_DRVR_EXTENSION));
- if (!pdriver->driver_ext) return FALSE;
- pdriver->driver_ext_size = sizeof(UMSS_DRVR_EXTENSION);
-
- RtlZeroMemory(pdriver->driver_ext, sizeof(UMSS_DRVR_EXTENSION));
- pdrvr_ext = (PUMSS_DRVR_EXTENSION) pdriver->driver_ext;
- pdrvr_ext->dev_count = 0;
- InitializeListHead(&pdrvr_ext->dev_list);
- ExInitializeFastMutex(&pdrvr_ext->dev_list_mutex);
-
- pdriver->disp_tbl.version = 1;
- pdriver->disp_tbl.dev_connect = umss_connect;
- pdriver->disp_tbl.dev_disconnect = umss_disconnect;
- pdriver->disp_tbl.dev_stop = umss_stop;
- pdriver->disp_tbl.dev_reserved = NULL;
-
- if ((pdrvr_ext->port_dev_obj = umss_create_port_device(dev_mgr, pdriver)) == NULL)
- {
- usb_free_mem(pdriver->driver_ext);
- pdriver->driver_ext = NULL;
- pdriver->driver_ext_size = 0;
- pdriver->disp_tbl.dev_connect = NULL;
- pdriver->disp_tbl.dev_stop = NULL;
- pdriver->disp_tbl.dev_disconnect = NULL;
- return FALSE;
- }
-
- umss_load_class_driver(NULL);
-
- // umss_schedule_workitem( NULL, umss_load_class_driver, NULL, 0 );
- usb_dbg_print(DBGLVL_MAXIMUM, ("umss_driver_init(): umss driver is initialized\n"));
- return TRUE;
-}
-
-BOOLEAN
-umss_driver_destroy(PUSB_DEV_MANAGER dev_mgr, PUSB_DRIVER pdriver)
-{
- PUMSS_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, ("umss_driver_destroy(): umss driver is destroyed\n"));
- return TRUE;
-}
-
-PDEVICE_OBJECT
-umss_create_device(PUSB_DEV_MANAGER dev_mgr, PUSB_DRIVER umss_drvr, DEV_HANDLE dev_handle, BOOLEAN is_if)
-{
-
- CHAR dev_name[64], dev_id;
- STRING string;
- NTSTATUS status;
- PDEVICE_OBJECT pdev;
- UNICODE_STRING name_string, symb_link;
- PUMSS_DRVR_EXTENSION pdrvr_ext;
- PUMSS_DEVICE_EXTENSION pdev_ext;
-
- usb_dbg_print(DBGLVL_MAXIMUM, ("umss_create_device(): entering...\n"));
- pdrvr_ext = (PUMSS_DRVR_EXTENSION) umss_drvr->driver_ext;
- dev_id = (UCHAR) dev_id_from_handle(dev_handle); // pdrvr_ext->dev_count;
-
- if (is_if == FALSE)
- sprintf(dev_name, "\\Device\\umssdev_%d", (int)dev_id);
- else
- sprintf(dev_name, "\\Device\\umssifdev_%d", (int)dev_id);
-
- RtlInitString(&string, dev_name);
- RtlAnsiStringToUnicodeString(&name_string, &string, TRUE);
- pdev = NULL;
-
- status = IoCreateDevice(dev_mgr->usb_driver_obj,
- sizeof(UMSS_DEVICE_EXTENSION),
- &name_string,
- FILE_USB_DEV_TYPE,
- 0,
- TRUE,
- &pdev);
-
- if (status == STATUS_SUCCESS)
- {
- //
- // We do direct io
- //
- pdev->Flags |= DO_DIRECT_IO;
-
- pdev->Flags &= ~DO_DEVICE_INITIALIZING;
- pdev->StackSize = 2; //one for fdo, one for file device obj
-
- pdev_ext = (PUMSS_DEVICE_EXTENSION) pdev->DeviceExtension;
-
- //may be accessed by other thread
- ExAcquireFastMutex(&pdrvr_ext->dev_list_mutex);
- InsertTailList(&pdrvr_ext->dev_list, &pdev_ext->dev_obj_link);
- pdrvr_ext->dev_count++;
- ExReleaseFastMutex(&pdrvr_ext->dev_list_mutex);
-
- if (is_if)
- pdev_ext->flags |= UMSS_DEV_FLAG_IF_DEV;
-
- pdev_ext->umss_dev_id = dev_id;
- pdev_ext->pdo = pdev;
- pdev_ext->dev_handle = dev_handle;
- pdev_ext->dev_mgr = dev_mgr;
- pdev_ext->pdriver = umss_drvr;
-
- pdev_ext->dev_ext_hdr.type = NTDEV_TYPE_CLIENT_DEV;
- pdev_ext->dev_ext_hdr.dispatch = umss_dispatch_routine;
- pdev_ext->dev_ext_hdr.start_io = umss_start_io;
- pdev_ext->dev_ext_hdr.dev_mgr = dev_mgr;
-
- if (is_if == FALSE)
- sprintf(dev_name, "\\DosDevices\\umssdev%d", (int)dev_id);
- else
- sprintf(dev_name, "\\DosDevices\\umssifdev%d", (int)dev_id);
-
- RtlInitString(&string, dev_name);
- RtlAnsiStringToUnicodeString(&symb_link, &string, TRUE);
- IoCreateSymbolicLink(&symb_link, &name_string);
- RtlFreeUnicodeString(&symb_link);
- KeInitializeEvent(&pdev_ext->sync_event, SynchronizationEvent, FALSE);
- KeInitializeSpinLock(&pdev_ext->dev_lock);
-
- }
- RtlFreeUnicodeString(&name_string);
- return pdev;
-}
-
-BOOLEAN
-umss_connect(PDEV_CONNECT_DATA param, DEV_HANDLE dev_handle)
-{
- PURB purb;
- NTSTATUS status;
- PUSB_CTRL_SETUP_PACKET psetup;
- PUSB_DEV_MANAGER dev_mgr;
- PUSB_DRIVER pdrvr;
-
- usb_dbg_print(DBGLVL_MAXIMUM, ("umss_connect(): entering...\n"));
-
- dev_mgr = param->dev_mgr;
- pdrvr = param->pdriver;
-
- //directly set the configuration
- purb = usb_alloc_mem(NonPagedPool, sizeof(URB));
- if (purb == NULL)
- return FALSE;
-
- psetup = (PUSB_CTRL_SETUP_PACKET) (purb)->setup_packet;
- urb_init((purb));
-
- purb->endp_handle = dev_handle | 0xffff;
- purb->data_buffer = NULL;
- purb->data_length = 0;
- purb->completion = umss_set_cfg_completion;
- purb->context = dev_mgr;
- purb->reference = (LONG) pdrvr;
- psetup->bmRequestType = 0;
- psetup->bRequest = USB_REQ_SET_CONFIGURATION;
- psetup->wValue = 1;
- psetup->wIndex = 0;
- psetup->wLength = 0;
-
- status = usb_submit_urb(dev_mgr, purb);
- if (status != STATUS_PENDING)
- {
- usb_free_mem(purb);
- return FALSE;
- }
- return TRUE;
-}
-
-VOID
-umss_set_cfg_completion(PURB purb, PVOID pcontext)
-{
- PUSB_CTRL_SETUP_PACKET psetup;
- PUCHAR buf;
- PWORK_QUEUE_ITEM pwork_item;
- PUMSS_CREATE_DATA pcd;
- DEV_HANDLE dev_handle;
- NTSTATUS status;
- PUSB_DEV_MANAGER dev_mgr;
- PUSB_DRIVER pdrvr;
-
- if (purb == NULL || pcontext == NULL)
- return;
-
- dev_mgr = (PUSB_DEV_MANAGER) pcontext;
- pdrvr = (PUSB_DRIVER) purb->reference;
- dev_handle = purb->endp_handle & ~0xffff;
-
-
- if (purb->status != STATUS_SUCCESS)
- {
- usb_free_mem(purb);
- return;
- }
-
- buf = usb_alloc_mem(NonPagedPool, 512);
- if (buf == NULL)
- {
- usb_free_mem(purb);
- return;
- }
-
- //now let's get the descs, one configuration, one interface and two endpoint
- psetup = (PUSB_CTRL_SETUP_PACKET) (purb)->setup_packet;
- purb->data_buffer = buf;
- purb->data_length = 512;
- purb->completion = NULL; //this is an immediate request, no needs completion
- purb->context = dev_mgr;
- purb->reference = 0;
- psetup->bmRequestType = 0x80;
- psetup->bRequest = USB_REQ_GET_DESCRIPTOR;
- psetup->wValue = USB_DT_CONFIG << 8;
- psetup->wIndex = 0;
- psetup->wLength = 512;
-
- status = usb_submit_urb(dev_mgr, purb);
- if (status == STATUS_PENDING)
- {
- TRAP();
- }
- usb_free_mem(purb);
- purb = NULL;
-
- if (status != STATUS_SUCCESS)
- {
- usb_free_mem(buf);
- buf = NULL;
- return;
- }
-
- pcd = usb_alloc_mem(NonPagedPool, sizeof(WORK_QUEUE_ITEM) + sizeof(UMSS_CREATE_DATA));
- if (pcd == NULL)
- {
- usb_free_mem(buf);
- buf = NULL;
- return;
- }
-
- pcd->desc_buf = buf;
- pcd->dev_handle = dev_handle;
- pcd->dev_mgr = dev_mgr;
- pcd->pdriver = pdrvr;
- pwork_item = (PWORK_QUEUE_ITEM) (&pcd[1]);
-
- ExInitializeWorkItem(pwork_item, umss_start_create_device, (PVOID) pcd);
- ExQueueWorkItem(pwork_item, DelayedWorkQueue);
-}
-
-VOID NTAPI
-umss_start_create_device(IN PVOID Parameter)
-{
- LONG i;
- PUCHAR desc_buf;
- NTSTATUS status;
- PUSB_DEV pdev;
- DEV_HANDLE dev_handle;
- PUSB_DRIVER pdrvr;
- PDEVICE_OBJECT pdev_obj;
- PUSB_DEV_MANAGER dev_mgr;
- PUMSS_CREATE_DATA pcd;
- PUSB_INTERFACE_DESC pif_desc;
- PUSB_ENDPOINT_DESC pendp_desc;
- PUMSS_DEVICE_EXTENSION pdev_ext;
- PUSB_CONFIGURATION_DESC pconfig_desc;
-
- USE_BASIC_NON_PENDING_IRQL;
-
- if (Parameter == NULL)
- return;
-
- pcd = (PUMSS_CREATE_DATA) Parameter;
- desc_buf = pcd->desc_buf;
- dev_mgr = pcd->dev_mgr;
- dev_handle = pcd->dev_handle;
- pdrvr = pcd->pdriver;
- usb_free_mem(pcd);
- pcd = NULL;
-
- status = usb_query_and_lock_dev(dev_mgr, dev_handle, &pdev);
- if (status != STATUS_SUCCESS)
- {
- usb_free_mem(desc_buf);
- return;
- }
-
- pdev_obj = umss_create_device(dev_mgr, pdrvr, dev_handle, FALSE);
-
- lock_dev(pdev, FALSE);
- if (pdev_obj == NULL ||
- dev_state(pdev) == USB_DEV_STATE_ZOMB ||
- dev_mgr_set_driver(dev_mgr, dev_handle, pdrvr, pdev) == FALSE)
- {
- usb_free_mem(desc_buf);
- unlock_dev(pdev, FALSE);
-
- if (pdev_obj)
- umss_delete_device(dev_mgr, pdrvr, pdev_obj, FALSE);
-
- usb_unlock_dev(pdev);
- return;
- }
- unlock_dev(pdev, FALSE);
-
- pdev_ext = (PUMSS_DEVICE_EXTENSION) pdev_obj->DeviceExtension;
-
- pdev_ext->desc_buf = desc_buf;
- pdev_ext->pif_desc = NULL;
- pdev_ext->pin_endp_desc = pdev_ext->pout_endp_desc = NULL;
-
- pconfig_desc = (PUSB_CONFIGURATION_DESC) desc_buf;
- pif_desc = (PUSB_INTERFACE_DESC) (&pconfig_desc[1]);
- //search for our if
- for(i = 0; ((UCHAR) i) < pconfig_desc->bNumInterfaces; i++)
- {
- if (pif_desc->bLength == sizeof(USB_INTERFACE_DESC) && pif_desc->bDescriptorType == USB_DT_INTERFACE)
- {
- if (pif_desc->bInterfaceClass == USB_CLASS_MASS_STORAGE)
- {
- pdev_ext->pif_desc = pif_desc;
- pdev_ext->if_idx = (UCHAR) i;
- break;
- }
- else
- {
- if (usb_skip_if_and_altif((PUCHAR *) & pif_desc) == FALSE)
- break;
- }
- }
- else
- {
- break;
- }
- }
-
- if (pdev_ext->pif_desc)
- {
- pendp_desc = (PUSB_ENDPOINT_DESC) & pif_desc[1];
- for(i = 0; ((UCHAR) i) < pif_desc->bNumEndpoints; i++)
- {
- if (pendp_desc->bDescriptorType == USB_DT_ENDPOINT
- && pendp_desc->bLength == sizeof(USB_ENDPOINT_DESC))
- {
- if ((pendp_desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT)
- {
- pdev_ext->pint_endp_desc = pendp_desc;
- pdev_ext->int_endp_idx = (UCHAR) i;
- }
- else if ((pendp_desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_BULK)
- {
- if (pendp_desc->bEndpointAddress & USB_DIR_IN)
- {
- pdev_ext->pin_endp_desc = pendp_desc;
- pdev_ext->in_endp_idx = (UCHAR) i;
- }
- else
- {
- pdev_ext->pout_endp_desc = pendp_desc;
- pdev_ext->out_endp_idx = (UCHAR) i;
- }
- }
- pendp_desc = &pendp_desc[1];
- }
- else
- break;
- }
- }
- usb_unlock_dev(pdev);
- return;
-}
-
-BOOLEAN
-umss_stop(PUSB_DEV_MANAGER dev_mgr, DEV_HANDLE dev_handle)
-{
- UNREFERENCED_PARAMETER(dev_handle);
- UNREFERENCED_PARAMETER(dev_mgr);
- return TRUE;
-}
-
-BOOLEAN
-umss_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 umss_delete_device(dev_mgr, pdrvr, dev_obj, FALSE);
-}
-
-VOID
-umss_deferred_delete_device(PVOID context)
-{
- PDEVICE_OBJECT dev_obj;
- PUMSS_DEVICE_EXTENSION pdev_ext;
- PUMSS_DRVR_EXTENSION pdrvr_ext;
- LARGE_INTEGER interval;
-
- if (context == NULL)
- return;
-
- dev_obj = (PDEVICE_OBJECT) context;
- pdev_ext = dev_obj->DeviceExtension;
- pdrvr_ext = (PUMSS_DRVR_EXTENSION) pdev_ext->pdriver->driver_ext;
-
- interval.QuadPart = -20000; //two ms
-
- for(;;)
- {
- if (dev_obj->ReferenceCount)
- KeDelayExecutionThread(KernelMode, TRUE, &interval);
- else
- {
- KeDelayExecutionThread(KernelMode, TRUE, &interval);
- if (dev_obj->ReferenceCount == 0)
- break;
- }
- }
- usb_dbg_print(DBGLVL_MAXIMUM, ("umss_deferred_delete_device(): delete device, 0x%x\n", dev_obj));
-
- ExAcquireFastMutex(&pdrvr_ext->dev_list_mutex);
- RemoveEntryList(&pdev_ext->dev_obj_link);
- pdrvr_ext->dev_count--;
- ExReleaseFastMutex(&pdrvr_ext->dev_list_mutex);
-
- IoDeleteDevice(dev_obj);
- return;
-}
-
-BOOLEAN
-umss_delete_device(PUSB_DEV_MANAGER dev_mgr, PUSB_DRIVER pdrvr, PDEVICE_OBJECT dev_obj, BOOLEAN is_if)
-{
- CHAR dev_name[64];
- STRING string;
- UNICODE_STRING symb_link;
- PUMSS_DEVICE_EXTENSION pdev_ext;
- PUMSS_DRVR_EXTENSION pdrvr_ext;
-
- if (dev_obj == NULL)
- return FALSE;
-
- if (pdrvr == NULL || dev_mgr == NULL)
- return FALSE;
-
- pdev_ext = (PUMSS_DEVICE_EXTENSION) dev_obj->DeviceExtension;
- pdrvr_ext = (PUMSS_DRVR_EXTENSION) pdrvr->driver_ext;
- if (is_if == FALSE)
- sprintf(dev_name, "\\DosDevices\\umssdev%d", (int)pdev_ext->umss_dev_id);
- else
- sprintf(dev_name, "\\DosDevices\\umssifdev%d", (int)pdev_ext->umss_dev_id);
-
- RtlInitString(&string, dev_name);
- RtlAnsiStringToUnicodeString(&symb_link, &string, TRUE);
- IoDeleteSymbolicLink(&symb_link);
- RtlFreeUnicodeString(&symb_link);
-
- if (pdev_ext->desc_buf)
- {
- usb_dbg_print(DBGLVL_MAXIMUM, ("umss_delete_device(): delete desc_buf\n"));
- usb_free_mem(pdev_ext->desc_buf);
- pdev_ext->desc_buf = NULL;
-
- }
-
- if (dev_obj->ReferenceCount == 0)
- {
- ExAcquireFastMutex(&pdrvr_ext->dev_list_mutex);
- RemoveEntryList(&pdev_ext->dev_obj_link);
- pdrvr_ext->dev_count--;
- ExReleaseFastMutex(&pdrvr_ext->dev_list_mutex);
-
- IoDeleteDevice(dev_obj);
- return TRUE;
- }
-
- //
- // FIXME: how if the driver unloading happens
- // since this is called in dev_mgr_disconnect_dev, umss_schedule_workitem
- // can not protect the USB_DEV object from be deleted. so the workitem
- // can not access anything relative to the USB_DEV object. In this case
- // we will tollerate the usb_query_and_lock_dev failure since it will
- // never success when come to this point, and we won't pass dev_mgr
- // and pdev to the function. But other scenarios, usb_query_and_lock_dev
- // can not fail if dev_mgr and pdev are passed valid.
- // When driver is unloading, don't know. Wish NT will unload the driver
- // only when all the devices to the driver are deleted.
- //
- umss_schedule_workitem(dev_obj, umss_deferred_delete_device, NULL, 0);
- return TRUE;
-}
-
-VOID
-umss_submit_io_packet(PDEVICE_OBJECT dev_obj, PIO_PACKET io_packet)
-{
- NTSTATUS status;
- PUMSS_DEVICE_EXTENSION pdev_ext;
- PUSB_DEV pdev;
-
- pdev_ext = dev_obj->DeviceExtension;
-
- // lock the dev, the pdev_ext->pif_desc won't go away.
- if ((status = usb_query_and_lock_dev(pdev_ext->dev_mgr, pdev_ext->dev_handle, &pdev)) != STATUS_SUCCESS)
- {
- usb_dbg_print(DBGLVL_MAXIMUM, ("umss_start_io(): error, device is not valid\n"));
- UMSS_COMPLETE_START_IO(dev_obj, status, io_packet->pirp);
- return;
- }
-
- if (pdev_ext->pif_desc->bInterfaceProtocol == PROTOCOL_BULKONLY)
- {
- status = umss_bulkonly_startio(pdev_ext, io_packet);
- }
- else if (pdev_ext->pif_desc->bInterfaceProtocol == PROTOCOL_CB
- || pdev_ext->pif_desc->bInterfaceProtocol == PROTOCOL_CBI)
- {
- status = umss_cbi_startio(pdev_ext, io_packet);
- }
- else
- {
- status = STATUS_DEVICE_PROTOCOL_ERROR;
- }
- usb_unlock_dev(pdev);
- UMSS_COMPLETE_START_IO(dev_obj, status, io_packet->pirp);
- return;
-}
-
-VOID
-NTAPI
-umss_start_io(IN PDEVICE_OBJECT dev_obj, IN PIRP irp)
-{
- ULONG ctrl_code;
- NTSTATUS status;
- PIO_STACK_LOCATION irp_stack;
- PUMSS_DEVICE_EXTENSION pdev_ext;
- IO_PACKET io_packet;
- PUSER_IO_PACKET user_io_packet;
-
- if (dev_obj == NULL || irp == NULL)
- return;
-
- status = STATUS_SUCCESS;
-
- irp_stack = IoGetCurrentIrpStackLocation(irp);
- ctrl_code = irp_stack->Parameters.DeviceIoControl.IoControlCode;
- pdev_ext = (PUMSS_DEVICE_EXTENSION) dev_obj->DeviceExtension;
-
- if (irp_stack->MajorFunction == IRP_MJ_SCSI)
- {
- umss_process_srb(dev_obj, irp);
- return;
- }
-
- if (irp_stack->MajorFunction != IRP_MJ_DEVICE_CONTROL)
- {
- UMSS_COMPLETE_START_IO(dev_obj, STATUS_INVALID_DEVICE_REQUEST, irp);
- }
-
- switch (ctrl_code)
- {
- case IOCTL_UMSS_SUBMIT_CDB_IN:
- case IOCTL_UMSS_SUBMIT_CDB_OUT:
- case IOCTL_UMSS_SUBMIT_CDB:
- {
- if (irp_stack->Parameters.DeviceIoControl.InputBufferLength < sizeof(USER_IO_PACKET))
- {
- UMSS_COMPLETE_START_IO(dev_obj, STATUS_INVALID_PARAMETER, irp);
- }
-
- user_io_packet = (PUSER_IO_PACKET) irp->AssociatedIrp.SystemBuffer;
-
- if (user_io_packet->sub_class != pdev_ext->pif_desc->bInterfaceSubClass)
- {
- // not agree with the dev's subclass
- UMSS_COMPLETE_START_IO(dev_obj, STATUS_DEVICE_PROTOCOL_ERROR, irp);
- }
-
- RtlZeroMemory(&io_packet, sizeof(io_packet));
- io_packet.cdb_length = user_io_packet->cdb_length;
- io_packet.lun = user_io_packet->lun;
-
- RtlCopyMemory(io_packet.cdb, user_io_packet->cdb, MAX_CDB_LENGTH);
-
- if (ctrl_code == IOCTL_UMSS_SUBMIT_CDB_IN)
- io_packet.flags |= USB_DIR_IN;
-
- if (ctrl_code != IOCTL_UMSS_SUBMIT_CDB)
- {
- if (irp_stack->Parameters.DeviceIoControl.OutputBufferLength == 0)
- UMSS_COMPLETE_START_IO(dev_obj, STATUS_BUFFER_TOO_SMALL, irp);
-
- io_packet.data_buffer = MmGetSystemAddressForMdl(irp->MdlAddress);
- io_packet.data_length = irp_stack->Parameters.DeviceIoControl.OutputBufferLength;
-
- if (io_packet.data_length > MAX_BULK_TRANSFER_LENGTH)
- UMSS_COMPLETE_START_IO(dev_obj, STATUS_BUFFER_TOO_SMALL, irp);
-
- //synchronize the buffer
- if (io_packet.flags & USB_DIR_IN)
- KeFlushIoBuffers(irp->MdlAddress, TRUE, TRUE);
- else
- KeFlushIoBuffers(irp->MdlAddress, FALSE, TRUE);
- }
-
- io_packet.pirp = irp;
- umss_submit_io_packet(dev_obj, &io_packet);
- return;
- }
- case IOCTL_SCSI_PASS_THROUGH:
- {
- PSCSI_PASS_THROUGH pass_through;
- IO_PACKET io_packet;
-
- pass_through = irp->AssociatedIrp.SystemBuffer;
-
- if (pass_through->DataTransferLength &&
- pass_through->DataBufferOffset != sizeof(SCSI_PASS_THROUGH))
- UMSS_COMPLETE_START_IO(dev_obj, STATUS_INVALID_PARAMETER, irp);
-
- if (pass_through->SenseInfoLength &&
- (pass_through->SenseInfoOffset !=
- pass_through->DataBufferOffset + pass_through->DataTransferLength))
- UMSS_COMPLETE_START_IO(dev_obj, STATUS_INVALID_PARAMETER, irp);
-
- if (irp_stack->Parameters.DeviceIoControl.InputBufferLength <
- (sizeof(SCSI_PASS_THROUGH) +
- pass_through->SenseInfoLength + pass_through->DataTransferLength))
- UMSS_COMPLETE_START_IO(dev_obj, STATUS_BUFFER_TOO_SMALL, irp);
-
- RtlZeroMemory(&io_packet, sizeof(io_packet));
-
- io_packet.flags |= IOP_FLAG_SCSI_CTRL_TRANSFER;
- if (pass_through->DataIn)
- io_packet.flags |= IOP_FLAG_DIR_IN;
-
- io_packet.data_buffer = (PVOID) & pass_through[1];
- io_packet.data_length = pass_through->DataTransferLength;
-
- if (pass_through->SenseInfoLength)
- {
- io_packet.sense_data = ((PUCHAR) pass_through) + pass_through->SenseInfoOffset;
- io_packet.sense_data_length = pass_through->SenseInfoLength;
- io_packet.flags |= IOP_FLAG_REQ_SENSE;
- }
-
- io_packet.cdb_length = pass_through->CdbLength;
- RtlCopyMemory(io_packet.cdb, pass_through->Cdb, sizeof(io_packet.cdb));
- io_packet.lun = 0;
- io_packet.pirp = irp;
- umss_submit_io_packet(dev_obj, &io_packet);
- return;
- }
- case IOCTL_SCSI_PASS_THROUGH_DIRECT:
- {
- PSCSI_PASS_THROUGH_DIRECT pass_through_direct;
- IO_PACKET io_packet;
-
- pass_through_direct = irp->AssociatedIrp.SystemBuffer;
-
- if (pass_through_direct->SenseInfoLength &&
- pass_through_direct->SenseInfoOffset != sizeof(SCSI_PASS_THROUGH_DIRECT))
- UMSS_COMPLETE_START_IO(dev_obj, STATUS_INVALID_PARAMETER, irp);
-
- if (irp_stack->Parameters.DeviceIoControl.InputBufferLength <
- sizeof(SCSI_PASS_THROUGH_DIRECT) + pass_through_direct->SenseInfoLength)
- UMSS_COMPLETE_START_IO(dev_obj, STATUS_BUFFER_TOO_SMALL, irp);
-
- RtlZeroMemory(&io_packet, sizeof(io_packet));
-
- io_packet.flags |= IOP_FLAG_SCSI_CTRL_TRANSFER;
- if (pass_through_direct->DataIn)
- io_packet.flags |= IOP_FLAG_DIR_IN;
-
- io_packet.data_buffer = pass_through_direct->DataBuffer;
- io_packet.data_length = pass_through_direct->DataTransferLength;
-
- if (pass_through_direct->SenseInfoLength)
- {
- io_packet.sense_data = ((PUCHAR) pass_through_direct) + pass_through_direct->SenseInfoOffset;
- io_packet.sense_data_length = pass_through_direct->SenseInfoLength;
- io_packet.flags |= IOP_FLAG_REQ_SENSE;
- }
-
- io_packet.cdb_length = pass_through_direct->CdbLength;
- RtlCopyMemory(io_packet.cdb, pass_through_direct->Cdb, sizeof(io_packet.cdb));
- io_packet.lun = 0;
- io_packet.pirp = irp;
- umss_submit_io_packet(dev_obj, &io_packet);
- return;
- }
- case IOCTL_SUBMIT_URB_RD:
- case IOCTL_SUBMIT_URB_NOIO:
- case IOCTL_SUBMIT_URB_WR:
- {
- gendrv_startio(dev_obj, irp);
- return;
- }
- default:
- UMSS_COMPLETE_START_IO(dev_obj, STATUS_INVALID_DEVICE_REQUEST, irp);
- }
- return;
-}
-
-// bugbug!!! there can not be sent IOCTL_SUBMIT_URB_XXX while
-// the IOCTL_SUBMIT_CDB_XXX are active. may confuse the device.
-// not resolved yet.
-NTSTATUS
-umss_dispatch_routine(PDEVICE_OBJECT pdev_obj, PIRP irp)
-{
- ULONG ctrl_code;
- NTSTATUS status;
- PIO_STACK_LOCATION irp_stack;
- PUMSS_DEVICE_EXTENSION pdev_ext;
- USE_BASIC_NON_PENDING_IRQL;
-
- if (pdev_obj == NULL || irp == NULL)
- return STATUS_INVALID_PARAMETER;
-
- status = STATUS_SUCCESS;
- irp_stack = IoGetCurrentIrpStackLocation(irp);
- ctrl_code = irp_stack->Parameters.DeviceIoControl.IoControlCode;
-
- pdev_ext = (PUMSS_DEVICE_EXTENSION) pdev_obj->DeviceExtension;
-
- switch (irp_stack->MajorFunction)
- {
- case IRP_MJ_CREATE:
- case IRP_MJ_CLOSE:
- {
- return dev_mgr_dispatch(pdev_ext->dev_mgr, irp);
- }
- case IRP_MJ_INTERNAL_DEVICE_CONTROL:
- {
- // function code to receive scsi request
- UMSS_EXIT_DISPATCH(pdev_obj, STATUS_PENDING, irp);
- }
- case IRP_MJ_DEVICE_CONTROL:
- {
- switch (ctrl_code)
- {
- case IOCTL_UMSS_SET_FDO:
- {
- PDEVICE_OBJECT fdo;
- PUSB_DEV pdev;
-
- if (irp_stack->Parameters.DeviceIoControl.InputBufferLength < sizeof(PDEVICE_OBJECT))
- {
- EXIT_DISPATCH(STATUS_INVALID_PARAMETER, irp);
- }
-
- fdo = (PDEVICE_OBJECT) ((PULONG) irp->AssociatedIrp.SystemBuffer)[0];
- if (fdo == NULL)
- EXIT_DISPATCH(STATUS_INVALID_PARAMETER, irp);
- //
- // we have to test the usb dev's state to determine whether set or not the fdo
- //
-
- if (usb_query_and_lock_dev(pdev_ext->dev_mgr, pdev_ext->dev_handle, &pdev) !=
- STATUS_SUCCESS)
- EXIT_DISPATCH(STATUS_DEVICE_DOES_NOT_EXIST, irp);
-
- lock_dev(pdev, FALSE);
-
- if (dev_state(pdev) >= USB_DEV_STATE_BEFORE_ZOMB || dev_state(pdev) == USB_DEV_STATE_ZOMB)
- {
- unlock_dev(pdev, FALSE);
- usb_unlock_dev(pdev);
- EXIT_DISPATCH(STATUS_DEVICE_DOES_NOT_EXIST, irp);
- }
-
- pdev_ext->fdo = fdo;
- unlock_dev(pdev, FALSE);
- usb_unlock_dev(pdev);
- irp->IoStatus.Information = 0;
- EXIT_DISPATCH(STATUS_SUCCESS, irp);
- }
-
- case IOCTL_GET_DEV_DESC:
- {
- PGET_DEV_DESC_REQ pgddr;
- if (irp_stack->Parameters.DeviceIoControl.InputBufferLength < sizeof(GET_DEV_DESC_REQ))
- {
- EXIT_DISPATCH(STATUS_INVALID_PARAMETER, irp);
- }
- pgddr = irp->AssociatedIrp.SystemBuffer;
- if (pgddr->dev_handle != (pdev_ext->dev_handle & 0xffff0000))
- {
- EXIT_DISPATCH(STATUS_INVALID_PARAMETER, irp);
- }
- // an immediate request
- return dev_mgr_dispatch(pdev_ext->dev_mgr, irp);
- }
- case IOCTL_SUBMIT_URB_RD:
- case IOCTL_SUBMIT_URB_NOIO:
- case IOCTL_SUBMIT_URB_WR:
- {
- PURB purb;
- DEV_HANDLE endp_handle;
-
- if (irp_stack->Parameters.DeviceIoControl.InputBufferLength < sizeof(URB))
- {
- EXIT_DISPATCH(STATUS_INVALID_PARAMETER, irp);
- }
-
- purb = (PURB) irp->AssociatedIrp.SystemBuffer;
- endp_handle = purb->endp_handle;
- if (!default_endp_handle(endp_handle))
- {
- //no permit to other interface if interface dev
- if ((pdev_ext->flags & UMSS_DEV_FLAG_IF_DEV)
- && if_idx_from_handle(endp_handle) != pdev_ext->if_idx)
- EXIT_DISPATCH(STATUS_INVALID_PARAMETER, irp);
- }
- // FIXME: this is dangeous
- // return dev_mgr_dispatch( pdev_ext->dev_mgr, irp );
- UMSS_EXIT_DISPATCH(pdev_obj, STATUS_PENDING, irp);
- }
- case IOCTL_GET_DEV_HANDLE:
- {
- if (irp_stack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(LONG))
- EXIT_DISPATCH(STATUS_INVALID_PARAMETER, irp);
-
- *((PLONG) irp->AssociatedIrp.SystemBuffer) = pdev_ext->dev_handle;
- irp->IoStatus.Information = sizeof(LONG);
- EXIT_DISPATCH(STATUS_SUCCESS, irp);
- }
-
- //
- // request from scsi class driver
- //
- case IOCTL_SCSI_PASS_THROUGH:
- case IOCTL_SCSI_PASS_THROUGH_DIRECT:
- //
- // direct cdb request
- //
- case IOCTL_UMSS_SUBMIT_CDB:
- case IOCTL_UMSS_SUBMIT_CDB_OUT:
- case IOCTL_UMSS_SUBMIT_CDB_IN:
- {
- UMSS_EXIT_DISPATCH(pdev_obj, STATUS_PENDING, irp);
- }
- case IOCTL_SCSI_GET_INQUIRY_DATA:
- {
- PSCSI_ADAPTER_BUS_INFO adapter_info;
- PSCSI_BUS_DATA bus_data;
- PSCSI_INQUIRY_DATA inq_dat;
- PINQUIRYDATA inq;
- IO_PACKET io_packet;
- ULONG required_size;
-
- required_size = sizeof(SCSI_ADAPTER_BUS_INFO)
- + sizeof(SCSI_BUS_DATA) + sizeof(SCSI_INQUIRY_DATA) + INQUIRYDATABUFFERSIZE;
-
- if (irp_stack->Parameters.DeviceIoControl.OutputBufferLength < required_size)
- UMSS_EXIT_DISPATCH(pdev_obj, STATUS_BUFFER_TOO_SMALL, irp);
-
- RtlZeroMemory(&io_packet, sizeof(io_packet));
-
- adapter_info = irp->AssociatedIrp.SystemBuffer;
- adapter_info->NumberOfBuses = 1;
- bus_data = &adapter_info->BusData[0];
- bus_data->NumberOfLogicalUnits = 1;
- bus_data->InitiatorBusId = 0;
- bus_data->InquiryDataOffset = sizeof(SCSI_ADAPTER_BUS_INFO);
- inq_dat = (PVOID) & bus_data[1];
- inq_dat->PathId = 0;
- inq_dat->TargetId = pdev_ext->umss_dev_id;
- //
- // this is the dev_id for usb dev_manager
- //
- inq_dat->Lun = (UCHAR) (pdev_ext->dev_handle >> 16);
- inq_dat->DeviceClaimed = FALSE;
- inq_dat->InquiryDataLength = 36;
- inq_dat->NextInquiryDataOffset = 0;
- inq = (PINQUIRYDATA) inq_dat->InquiryData;
-
- RtlZeroMemory(inq, sizeof(INQUIRYDATA));
- inq->DeviceType = DIRECT_ACCESS_DEVICE;
- inq->DeviceTypeQualifier = 0;
- inq->RemovableMedia = 1;
-
- //
- // pretend to comply scsi primary 2 command set
- //
-
- inq->Versions = 0x04;
-
- //
- // the format is in scsi-2 format
- //
-
- inq->ResponseDataFormat = 0x02;
-
- //
- // we are the poor scsi device
- //
-
- inq->AdditionalLength = 31;
- inq->SoftReset = 0;
- inq->CommandQueue = 0;
- inq->LinkedCommands = 0;
- inq->RelativeAddressing = 0;
- RtlCopyMemory(&inq->VendorId, "Unknown", 7);
- RtlCopyMemory(&inq->ProductId, "USB Mass Storage", 16);
- irp->IoStatus.Information = required_size;
- EXIT_DISPATCH(STATUS_SUCCESS, irp);
- }
- case IOCTL_SCSI_GET_CAPABILITIES:
- {
- PIO_SCSI_CAPABILITIES port_cap;
-
- if (irp_stack->Parameters.DeviceIoControl.OutputBufferLength <
- sizeof(IO_SCSI_CAPABILITIES))
- EXIT_DISPATCH(STATUS_INVALID_PARAMETER, irp);
-
- port_cap = (PIO_SCSI_CAPABILITIES) irp->AssociatedIrp.SystemBuffer;
- port_cap->Length = sizeof(IO_SCSI_CAPABILITIES);
- port_cap->MaximumTransferLength = 65536;
- port_cap->MaximumPhysicalPages = 65536 / PAGE_SIZE;
- port_cap->SupportedAsynchronousEvents = 0;
- port_cap->AlignmentMask = 0x10;
- port_cap->TaggedQueuing = FALSE;
- port_cap->AdapterScansDown = FALSE;
- port_cap->AdapterUsesPio = FALSE;
- irp->IoStatus.Information = sizeof(IO_SCSI_CAPABILITIES);
- EXIT_DISPATCH(STATUS_SUCCESS, irp);
- }
- case IOCTL_SCSI_GET_ADDRESS:
- {
- PSCSI_ADDRESS paddr;
- if (irp_stack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(SCSI_ADDRESS))
- EXIT_DISPATCH(STATUS_INVALID_PARAMETER, irp);
-
- paddr = (PSCSI_ADDRESS) irp->AssociatedIrp.SystemBuffer;
-
- paddr->Length = sizeof(SCSI_ADDRESS);
- paddr->PortNumber = 0;
- paddr->PathId = 0;
- paddr->TargetId = pdev_ext->umss_dev_id;
- paddr->Lun = (UCHAR) (pdev_ext->dev_handle >> 16);
- irp->IoStatus.Information = sizeof(SCSI_ADDRESS);
- EXIT_DISPATCH(STATUS_SUCCESS, irp);
- }
- case IOCTL_SCSI_RESCAN_BUS:
- {
- irp->IoStatus.Information = 0;
- EXIT_DISPATCH(STATUS_SUCCESS, irp);
- }
- default:
- {
- EXIT_DISPATCH(STATUS_INVALID_DEVICE_REQUEST, irp);
- }
- }
- }
- }
- EXIT_DISPATCH(STATUS_NOT_SUPPORTED, irp);
-}
-
-VOID
-umss_reset_pipe_completion(PURB purb, PVOID context)
-{
- PUMSS_DEVICE_EXTENSION pdev_ext;
- if (context == NULL)
- return;
-
- pdev_ext = (PUMSS_DEVICE_EXTENSION) context;
- pdev_ext->reset_pipe_status = purb->status;
- KeSetEvent(&pdev_ext->sync_event, 0, FALSE);
- return;
-}
-
-//can only be called at passive level
-NTSTATUS
-umss_reset_pipe(PUMSS_DEVICE_EXTENSION pdev_ext, DEV_HANDLE endp_handle)
-{
- NTSTATUS status;
- PUSB_DEV pdev;
-
- if (pdev_ext == NULL)
- return STATUS_INVALID_PARAMETER;
-
- status = usb_query_and_lock_dev(pdev_ext->dev_mgr, pdev_ext->dev_handle, &pdev);
-
- if (status != STATUS_SUCCESS)
- return STATUS_UNSUCCESSFUL;
-
- status = usb_reset_pipe_ex(pdev_ext->dev_mgr, endp_handle, umss_reset_pipe_completion, pdev_ext);
-
- if (status == STATUS_PENDING)
- {
- KeWaitForSingleObject(&pdev_ext->sync_event, Executive, KernelMode, TRUE, NULL);
- status = pdev_ext->reset_pipe_status;
- }
- usb_unlock_dev(pdev);
- return status;
-}
-
-BOOLEAN
-umss_gen_result_srb(PIO_PACKET io_packet, PSCSI_REQUEST_BLOCK srb, NTSTATUS status)
-{
-
- if (srb == NULL || io_packet == NULL)
- {
- return FALSE;
- }
- if (status == STATUS_SUCCESS)
- {
- PULONG dest_buf, src_buf;
- ULONG i;
-
- srb->SrbStatus = SRB_STATUS_SUCCESS;
-
- io_packet->pirp->IoStatus.Information = srb->DataTransferLength;
- if ((io_packet->pirp->Flags & IRP_READ_OPERATION) && !(io_packet->pirp->Flags & IRP_PAGING_IO))
- {
- src_buf = (PULONG) io_packet->data_buffer;
- dest_buf = (PULONG) srb->DataBuffer;
- if (src_buf && dest_buf)
- {
- for(i = 0; i < (srb->DataTransferLength >> 2); i++)
- {
- dest_buf[i] = src_buf[i];
- }
- }
- }
- }
- else if (status == STATUS_DEVICE_DOES_NOT_EXIST)
- {
- PSENSE_DATA sense_buf;
- srb->SrbStatus = SRB_STATUS_NO_DEVICE;
- srb->ScsiStatus = SCSISTAT_CHECK_CONDITION;
-
- //
- // let's build the srb status for class driver
- //
-
- srb->SrbStatus |= SRB_STATUS_AUTOSENSE_VALID;
- sense_buf = (PSENSE_DATA) srb->SenseInfoBuffer;
-
- if (!(srb->SrbFlags & SRB_FLAGS_DISABLE_AUTOSENSE))
- {
- RtlZeroMemory(srb->SenseInfoBuffer, srb->SenseInfoBufferLength);
- sense_buf->ErrorCode = 0x70;
- sense_buf->Valid = 1;
- sense_buf->SenseKey = SCSI_SENSE_NOT_READY;
- sense_buf->AdditionalSenseCode = SCSI_ADSENSE_NO_MEDIA_IN_DEVICE;
- sense_buf->AdditionalSenseLength = 10;
- }
- }
- else if (status == USB_STATUS_STALL_PID || status == USB_STATUS_CRC ||
- status == USB_STATUS_BTSTUFF || status == USB_STATUS_DATA_OVERRUN)
- {
- PSENSE_DATA sense_buf;
- srb->SrbStatus = SRB_STATUS_ERROR;
- srb->ScsiStatus = SCSISTAT_CHECK_CONDITION;
-
- srb->SrbStatus |= SRB_STATUS_AUTOSENSE_VALID;
- sense_buf = (PSENSE_DATA) srb->SenseInfoBuffer;
-
- if (!(srb->SrbFlags & SRB_FLAGS_DISABLE_AUTOSENSE))
- {
- RtlZeroMemory(srb->SenseInfoBuffer, srb->SenseInfoBufferLength);
- sense_buf->ErrorCode = 0x70;
- sense_buf->Valid = 1;
- sense_buf->SenseKey = SCSI_SENSE_HARDWARE_ERROR;
- sense_buf->AdditionalSenseCode = 0;
- sense_buf->AdditionalSenseLength = 10;
- }
- }
- else
- {
- srb->SrbStatus = SRB_STATUS_ERROR;
- }
-
- if ((io_packet->pirp->Flags & (IRP_READ_OPERATION | IRP_WRITE_OPERATION))
- && !(io_packet->pirp->Flags & IRP_PAGING_IO))
- {
- if (io_packet->data_buffer)
- {
- usb_free_mem(io_packet->data_buffer);
- io_packet->data_buffer = NULL;
- }
- }
- return TRUE;
-}
-
-BOOLEAN
-umss_gen_result_ctrl(PDEVICE_OBJECT dev_obj, PIRP irp, NTSTATUS status)
-{
- PIO_STACK_LOCATION irp_stack;
- ULONG ctrl_code;
- PUMSS_DEVICE_EXTENSION pdev_ext;
-
- if (irp == NULL)
- return FALSE;
-
- irp->IoStatus.Information = 0;
- irp_stack = IoGetCurrentIrpStackLocation(irp);
- ctrl_code = irp_stack->Parameters.DeviceIoControl.IoControlCode;
- pdev_ext = dev_obj->DeviceExtension;
-
- switch (ctrl_code)
- {
- case IOCTL_SCSI_PASS_THROUGH:
- {
- PSCSI_PASS_THROUGH pass_through;
- pass_through = irp->AssociatedIrp.SystemBuffer;
- irp->IoStatus.Status = status;
-
- // we have set these two value in bulkonly.c when data transfer complete
- // pass_through_direct->DataTransferLength = pdev_ext->io_packet.data_length;
- // pass_through_direct->SenseInfoLength = pdev_ext->io_packet.sense_data_length;
-
- if (status == STATUS_SUCCESS)
- irp->IoStatus.Information = pass_through->SenseInfoOffset + pass_through->SenseInfoLength;
- else
- pass_through->ScsiStatus = SCSISTAT_CHECK_CONDITION;
- return TRUE;
- }
- case IOCTL_SCSI_PASS_THROUGH_DIRECT:
- {
- PSCSI_PASS_THROUGH_DIRECT pass_through_direct;
-
- pass_through_direct = irp->AssociatedIrp.SystemBuffer;
- pass_through_direct->ScsiStatus = 0;
- irp->IoStatus.Status = status;
-
- // we have set these two value in bulkonly.c when data transfer complete
- // pass_through_direct->DataTransferLength = pdev_ext->io_packet.data_length;
- // pass_through_direct->SenseInfoLength = pdev_ext->io_packet.sense_data_length;
-
- if (status == STATUS_SUCCESS)
- irp->IoStatus.Information =
- pass_through_direct->SenseInfoOffset + pass_through_direct->SenseInfoLength;
- else
- pass_through_direct->ScsiStatus = SCSISTAT_CHECK_CONDITION;
-
- return TRUE;
- }
- }
- return FALSE;
-}
-
-
-VOID
-umss_complete_request(PUMSS_DEVICE_EXTENSION pdev_ext, NTSTATUS status)
-{
- PIRP pirp;
- KIRQL old_irql;
-
- PDEVICE_OBJECT dev_obj;
- PIO_STACK_LOCATION irp_stack;
-
- usb_dbg_print(DBGLVL_MAXIMUM, ("umss_complete_request(): entering...\n"));
-
- pirp = pdev_ext->io_packet.pirp;
- dev_obj = pdev_ext->pdo;
-
- irp_stack = IoGetCurrentIrpStackLocation(pirp);
-
- if (pdev_ext->io_packet.flags & IOP_FLAG_SRB_TRANSFER)
- {
- if (pdev_ext->pif_desc->bInterfaceSubClass == UMSS_SUBCLASS_SFF8070I)
- {
- umss_fix_sff_result(&pdev_ext->io_packet, irp_stack->Parameters.Scsi.Srb);
- }
- umss_gen_result_srb(&pdev_ext->io_packet, irp_stack->Parameters.Scsi.Srb, status);
- }
- else if (pdev_ext->io_packet.flags & IOP_FLAG_SCSI_CTRL_TRANSFER)
- umss_gen_result_ctrl(dev_obj, pirp, status);
-
- //this device has its irp queued
- if (status == STATUS_CANCELLED)
- {
- usb_dbg_print(DBGLVL_MAXIMUM, ("umss_complete_request(): status of irp is cancelled\n"));
- IoAcquireCancelSpinLock(&old_irql);
- if (dev_obj->CurrentIrp == pirp)
- {
- IoReleaseCancelSpinLock(old_irql);
- IoStartNextPacket(dev_obj, FALSE);
- }
- else
- {
- KeRemoveEntryDeviceQueue(&dev_obj->DeviceQueue, &pirp->Tail.Overlay.DeviceQueueEntry);
- IoReleaseCancelSpinLock(old_irql);
- }
- }
- else
- {
- // all requests come to this point from the irp queue
- IoStartNextPacket(dev_obj, FALSE);
-
- // we are going to complete the request, so set it's cancel routine to NULL
- IoAcquireCancelSpinLock(&old_irql);
- (void)IoSetCancelRoutine(pirp, NULL);
- IoReleaseCancelSpinLock(old_irql);
- }
-
- pirp->IoStatus.Status = status;
-
- if (status != STATUS_SUCCESS)
- pirp->IoStatus.Information = 0;
-
- IoCompleteRequest(pirp, IO_NO_INCREMENT);
- return;
-}
-
-BOOLEAN
-umss_if_connect(PDEV_CONNECT_DATA params, DEV_HANDLE if_handle)
-{
- PURB purb;
- LONG if_idx, i;
- PUCHAR desc_buf;
- NTSTATUS status;
- PUSB_DEV pdev;
- PUSB_DRIVER pdrvr;
- PUSB_INTERFACE_DESC pif_desc;
- PUSB_CTRL_SETUP_PACKET psetup;
- PUMSS_DEVICE_EXTENSION pdev_ext;
- PUSB_CONFIGURATION_DESC pconfig_desc;
- PUSB_DEV_MANAGER dev_mgr;
- PUSB_ENDPOINT_DESC pendp_desc;
- PUMSS_DRVR_EXTENSION pdrvr_ext;
- PDEVICE_OBJECT pdev_obj;
- USE_BASIC_NON_PENDING_IRQL;
-
- //configuration is already set
- purb = NULL;
- desc_buf = NULL;
- pdev = NULL;
-
- usb_dbg_print(DBGLVL_MAXIMUM, ("umss_if_connect(): entering...\n"));
-
- if (params == NULL)
- return FALSE;
-
- dev_mgr = params->dev_mgr;
- pdrvr = params->pdriver;
-
- if_idx = if_idx_from_handle(if_handle);
-
- purb = usb_alloc_mem(NonPagedPool, sizeof(URB));
- if (purb == NULL)
- goto ERROR_OUT;
-
- desc_buf = usb_alloc_mem(NonPagedPool, 512);
- if (desc_buf == NULL)
- goto ERROR_OUT;
-
- psetup = (PUSB_CTRL_SETUP_PACKET) (purb)->setup_packet;
- urb_init((purb));
-
- // now let's get the descs, one configuration, one interface and two endpoint
- psetup = (PUSB_CTRL_SETUP_PACKET) (purb)->setup_packet;
- purb->endp_handle = if_handle | 0xffff;
- purb->data_buffer = desc_buf;
- purb->data_length = 512;
- purb->completion = NULL; // this is an immediate request, no needs completion
- purb->context = dev_mgr;
- purb->reference = 0;
- psetup->bmRequestType = 0x80;
- psetup->bRequest = USB_REQ_GET_DESCRIPTOR;
- psetup->wValue = USB_DT_CONFIG << 8;
- psetup->wIndex = 0;
- psetup->wLength = 512;
-
- status = usb_submit_urb(dev_mgr, purb);
- if (status == STATUS_PENDING)
- {
- TRAP();
- }
- usb_free_mem(purb);
- purb = NULL;
-
- if (status != STATUS_SUCCESS)
- {
- goto ERROR_OUT;
- }
-
- status = usb_query_and_lock_dev(dev_mgr, if_handle, &pdev);
- if (status != STATUS_SUCCESS)
- {
- goto ERROR_OUT;
- }
-
-#ifdef _TIANSHENG_DRIVER
- if (!((pdev->pusb_dev_desc->idVendor == 0x03eb && pdev->pusb_dev_desc->idProduct == 0x2002)
- || (pdev->pusb_dev_desc->idVendor == 0x0ea0 && pdev->pusb_dev_desc->idProduct == 0x6803)
- || (pdev->pusb_dev_desc->idVendor == 0x0ef5 && pdev->pusb_dev_desc->idProduct == 0x2202)))
- {
- // check TianSheng's product
- goto ERROR_OUT;
- }
-#endif
-
- pdev_obj = umss_create_device(dev_mgr, pdrvr, if_handle, TRUE);
- if (pdev_obj == NULL)
- {
- goto ERROR_OUT;
- }
-
- lock_dev(pdev, FALSE);
- if (dev_state(pdev) == USB_DEV_STATE_ZOMB ||
- dev_mgr_set_if_driver(dev_mgr, if_handle, pdrvr, pdev) == FALSE)
- {
- unlock_dev(pdev, FALSE);
- if (pdev_obj)
- {
- umss_delete_device(dev_mgr, pdrvr, pdev_obj, TRUE);
- }
- goto ERROR_OUT;
- }
-
- if (pdev->usb_config)
- {
- pdev->usb_config->interf[if_idx].if_ext = pdev_obj;
- pdev->usb_config->interf[if_idx].if_ext_size = 0;
- }
- // olympus dev needs special care
- if (UMSS_OLYMPUS_VENDOR_ID == pdev->pusb_dev_desc->idVendor)
- status = TRUE;
- else
- status = FALSE;
-
- unlock_dev(pdev, FALSE);
-
- pdev_ext = (PUMSS_DEVICE_EXTENSION) pdev_obj->DeviceExtension;
-
- pdev_ext->desc_buf = desc_buf;
- pdev_ext->pif_desc = NULL;
- pdev_ext->pin_endp_desc = pdev_ext->pout_endp_desc = NULL;
- pconfig_desc = (PUSB_CONFIGURATION_DESC) desc_buf;
- pif_desc = (PUSB_INTERFACE_DESC) (&pconfig_desc[1]);
-
- if (status)
- pdev_ext->flags |= UMSS_DEV_FLAG_OLYMPUS_DEV;
-
- //search for our if
- for(i = 0; ((UCHAR) i) < if_idx; i++)
- {
- if (usb_skip_if_and_altif((PUCHAR *) & pif_desc) == FALSE)
- break;
- }
- pdev_ext->pif_desc = pif_desc;
-
- if (pdev_ext->pif_desc)
- {
- pendp_desc = (PUSB_ENDPOINT_DESC) & pif_desc[1];
- for(i = 0; ((UCHAR) i) < pif_desc->bNumEndpoints; i++)
- {
- if (pendp_desc->bDescriptorType == USB_DT_ENDPOINT
- && pendp_desc->bLength == sizeof(USB_ENDPOINT_DESC))
- {
- if ((pendp_desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT)
- {
- pdev_ext->pint_endp_desc = pendp_desc;
- pdev_ext->int_endp_idx = (UCHAR) i;
- }
- else if ((pendp_desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_BULK)
- {
- if (pendp_desc->bEndpointAddress & USB_DIR_IN)
- {
- pdev_ext->pin_endp_desc = pendp_desc;
- pdev_ext->in_endp_idx = (UCHAR) i;
- }
- else
- {
- pdev_ext->pout_endp_desc = pendp_desc;
- pdev_ext->out_endp_idx = (UCHAR) i;
- }
- }
- pendp_desc = &pendp_desc[1];
- }
- else
- break;
- }
- }
-
- // notify the class driver, some device comes
- pdrvr_ext = (PUMSS_DRVR_EXTENSION) pdrvr->driver_ext;
- if (pdrvr_ext && pdrvr_ext->class_driver_info.add_device && pdrvr_ext->class_driver_info.fdo_driver)
- pdrvr_ext->class_driver_info.add_device(pdrvr_ext->class_driver_info.fdo_driver, pdev_obj);
-
- usb_unlock_dev(pdev);
- return TRUE;
-
-ERROR_OUT:
- if (desc_buf)
- usb_free_mem(desc_buf);
-
- if (purb)
- usb_free_mem(purb);
-
- usb_unlock_dev(pdev);
-
- desc_buf = NULL;
- purb = NULL;
-
- return FALSE;
-}
-
-BOOLEAN
-umss_if_disconnect(PUSB_DEV_MANAGER dev_mgr, DEV_HANDLE if_handle)
-{
- LONG if_idx;
- NTSTATUS status;
- PUSB_DEV pdev;
- PUSB_DRIVER pdrvr = NULL;
- PDEVICE_OBJECT dev_obj = NULL;
- PUMSS_DRVR_EXTENSION pdrvr_ext;
- PUMSS_DEVICE_EXTENSION pdev_ext;
-
- if (dev_mgr == NULL || if_handle == 0)
- return FALSE;
-
- pdev = NULL;
- if_idx = if_idx_from_handle(if_handle);
- //
- // special use of the lock dev, simply use this routine to get the dev
- //
- status = usb_query_and_lock_dev(dev_mgr, if_handle, &pdev);
- if (pdev == NULL)
- {
- return FALSE;
- }
- if (status == STATUS_SUCCESS)
- {
- // must be a bug
- TRAP();
- }
- if (pdev->usb_config)
- {
- pdrvr = pdev->usb_config->interf[if_idx].pif_drv;
- dev_obj = (PDEVICE_OBJECT) pdev->usb_config->interf[if_idx].if_ext;
- }
- pdev = NULL;
-
- // notify the class driver, some device gone
- pdrvr_ext = (PUMSS_DRVR_EXTENSION) pdrvr->driver_ext;
- pdev_ext = dev_obj->DeviceExtension;
- if (pdrvr_ext && pdrvr_ext->class_driver_info.pnp_dispatch)
- pdrvr_ext->class_driver_info.pnp_dispatch(dev_obj, UMSS_PNPMSG_DISCONNECT, NULL);
-
- // no need to unlock the dev
- return umss_delete_device(dev_mgr, pdrvr, dev_obj, TRUE);
-}
-
-BOOLEAN
-umss_if_stop(PUSB_DEV_MANAGER dev_mgr, DEV_HANDLE if_handle)
-{
- LONG if_idx;
- NTSTATUS status;
- PUSB_DEV pdev;
- PUSB_DRIVER pdrvr = NULL;
- PDEVICE_OBJECT dev_obj = NULL;
- PUMSS_DRVR_EXTENSION pdrvr_ext;
- PUMSS_DEVICE_EXTENSION pdev_ext;
- USE_BASIC_NON_PENDING_IRQL;
-
- if (dev_mgr == NULL || if_handle == 0)
- return FALSE;
-
- pdev = NULL;
- if_idx = if_idx_from_handle(if_handle);
-
- // special use of the lock dev, simply use this routine to get the dev
- status = usb_query_and_lock_dev(dev_mgr, if_handle, &pdev);
- if (status != STATUS_SUCCESS)
- {
- return FALSE;
- }
-
- lock_dev(pdev, FALSE);
- if (dev_state(pdev) == USB_DEV_STATE_ZOMB)
- {
- return FALSE;
- }
-
- if (pdev->usb_config)
- {
- pdrvr = pdev->usb_config->interf[if_idx].pif_drv;
- dev_obj = (PDEVICE_OBJECT) pdev->usb_config->interf[if_idx].if_ext;
- }
- unlock_dev(pdev, FALSE);
-
- // notify the class driver, some device stops
- pdev_ext = dev_obj->DeviceExtension;
- pdrvr_ext = (PUMSS_DRVR_EXTENSION) pdrvr->driver_ext;
- if (pdrvr_ext && pdrvr_ext->class_driver_info.pnp_dispatch)
- pdrvr_ext->class_driver_info.pnp_dispatch(dev_obj, UMSS_PNPMSG_STOP, NULL);
-
- usb_unlock_dev(pdev);
- return TRUE;
-}
-
-VOID
-umss_load_class_driver(PVOID context)
-{
- NTSTATUS status;
- UNICODE_STRING unicode_string;
-
- UNREFERENCED_PARAMETER(context);
-
- //
- // let's load the class driver
- //
- RtlInitUnicodeString(&unicode_string,
- L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\usbstor");
- status = ZwLoadDriver(&unicode_string);
- usb_dbg_print(DBGLVL_MAXIMUM,
- ("umss_load_class_driver(): try to load class driver, status=0x%x\n", status));
-}
-
-BOOLEAN
-umss_if_driver_init(PUSB_DEV_MANAGER dev_mgr, PUSB_DRIVER pdriver)
-{
- PUMSS_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 = 0x0000; // USB Vendor ID
- pdriver->driver_desc.product_id = 0x0000; // 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_MASS_STORAGE; // Interface Class
- pdriver->driver_desc.if_sub_class = 0; // Interface SubClass
- pdriver->driver_desc.if_protocol = 0; // Interface Protocol
-
- pdriver->driver_desc.driver_name = "USB Mass Storage interface driver"; // Driver name for Name Registry
- pdriver->driver_desc.dev_class = USB_CLASS_PER_INTERFACE;
- pdriver->driver_desc.dev_sub_class = 0; // Device Subclass
- pdriver->driver_desc.dev_protocol = 0; // Protocol Info.
-
- pdriver->driver_ext = usb_alloc_mem(NonPagedPool, sizeof(UMSS_DRVR_EXTENSION));
- if (!pdriver->driver_ext) return FALSE;
-
- pdriver->driver_ext_size = sizeof(UMSS_DRVR_EXTENSION);
-
- RtlZeroMemory(pdriver->driver_ext, sizeof(UMSS_DRVR_EXTENSION));
-
- pdrvr_ext = (PUMSS_DRVR_EXTENSION) pdriver->driver_ext;
- pdrvr_ext->dev_count = 0;
- InitializeListHead(&pdrvr_ext->dev_list);
- ExInitializeFastMutex(&pdrvr_ext->dev_list_mutex);
-
- pdriver->disp_tbl.version = 1;
- pdriver->disp_tbl.dev_connect = umss_if_connect;
- pdriver->disp_tbl.dev_disconnect = umss_if_disconnect;
- pdriver->disp_tbl.dev_stop = umss_if_stop;
- pdriver->disp_tbl.dev_reserved = NULL;
-
- if ((pdrvr_ext->port_dev_obj = umss_create_port_device(dev_mgr, pdriver)) == NULL)
- {
- usb_free_mem(pdriver->driver_ext);
- pdriver->driver_ext = NULL;
- pdriver->driver_ext_size = 0;
- pdriver->disp_tbl.dev_connect = NULL;
- pdriver->disp_tbl.dev_stop = NULL;
- pdriver->disp_tbl.dev_disconnect = NULL;
- return FALSE;
- }
-
- //
- // let's load the class driver
- //
- umss_load_class_driver(NULL);
-
- // umss_schedule_workitem( NULL, umss_load_class_driver, NULL, 0 );
- usb_dbg_print(DBGLVL_MAXIMUM, ("umss_if_driver_init(): umss driver is initialized\n"));
-
- return TRUE;
-}
-
-// get the driver reg information for pnp notification to class
-// driver.
-// bug??? how if the driver info is returned while the driver
-// is being unloaded.
-// So the routine must be called when usb_query_and_lock_dev is
-// called.
-PCLASS_DRV_REG_INFO
-umss_get_if_driver_info(PUSB_DEV_MANAGER dev_mgr, PUSB_DEV pdev, DEV_HANDLE if_handle)
-{
- PUMSS_DRVR_EXTENSION drvr_ext;
- ULONG if_idx;
- USE_BASIC_NON_PENDING_IRQL;
-
- UNREFERENCED_PARAMETER(dev_mgr);
-
- if_idx = if_idx_from_handle(if_handle);
- if (if_idx >= 4) // max interfaces per config supports. defined in td.h
- return NULL;
-
- ASSERT(pdev != NULL);
-
- lock_dev(pdev, FALSE);
- if (dev_state(pdev) == USB_DEV_STATE_ZOMB)
- {
- unlock_dev(pdev, FALSE);
- usb_unlock_dev(pdev);
- return NULL;
- }
-
- drvr_ext = NULL;
-
- if (pdev->usb_config->interf[if_idx].pif_drv)
- drvr_ext = (PUMSS_DRVR_EXTENSION) pdev->usb_config->interf[if_idx].pif_drv->driver_ext;
- else
- TRAP();
-
- unlock_dev(pdev, FALSE);
-
- if (drvr_ext == NULL)
- {
- return NULL;
- }
-
- return &drvr_ext->class_driver_info;
-}
-
-VOID NTAPI
-umss_worker(IN PVOID reference)
-{
- PUMSS_WORKER_PACKET worker_packet;
- PUSB_DEV pdev;
-
- usb_dbg_print(DBGLVL_MAXIMUM, ("umss_worker(): entering...\n"));
- worker_packet = (PUMSS_WORKER_PACKET) reference;
- worker_packet->completion(worker_packet->context);
- if (worker_packet->dev_mgr && worker_packet->pdev)
- {
- pdev = (PUSB_DEV) worker_packet->pdev;
- usb_unlock_dev(pdev);
- pdev = NULL;
- }
- usb_free_mem(worker_packet);
- usb_dbg_print(DBGLVL_MAXIMUM, ("umss_worker(): exit\n"));
-}
-
-/*++
-Routine Description:
-
- Wrapper for handling worker thread callbacks, it is importent to
- lock the dev from being deleted by calling usb_query_and_lock_dev
- and in umss_worker, call the usb_unlock_dev to release the ref
- count. One exception is that the umss_if_disconnect call this
- function to delete the device object that is still held by some
- others, and deferred deletion is required.
-
-Arguments:
-
- Routine - Routine to be called when this work-item is processed
- Context - Value to be passed to worker routine
-
-Return Value:
- TRUE if work item queued
- FALSE if work item not queued
-
---*/
-BOOLEAN
-umss_schedule_workitem(PVOID context,
- UMSS_WORKER_ROUTINE completion, PUSB_DEV_MANAGER dev_mgr, DEV_HANDLE dev_handle)
-{
- BOOLEAN ret_val = TRUE;
- PWORK_QUEUE_ITEM workitem;
- PUMSS_WORKER_PACKET worker_packet;
-
- worker_packet = usb_alloc_mem(NonPagedPool, sizeof(WORK_QUEUE_ITEM) + sizeof(UMSS_WORKER_PACKET));
-
- if (worker_packet)
- {
- RtlZeroMemory(worker_packet, sizeof(WORK_QUEUE_ITEM) + sizeof(UMSS_WORKER_PACKET));
-
- workitem = (PWORK_QUEUE_ITEM) & worker_packet[1];
- worker_packet->completion = completion;
- worker_packet->context = context;
-
- if (dev_mgr != NULL && dev_handle != 0)
- {
- PUSB_DEV pdev;
- // lock the device until the workitem is executed.
- if (usb_query_and_lock_dev(dev_mgr, dev_handle, &pdev) == STATUS_SUCCESS)
- {
- worker_packet->dev_mgr = dev_mgr;
- worker_packet->pdev = pdev;
- }
- else
- {
- usb_free_mem(worker_packet);
- return FALSE;
- }
- }
- // Initialize the work-item
- ExInitializeWorkItem(workitem, umss_worker, worker_packet);
-
- // Schedule the work-item
- ExQueueWorkItem(workitem, DelayedWorkQueue);
-
- usb_dbg_print(DBGLVL_MINIMUM, ("umss_schedule_workitem(): work-item queued\n"));
- }
- else
- {
- usb_dbg_print(DBGLVL_MINIMUM, ("umss_schedule_workitem(): Failed to allocate work-item\n"));
- ret_val = FALSE;
- }
-
- return ret_val;
-}
-
-NTSTATUS
-umss_process_srb(PDEVICE_OBJECT dev_obj, PIRP irp)
-{
- NTSTATUS status;
- PUSB_DEV pdev;
- PIO_STACK_LOCATION cur_stack;
- PUMSS_DEVICE_EXTENSION pdev_ext;
- PSCSI_REQUEST_BLOCK srb;
-
- if (dev_obj == NULL || irp == NULL)
- return STATUS_INVALID_PARAMETER;
-
- pdev = NULL;
- cur_stack = IoGetCurrentIrpStackLocation(irp);
- srb = cur_stack->Parameters.Scsi.Srb;
-
- if (srb == NULL || srb->DataTransferLength > 65536)
- {
- status = STATUS_INVALID_PARAMETER;
- goto ERROR_OUT;
- }
-
- irp->IoStatus.Status = STATUS_SUCCESS;
- irp->IoStatus.Information = 0;
-
- pdev_ext = (PUMSS_DEVICE_EXTENSION) dev_obj->DeviceExtension;
- if ((status = usb_query_and_lock_dev(pdev_ext->dev_mgr, pdev_ext->dev_handle, &pdev)) != STATUS_SUCCESS)
- {
- PSENSE_DATA sense_buf;
- srb->SrbStatus = SRB_STATUS_NO_DEVICE;
-
- //
- // let's build the srb status for class driver
- //
- srb->SrbStatus |= SRB_STATUS_AUTOSENSE_VALID;
- RtlZeroMemory(srb->SenseInfoBuffer, srb->SenseInfoBufferLength);
- if (!(srb->SrbFlags & SRB_FLAGS_DISABLE_AUTOSENSE))
- {
- sense_buf = (PSENSE_DATA) srb->SenseInfoBuffer;
- sense_buf->ErrorCode = 0x70;
- sense_buf->Valid = 1;
- sense_buf->SenseKey = SCSI_SENSE_NOT_READY;
- sense_buf->AdditionalSenseCode = SCSI_ADSENSE_NO_MEDIA_IN_DEVICE;
- sense_buf->AdditionalSenseLength = 10;
- }
- goto ERROR_OUT;
- }
-
- switch (srb->Function)
- {
- case SRB_FUNCTION_EXECUTE_SCSI:
- {
- IO_PACKET io_packet;
- RtlZeroMemory(&io_packet, sizeof(io_packet));
-
- io_packet.flags |= IOP_FLAG_SRB_TRANSFER;
- if (srb->SrbFlags & SRB_FLAGS_DATA_IN)
- io_packet.flags |= IOP_FLAG_DIR_IN;
- if (!(srb->SrbFlags & SRB_FLAGS_DISABLE_AUTOSENSE))
- io_packet.flags |= IOP_FLAG_REQ_SENSE;
-
- io_packet.cdb_length = srb->CdbLength;
- RtlCopyMemory(io_packet.cdb, srb->Cdb, sizeof(io_packet.cdb));
- io_packet.lun = 0;
-
- if (srb->SrbFlags & SRB_FLAGS_NO_DATA_TRANSFER)
- {
- io_packet.data_buffer = NULL;
- io_packet.data_length = 0;
- }
- else
- {
- if ((irp->Flags & (IRP_READ_OPERATION | IRP_WRITE_OPERATION))
- && !(irp->Flags & IRP_PAGING_IO))
- {
- //
- // since these operations does not allign the buffer on page boundary
- // and some unknown traps in window NT, we have to copy to a buffer
- // we allocated
- io_packet.data_buffer = usb_alloc_mem(NonPagedPool, srb->DataTransferLength);
- if (irp->Flags & IRP_WRITE_OPERATION)
- {
- PULONG dest_buf, src_buf;
- ULONG i;
-
- dest_buf = (PULONG) io_packet.data_buffer;
- src_buf = (PULONG) srb->DataBuffer;
-
- if (src_buf && dest_buf)
- {
- for(i = 0; i < (srb->DataTransferLength >> 2); i++)
- {
- dest_buf[i] = src_buf[i];
- }
- }
- }
- }
- else
- io_packet.data_buffer = srb->DataBuffer;
-
- io_packet.data_length = srb->DataTransferLength;
- }
-
- if (io_packet.flags & IOP_FLAG_REQ_SENSE)
- {
- io_packet.sense_data = srb->SenseInfoBuffer;
- io_packet.sense_data_length = srb->SenseInfoBufferLength;
- }
-
- io_packet.pirp = irp;
-
- // do some conversions
- if (pdev_ext->pif_desc->bInterfaceSubClass == UMSS_SUBCLASS_SFF8070I)
- {
- if (umss_tsc_to_sff(&io_packet) == FALSE)
- {
- status = STATUS_DEVICE_PROTOCOL_ERROR;
-
- usb_dbg_print(DBGLVL_MAXIMUM,
- ("umss_process_srb(): error converting to sff proto, 0x%x\n", status));
- srb->SrbStatus = SRB_STATUS_ERROR;
- break;
- }
- }
-
- if (pdev_ext->pif_desc->bInterfaceProtocol == PROTOCOL_BULKONLY)
- {
- //
- // currently we support only transparent scsi command set
- //
- if (pdev_ext->pif_desc->bInterfaceSubClass == UMSS_SUBCLASS_SCSI_TCS ||
- pdev_ext->pif_desc->bInterfaceSubClass == UMSS_SUBCLASS_SFF8070I)
- status = umss_bulkonly_startio(pdev_ext, &io_packet);
- else
- status = STATUS_DEVICE_PROTOCOL_ERROR;
- }
- else if (pdev_ext->pif_desc->bInterfaceProtocol == PROTOCOL_CB
- || pdev_ext->pif_desc->bInterfaceProtocol == PROTOCOL_CBI)
- {
- status = umss_cbi_startio(pdev_ext, &io_packet);
- }
- else
- {
- status = STATUS_DEVICE_PROTOCOL_ERROR;
- }
-
- if (status != STATUS_PENDING && status != STATUS_SUCCESS)
- {
- // error occured
- usb_dbg_print(DBGLVL_MAXIMUM, ("umss_process_srb(): error sending request, 0x%x\n", status));
- srb->SrbStatus = SRB_STATUS_ERROR;
- }
- break;
- }
- case SRB_FUNCTION_CLAIM_DEVICE:
- {
- srb->DataBuffer = (PVOID) dev_obj;
- }
- case SRB_FUNCTION_SHUTDOWN:
- case SRB_FUNCTION_FLUSH:
- case SRB_FUNCTION_RESET_BUS:
- case SRB_FUNCTION_FLUSH_QUEUE:
- case SRB_FUNCTION_RELEASE_QUEUE:
- case SRB_FUNCTION_RELEASE_DEVICE:
- default:
- {
- // for usb flash disk, they are luxurious
-
- usb_dbg_print(DBGLVL_MAXIMUM, ("umss_process_srb(): current srb->Function=0x%x\n",
- srb->Function));
-
- status = STATUS_SUCCESS;
- srb->SrbStatus = SRB_STATUS_SUCCESS;
- break;
- }
- }
-
- usb_unlock_dev(pdev);
- pdev = NULL;
-
-ERROR_OUT:
- irp->IoStatus.Status = status;
- if (status != STATUS_PENDING)
- {
- IoStartNextPacket(dev_obj, FALSE);
- IoCompleteRequest(irp, IO_NO_INCREMENT);
- }
-
- //
- // UMSS_COMPLETE_START_IO( dev_obj, status, irp );
- //
- return status;
-}
-
-BOOLEAN
-umss_tsc_to_sff(PIO_PACKET io_packet)
-{
- if (io_packet == NULL)
- return FALSE;
-
- io_packet->cdb_length = 12;
- if (io_packet->cdb[0] == SCSIOP_MODE_SENSE)
- {
- io_packet->cdb[0] = 0x5a; // mode sense( 10 )
- io_packet->cdb[8] = io_packet->cdb[4];
- io_packet->cdb[4] = 0;
- if (io_packet->cdb[8] < 8)
- io_packet->cdb[8] = 8;
-
- io_packet->data_length = 8;
- return TRUE;
- }
- if (io_packet->cdb[0] == SCSIOP_REASSIGN_BLOCKS ||
- io_packet->cdb[0] == SCSIOP_RESERVE_UNIT || io_packet->cdb[0] == SCSIOP_RELEASE_UNIT)
- return FALSE;
-
- return TRUE;
-}
-
-VOID
-umss_fix_sff_result(PIO_PACKET io_packet, SCSI_REQUEST_BLOCK *srb)
-{
- PBYTE buf;
- if (io_packet->cdb[0] != 0x5a)
- return;
- // the following is not right since it has to be 0x3f, return all pages
- // if( io_packet->cdb[ 2 ] != 0 )
- // return;
- srb->DataTransferLength = 4;
- buf = io_packet->data_buffer;
- // convert the mode param to scsi II
- buf[0] = buf[1];
- buf[1] = buf[2];
- buf[2] = buf[3];
- buf[3] = 0;
- return;
-}
diff --git a/reactos/drivers/usb/nt4compat/usbdrv/umss.h b/reactos/drivers/usb/nt4compat/usbdrv/umss.h
deleted file mode 100644
index ca67e03f027..00000000000
--- a/reactos/drivers/usb/nt4compat/usbdrv/umss.h
+++ /dev/null
@@ -1,350 +0,0 @@
-#ifndef __UMSS_H__
-#define __UMSS_H__
-
-#define MAX_BULK_TRANSFER_LENGTH 0x100000
-
-#define PROTOCOL_CBI 0x00
-#define PROTOCOL_CB 0x01
-#define PROTOCOL_BULKONLY 0x50
-
-#define PROTOCOL_UNDEFINED 0xFF // Not in spec
-
-#define UMSS_SUBCLASS_RBC 0x01
-#define UMSS_SUBCLASS_SFF8020I 0X02
-#define UMSS_SUBCLASS_QIC157 0x03
-#define UMSS_SUBCLASS_UFI 0x04
-#define UMSS_SUBCLASS_SFF8070I 0x05
-#define UMSS_SUBCLASS_SCSI_TCS 0x06
-
-#define ACCEPT_DEVICE_SPECIFIC_COMMAND 0
-
-#define BULK_ONLY_MASS_STORAGE_RESET 0xFF
-#define BULK_ONLY_GET_MAX_LUN 0xFE
-
-#define CBW_SIGNATURE 0x43425355L
-#define CSW_SIGNATURE 0x53425355L
-#define CSW_OLYMPUS_SIGNATURE 0x55425355L
-
-#define CSW_STATUS_PASSED 0x00
-#define CSW_STATUS_FAILED 0x01
-#define CSW_STATUS_PHASE_ERROR 0x02
-
-#define IOCTL_UMSS_SUBMIT_CDB CTL_CODE( FILE_USB_DEV_TYPE, 4200, METHOD_BUFFERED, FILE_ANY_ACCESS )
-// for request with no other input and output
-// input buffer is a _USER_IO_PACKET and input_buffer_length is length of the _USER_IO_PACKET
-// output_buffer is NULL, and output_buffer_length is zero
-
-#define IOCTL_UMSS_SUBMIT_CDB_IN CTL_CODE( FILE_USB_DEV_TYPE, 4201, METHOD_IN_DIRECT, FILE_ANY_ACCESS )
-// for request to read in data
-// input_buffer is a _USER_IO_PACKET and input_buffer_length is length to the _USER_IO_PACKET
-// output_buffer is a buffer to receive the data from dev, and
-// output_buffer_length is the size of the buffer
-
-#define IOCTL_UMSS_SUBMIT_CDB_OUT CTL_CODE( FILE_USB_DEV_TYPE, 4202, METHOD_OUT_DIRECT, FILE_ANY_ACCESS )
-// for request to write data to device
-// input_buffer is a _USER_IO_PACKET and input_buffer_length is length to the _USER_IO_PACKET
-// output_buffer is data to send to the device, and
-// output_buffer_length is the size of the buffer
-
-#define IOCTL_REGISTER_DRIVER CTL_CODE( FILE_USB_DEV_TYPE, 4203, METHOD_BUFFERED, FILE_ANY_ACCESS )
-// input_buffer is a CLASS_DRV_REG_INFO, and input_buffer_length is equal to or greater than
-// sizeof( CLASS_DRV_REG_INFO ); the output_buffer is null and no output_buffer_length,
-// only the following fields in urb can be accessed, others must be zeroed.
-
-#define IOCTL_REVOKE_DRIVER CTL_CODE( FILE_USB_DEV_TYPE, 4204, METHOD_BUFFERED, FILE_ANY_ACCESS )
-// tell the umss driver to clear the information in the drivers registry
-// no other parameters
-
-#define IOCTL_UMSS_SUBMIT_SRB CTL_CODE( FILE_USB_DEV_TYPE, 4205, METHOD_BUFFERED, FILE_ANY_ACCESS )
-// irpStack->Parameters.Scsi.Srb points to an Srb structure and all the data buffer and buffer
-// size are stored in the srb
-
-
-#define IOCTL_UMSS_SET_FDO CTL_CODE( FILE_USB_DEV_TYPE, 4206, METHOD_BUFFERED, FILE_ANY_ACCESS )
-// input_buffer is a pointer to PDEVICE_OBJECT, and input_buffer_length should be
-// no less than sizeof( PDEVICE_OBJECT )
-// output buffer is NULL, and output_buffer_length is zero
-// if the deivce is accessable, the fdo is set, else, the fdo is not set and return
-// STATUS_DEVICE_DOES_NOT_EXIST
-
-#define SFF_FORMAT_UNIT 0x04
-#define SFF_INQUIRY 0x12
-#define SFF_MODE_SELECT 0x55
-#define SFF_MODE_SENSE 0x5a
-#define SFF_ALLOW_REMOVE 0x1e
-#define SFF_READ10 0x28
-#define SFF_READ12 0xa8
-#define SFF_READ_CAPACITY 0x25
-#define SFF_REQUEST_SENSEE 0x03
-#define SFF_SEEK 0x2b
-#define SFF_START_STOP 0x1b
-#define SFF_TUR 0x00
-#define SFF_VERIFY 0x2f
-#define SFF_WRITE10 0x2a
-#define SFF_WRITE12 0xaa
-#define SFF_READ_FMT_CAPACITY 0x23
-#define SFF_WRITE_VERIFY 0x2e
-
-#define MAX_CDB_LENGTH 0x10
-
-typedef struct _USER_IO_PACKET
-{
- UCHAR sub_class;
- UCHAR lun;
- UCHAR cdb_length;
- UCHAR cdb[ MAX_CDB_LENGTH ];
-
-} USER_IO_PACKET, *PUSER_IO_PACKET;
-
-//flags for IO_PACKET::flags
-#define IOP_FLAG_REQ_SENSE 0x80000000 // sense data would be fetched if error occurs
-#define IOP_FLAG_SRB_TRANSFER 0x40000000 // current tranfer is initiated by an srb request, the srb is held by the irp
-#define IOP_FLAG_SCSI_CTRL_TRANSFER 0x20000000 // current transfer is initiated by an scsi ioctrl request
-
-#define IOP_FLAG_DIR_IN USB_DIR_IN
-#define IOP_FLAG_STAGE_MASK 0x03
-#define IOP_FLAG_STAGE_NORMAL 0x00
-#define IOP_FLAG_STAGE_SENSE 0x01
-
-typedef struct _IO_PACKET
-{
- ULONG flags;
- UCHAR cdb_length;
- UCHAR cdb[ MAX_CDB_LENGTH ];
- UCHAR lun;
- PVOID data_buffer;
- ULONG data_length;
- PVOID sense_data;
- ULONG sense_data_length;
- PIRP pirp;
-
-} IO_PACKET, *PIO_PACKET;
-
-#pragma pack( 1 )
-
-typedef struct _COMMAND_BLOCK_WRAPPER
-{
- ULONG dCBWSignature;
- ULONG dCBWTag;
- ULONG dCBWDataTransferLength;
- UCHAR bmCBWFlags;
- UCHAR bCBWLun;
- UCHAR bCBWLength;
- UCHAR CBWCB[ MAX_CDB_LENGTH ];
-
-} COMMAND_BLOCK_WRAPPER, *PCOMMAND_BLOCK_WRAPPER;
-
-typedef struct _COMMAND_STATUS_WRAPPER
-{
- ULONG dCSWSignature;
- ULONG dCSWTag;
- ULONG dCSWDataResidue;
- UCHAR bCSWStatus;
-
-} COMMAND_STATUS_WRAPPER, *PCOMMAND_STATUS_WRAPPER;
-
-
-typedef struct _INTERRUPT_DATA_BLOCK
-{
- UCHAR bType;
- UCHAR bValue;
-
-} INTERRUPT_DATA_BLOCK, *PINTERRUPT_DATA_BLOCK;
-
-#pragma pack()
-
-#define UMSS_PNPMSG_STOP 0x01
-#define UMSS_PNPMSG_DISCONNECT 0x02
-
-typedef NTSTATUS ( *PCLASS_DRVR_PNP_DISP )( PDEVICE_OBJECT pdo, ULONG ctrl_code, PVOID context );
- // pdo is the device object umss created
-
-typedef PDEVICE_OBJECT ( *PCLASS_DRIVER_ADD_DEV )( PDRIVER_OBJECT fdo_drvr, PDEVICE_OBJECT pdo );
- // if the return value is not zero, it is a pointer to the
- // fdo sitting over the pdo of this driver. if it is null,
- // the add_device failed, and initialization process should
- // stall.
-
-typedef struct _CLASS_DRV_REGISTRY_INFO
-{
- // class driver will pass this structure to umss port
- // driver after loaded
- PDRIVER_OBJECT fdo_driver;
- PCLASS_DRIVER_ADD_DEV add_device;
- PCLASS_DRVR_PNP_DISP pnp_dispatch;
-
-} CLASS_DRV_REG_INFO, *PCLASS_DRV_REG_INFO;
-
-typedef struct _UMSS_PORT_DEVICE_EXTENSION
-{
- // this structure is the device extension for port dev_obj
- // it is used to has class driver pass CLASS_DRV_REG_INFO
- // to our umss driver.
- DEVEXT_HEADER dev_ext_hdr;
- PUSB_DRIVER pdriver;
-
-} UMSS_PORT_DEV_EXT, *PUMSS_PORT_DEV_EXT;
-
-typedef struct _UMSS_DRVR_EXTENSION
-{
- LIST_HEAD dev_list;
- FAST_MUTEX dev_list_mutex;
- UCHAR dev_count;
- CLASS_DRV_REG_INFO class_driver_info;
- PDEVICE_OBJECT port_dev_obj; // we use this obj as a connection point for class driver, its name usbPort0
-
-} UMSS_DRVR_EXTENSION, *PUMSS_DRVR_EXTENSION;
-
-#define UMSS_DEV_FLAG_IF_DEV 0x01
-#define UMSS_DEV_FLAG_OLYMPUS_DEV 0x02
-
-#define UMSS_OLYMPUS_VENDOR_ID 0x07b4
-
-typedef struct _UMSS_DEVICE_EXTENSION
-{
- //this structure is the device extension for dev_obj
- //created for the device.
- DEVEXT_HEADER dev_ext_hdr;
-
- ULONG flags;
- LIST_ENTRY dev_obj_link; // this link is used by the driver object to track the existing dev_objs
-
- PDEVICE_OBJECT pdo; // this is the pdo
- PDEVICE_OBJECT fdo; // driver object for the dev_obj
-
- DEV_HANDLE dev_handle; // handle to the usb_dev under
-
- PUCHAR desc_buf;
- UCHAR umss_dev_id; // used to build symbolic link
-
- PUSB_INTERFACE_DESC pif_desc;
- PUSB_ENDPOINT_DESC pout_endp_desc, pin_endp_desc, pint_endp_desc;
- UCHAR if_idx, out_endp_idx, in_endp_idx, int_endp_idx;
-
- struct _USB_DEV_MANAGER *dev_mgr;
-
- //working data
- COMMAND_BLOCK_WRAPPER cbw;
- union
- {
- INTERRUPT_DATA_BLOCK idb;
- COMMAND_STATUS_WRAPPER csw;
- };
-
- KEVENT sync_event; //for umss_sync_submit_urb
- KSPIN_LOCK dev_lock;
- IO_PACKET io_packet;
- BOOLEAN retry;
-
- PUSB_DRIVER pdriver; //used by umss_delete_device
- NTSTATUS reset_pipe_status;
-} UMSS_DEVICE_EXTENSION, *PUMSS_DEVICE_EXTENSION;
-
-// for device creation workitem
-typedef struct _UMSS_CREATE_DATA
-{
- DEV_HANDLE dev_handle;
- PUCHAR desc_buf;
- PUSB_DEV_MANAGER dev_mgr;
- PUSB_DRIVER pdriver;
-
-} UMSS_CREATE_DATA, *PUMSS_CREATE_DATA;
-
-// for reset pipe item
-//typedef void ( _stdcall *COMPLETION_HANDLER )( PVOID );
-typedef void ( *UMSS_WORKER_ROUTINE )( PVOID );
-
-typedef struct _UMSS_WORKER_PACKET
-{
- UMSS_WORKER_ROUTINE completion;
- PVOID context;
- PUSB_DEV_MANAGER dev_mgr;
- PVOID pdev;
-
-} UMSS_WORKER_PACKET, *PUMSS_WORKER_PACKET;
-
-BOOLEAN
-umss_driver_init(
-PUSB_DEV_MANAGER dev_mgr,
-PUSB_DRIVER pdriver
-);
-
-BOOLEAN
-umss_if_driver_init(
-PUSB_DEV_MANAGER dev_mgr,
-PUSB_DRIVER pdriver
-);
-
-BOOLEAN
-umss_driver_destroy(
-PUSB_DEV_MANAGER dev_mgr,
-PUSB_DRIVER pdriver
-);
-
-#define umss_if_driver_destroy umss_driver_destroy
-
-BOOLEAN
-umss_if_driver_destroy(
-PUSB_DEV_MANAGER dev_mgr,
-PUSB_DRIVER pdriver
-);
-
-VOID
-umss_complete_request(
-PUMSS_DEVICE_EXTENSION pdev_ext,
-NTSTATUS status
-);
-
-NTSTATUS
-umss_reset_pipe(
-PUMSS_DEVICE_EXTENSION pdev_ext,
-DEV_HANDLE endp_handle
-);
-
-PVOID
-umss_get_buffer(
-PUMSS_DEVICE_EXTENSION pdev_ext,
-ULONG* buf_length
-);
-
-NTSTATUS
-umss_bulk_transfer(
-IN PUMSS_DEVICE_EXTENSION pdev_ext,
-IN UCHAR trans_dir,
-IN PVOID buf,
-IN ULONG buf_length,
-IN PURBCOMPLETION completion
-);
-
-BOOLEAN
-umss_schedule_workitem(
-PVOID context,
-UMSS_WORKER_ROUTINE completion,
-PUSB_DEV_MANAGER dev_mgr,
-DEV_HANDLE dev_handle
-);
-
-NTSTATUS
-umss_bulkonly_startio(
-IN PUMSS_DEVICE_EXTENSION pdev_ext,
-IN PIO_PACKET io_packet
-);
-
-NTSTATUS
-umss_cbi_startio(
-IN PUMSS_DEVICE_EXTENSION pdev_ext,
-IN PIO_PACKET io_packet
-);
-
-#define UMSS_FORGE_GOOD_SENSE( sense_BUF ) \
-{\
- int i;\
- PUCHAR buf = ( PUCHAR )( sense_BUF ); \
- for( i = 0; i < 18; i++)\
- {\
- buf[i] = 0;\
- }\
- buf[7] = 10;\
-}
-
-#endif
diff --git a/reactos/drivers/usb/nt4compat/usbdrv/usb.c b/reactos/drivers/usb/nt4compat/usbdrv/usb.c
deleted file mode 100644
index 65cddd0d7f0..00000000000
--- a/reactos/drivers/usb/nt4compat/usbdrv/usb.c
+++ /dev/null
@@ -1,1343 +0,0 @@
-/**
- * usb.c - USB driver stack project for Windows NT 4.0
- *
- * Copyright (c) 2002-2004 Zhiming mypublic99@yahoo.com
- *
- * This program/include file is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program/include file is distributed in the hope that it will be
- * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
- * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program (in the main directory of the distribution, the file
- * COPYING); if not, write to the Free Software Foundation,Inc., 59 Temple
- * Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "usbdriver.h"
-
-LONG g_alloc_cnt = 0;
-ULONG cpu_clock_freq = 0;
-
-NTSTATUS usb_get_descriptor(PUSB_DEV pdev, PURB purb);
-VOID usb_set_interface_completion(PURB purb, PVOID context);
-NTSTATUS usb_set_interface(PURB purb);
-
-PVOID
-usb_alloc_mem(POOL_TYPE pool_type, LONG size)
-{
- PVOID ret;
- g_alloc_cnt++;
- ret = ExAllocatePool(pool_type, size);
- usb_dbg_print(DBGLVL_ULTRA, ("usb_alloc_mem(): alloced=0x%x\n", g_alloc_cnt));
- return ret;
-}
-
-VOID
-usb_free_mem(PVOID pbuf)
-{
- g_alloc_cnt--;
- usb_dbg_print(DBGLVL_ULTRA, ("usb_free_mem(): alloced=0x%x\n", g_alloc_cnt));
- ExFreePool(pbuf);
-}
-
-VOID usb_config_dev_completion(PURB purb, PVOID context);
-
-//shamelessly pasted from linux's usb.c
-LONG
-usb_calc_bus_time(LONG speed, LONG input_dir, LONG is_iso, LONG byte_count)
-{
- LONG tmp;
-
- switch (speed & 0x3) /* no isoc. here */
- {
- case USB_SPEED_LOW:
- {
- if (input_dir)
- {
- tmp = (67667L * (31L + 10L * bit_time(byte_count))) / 1000L;
- return (64060L + (2 * BW_HUB_LS_SETUP) + BW_HOST_DELAY + tmp);
- }
- else
- {
- tmp = (66700L * (31L + 10L * bit_time(byte_count))) / 1000L;
- return (64107L + (2 * BW_HUB_LS_SETUP) + BW_HOST_DELAY + tmp);
- }
- break;
- }
- /* for full-speed: */
- case USB_SPEED_FULL:
- {
- if (!is_iso) /* Input or Output */
- {
- tmp = (8354L * (31L + 10L * bit_time(byte_count))) / 1000L;
- return (9107L + BW_HOST_DELAY + tmp);
- } /* end not Isoc */
-
- /* for isoc: */
-
- tmp = (8354L * (31L + 10L * bit_time(byte_count))) / 1000L;
- return (((input_dir) ? 7268L : 6265L) + BW_HOST_DELAY + tmp);
- }
- case USB_SPEED_HIGH:
- {
- if (!is_iso)
- {
- tmp = (999 + 926520 + 2083 * ((LONG) ((19 + 7 * 8 * byte_count) / 6))) / 1000;
- }
- else
- {
- tmp = (999 + 633232 + 2083 * ((LONG) ((19 + 7 * 8 * byte_count) / 6))) / 1000;
- }
- return tmp + USB2_HOST_DELAY;
- }
- default:
- {
- break;
- }
- }
- return 125001;
-}
-
-//
-// if the dev is not in the list, return value is not success and the pointer is nulled
-// if the dev is in the list but zomb, return value is error code and the pointer is the dev( no ref_count guarded )
-// if the dev is alive and in the list, return is success and the pointer is the dev.
-// one must be aware of what his doing before he uses the ppdev
-//
-NTSTATUS
-usb_query_and_lock_dev(PUSB_DEV_MANAGER dev_mgr, DEV_HANDLE dev_handle, PUSB_DEV * ppdev)
-{
- int i;
- PLIST_ENTRY pthis, pnext;
- PUSB_DEV pdev = NULL;
- BOOLEAN valid_dev;
-
- USE_NON_PENDING_IRQL;
-
- *ppdev = NULL;
-
- if (dev_mgr == NULL || dev_handle == 0)
- return STATUS_INVALID_PARAMETER;
-
- i = dev_id_from_handle(dev_handle);
-
- KeAcquireSpinLock(&dev_mgr->dev_list_lock, &old_irql);
- ListFirst(&dev_mgr->dev_list, pthis);
-
- while (pthis)
- {
- pdev = (PUSB_DEV) pthis;
- if (pdev->dev_id != (ULONG) i)
- {
- ListNext(&dev_mgr->dev_list, pthis, pnext);
- pthis = pnext;
- continue;
- }
- else
- break;
- }
- if (pthis == NULL)
- {
- //no such device
- KeReleaseSpinLock(&dev_mgr->dev_list_lock, old_irql);
- return STATUS_INVALID_PARAMETER;
- }
-
- valid_dev = TRUE;
-
- lock_dev(pdev, TRUE);
-
- if (dev_state(pdev) == USB_DEV_STATE_ZOMB)
- {
- valid_dev = FALSE;
- }
- else
- pdev->ref_count++; //guard the dev by increasing the ref count
-
- unlock_dev(pdev, TRUE);
-
- KeReleaseSpinLock(&dev_mgr->dev_list_lock, old_irql);
-
- *ppdev = pdev;
-
- if (!valid_dev)
- return STATUS_DEVICE_DOES_NOT_EXIST;
-
- return STATUS_SUCCESS;
-
-}
-
-NTSTATUS
-usb_unlock_dev(PUSB_DEV dev)
-{
- USE_BASIC_NON_PENDING_IRQL;
-
- if (dev == NULL)
- return STATUS_INVALID_PARAMETER;
-
- lock_dev(dev, FALSE);
- dev->ref_count--;
- if (dev->ref_count < 0)
- dev->ref_count = 0;
- unlock_dev(dev, FALSE);
- return STATUS_SUCCESS;
-}
-
-NTSTATUS
-usb_reset_pipe_ex(PUSB_DEV_MANAGER dev_mgr,
- DEV_HANDLE endp_handle, //endp handle to reset
- PURBCOMPLETION reset_completion, //note: this reset completion has no right to delete the urb, that is only for reference
- PVOID param)
-{
- NTSTATUS status;
- PUSB_DEV pdev;
- LONG if_idx, endp_idx;
- PUSB_ENDPOINT pendp;
- USE_BASIC_NON_PENDING_IRQL;
-
- if (dev_mgr == NULL)
- return STATUS_INVALID_PARAMETER;
-
- status = usb_query_and_lock_dev(dev_mgr, (endp_handle & 0xffff0000), &pdev);
- if (status != STATUS_SUCCESS)
- return STATUS_UNSUCCESSFUL;
-
- lock_dev(pdev, FALSE);
- if (dev_state(pdev) == USB_DEV_STATE_ZOMB)
- {
- status = STATUS_UNSUCCESSFUL;
- goto LBL_OUT;
- }
-
- if_idx = if_idx_from_handle(endp_handle);
- endp_idx = endp_idx_from_handle(endp_handle);
-
- if (default_endp_handle(endp_handle))
- {
- status = STATUS_UNSUCCESSFUL;
- goto LBL_OUT;
- }
-
- if (dev_state(pdev) < USB_DEV_STATE_CONFIGURED)
- {
- status = STATUS_DEVICE_NOT_READY;
- goto LBL_OUT;
- }
-
- pendp = &pdev->usb_config->interf[if_idx].endp[endp_idx];
- unlock_dev(pdev, FALSE) status = usb_reset_pipe(pdev, pendp, reset_completion, param);
- usb_unlock_dev(pdev);
- return status;
-
-LBL_OUT:
- unlock_dev(pdev, FALSE);
- usb_unlock_dev(pdev);
-
- return status;
-}
-
-// caller must guarantee the pdev exist before the routine exit
-NTSTATUS
-usb_reset_pipe(PUSB_DEV pdev, PUSB_ENDPOINT pendp, PURBCOMPLETION client_reset_pipe_completion, PVOID param)
-{
-
- PHCD hcd;
- PURB purb;
- BYTE endp_addr;
- NTSTATUS status;
- DEV_HANDLE dev_handle;
-
- USE_BASIC_NON_PENDING_IRQL;
-
- if (pdev == NULL || pendp == NULL)
- return STATUS_INVALID_PARAMETER;
-
- lock_dev(pdev, FALSE);
- if (dev_state(pdev) == USB_DEV_STATE_ZOMB)
- {
- unlock_dev(pdev, FALSE);
- return STATUS_DEVICE_DOES_NOT_EXIST;
- }
-
- hcd = pdev->hcd;
- endp_addr = pendp->pusb_endp_desc->bEndpointAddress;
- dev_handle = usb_make_handle(pdev->dev_id, 0, 0);
- unlock_dev(pdev, FALSE);
-
- purb = (PURB) usb_alloc_mem(NonPagedPool, sizeof(URB) + sizeof(PIRP));
-
- if (purb == NULL)
- return STATUS_NO_MEMORY;
-
- UsbBuildResetPipeRequest(purb,
- dev_handle,
- endp_addr,
- usb_reset_pipe_completion,
- pendp,
- (LONG)client_reset_pipe_completion);
-
- *((PULONG)&purb[1]) = (ULONG)param;
-
- if ((status = hcd->hcd_submit_urb(hcd, pdev, &pdev->default_endp, purb)) != STATUS_PENDING)
- {
- usb_free_mem(purb);
- purb = NULL;
- }
- return status;
-}
-
-VOID
-usb_reset_pipe_completion(PURB purb, PVOID context)
-{
- PUSB_DEV pdev;
- PUSB_ENDPOINT pendp;
-
- USE_BASIC_NON_PENDING_IRQL;
-
- if (purb == NULL || context == NULL)
- return;
-
- pdev = purb->pdev;
- pendp = (PUSB_ENDPOINT) context;
-
- lock_dev(pdev, TRUE);
- if (dev_state(pdev) == USB_DEV_STATE_ZOMB)
- {
- goto LBL_OUT;
- }
-
- if (usb_error(purb->status))
- {
- goto LBL_OUT;
- }
- //clear stall
- pendp->flags &= ~USB_ENDP_FLAG_STAT_MASK;
-
- //reset toggle endp_type
- if ((pendp->pusb_endp_desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_BULK ||
- (pendp->pusb_endp_desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT)
- {
- pendp->flags &= ~USB_ENDP_FLAG_DATATOGGLE;
- }
-
-LBL_OUT:
- unlock_dev(pdev, TRUE);
-
- if (purb->reference)
- ((PURBCOMPLETION) purb->reference) (purb, (PVOID) (*((PULONG) & purb[1])));
-
- usb_free_mem(purb);
- purb = NULL;
- return;
-
-}
-
-void
-usb_reset_pipe_from_dispatch_completion(PURB purb, PVOID param)
-{
- PURB pclient_urb;
- if (purb == NULL || param == NULL)
- TRAP();
- pclient_urb = (PURB) param;
- pclient_urb->status = purb->status;
-
- if (pclient_urb->completion)
- {
- pclient_urb->completion(pclient_urb, pclient_urb->context);
- }
- // the urb can not be freed here because it is owned by the reset
- // pipe completion
- return;
-}
-
-//used to check descriptor validity
-BOOLEAN
-is_header_match(PUCHAR pbuf, ULONG type)
-{
- BOOLEAN ret;
- PUSB_DESC_HEADER phdr;
- phdr = (PUSB_DESC_HEADER) pbuf;
-
- switch (type)
- {
- case USB_DT_DEVICE:
- {
- ret = (phdr->bLength == sizeof(USB_DEVICE_DESC) && phdr->bDescriptorType == USB_DT_DEVICE);
- break;
- }
- case USB_DT_CONFIG:
- {
- ret = (phdr->bLength == sizeof(USB_CONFIGURATION_DESC) && phdr->bDescriptorType == USB_DT_CONFIG);
- break;
- }
- case USB_DT_INTERFACE:
- {
- ret = (phdr->bLength == sizeof(USB_INTERFACE_DESC) && phdr->bDescriptorType == USB_DT_INTERFACE);
- break;
- }
- case USB_DT_ENDPOINT:
- {
- ret = (phdr->bLength == sizeof(USB_ENDPOINT_DESC) && phdr->bDescriptorType == USB_DT_ENDPOINT);
- break;
- }
- default:
- ret = FALSE;
- }
- return ret;
-}
-
-BOOLEAN
-usb_skip_endp_desc(PBYTE * pbUF, LONG n)
-{
- if (is_header_match(*pbUF, USB_DT_ENDPOINT))
- {
- (*pbUF) += sizeof(USB_ENDPOINT_DESC) * n;
- return TRUE;
- }
- return FALSE;
-}
-
-BOOLEAN
-usb_skip_if_desc(PBYTE * pBUF)
-{
- BOOLEAN ret;
- PUSB_INTERFACE_DESC pif_desc = (PUSB_INTERFACE_DESC) * pBUF;
- LONG endp_count;
- ret = is_header_match((PBYTE) * pBUF, USB_DT_INTERFACE);
- if (ret == TRUE)
- {
- endp_count = pif_desc->bNumEndpoints;
- if (endp_count < MAX_ENDPS_PER_IF)
- {
- pif_desc++;
- ret = usb_skip_endp_desc((PBYTE *) & pif_desc, endp_count);
- if (ret)
- *(pBUF) = (PBYTE) pif_desc;
- }
- else
- ret = FALSE;
- }
- return ret;
-}
-
-BOOLEAN
-usb_skip_if_and_altif(PUCHAR * pdesc_BUF)
-{
- BOOLEAN ret;
- PUSB_INTERFACE_DESC pif_desc1 = (PUSB_INTERFACE_DESC) * pdesc_BUF;
- ret = is_header_match(*pdesc_BUF, USB_DT_INTERFACE);
- if (ret == TRUE)
- {
- if (pif_desc1->bAlternateSetting == 0)
- ret = usb_skip_if_desc((PUCHAR *) & pif_desc1);
- else
- //no default interface
- ret = FALSE;
-
- while (ret && pif_desc1->bAlternateSetting != 0)
- ret = usb_skip_if_desc((PUCHAR *) & pif_desc1);
- }
- if (ret)
- *pdesc_BUF = (PUCHAR) pif_desc1;
-
- return ret;
-}
-
-BOOLEAN
-usb_skip_one_config(PUCHAR *pconfig_desc_BUF)
-{
- LONG if_count, i;
- BOOLEAN ret;
- PUSB_CONFIGURATION_DESC pcfg_DESC = (PUSB_CONFIGURATION_DESC) * pconfig_desc_BUF;
- PUSB_INTERFACE_DESC pif_desc2 = (PUSB_INTERFACE_DESC) & pcfg_DESC[1];
-
- ret = is_header_match((PUCHAR) pcfg_DESC, USB_DT_CONFIG);
- if (ret)
- *pconfig_desc_BUF = &((BYTE *) pcfg_DESC)[pcfg_DESC->wTotalLength];
- return ret;
-
- ret = is_header_match((PUCHAR) pcfg_DESC, USB_DT_CONFIG)
- && is_header_match((PUCHAR) pif_desc2, USB_DT_INTERFACE);
-
- if (ret)
- {
- if_count = pcfg_DESC->bNumInterfaces;
- if (if_count < MAX_INTERFACES_PER_CONFIG)
- {
- for(i = 0; i < if_count; i++)
- {
- ret = usb_skip_if_and_altif((PUCHAR *) & pif_desc2);
- if (ret == FALSE)
- break;
- }
- if (ret)
- *pconfig_desc_BUF = (PUCHAR) pif_desc2;
- }
- }
- return ret;
-}
-
-PUSB_CONFIGURATION_DESC
-usb_find_config_desc_by_idx(PUCHAR pbuf, LONG idx, LONG cfg_count)
-{
- LONG i;
- BOOLEAN ret;
- PUSB_CONFIGURATION_DESC pcfg_desc = (PUSB_CONFIGURATION_DESC) pbuf;
- if (pcfg_desc == NULL)
- return NULL;
-
- if (cfg_count > MAX_CONFIGS_PER_DEV)
- return NULL;
-
- if (idx > cfg_count)
- return NULL;
-
- if (idx == 0)
- return pcfg_desc;
-
- for(i = 0; i < idx - 1; i++)
- {
- ret = usb_skip_one_config((PBYTE *) & pcfg_desc);
- if (ret == FALSE)
- return NULL;
- }
- return pcfg_desc;
-}
-
-PUSB_CONFIGURATION_DESC
-usb_find_config_desc_by_val(PBYTE pbuf, LONG val, LONG cfg_count)
-{
- LONG i;
- BOOLEAN ret;
- PUSB_CONFIGURATION_DESC pcfg_desc = (PUSB_CONFIGURATION_DESC) pbuf;
- if (pcfg_desc == NULL)
- return NULL;
-
- if (cfg_count > MAX_CONFIGS_PER_DEV)
- return NULL;
-
- for(i = 0; i < cfg_count; i++)
- {
- if (pcfg_desc->bConfigurationValue == val)
- return pcfg_desc;
-
- ret = usb_skip_one_config((PBYTE *) & pcfg_desc);
- if (ret == FALSE)
- return NULL;
- }
-
- return NULL;
-}
-
-#define if_from_handle( handle ) ( ( handle & 0xff00 ) >> 8 )
-
-NTSTATUS
-usb_submit_config_urb(PURB purb)
-{
- PUSB_DEV pdev;
- PUSB_DEV_MANAGER dev_mgr;
- PUSB_ENDPOINT pendp;
- PURB purb1;
- PUSB_CTRL_SETUP_PACKET psetup;
- NTSTATUS status;
- PHCD hcd;
-
- USE_BASIC_NON_PENDING_IRQL;
-
- if (purb == NULL)
- return STATUS_INVALID_PARAMETER;
-
- pdev = purb->pdev;
- pendp = purb->pendp;
-
- lock_dev(pdev, FALSE);
-
- dev_mgr = dev_mgr_from_dev(pdev);
- hcd = pdev->hcd;
-
- if (dev_state(pdev) == USB_DEV_STATE_ZOMB)
- {
- status = STATUS_DEVICE_DOES_NOT_EXIST;
- goto LBL_OUT;
- }
-
- if (dev_state(pdev) == USB_DEV_STATE_FIRST_CONFIG || dev_state(pdev) == USB_DEV_STATE_RECONFIG)
- {
- //outstanding request of set configuration exists in process
- status = STATUS_UNSUCCESSFUL;
- goto LBL_OUT;
- }
-
- psetup = (PUSB_CTRL_SETUP_PACKET) purb->setup_packet;
-
- if (dev_state(pdev) == USB_DEV_STATE_CONFIGURED
- && pdev->usb_config->pusb_config_desc->bConfigurationValue == (BYTE) psetup->wValue)
- {
- //already the current config
- status = STATUS_SUCCESS;
- goto LBL_OUT;
- }
-
-
- if (dev_state(pdev) == USB_DEV_STATE_CONFIGURED)
- {
- // not support re-configuration yet
- status = STATUS_NOT_SUPPORTED;
- goto LBL_OUT;
- }
-
- psetup = (PUSB_CTRL_SETUP_PACKET) purb->setup_packet;
- purb1 = usb_alloc_mem(NonPagedPool, sizeof(URB));
- if (purb1 == NULL)
- {
- status = STATUS_NO_MEMORY;
- goto LBL_OUT;
- }
-
- UsbBuildSelectConfigurationRequest(purb1,
- usb_make_handle(pdev->dev_id, 0, 0) | 0xffff,
- psetup->wValue, usb_config_dev_completion, 0, ((ULONG) purb));
- purb1->pdev = pdev;
- purb1->pendp = pendp;
-
- //change the dev state
- pdev->flags &= ~USB_DEV_STATE_MASK;
- pdev->flags |= USB_DEV_STATE_FIRST_CONFIG;
-
- unlock_dev(pdev, FALSE);
-
- status = hcd->hcd_submit_urb(hcd, pdev, pendp, purb1);
- if (status != STATUS_PENDING)
- {
- usb_free_mem(purb1);
- purb1 = NULL;
- }
- return status;
-
- LBL_OUT:
- unlock_dev(pdev, FALSE);
- return status;
-}
-
-
-NTSTATUS
-usb_submit_urb(PUSB_DEV_MANAGER dev_mgr, PURB purb)
-{
- NTSTATUS status;
- PUSB_DEV pdev;
- LONG if_idx, endp_idx;
- DEV_HANDLE endp_handle;
- PUSB_CTRL_SETUP_PACKET psetup;
- PUSB_ENDPOINT pendp;
-
- PHCD hcd;
- USE_BASIC_NON_PENDING_IRQL;
-
- if (purb == NULL || dev_mgr == NULL)
- return STATUS_INVALID_PARAMETER;
-
- endp_handle = purb->endp_handle;
-
- if (endp_handle == 0)
- return STATUS_INVALID_PARAMETER;
-
- status = usb_query_and_lock_dev(dev_mgr, endp_handle, &pdev);
- if (status != STATUS_SUCCESS)
- {
- return status;
- }
-
- if_idx = if_idx_from_handle(endp_handle);
- endp_idx = endp_idx_from_handle(endp_handle);
-
- lock_dev(pdev, FALSE);
- if (dev_state(pdev) == USB_DEV_STATE_ZOMB)
- {
- unlock_dev(pdev, FALSE);
- status = STATUS_DEVICE_DOES_NOT_EXIST;
- goto LBL_OUT;
- }
-
- if (dev_state(pdev) < USB_DEV_STATE_ADDRESSED)
- {
- unlock_dev(pdev, FALSE);
- status = STATUS_DEVICE_NOT_READY;
- goto LBL_OUT;
- }
-
- dev_mgr = dev_mgr_from_dev(pdev);
- hcd = pdev->hcd;
-
- if (default_endp_handle(endp_handle))
- {
- //default endp
- pendp = &pdev->default_endp;
- }
- else if (if_idx >= MAX_INTERFACES_PER_CONFIG || endp_idx >= MAX_ENDPS_PER_IF)
- {
- status = STATUS_INVALID_PARAMETER;
- unlock_dev(pdev, FALSE);
- goto LBL_OUT;
- }
- else
- {
- if (dev_state(pdev) < USB_DEV_STATE_CONFIGURED)
- {
- status = STATUS_DEVICE_NOT_READY;
- unlock_dev(pdev, FALSE);
- goto LBL_OUT;
- }
- pendp = &pdev->usb_config->interf[if_idx].endp[endp_idx];
-
- }
-
- purb->pdev = pdev;
- purb->pendp = pendp;
-
- //for default endpoint we have some special process
- if (default_endp_handle(endp_handle))
- {
- psetup = (PUSB_CTRL_SETUP_PACKET) purb->setup_packet;
- if (psetup->bmRequestType == 0 && psetup->bRequest == USB_REQ_SET_CONFIGURATION)
- {
- unlock_dev(pdev, FALSE);
- status = usb_submit_config_urb(purb);
- goto LBL_OUT;
- }
- else if (psetup->bmRequestType == 1 && psetup->bRequest == USB_REQ_SET_INTERFACE)
- {
- unlock_dev(pdev, FALSE);
- // status = STATUS_NOT_SUPPORTED;
- status = usb_set_interface(purb);
- goto LBL_OUT;
- }
- else if (psetup->bmRequestType == 0x80 && psetup->bRequest == USB_REQ_GET_DESCRIPTOR)
- {
- if ((psetup->wValue >> 8) == USB_DT_CONFIG || (psetup->wValue >> 8) == USB_DT_DEVICE)
- {
- unlock_dev(pdev, FALSE);
- status = usb_get_descriptor(pdev, purb);
- goto LBL_OUT;
-
- //get the descriptor directly
- //status = hcd->hcd_submit_urb( hcd, pdev, purb->pendp, purb );
- //goto LBL_OUT;
- }
- }
- else if (psetup->bmRequestType == 0x02 && psetup->bRequest == USB_REQ_CLEAR_FEATURE && psetup->wValue == 0) //reset pipe
- {
- ULONG endp_addr;
- BOOLEAN found;
- endp_addr = psetup->wIndex;
- if ((endp_addr & 0xf) == 0)
- {
- unlock_dev(pdev, FALSE);
- status = STATUS_INVALID_PARAMETER;
- goto LBL_OUT;
- }
-
- // search for the endp by the endp addr in the wIndex
- found = FALSE;
- for(if_idx = 0; if_idx < pdev->usb_config->if_count; if_idx++)
- {
- for(endp_idx = 0; endp_idx < 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->bEndpointAddress == endp_addr)
- {
- found = TRUE;
- break;
- }
- }
- if (found == TRUE)
- break;
- }
- if (found)
- endp_handle = usb_make_handle(pdev->dev_id, if_idx, endp_idx);
- else
- {
- unlock_dev(pdev, FALSE);
- status = STATUS_INVALID_PARAMETER;
- goto LBL_OUT;
- }
- unlock_dev(pdev, FALSE);
- status = usb_reset_pipe_ex(dev_mgr, endp_handle, usb_reset_pipe_from_dispatch_completion, purb);
-
- goto LBL_OUT;
- }
- }
-
- unlock_dev(pdev, FALSE);
- status = hcd->hcd_submit_urb(hcd, pdev, purb->pendp, purb);
-
-LBL_OUT:
- usb_unlock_dev(pdev);
- return status;
-}
-
-void
-usb_config_dev_completion(PURB purb, PVOID context)
-{
- PURB puser_urb;
- PUSB_DEV pdev;
- PUSB_ENDPOINT pendp;
- PUSB_CTRL_SETUP_PACKET psetup;
- ULONG config_val;
- NTSTATUS status;
-
- USE_BASIC_NON_PENDING_IRQL;
-
- UNREFERENCED_PARAMETER(context);
-
- if (purb == NULL)
- {
- return;
- }
- pdev = purb->pdev;
- pendp = purb->pendp;
-
- if (pdev == NULL)
- return;
-
- if (purb->reference != 0)
- puser_urb = (PURB) purb->reference;
- else
- puser_urb = NULL;
-
- lock_dev(pdev, TRUE);
-
- if (puser_urb)
- puser_urb->status = purb->status;
-
- if (purb->status != STATUS_SUCCESS)
- {
- if (dev_state(pdev) == USB_DEV_STATE_ZOMB)
- {
- goto LBL_OUT;
- }
-
- if (dev_state(pdev) == USB_DEV_STATE_FIRST_CONFIG)
- {
- pdev->flags &= ~USB_DEV_STATE_MASK;
- pdev->flags |= USB_DEV_STATE_ADDRESSED;
- }
- else if (dev_state(pdev) == USB_DEV_STATE_RECONFIG)
- {
- pdev->flags &= ~USB_DEV_STATE_MASK;
- pdev->flags |= USB_DEV_STATE_CONFIGURED;
-
- }
- goto LBL_OUT;
- }
- // now let's construct usb_config
- if (!pdev->usb_config)
- {
- psetup = (PUSB_CTRL_SETUP_PACKET) purb->setup_packet;
- config_val = psetup->wValue;
- status = dev_mgr_build_usb_config(pdev,
- &pdev->desc_buf[sizeof(USB_DEVICE_DESC)],
- config_val, pdev->pusb_dev_desc->bNumConfigurations);
- if (status != STATUS_SUCCESS)
- {
- pdev->flags &= ~USB_DEV_STATE_MASK;
- pdev->flags |= USB_DEV_STATE_ADDRESSED;
- goto LBL_OUT;
- }
- pdev->flags &= ~USB_DEV_STATE_MASK;
- pdev->flags |= USB_DEV_STATE_CONFIGURED;
- //this usb dev represents physical dev
- if (pdev->pusb_dev_desc->bDeviceClass == USB_CLASS_HUB && pdev->pusb_dev_desc->bDeviceSubClass == 0)
- {
- pdev->flags &= ~USB_DEV_CLASS_MASK;
- pdev->flags |= USB_DEV_CLASS_HUB;
- }
- else if (pdev->pusb_dev_desc->bDeviceClass == USB_CLASS_MASS_STORAGE
- && pdev->pusb_dev_desc->bDeviceSubClass == 0)
- {
- pdev->flags &= ~USB_DEV_CLASS_MASK;
- pdev->flags |= USB_DEV_CLASS_MASSSTOR;
- }
- else
- {
- pdev->flags &= ~USB_DEV_CLASS_MASK;
- pdev->flags |= USB_DEV_CLASS_SCANNER;
- }
- }
- else
- {
- //not supported
- puser_urb->status = STATUS_NOT_SUPPORTED;
- pdev->flags &= ~USB_DEV_STATE_MASK;
- pdev->flags |= USB_DEV_STATE_CONFIGURED;
- }
-
-LBL_OUT:
- unlock_dev(pdev, TRUE);
- usb_free_mem(purb);
- if (puser_urb && puser_urb->completion)
- puser_urb->completion(puser_urb, puser_urb->context);
-
- return;
-}
-
-NTSTATUS
-usb_get_descriptor(PUSB_DEV pdev, PURB purb)
-{
- PUSB_CTRL_SETUP_PACKET psetup;
- LONG idx, size, count, i;
- PBYTE buf;
- PUSB_CONFIGURATION_DESC pcfg_desc1;
-
- USE_BASIC_NON_PENDING_IRQL;
-
- if (pdev == NULL || purb == NULL)
- return STATUS_INVALID_PARAMETER;
-
- if (purb->data_buffer == NULL || purb->data_length == 0)
- {
- return purb->status = STATUS_INVALID_PARAMETER;
- }
-
- lock_dev(pdev, FALSE);
- psetup = (PUSB_CTRL_SETUP_PACKET) purb->setup_packet;
- if (pdev->desc_buf == NULL)
- {
- purb->status = STATUS_DEVICE_NOT_READY;
- goto LBL_OUT;
- }
-
- if ((psetup->wValue >> 8) == USB_DT_CONFIG)
- {
- idx = (psetup->wValue & 0xff);
-
- count = pdev->pusb_dev_desc->bNumConfigurations;
-
- if (idx >= count)
- {
- purb->status = STATUS_INVALID_PARAMETER;
- goto LBL_OUT;
- }
- buf = &pdev->desc_buf[sizeof(USB_DEVICE_DESC)];
- pcfg_desc1 = usb_find_config_desc_by_idx(buf, idx, count);
- if (pcfg_desc1 == NULL)
- {
- purb->status = STATUS_UNSUCCESSFUL;
- goto LBL_OUT;
- }
-
- size = pcfg_desc1->wTotalLength;
- size = size > purb->data_length ? purb->data_length : size;
- for(i = 0; i < size; i++)
- {
- purb->data_buffer[i] = ((PBYTE) pcfg_desc1)[i];
- }
- purb->status = STATUS_SUCCESS;
- goto LBL_OUT;
-
- }
- else if ((psetup->wValue >> 8) == USB_DT_DEVICE)
- {
- size = purb->data_length > sizeof(USB_DEVICE_DESC) ? sizeof(USB_DEVICE_DESC) : purb->data_length;
-
- for(i = 0; i < size; i++)
- {
- purb->data_buffer[i] = ((PBYTE) pdev->pusb_dev_desc)[i];
- }
- purb->status = STATUS_SUCCESS;
- }
-
-LBL_OUT:
- unlock_dev(pdev, FALSE);
- return purb->status;
-}
-
-LONG
-usb_count_list(PLIST_HEAD list_head)
-{
- LONG count;
- PLIST_ENTRY pthis, pnext;
-
- if (list_head == NULL)
- return 0;
-
- count = 0;
- ListFirst(list_head, pthis);
-
- while (pthis)
- {
- ListNext(list_head, pthis, pnext);
- pthis = pnext;
- count++;
- }
- return count;
-}
-
-// checks if processor supports Time Stamp Counter
-__inline BOOLEAN
-usb_query_clicks(PLARGE_INTEGER clicks)
-{
- BOOLEAN ret_val = FALSE;
- int cpu_info[4];
- //so we have to use intel's cpu???
-
-#if defined(_M_IX86) || defined(_M_AMD64)
- __cpuid(cpu_info, 1);
- if (cpu_info[3] & 0x10) // Time Stamp Counter (TSC) bit
- {
- clicks->QuadPart = __rdtsc();
- ret_val = TRUE;
- }
-#endif
- return ret_val;
-}
-
-VOID
-usb_wait_ms_dpc(ULONG ms)
-{
- LARGE_INTEGER Interval;
- if (ms <= 0)
- return;
-
- Interval.QuadPart = -ms * 10000;
- KeDelayExecutionThread(KernelMode, FALSE, &Interval);
-}
-
-
-VOID
-usb_wait_us_dpc(ULONG us)
-{
- LARGE_INTEGER Interval;
- if (us <= 0)
- return;
-
- Interval.QuadPart = -us;
- KeDelayExecutionThread(KernelMode, FALSE, &Interval);
-}
-
-VOID
-usb_cal_cpu_freq()
-{
- LARGE_INTEGER tick1, tick2;
- LONG i;
- // interval.QuadPart = -40 * 1000 * 1000;
-
- if (cpu_clock_freq >= 100 * 1000 * 1000) // assume it is valid
- return;
-
- if (usb_query_clicks(&tick1))
- {
- for(i = 0; i < 25; i++)
- {
- usb_query_clicks(&tick1);
- KeStallExecutionProcessor(40 * 1000);
- usb_query_clicks(&tick2);
- cpu_clock_freq += (ULONG) (tick2.QuadPart - tick1.QuadPart);
- }
- // cpu_clock_freq *= 1000;
- usb_dbg_print(DBGLVL_MAXIMUM, ("usb_cal_cpu_freq(): cpu frequency = %d Hz\n", cpu_clock_freq));
- }
-}
-
-NTSTATUS
-usb_set_interface(PURB purb)
-{
- ULONG u;
- PURB purb1;
- PCTRL_REQ_STACK pstack;
- PUSB_DEV pdev;
- PUSB_CTRL_SETUP_PACKET psetup;
- PUSB_ENDPOINT pendp;
- NTSTATUS status;
-
- PHCD hcd;
- USE_BASIC_NON_PENDING_IRQL;
-
- purb1 = purb;
- pdev = purb->pdev;
- psetup = (PUSB_CTRL_SETUP_PACKET) purb->setup_packet;
-
- lock_dev(pdev, FALSE);
- if (dev_state(pdev) == USB_DEV_STATE_ZOMB)
- {
- unlock_dev(pdev, FALSE);
- return STATUS_DEVICE_NOT_CONNECTED;
- }
- if (dev_state(pdev) < USB_DEV_STATE_CONFIGURED)
- {
- unlock_dev(pdev, FALSE);
- return STATUS_DEVICE_NOT_READY;
- }
-
- hcd = pdev->hcd;
-
- if (psetup->wIndex >= pdev->usb_config->if_count)
- {
- unlock_dev(pdev, FALSE);
- return STATUS_INVALID_PARAMETER;
- }
- if (psetup->wValue >= pdev->usb_config->interf[psetup->wIndex].altif_count + 1)
- {
- unlock_dev(pdev, FALSE);
- return STATUS_INVALID_PARAMETER;
- }
- if (pdev->usb_config->interf[psetup->wIndex].pusb_if_desc->bAlternateSetting == psetup->wValue)
- {
- // already the current interface
- unlock_dev(pdev, FALSE);
- return STATUS_SUCCESS;
- }
- // check to see if the endp is busy
- for(u = 0; u < pdev->usb_config->interf[psetup->wIndex].endp_count; u++)
- {
- // This check is not adquate. Since we do not have mechanism to block the new coming
- // request during this request. the caller must guarantee no active or pending
- // usb request on these endpoint.
- pendp = &pdev->usb_config->interf[psetup->wIndex].endp[u];
- if (usb_endp_busy_count(pendp))
- {
- // active urb on that endp
- unlock_dev(pdev, FALSE);
- return STATUS_DEVICE_NOT_READY;
- }
- if (IsListEmpty(&pendp->urb_list))
- {
- // pending urb on that endp
- unlock_dev(pdev, FALSE);
- return STATUS_DEVICE_NOT_READY;
- }
- }
- unlock_dev(pdev, FALSE);
-
- if (purb1->ctrl_req_context.ctrl_stack_count == 0)
- {
- // ok, we have one stack cell for our use
- if (purb1->completion != NULL)
- {
- purb1->ctrl_req_context.ctrl_stack_count = 1;
- purb1->ctrl_req_context.ctrl_cur_stack = 0;
- }
- else
- {
- // use urb's completion and context
- purb1->completion = usb_set_interface_completion;
- purb1->context = pdev;
- }
- }
- else
- {
- if (purb->ctrl_req_context.ctrl_cur_stack + 1 >= purb->ctrl_req_context.ctrl_stack_count)
- {
- // stack full, let's allocate one new urb, we need stack size one
- purb1 = usb_alloc_mem(NonPagedPool, sizeof(URB));
- if (purb1 == NULL)
- return STATUS_NO_MEMORY;
-
- RtlCopyMemory(purb1, purb, sizeof(URB));
-
- // we do not use stack
- RtlZeroMemory(purb1->ctrl_req_stack, sizeof(CTRL_REQ_STACK));
- purb1->context = pdev;
- purb1->completion = usb_set_interface_completion;
- purb1->ctrl_parent_urb = purb;
- purb1->ctrl_req_context.ctrl_req_flags = CTRL_PARENT_URB_VALID;
-
- goto LBL_SEND_URB;
- }
- else
- purb->ctrl_req_context.ctrl_cur_stack++;
- }
-
- u = purb1->ctrl_req_context.ctrl_cur_stack;
- RtlZeroMemory(&purb1->ctrl_req_stack[u], sizeof(CTRL_REQ_STACK));
- pstack = &purb1->ctrl_req_stack[u];
- pstack->context = pdev;
- pstack->urb_completion = usb_set_interface_completion;
-
-LBL_SEND_URB:
- if (hcd == NULL)
- return STATUS_INVALID_PARAMETER;
-
- status = hcd->hcd_submit_urb(hcd, purb->pdev, purb->pendp, purb);
- return status;
-}
-
-#define usb_complete_and_free_ctrl_urb( pURB ) \
-{\
- UCHAR i, j;\
- i = pURB->ctrl_req_context.ctrl_cur_stack;\
- j = pURB->ctrl_req_context.ctrl_stack_count;\
- usb_call_ctrl_completion( pURB );\
- if( i == 0xff || j == 0 )\
- usb_free_mem( pURB );\
-}
-
-VOID
-usb_set_interface_completion(PURB purb, PVOID context)
-{
- PUSB_CTRL_SETUP_PACKET psetup;
- PUSB_INTERFACE pif, palt_if;
- USB_INTERFACE temp_if;
- UCHAR if_idx, if_alt_idx;
- PUSB_DEV pdev;
- PUSB_ENDPOINT pendp;
- ULONG i;
- PLIST_ENTRY pthis, pnext;
-
- USE_BASIC_NON_PENDING_IRQL;
-
- UNREFERENCED_PARAMETER(context);
-
- if (purb == NULL)
- return;
-
- if (purb->status == STATUS_SUCCESS)
- {
- psetup = (PUSB_CTRL_SETUP_PACKET) purb->setup_packet;
- if_idx = (UCHAR) psetup->wIndex;
- if_alt_idx = (UCHAR) psetup->wValue;
- pdev = purb->pdev;
- RtlZeroMemory(&temp_if, sizeof(USB_INTERFACE));
-
- lock_dev(pdev, TRUE);
- if (dev_state(pdev) == USB_DEV_STATE_ZOMB)
- {
- unlock_dev(pdev, TRUE);
- purb->status = STATUS_DEVICE_NOT_CONNECTED;
- purb->data_length = 0;
- }
- else
- {
- // let's swap the interface
- pif = &pdev->usb_config->interf[if_idx];
- ListFirst(&pif->altif_list, pthis);
- pnext = pthis;
- do
- {
- palt_if = struct_ptr(pthis, USB_INTERFACE, altif_list);
- if (palt_if->pusb_if_desc->bAlternateSetting == if_alt_idx)
- {
- break;
- }
- palt_if = NULL;
- ListNext(&pif->altif_list, pthis, pnext);
- pthis = pnext;
-
- } while (pthis);
-
- if (palt_if != NULL)
- {
- RtlCopyMemory(&temp_if, palt_if, sizeof(USB_INTERFACE));
-
- palt_if->endp_count = pif->endp_count;
- RtlCopyMemory(palt_if->endp, pif->endp, sizeof(pif->endp));
- palt_if->pif_drv = pif->pif_drv;
- palt_if->pusb_if_desc = pif->pusb_if_desc;
- for(i = 0; i < palt_if->endp_count; i++)
- {
- pendp = &palt_if->endp[i];
- InitializeListHead(&pendp->urb_list);
- pendp->flags = 0;
- }
-
- RtlCopyMemory(pif->endp, temp_if.endp, sizeof(temp_if.endp));
- pif->endp_count = temp_if.endp_count;
- pif->pusb_if_desc = temp_if.pusb_if_desc;
- for(i = 0; i < pif->endp_count; i++)
- {
- pendp = &pif->endp[i];
- InitializeListHead(&pendp->urb_list);
- pendp->flags = 0;
- }
- }
- else
- {
- TRAP();
- purb->status = STATUS_UNSUCCESSFUL;
- }
- }
- unlock_dev(pdev, TRUE);
- }
-
- // for recursive reason, we have to store the parameter ahead
- usb_complete_and_free_ctrl_urb(purb);
-}
-
-// can only be called when current completion finished and called only in
-// urb completion. And this func may be called recursively, if this routine
-// is called, the urb must be treated as released.
-VOID
-usb_call_ctrl_completion(PURB purb)
-{
- PURB parent_urb;
- PCTRL_REQ_STACK pstack;
- ULONG i;
-
-
- if (purb == NULL)
- return;
-
- if (purb->ctrl_req_context.ctrl_stack_count != 0)
- {
- i = purb->ctrl_req_context.ctrl_cur_stack;
- if (i > 0 && i < 0x10)
- {
- i--;
- purb->ctrl_req_context.ctrl_cur_stack = (UCHAR) i;
- pstack = &purb->ctrl_req_stack[i];
- if (pstack->urb_completion)
- {
- pstack->urb_completion(purb, pstack->context);
- }
- else
- TRAP();
- }
- else if (i == 0)
- {
- i = purb->ctrl_req_context.ctrl_cur_stack = 0xff;
- if (purb->completion)
- {
- purb->completion(purb, purb->context);
- }
- else
- TRAP();
- }
- else if (i == 0xff)
- {
- // only parent urb's completion, if parent urb exists, can be called
- if (purb->ctrl_req_context.ctrl_req_flags & CTRL_PARENT_URB_VALID)
- {
- parent_urb = purb->ctrl_parent_urb;
- if (parent_urb)
- {
- pstack = &parent_urb->ctrl_req_stack[parent_urb->ctrl_req_context.ctrl_cur_stack];
- pstack->urb_completion(parent_urb, pstack->context);
- }
- else
- TRAP();
- }
- }
- else
- TRAP();
- }
- else if (purb->ctrl_req_context.ctrl_req_flags & CTRL_PARENT_URB_VALID)
- {
- // this is the case when the child urb won't use the stack
- parent_urb = purb->ctrl_parent_urb;
- if (parent_urb)
- {
- // pstack = &parent_urb->ctrl_req_stack[ parent_urb->ctrl_req_context.ctrl_cur_stack ];
- // pstack->urb_completion( parent_urb, pstack->context );
- usb_call_ctrl_completion(parent_urb);
- }
- else
- TRAP();
- }
- else
- return;
-}
diff --git a/reactos/drivers/usb/nt4compat/usbdrv/usb.h b/reactos/drivers/usb/nt4compat/usbdrv/usb.h
deleted file mode 100644
index 29a8ce91d50..00000000000
--- a/reactos/drivers/usb/nt4compat/usbdrv/usb.h
+++ /dev/null
@@ -1,1072 +0,0 @@
-#ifndef __USBD_H__
-#define __USBD_H__
-/*
- * Some USB bandwidth allocation constants.
- */
-
-#define USB2_HOST_DELAY 5 /* nsec, guess */
-#define BW_HOST_DELAY 1000L /* nanoseconds */
-#define BW_HUB_LS_SETUP 333L /* nanoseconds */
- /* 4 full-speed bit times (est.) */
-
-#define FRAME_TIME_BITS 12000L /* frame = 1 millisecond */
-#define FRAME_TIME_MAX_BITS_ALLOC (90L * FRAME_TIME_BITS / 100L)
-#define FRAME_TIME_USECS 1000L
-#define FRAME_TIME_MAX_USECS_ALLOC (90L * FRAME_TIME_USECS / 100L)
-
-#define bit_time(bytecount) (7 * 8 * bytecount / 6) /* with integer truncation */
- /* Trying not to use worst-case bit-stuffing
- of (7/6 * 8 * bytecount) = 9.33 * bytecount */
- /* bytecount = data payload byte count */
-
-#define ns_to_us(ns) ((ns + 500L) / 1000L)
- /* convert & round nanoseconds to microseconds */
-
-#define usb_make_handle( dev_Id, if_iDx, endp_iDx) \
-( ( DEV_HANDLE )( ( ( ( ( ULONG )dev_Id ) << 16 ) | ( ( ( ULONG )if_iDx ) << 8 ) ) | ( ( ULONG ) endp_iDx ) ) )
-
-#define usb_make_ref( poinTER ) \
-( poinTER ^ 0xffffffff )
-
-#define ptr_from_ref uhci_make_ref
-
-#define dev_id_from_handle( hanDLE ) ( ( ( ULONG ) ( hanDLE ) ) >> 16 )
-#define if_idx_from_handle( hanDLE ) ( ( ( ( ULONG ) ( hanDLE ) ) << 16 ) >> 24 )
-#define endp_idx_from_handle( hanDLE ) ( ( ( ULONG ) ( hanDLE ) ) & 0xff )
-
-#define endp_from_handle( pDEV, hanDLE, peNDP ) \
-{\
- LONG if_idx, endp_idx;\
- BOOLEAN def_endp; \
- endp_idx = endp_idx_from_handle( hanDLE );\
- if_idx = if_idx_from_handle( hanDLE );\
- def_endp = ( ( hanDLE & 0xffff ) == 0xffff ); \
- if( def_endp ) \
- peNDP = &pdev->default_endp; \
- else \
- { \
- if( if_idx >= pdev->usb_config->if_count ) \
- peNDP = NULL; \
- else if( endp_idx >= pdev->usb_config->interf[ if_idx ].endp_count ) \
- peNDP = NULL; \
- else \
- peNDP = &( pDEV )->usb_config->interf[ if_idx ].endp[ endp_idx ]; \
- } \
-}
-
-#define endp_type( enDP ) \
-( ( enDP->flags & USB_ENDP_FLAG_DEFAULT_ENDP ) \
- ? USB_ENDPOINT_XFER_CONTROL\
- : ( ( enDP )->pusb_endp_desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK ) )
-
-
-//init work data for urb
-#define urb_init( uRb ) \
-{\
- RtlZeroMemory( ( uRb ), sizeof( URB ) ); \
- InitializeListHead( &( uRb )->trasac_list ); \
-}
-
-#define UsbBuildInterruptOrBulkTransferRequest(uRb, \
- endp_hanDle, \
- data_Buf, \
- data_sIze, \
- completIon, \
- contExt, \
- refereNce ) \
-{ \
- urb_init( ( uRb ) );\
- ( uRb )->endp_handle = endp_hanDle;\
- ( uRb )->data_buffer = data_Buf;\
- ( uRb )->data_length = data_sIze;\
- ( uRb )->completion = completIon;\
- ( uRb )->context = contExt; \
- ( uRb )->reference = refereNce; \
-}
-
-
-
-#define UsbBuildGetDescriptorRequest(uRb, \
- endp_hAndle, \
- descriPtorType, \
- descriPtorIndex, \
- languaGeId, \
- data_bUffer, \
- data_sIze, \
- compleTion, \
- contexT, \
- refereNce ) \
-{ \
- PUSB_CTRL_SETUP_PACKET pseTup;\
- pseTup = ( PUSB_CTRL_SETUP_PACKET )( uRb )->setup_packet;\
- urb_init( ( uRb ) );\
- ( uRb )->endp_handle = ( endp_hAndle );\
- ( uRb )->data_length = ( data_sIze ); \
- ( uRb )->data_buffer = ( ( PUCHAR )data_bUffer ); \
- ( uRb )->completion = ( compleTion );\
- ( uRb )->context = ( ( PVOID )contexT ); \
- ( uRb )->reference = ( ULONG )refereNce; \
- pseTup->wValue = ( ( descriPtorType ) << 8 )| ( descriPtorIndex ); \
- pseTup->wLength = ( data_sIze ); \
- pseTup->wIndex = ( languaGeId );\
- pseTup->bRequest = USB_REQ_GET_DESCRIPTOR;\
- pseTup->bmRequestType = 0x80;\
-}
-
-
-
-#define UsbBuildGetStatusRequest(uRb, \
- endp_hanDle, \
- recipiEnt, \
- inDex, \
- transferBufFer, \
- completIon, \
- contExt, \
- refereNce ) \
-{ \
- PUSB_CTRL_SETUP_PACKET pseTup = ( PUSB_CTRL_SETUP_PACKET )( uRb )->setup_packet;\
- urb_init( ( uRb ) );\
- ( uRb )->endp_handle = ( endp_hanDle ); \
- ( uRb )->data_buffer = ( transferBufFer ); \
- ( uRb )->data_length = sizeof(USHORT); \
- ( uRb )->completion = ( completIon );\
- ( uRb )->context = ( contExt );\
- ( uRb )->reference = ( refereNce );\
- pseTup->bmRequestType = ( 0x80 | recipiEnt );\
- pseTup->bRequest = USB_REQ_GET_STATUS;\
- pseTup->wIndex = ( inDex ); \
- pseTup->wValue = 0;\
- pseTup->wLength = sizeof( USHORT );\
-}
-
-
-#define UsbBuildFeatureRequest(uRb, \
- endp_hanDle,\
- recipiEnt, \
- featureSelecTor, \
- inDex, \
- completIon, \
- contExt, \
- refereNce ) \
- { \
- PUSB_CTRL_SETUP_PACKET pseTup = ( PUSB_CTRL_SETUP_PACKET )( uRb )->setup_packet;\
- urb_init( ( uRb ) );\
- ( uRb )->endp_handle = ( endp_hanDle ); \
- ( uRb )->data_buffer = NULL;\
- ( uRb )->data_length = ( 0 );\
- ( uRb )->completion = ( completIon );\
- ( uRb )->context = ( contExt ); \
- ( uRb )->reference = ( refereNce ); \
- pseTup->bmRequestType = recipiEnt; \
- pseTup->bRequest = USB_REQ_SET_FEATURE;\
- pseTup->wValue = ( featureSelecTor );\
- pseTup->wIndex = ( inDex );\
- pseTup->wLength = 0;\
-}
-
-#define UsbBuildSelectConfigurationRequest(uRb, \
- endp_hanDle,\
- config_Val,\
- completIon, \
- contExt, \
- refereNce ) \
- { \
- PUSB_CTRL_SETUP_PACKET pseTup = ( PUSB_CTRL_SETUP_PACKET )( uRb )->setup_packet;\
- urb_init( ( uRb ) );\
- ( uRb )->endp_handle = ( endp_hanDle ); \
- ( uRb )->data_buffer = NULL;\
- ( uRb )->data_length = 0;\
- ( uRb )->completion = ( completIon );\
- ( uRb )->context = ( contExt ); \
- ( uRb )->reference = ( refereNce ); \
- pseTup->bmRequestType = 0;\
- pseTup->bRequest = USB_REQ_SET_CONFIGURATION;\
- pseTup->wValue = ( config_Val );\
- pseTup->wIndex = 0;\
- pseTup->wLength = 0;\
-}
-
-#define UsbBuildSelectInterfaceRequest(uRb, \
- endp_hanDle,\
- if_Num, \
- alt_Num,\
- completIon, \
- contExt, \
- refereNce ) \
- { \
- PUSB_CTRL_SETUP_PACKET pseTup = ( PUSB_CTRL_SETUP_PACKET )( uRb )->setup_packet;\
- urb_init( ( uRb ) );\
- ( uRb )->endp_handle = ( endp_hanDle ); \
- ( uRb )->data_buffer = NULL;\
- ( uRb )->data_length = 0;\
- ( uRb )->completion = ( completIon );\
- ( uRb )->context = ( contExt ); \
- ( uRb )->reference = ( refereNce ); \
- pseTup->bmRequestType = 1;\
- pseTup->bRequest = USB_REQ_SET_INERFACE;\
- pseTup->wValue = ( alt_Num );\
- pseTup->wIndex = ( if_Num );\
- pseTup->wLength = 0;\
-}
-
-
-#define UsbBuildVendorRequest(uRb, \
- endp_hanDle,\
- data_bufFer, \
- data_sIze, \
- request_tYpe, \
- requEst, \
- vaLue, \
- inDex, \
- completIon, \
- contExt, \
- refereNce ) \
- { \
- PUSB_CTRL_SETUP_PACKET pseTup = ( PUSB_CTRL_SETUP_PACKET )( uRb )->setup_packet;\
- urb_init( ( uRb ) );\
- ( uRb )->endp_handle = ( endp_hanDle ); \
- ( uRb )->data_buffer = data_bufFer;\
- ( uRb )->data_length = data_sIze;\
- ( uRb )->completion = ( completIon );\
- ( uRb )->context = ( contExt ); \
- ( uRb )->reference = ( refereNce ); \
- pseTup->bmRequestType = request_tYpe;\
- pseTup->bRequest = requEst;\
- pseTup->wValue = vaLue;\
- pseTup->wIndex = inDex;\
- pseTup->wLength = ( USHORT )data_sIze;\
-}
-
-#define UsbBuildResetPipeRequest(uRb, \
- dev_hanDle, \
- endp_aDdr, \
- completIon, \
- contExt, \
- refereNce ) \
-{\
- PUSB_CTRL_SETUP_PACKET pseTup = ( PUSB_CTRL_SETUP_PACKET )( uRb )->setup_packet;\
- urb_init( ( uRb ) );\
- ( uRb )->endp_handle = ( dev_hanDle | 0xffff ); \
- ( uRb )->completion = ( completIon );\
- ( uRb )->context = ( contExt ); \
- ( uRb )->reference = ( refereNce ); \
- pseTup->bmRequestType = 0x02;\
- pseTup->bRequest = USB_REQ_CLEAR_FEATURE;\
- pseTup->wIndex = endp_aDdr;\
-}
-
-// Forward structs declarations
-struct _URB;
-struct _HCD;
-struct _USB_DEV_MANAGER;
-struct _USB_DEV;
-struct _USB_ENDPOINT;
-struct _USB_EVENT;
-struct _USB_EVENT_POOL;
-struct _USB_DRIVER;
-
-/* USB constants */
-
-#define USB_SPEED_FULL 0x00
-#define USB_SPEED_LOW 0x01
-#define USB_SPEED_HIGH 0x02
-
-/*
- * Device and/or Interface Class codes
- */
-#define USB_CLASS_PER_INTERFACE 0 /* for DeviceClass */
-#define USB_CLASS_AUDIO 1
-#define USB_CLASS_COMM 2
-#define USB_CLASS_HID 3
-#define USB_CLASS_PHYSICAL 5
-#define USB_CLASS_PRINTER 7
-#define USB_CLASS_MASS_STORAGE 8
-#define USB_CLASS_HUB 9
-#define USB_CLASS_DATA 10
-#define USB_CLASS_APP_SPEC 0xfe
-#define USB_CLASS_VENDOR_SPEC 0xff
-
-/*
- * USB types
- */
-#define USB_TYPE_MASK (0x03 << 5)
-#define USB_TYPE_STANDARD (0x00 << 5)
-#define USB_TYPE_CLASS (0x01 << 5)
-#define USB_TYPE_VENDOR (0x02 << 5)
-#define USB_TYPE_RESERVED (0x03 << 5)
-
-/*
- * USB recipients
- */
-#define USB_RECIP_MASK 0x1f
-#define USB_RECIP_DEVICE 0x00
-#define USB_RECIP_INTERFACE 0x01
-#define USB_RECIP_ENDPOINT 0x02
-#define USB_RECIP_OTHER 0x03
-
-/*
- * USB directions
- */
-#define USB_DIR_OUT 0
-#define USB_DIR_IN 0x80
-
-/*
- * Descriptor types
- */
-#define USB_DT_DEVICE 0x01
-#define USB_DT_CONFIG 0x02
-#define USB_DT_STRING 0x03
-#define USB_DT_INTERFACE 0x04
-#define USB_DT_ENDPOINT 0x05
-
-#define USB_DT_HID (USB_TYPE_CLASS | 0x01)
-#define USB_DT_REPORT (USB_TYPE_CLASS | 0x02)
-#define USB_DT_PHYSICAL (USB_TYPE_CLASS | 0x03)
-#define USB_DT_HUB (USB_TYPE_CLASS | 0x09)
-
-/*
- * Descriptor sizes per descriptor type
- */
-#define USB_DT_DEVICE_SIZE 18
-#define USB_DT_CONFIG_SIZE 9
-#define USB_DT_INTERFACE_SIZE 9
-#define USB_DT_ENDPOINT_SIZE 7
-#define USB_DT_ENDPOINT_AUDIO_SIZE 9 /* Audio extension */
-#define USB_DT_HUB_NONVAR_SIZE 7
-#define USB_DT_HID_SIZE 9
-
-/*
- * Endpoints
- */
-#define USB_ENDPOINT_NUMBER_MASK 0x0f /* in bEndpointAddress */
-#define USB_ENDPOINT_DIR_MASK 0x80
-
-#define USB_ENDPOINT_XFERTYPE_MASK 0x03 /* in bmAttributes */
-#define USB_ENDPOINT_XFER_CONTROL 0
-#define USB_ENDPOINT_XFER_ISOC 1
-#define USB_ENDPOINT_XFER_BULK 2
-#define USB_ENDPOINT_XFER_INT 3
-
-/*
- * USB Packet IDs (PIDs)
- */
-#define USB_PID_UNDEF_0 0xf0
-#define USB_PID_OUT 0xe1
-#define USB_PID_ACK 0xd2
-#define USB_PID_DATA0 0xc3
-#define USB_PID_PING 0xb4 /* USB 2.0 */
-#define USB_PID_SOF 0xa5
-#define USB_PID_NYET 0x96 /* USB 2.0 */
-#define USB_PID_DATA2 0x87 /* USB 2.0 */
-#define USB_PID_SPLIT 0x78 /* USB 2.0 */
-#define USB_PID_IN 0x69
-#define USB_PID_NAK 0x5a
-#define USB_PID_DATA1 0x4b
-#define USB_PID_PREAMBLE 0x3c /* Token mode */
-#define USB_PID_ERR 0x3c /* USB 2.0: handshake mode */
-#define USB_PID_SETUP 0x2d
-#define USB_PID_STALL 0x1e
-#define USB_PID_MDATA 0x0f /* USB 2.0 */
-
-/*
- * Standard requests
- */
-#define USB_REQ_GET_STATUS 0x00
-#define USB_REQ_CLEAR_FEATURE 0x01
-#define USB_REQ_SET_FEATURE 0x03
-#define USB_REQ_SET_ADDRESS 0x05
-#define USB_REQ_GET_DESCRIPTOR 0x06
-#define USB_REQ_SET_DESCRIPTOR 0x07
-#define USB_REQ_GET_CONFIGURATION 0x08
-#define USB_REQ_SET_CONFIGURATION 0x09
-#define USB_REQ_GET_INTERFACE 0x0A
-#define USB_REQ_SET_INTERFACE 0x0B
-#define USB_REQ_SYNCH_FRAME 0x0C
-
-/*
- * HID requests
- */
-#define USB_REQ_GET_REPORT 0x01
-#define USB_REQ_GET_IDLE 0x02
-#define USB_REQ_GET_PROTOCOL 0x03
-#define USB_REQ_SET_REPORT 0x09
-#define USB_REQ_SET_IDLE 0x0A
-#define USB_REQ_SET_PROTOCOL 0x0B
-
-// HUB request
-#define HUB_REQ_GET_STATE 0x02
-
-// usb2.0 hub
-#define HUB_REQ_CLEAR_TT_BUFFER 0x08
-
-
-typedef LONG USBD_STATUS;
-
-//
-// USBD status codes
-//
-// Status values are 32 bit values layed out as follows:
-//
-// 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
-// 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
-// +---+---------------------------+-------------------------------+
-// | S | Status Code |
-// +---+---------------------------+-------------------------------+
-//
-// where
-//
-// S - is the state code
-//
-// 00 - completed with success
-// 01 - request is pending
-// 10 - completed with error, endpoint not stalled
-// 11 - completed with error, endpoint stalled
-//
-//
-// Code - is the status code
-//
-
-//
-// Generic test for success on any status value (non-negative numbers
-// indicate success).
-//
-
-#define usb_success(Status) ((USBD_STATUS)(Status) >= 0)
-
-//
-// Generic test for pending status value.
-//
-
-#define usb_pending(Status) ((ULONG)(Status) >> 30 == 1)
-
-//
-// Generic test for error on any status value.
-//
-
-#define usb_error(Status) ((USBD_STATUS)(Status) < 0)
-
-//
-// Generic test for stall on any status value.
-//
-
-#define usb_halted(Status) ((ULONG)(Status) >> 30 == 3)
-
-//
-// Macro to check the status code only
-//
-
-#define usb_status(Status) ((ULONG)(Status) & 0x0FFFFFFFL)
-
-
-#define USB_STATUS_SUCCESS ((USBD_STATUS)0x00000000L)
-#define USB_STATUS_PENDING ((USBD_STATUS)0x40000000L)
-#define USB_STATUS_HALTED ((USBD_STATUS)0xC0000000L)
-#define USB_STATUS_ERROR ((USBD_STATUS)0x80000000L)
-
-//
-// HC status codes
-// Note: these status codes have both the error and the stall bit set.
-//
-#define USB_STATUS_CRC ((USBD_STATUS)0xC0000401L)
-#define USB_STATUS_BTSTUFF ((USBD_STATUS)0xC0000402L)
-#define USB_STATUS_DATA_TOGGLE_MISMATCH ((USBD_STATUS)0xC0000403L)
-#define USB_STATUS_STALL_PID ((USBD_STATUS)0xC0000404L)
-#define USB_STATUS_DEV_NOT_RESPONDING ((USBD_STATUS)0xC0000405L)
-#define USB_STATUS_PID_CHECK_FAILURE ((USBD_STATUS)0xC0000406L)
-#define USB_STATUS_UNEXPECTED_PID ((USBD_STATUS)0xC0000407L)
-#define USB_STATUS_DATA_OVERRUN ((USBD_STATUS)0xC0000408L)
-#define USB_STATUS_DATA_UNDERRUN ((USBD_STATUS)0xC0000409L)
-#define USB_STATUS_RESERVED1 ((USBD_STATUS)0xC000040AL)
-#define USB_STATUS_RESERVED2 ((USBD_STATUS)0xC000040BL)
-#define USB_STATUS_BUFFER_OVERRUN ((USBD_STATUS)0xC000040CL)
-#define USB_STATUS_BUFFER_UNDERRUN ((USBD_STATUS)0xC000040DL)
-#define USB_STATUS_NOT_ACCESSED ((USBD_STATUS)0xC000040FL)
-#define USB_STATUS_FIFO ((USBD_STATUS)0xC0000410L)
-#define USB_STATUS_BABBLE_DETECTED ((USBD_STATUS)0xC0000408L)
-
-//
-// returned by HCD if a transfer is submitted to an endpoint that is
-// stalled
-//
-#define USB_STATUS_ENDPOINT_HALTED ((USBD_STATUS)0xC0000430L)
-
-//
-// Software status codes
-// Note: the following status codes have only the error bit set
-//
-#define USB_STATUS_NO_MEMORY ((USBD_STATUS)0x80000100L)
-#define USB_STATUS_INVALID_URB_FUNCTION ((USBD_STATUS)0x80000200L)
-#define USB_STATUS_INVALID_PARAMETER ((USBD_STATUS)0x80000300L)
-
-//
-// returned if client driver attempts to close an endpoint/interface
-// or configuration with outstanding transfers.
-//
-#define USB_STATUS_ERROR_BUSY ((USBD_STATUS)0x80000400L)
-//
-// returned by USBD if it cannot complete a URB request, typically this
-// will be returned in the URB status field when the Irp is completed
-// with a more specific NT error code in the irp.status field.
-//
-#define USB_STATUS_REQUEST_FAILED ((USBD_STATUS)0x80000500L)
-
-#define USB_STATUS_INVALID_PIPE_HANDLE ((USBD_STATUS)0x80000600L)
-
-// returned when there is not enough bandwidth avialable
-// to open a requested endpoint
-#define USB_STATUS_NO_BANDWIDTH ((USBD_STATUS)0x80000700L)
-//
-// generic HC error
-//
-#define USB_STATUS_INTERNAL_HC_ERROR ((USBD_STATUS)0x80000800L)
-//
-// returned when a short packet terminates the transfer
-// ie USBD_SHORT_TRANSFER_OK bit not set
-//
-#define USB_STATUS_ERROR_SHORT_TRANSFER ((USBD_STATUS)0x80000900L)
-//
-// returned if the requested start frame is not within
-// USBD_ISO_START_FRAME_RANGE of the current USB frame,
-// note that the stall bit is set
-//
-#define USB_STATUS_BAD_START_FRAME ((USBD_STATUS)0xC0000A00L)
-//
-// returned by HCD if all packets in an iso transfer complete with an error
-//
-#define USB_STATUS_ISOCH_REQUEST_FAILED ((USBD_STATUS)0xC0000B00L)
-//
-// returned by USBD if the frame length control for a given
-// HC is already taken by anothe driver
-//
-#define USB_STATUS_FRAME_CONTROL_OWNED ((USBD_STATUS)0xC0000C00L)
-//
-// returned by USBD if the caller does not own frame length control and
-// attempts to release or modify the HC frame length
-//
-#define USB_STATUS_FRAME_CONTROL_NOT_OWNED ((USBD_STATUS)0xC0000D00L)
-
-//
-// set when a transfers is completed due to an AbortPipe request from
-// the client driver
-//
-// Note: no error or stall bit is set for these status codes
-//
-#define USB_STATUS_CANCELED ((USBD_STATUS)0x00010000L)
-
-#define USB_STATUS_CANCELING ((USBD_STATUS)0x00020000L)
-
-// Device type -- in the "User Defined" range."
-#define FILE_HCD_DEV_TYPE 45000
-#define FILE_UHCI_DEV_TYPE ( FILE_HCD_DEV_TYPE + 1 )
-#define FILE_OHCI_DEV_TYPE ( FILE_HCD_DEV_TYPE + 2 )
-#define FILE_EHCI_DEV_TYPE ( FILE_HCD_DEV_TYPE + 3 )
-#define FILE_USB_DEV_TYPE ( FILE_HCD_DEV_TYPE + 8 )
-
-#define IOCTL_GET_DEV_COUNT CTL_CODE( FILE_HCD_DEV_TYPE, 4093, METHOD_BUFFERED, FILE_ANY_ACCESS )
-//input_buffer and input_buffer_length is zero, output_buffer is to receive a dword value of the
-//dev count, output_buffer_length must be no less than sizeof( unsigned long ).
-
-#define IOCTL_ENUM_DEVICES CTL_CODE( FILE_HCD_DEV_TYPE, 4094, METHOD_BUFFERED, FILE_ANY_ACCESS )
-//input_buffer is a dword value to indicate the count of elements in the array
-//input_buffer_length is sizeof( unsigned long ), output_buffer is to receive a
-//structure ENUM_DEV_ARRAY where dev_count is the elements hold in this array.
-
-#define IOCTL_GET_DEV_DESC CTL_CODE( FILE_HCD_DEV_TYPE, 4095, METHOD_BUFFERED, FILE_ANY_ACCESS )
-//input_buffer is a structure GET_DEV_DESC_REQ, and the input_buffer_length is
-//no less than sizeof( input_buffer ), output_buffer is a buffer to receive the
-//requested dev's desc, and output_buffer_length specifies the length of the
-//buffer
-
-#define IOCTL_SUBMIT_URB_RD CTL_CODE( FILE_HCD_DEV_TYPE, 4096, METHOD_IN_DIRECT, FILE_ANY_ACCESS )
-#define IOCTL_SUBMIT_URB_WR CTL_CODE( FILE_HCD_DEV_TYPE, 4097, METHOD_OUT_DIRECT, FILE_ANY_ACCESS )
-// if the major_function is IRP_MJ_DEVICE_CONTROL
-// input_buffer is a URB, and input_buffer_length is equal to or greater than
-// sizeof( URB ); the output_buffer is a buffer to receive data from or send data
-// to device. only the following urb fields can be accessed, others must be zeroed.
-// DEV_HANDLE endp_handle;
-// UCHAR setup_packet[8]; // for control pipe
-// the choosing of IOCTL_SUBMIT_URB_RD or IOCTL_SUBMIT_URB_WR should be determined
-// by the current URB, for example, a request string from device will use XXX_RD,
-// and a write to the bulk endpoint will use XXX_WR
-// if the major_function is IRP_MJ_INTERNAL_DEVICE_CONTROL
-// input_buffer is a URB, and input_buffer_length is equal to or greater than
-// sizeof( URB );
-// only the following urb fields can be accessed, others must be zeroed.
-// DEV_HANDLE endp_handle;
-// UCHAR setup_packet[8]; // for control pipe, or zeroed
-// PUCHAR data_buffer; // buffer for READ/WRITE
-// ULONG data_length; // buffer size in bytes
-
-#define IOCTL_SUBMIT_URB_NOIO CTL_CODE( FILE_HCD_DEV_TYPE, 4098, METHOD_BUFFERED, FILE_ANY_ACCESS )
-// input_buffer is a URB, and input_buffer_length is equal to or greater than
-// sizeof( URB ); the output_buffer is null and no output_buffer_length,
-// only the following fields in urb can be accessed, others must be zeroed.
-// DEV_HANDLE endp_handle;
-// UCHAR setup_packet[8]; //for control pipe
-// there is no difference between IRP_MJ_DEVICE_CONTROL and IRP_MJ_INTERNAL_DEVICE_CONTROL
-#define IOCTL_GET_DEV_HANDLE CTL_CODE( FILE_HCD_DEV_TYPE, 4099, METHOD_BUFFERED, FILE_ANY_ACCESS )
-// input_buffer is null ,and input_buffer_length is zero.
-// output_buffer will hold the handle to this dev, output_buffer_length is 4
-// or bigger
-
-typedef ULONG DEV_HANDLE, ENDP_HANDLE, IF_HANDLE;
-
-struct URB;
-#pragma pack( push, usb_align, 1 )
-
-//structures for DeviceIoControl
-typedef struct _ENUM_DEV_ELEMENT
-{
- DEV_HANDLE dev_handle;
- USHORT product_id;
- USHORT vendor_id;
- UCHAR dev_addr;
-
-} ENUM_DEV_ELEMENT, *PENUM_DEV_ELEMENT;
-
-typedef struct _ENUM_DEV_ARRAY
-{
- UCHAR dev_count;
- ENUM_DEV_ELEMENT dev_arr[ 1 ];
-
-} ENUM_DEV_ARRAY, *PENUM_DEV_ARRAY;
-
-typedef struct _GET_DEV_DESC_REQ
-{
- DEV_HANDLE dev_handle;
- UCHAR desc_type;
- UCHAR desc_idx;
-
-} GET_DEV_DESC_REQ, *PGET_DEV_DESC_REQ;
-
-//usb definitions
-typedef struct _USB_CTRL_SETUP_PACKET
-{
- UCHAR bmRequestType;
- UCHAR bRequest;
- USHORT wValue;
- USHORT wIndex;
- USHORT wLength;
-
-}USB_CTRL_SETUP_PACKET, *PUSB_CTRL_SETUP_PACKET;
-
-typedef struct _USB_STRING_DESCRIPTOR
-{
- UCHAR bLength;
- UCHAR bDescriptorType;
- USHORT wData[1];
-
-} USB_STRING_DESCRIPTOR, *PUSB_STRING_DESCRIPTOR;
-
-typedef struct _USB_DESC_HEADER
-{
- UCHAR bLength;
- UCHAR bDescriptorType;
-
-} USB_DESC_HEADER, *PUSB_DESC_HEADER;
-
-typedef struct _USB_ENDPOINT_DESC
-{
- UCHAR bLength;
- UCHAR bDescriptorType;
- UCHAR bEndpointAddress;
- UCHAR bmAttributes;
- USHORT wMaxPacketSize;
- UCHAR bInterval;
-
-} USB_ENDPOINT_DESC, *PUSB_ENDPOINT_DESC;
-
-typedef struct _USB_INTERFACE_DESC
-{
- UCHAR bLength;
- UCHAR bDescriptorType;
- UCHAR bInterfaceNumber;
- UCHAR bAlternateSetting;
- UCHAR bNumEndpoints;
- UCHAR bInterfaceClass;
- UCHAR bInterfaceSubClass;
- UCHAR bInterfaceProtocol;
- UCHAR iInterface;
-
-} USB_INTERFACE_DESC, *PUSB_INTERFACE_DESC;
-
-typedef struct _USB_CONFIGURATION_DESC
-{
- UCHAR bLength;
- UCHAR bDescriptorType;
- USHORT wTotalLength;
- UCHAR bNumInterfaces;
- UCHAR bConfigurationValue;
- UCHAR iConfiguration;
- UCHAR bmAttributes;
- UCHAR MaxPower;
-
-} USB_CONFIGURATION_DESC, *PUSB_CONFIGURATION_DESC;
-
-typedef struct _USB_DEVICE_DESC
-{
- UCHAR bLength;
- UCHAR bDescriptorType;
- USHORT bcdUSB;
- UCHAR bDeviceClass;
- UCHAR bDeviceSubClass;
- UCHAR bDeviceProtocol;
- UCHAR bMaxPacketSize0;
- USHORT idVendor;
- USHORT idProduct;
- USHORT bcdDevice;
- UCHAR iManufacturer;
- UCHAR iProduct;
- UCHAR iSerialNumber;
- UCHAR bNumConfigurations;
-
-} USB_DEVICE_DESC, *PUSB_DEVICE_DESC;
-
-
-#define URB_FLAG_STATE_MASK 0x0f
-#define URB_FLAG_STATE_PENDING 0x00
-#define URB_FLAG_STATE_IN_PROCESS 0x01
-#define URB_FLAG_STATE_FINISHED 0x02
-
-// USB2.0 state
-#define URB_FLAG_STATE_DOORBELL 0x03 // for async request removal
-#define URB_FLAG_STATE_WAIT_FRAME 0x04 // for sync request removal( for cancel only )
-#define URB_FLAG_STATE_ERROR 0x05
-
-#define URB_FLAG_IN_SCHEDULE 0x10
-#define URB_FLAG_FORCE_CANCEL 0x20
-#define URB_FLAG_SHORT_PACKET 0x80000000
-
-typedef struct _SPLIT_ISO_BUS_TIME
-{
- USHORT bus_time;
- USHORT start_uframe;
-
-} SPLIT_ISO_BUS_TIME, *PSPLIT_ISO_BUS_TIME;
-
-typedef struct _ISO_PACKET_DESC
-{
- LONG offset;
- LONG length; // expected length
- LONG actual_length;
- LONG status;
- union
- {
- LONG bus_time; //opaque for client request of split iso, the bus_time is the start_uframe for each transaction
- SPLIT_ISO_BUS_TIME params;
- };
-
-} ISO_PACKET_DESC, *PISO_PACKET_DESC;
-
-#define CTRL_PARENT_URB_VALID 1
-
-typedef void ( *PURBCOMPLETION )( struct _URB *purb, PVOID pcontext);
-
-typedef struct _CTRL_REQ_STACK
-{
- PURBCOMPLETION urb_completion; // the last step of the urb_completion is to call the
- // the prevoius stack's callback if has, and the last
- // one is purb->completion
- PVOID context;
- ULONG params[ 3 ];
-
-} CTRL_REQ_STACK, *PCTRL_REQ_STACK;
-
-#pragma pack( pop, usb_align )
-
-typedef struct _URB_HS_PIPE_CONTENT
-{
- ULONG trans_type : 2; // bit 0-1
- ULONG mult_count : 2; // bit 2-3, used in high speed int and iso requests
- ULONG reserved : 1; // bit 1
- ULONG speed_high : 1; // bit 5
- ULONG speed_low : 1; // bit 6
- ULONG trans_dir : 1; // bit 7
- ULONG dev_addr : 7; // bit 8-14
- ULONG endp_addr : 4; // bit 15-18
- ULONG data_toggle : 1; // bit 19
- ULONG max_packet_size : 4; // bit 20-23 log( max_packet_size )
- ULONG interval : 4; // bit 24-27 the same definition in USB2.0, for high or full/low speed
- ULONG start_uframe : 3; // bit 28-30
- ULONG reserved1 : 1; //
-
-} URB_HS_PIPE_CONTENT, *PURB_HS_PIPE_CONTENT;
-
-typedef struct _URB_HS_CONTEXT_CONTENT
-{
- ULONG hub_addr : 7; // high speed hub addr for split transfer
- ULONG port_idx : 7;
- ULONG reserved : 18;
-
-} URB_HS_CONTEXT_CONTENT, *PURB_HS_CONTEXT_CONTENT;
-
-typedef struct _URB
-{
- LIST_ENTRY urb_link;
- ULONG flags;
- DEV_HANDLE endp_handle;
- LONG status;
- //record info for isr use, similar to td.status
- //int pipe has different content in the 8 msb
- //the eight bits contain interrupt interval.
- //and max packet length is encoded in 3 bits from 23-21
- //that means 2^(x) bytes in the packet.
- ULONG pipe; // bit0-1: endp type, bit 6: ls or fs. bit 7: dir
-
- union
- {
- UCHAR setup_packet[8]; // for control
- LONG params[ 2 ]; // params[ 0 ] is used in iso transfer as max_packet_size
- };
-
- PUCHAR data_buffer; //user data
- LONG data_length; //user data length
-
- struct _USB_DEV *pdev;
- struct _USB_ENDPOINT *pendp; //pipe for current transfer
-
- PURBCOMPLETION completion;
- PVOID context; //parameter of completion
-
- PVOID urb_ext; //for high speed hcd use
- ULONG hs_context; //for high speed hcd use
-
- PIRP pirp; //irp from client driver
- LONG reference; //for caller private use
-
- LONG td_count; //for any kinds of transfer
- LONG rest_bytes; //for split bulk transfer involving more than 1024 tds
- LONG bytes_to_transfer;
- LONG bytes_transfered; //( bulk transfer )accumulate one split-transfer by xfered bytes of the executed transactions
- PLIST_ENTRY last_finished_td; //last inactive td useful for large amount transfer
- LIST_ENTRY trasac_list; //list of tds or qhs
-
- union
- {
- LONG iso_start_frame; // for high speed endp, this is uframe index, and not used for full/low speed endp, instead,
- // iso_packet_desc.param.start_uframe is used.
- LONG int_start_frame; // frame( ms ) index for high/full/low speed endp
- struct
- {
- UCHAR ctrl_req_flags;
- UCHAR ctrl_stack_count;
- UCHAR ctrl_cur_stack; // the receiver uses this by increment the stack pointer first. if the requester
- UCHAR ctrl_reserved; // send it down with ctrl_stack_count zero, that means the stack is not initialized,
- // and can be initialized by receiver to 1 and only 1.
- // If the initializer found the stack size won't meet the number down the drivers, it must
- // reallocate one urb with the required stack size. and store the previous urb in
- // ctrl_parent_urb
- } ctrl_req_context;
- };
-
- union
- {
- LONG iso_frame_count; // uframe for high speed and frame for full/low speed
- struct _URB* ctrl_parent_urb;
- };
-
- union
- {
- ISO_PACKET_DESC iso_packet_desc[ 1 ]; //used to build up trasac_list for iso transfer and claim bandwidth
- CTRL_REQ_STACK ctrl_req_stack[ 1 ];
- };
-
-} URB, *PURB;
-
-
-NTSTATUS
-usb_set_dev_ext(
-ULONG dev_ref,
-PVOID dev_ext,
-LONG size
-);
-
-NTSTATUS
-usb_set_if_ext(
-ULONG dev_ref,
-ULONG if_ref,
-PVOID if_ext,
-LONG size
-);
-
-PVOID
-usb_get_dev_ext(
-ULONG dev_ref
-);
-
-PVOID
-usb_get_if_ext(
-ULONG dev_ref,
-ULONG if_ref
-);
-
-NTSTATUS
-usb_claim_interface(
-ULONG dev_ref,
-ULONG if_ref,
-struct _USB_DRIVER *usb_drvr
-);
-
-//return reference to the endp
-ULONG
-usb_get_endp(
-ULONG dev_ref,
-LONG endp_addr
-);
-
-//return reference to the interface
-ULONG
-usb_get_interface(
-ULONG dev_ref,
-LONG if_idx
-);
-
-NTSTATUS
-usb_set_configuration(
-ULONG dev_ref,
-LONG config_value
-);
-
-// each call will return full size of the config desc and
-// its if, endp descs.
-// return value is the bytes actually returned.
-// if the return value is equal to wTotalLength, all the descs of the
-// configuration returned.
-NTSTATUS
-usb_get_config_desc(
-ULONG dev_ref,
-LONG config_idx,
-PCHAR buffer,
-PLONG psize
-);
-
-NTSTATUS
-usb_submit_urb(
-struct _USB_DEV_MANAGER* dev_mgr,
-PURB purb
-);
-
-NTSTATUS
-usb_cancel_urb(
-ULONG dev_ref,
-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,
-LONG input_dir,
-LONG isoc,
-LONG bytecount
-);
-
-//increment the dev->ref_count to lock the dev
-NTSTATUS
-usb_query_and_lock_dev(
-struct _USB_DEV_MANAGER* dev_mgr,
-DEV_HANDLE dev_handle,
-struct _USB_DEV** ppdev
-);
-
-//decrement the dev->ref_count
-NTSTATUS
-usb_unlock_dev(
-struct _USB_DEV *dev
-);
-
-NTSTATUS
-usb_reset_pipe(
-struct _USB_DEV *pdev,
-struct _USB_ENDPOINT *pendp,
-PURBCOMPLETION client_completion,
-PVOID param //parameter for client_completion
-);
-
-VOID
-usb_reset_pipe_completion(
-PURB purb,
-PVOID pcontext
-);
-
-PVOID
-usb_alloc_mem(
-POOL_TYPE pool_type,
-LONG size
-);
-
-VOID
-usb_free_mem(
-PVOID pbuf
-);
-
-PUSB_CONFIGURATION_DESC
-usb_find_config_desc_by_val(
-PUCHAR pbuf,
-LONG val,
-LONG cfg_count
-);
-
-PUSB_CONFIGURATION_DESC
-usb_find_config_desc_by_idx(
-PUCHAR pbuf,
-LONG idx,
-LONG cfg_count
-);
-
-BOOLEAN
-usb_skip_if_and_altif(
-PUCHAR* pdesc_BUF
-);
-
-BOOLEAN
-usb_skip_one_config(
-PUCHAR* pconfig_desc_BUF
-);
-
-VOID
-usb_wait_ms_dpc(
-ULONG ms
-);
-
-VOID
-usb_wait_us_dpc(
-ULONG us
-);
-
-BOOLEAN
-usb_query_clicks(
-PLARGE_INTEGER clicks
-);
-
-VOID
-usb_cal_cpu_freq(VOID);
-
-NTSTATUS
-usb_reset_pipe_ex(
-struct _USB_DEV_MANAGER *dev_mgr,
-DEV_HANDLE endp_handle,
-PURBCOMPLETION reset_completion,
-PVOID param
-);
-
-VOID
-usb_call_ctrl_completion(
-PURB purb
-);
-
-BOOLEAN
-is_header_match(
-PUCHAR pbuf,
-ULONG type
-); //used to check descriptor validity
-#endif
diff --git a/reactos/drivers/usb/nt4compat/usbdrv/usbdriver.h b/reactos/drivers/usb/nt4compat/usbdrv/usbdriver.h
deleted file mode 100644
index a504df95490..00000000000
--- a/reactos/drivers/usb/nt4compat/usbdrv/usbdriver.h
+++ /dev/null
@@ -1,31 +0,0 @@
-//#define NTDDI_VERSION NTDDI_WIN2K
-//#define _WIN32_WINNT _WIN32_WINNT_WIN2K
-
-#include
-#include
-
-// NT4 DDK-compatibility
-#ifndef RTL_CONSTANT_STRING
-# define RTL_CONSTANT_STRING(s) { sizeof( s ) - sizeof( (s)[0] ), sizeof( s ), s }
-#endif
-
-#ifndef OBJ_KERNEL_HANDLE
-# define OBJ_KERNEL_HANDLE 0x00000200L
-#endif
-
-#ifndef FILE_DEVICE_SECURE_OPEN
-# define FILE_DEVICE_SECURE_OPEN 0x00000100
-#endif
-
-#include "debug.h"
-#include "usb.h"
-#include "hcd.h"
-#include "td.h"
-#include "irplist.h"
-#include "events.h"
-#include "devmgr.h"
-#include "hub.h"
-#include "umss.h"
-#include "mouse.h"
-#include "keyboard.h"
-#include "uhciver.h"
diff --git a/reactos/drivers/usb/nt4compat/usbdrv/usbdriver.rc b/reactos/drivers/usb/nt4compat/usbdrv/usbdriver.rc
deleted file mode 100644
index 4a1139d5ba2..00000000000
--- a/reactos/drivers/usb/nt4compat/usbdrv/usbdriver.rc
+++ /dev/null
@@ -1,45 +0,0 @@
-// Resource script for USBISO driver
-// Generated by Walt Oney's driver wizard
-
-#include
-
-LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
-
-
-VS_VERSION_INFO VERSIONINFO
- FILEVERSION 0,0,1,0
- PRODUCTVERSION 0,0,1,0
- FILEFLAGSMASK 0x3fL
-#ifdef _DEBUG
- FILEFLAGS 0x1L
-#else
- FILEFLAGS 0x0L
-#endif
- FILEOS 0x40004L
- FILETYPE 0x1L
- FILESUBTYPE 0x0L
-BEGIN
- BLOCK "StringFileInfo"
- BEGIN
- BLOCK "040904b0"
- BEGIN
- VALUE "Comments", "This is a beta version of usb driver stack( ehci ), contact me at mypublic99@yahoo.com\0"
- VALUE "CompanyName", "Woodhead Software\0"
- VALUE "FileDescription", "usbdriver.sys\0"
- VALUE "FileVersion", "0, 0, 1, 0\0"
- VALUE "InternalName", "usbdriver.sys\0"
- VALUE "LegalCopyright", "Copyright © 2002-2004 Woodhead Software\0"
- VALUE "LegalTrademarks", "\0"
- VALUE "OriginalFilename", "usbdriver.sys\0"
- VALUE "PrivateBuild", "0.01\0"
- VALUE "ProductName", "usb driver stack for windows NT\0"
- VALUE "ProductVersion", "0, 0, 1, 0\0"
- VALUE "SpecialBuild", "0131.d\0"
- END
- END
- BLOCK "VarFileInfo"
- BEGIN
- VALUE "Translation", 0x409, 1200
- END
-END
-
diff --git a/reactos/drivers/usb/nt4compat/usbdrv/usbdrv.rbuild b/reactos/drivers/usb/nt4compat/usbdrv/usbdrv.rbuild
deleted file mode 100644
index 9aad31dadba..00000000000
--- a/reactos/drivers/usb/nt4compat/usbdrv/usbdrv.rbuild
+++ /dev/null
@@ -1,31 +0,0 @@
-
-
-
-
-
-
-
-
- .
- ntoskrnl
- hal
- ehci.c
- ohci.c
- uhci.c
- roothub.c
- hub.c
- td.c
- usb.c
- umss.c
- bulkonly.c
- cbi.c
- devmgr.c
- dmgrdisp.c
- compdrv.c
- etd.c
- gendrv.c
- mouse.c
- keyboard.c
- usbdriver.rc
- usbdriver.h
-