diff --git a/reactos/drivers/usb/nt4compat/usbdriver/bulkonly.c b/reactos/drivers/usb/nt4compat/usbdriver/bulkonly.c index ddcde1bfd18..6692e200275 100644 --- a/reactos/drivers/usb/nt4compat/usbdriver/bulkonly.c +++ b/reactos/drivers/usb/nt4compat/usbdriver/bulkonly.c @@ -32,71 +32,28 @@ typedef unsigned long ULONG_PTR, *PULONG_PTR; #define OLYMPUS_CSW( pdev_EXT, staTUS ) \ ( ( ( pdev_EXT )->flags & UMSS_DEV_FLAG_OLYMPUS_DEV ) ? ( ( staTUS ) == CSW_OLYMPUS_SIGNATURE ) : FALSE ) -BOOL -umss_clear_pass_through_length( -PIO_PACKET io_packet -); +BOOL umss_clear_pass_through_length(PIO_PACKET io_packet); -NTSTATUS -umss_bulkonly_send_sense_req( -PUMSS_DEVICE_EXTENSION pdev_ext -); +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_send_cbw_completion(IN PURB purb, IN PVOID context); -VOID -umss_bulkonly_transfer_data( -PUMSS_DEVICE_EXTENSION pdev_ext -); +VOID umss_bulkonly_transfer_data(PUMSS_DEVICE_EXTENSION pdev_ext); -VOID -umss_sync_submit_urb_completion( -PURB purb, -PVOID context -); +VOID umss_sync_submit_urb_completion(PURB purb, PVOID context); -NTSTATUS -umss_sync_submit_urb( -PUMSS_DEVICE_EXTENSION pdev_ext, -PURB purb -); +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_get_status(PUMSS_DEVICE_EXTENSION pdev_ext); -VOID -umss_bulkonly_transfer_data_complete( -PURB purb, -PVOID reference -); +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_pipe_and_get_status(IN PVOID reference); -VOID -umss_bulkonly_reset_recovery( -IN PVOID reference -); +VOID umss_bulkonly_reset_recovery(IN PVOID reference); -VOID -umss_bulkonly_get_status_complete( -IN PURB purb, -IN PVOID context -); +VOID umss_bulkonly_get_status_complete(IN PURB purb, IN PVOID context); -NTSTATUS -umss_bulkonly_startio( -IN PUMSS_DEVICE_EXTENSION pdev_ext, -IN PIO_PACKET io_packet -) /*++ Routine Description: @@ -111,202 +68,171 @@ Return Value: NONE --*/ - +NTSTATUS +umss_bulkonly_startio(IN PUMSS_DEVICE_EXTENSION pdev_ext, IN PIO_PACKET io_packet) { PCOMMAND_BLOCK_WRAPPER cbw; - NTSTATUS status; + NTSTATUS status; - if( pdev_ext == NULL || io_packet == NULL || io_packet->pirp == NULL ) - return STATUS_INVALID_PARAMETER; + 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 ) ); + RtlCopyMemory(&pdev_ext->io_packet, io_packet, sizeof(pdev_ext->io_packet)); - // Setup the command block wrapper for this request + // 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->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 ) ); + RtlCopyMemory(cbw->CBWCB, io_packet->cdb, sizeof(cbw->CBWCB)); - RtlZeroMemory( &pdev_ext->csw, sizeof( pdev_ext->csw ) ); + 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 - ); + status = umss_bulk_transfer(pdev_ext, + USB_DIR_OUT, + cbw, sizeof(COMMAND_BLOCK_WRAPPER), umss_bulkonly_send_cbw_completion); - return status; + 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 -) +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; + PURB purb; + NTSTATUS status; + DEV_HANDLE endp_handle; - if( pdev_ext == NULL || buf == NULL || completion == NULL ) - return STATUS_INVALID_PARAMETER; + if (pdev_ext == NULL || buf == NULL || completion == NULL) + return STATUS_INVALID_PARAMETER; - if( buf_length > ( ULONG )MAX_BULK_TRANSFER_LENGTH ) - return STATUS_INVALID_PARAMETER; + if (buf_length > (ULONG) MAX_BULK_TRANSFER_LENGTH) + return STATUS_INVALID_PARAMETER; - purb = usb_alloc_mem( NonPagedPool, sizeof( URB ) ); + purb = usb_alloc_mem(NonPagedPool, sizeof(URB)); - if( purb == NULL ) - return STATUS_NO_MEMORY; + 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 ); - } + 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; - } + 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; + 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 -) +umss_bulkonly_send_cbw_completion(IN PURB purb, IN PVOID context) { NTSTATUS status; PUMSS_DEVICE_EXTENSION pdev_ext; - pdev_ext = ( PUMSS_DEVICE_EXTENSION )context; + pdev_ext = (PUMSS_DEVICE_EXTENSION) context; - status = purb->status; - dev_mgr_remove_irp( pdev_ext->dev_mgr, pdev_ext->io_packet.pirp ); + 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 ((pdev_ext->io_packet.flags & IOP_FLAG_STAGE_MASK) == IOP_FLAG_STAGE_SENSE) { - if ( usb_halted( status ) ) + 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 ); - } + 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 ); + 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 ); + umss_bulkonly_transfer_data(pdev_ext); } - if( purb ) - usb_free_mem( purb ); + if (purb) + usb_free_mem(purb); - purb = NULL; - return; + purb = NULL; + return; } -NTSTATUS -umss_sync_submit_urb( -PUMSS_DEVICE_EXTENSION pdev_ext, -PURB purb -) //can only be called at passive level +NTSTATUS +umss_sync_submit_urb(PUMSS_DEVICE_EXTENSION pdev_ext, PURB purb) { - NTSTATUS status; + NTSTATUS status; - if( pdev_ext == NULL || purb == NULL ) - return STATUS_INVALID_PARAMETER; + if (pdev_ext == NULL || purb == NULL) + return STATUS_INVALID_PARAMETER; - purb->completion = umss_sync_submit_urb_completion; - purb->context = ( PVOID )pdev_ext; + 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 ); + 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; + return status; } VOID -umss_sync_submit_urb_completion( -PURB purb, -PVOID context -) +umss_sync_submit_urb_completion(PURB purb, PVOID context) { - PUMSS_DEVICE_EXTENSION pdev_ext; + PUMSS_DEVICE_EXTENSION pdev_ext; - if( purb == NULL || context == NULL ) - return; + 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; + 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; } -VOID -umss_bulkonly_reset_recovery( -IN PVOID reference -) /*++ Routine Description: @@ -321,16 +247,17 @@ Return Value: NONE --*/ - +VOID +umss_bulkonly_reset_recovery(IN PVOID reference) { PUMSS_DEVICE_EXTENSION pdev_ext; URB urb; NTSTATUS status; - DEV_HANDLE endp_handle; + 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: + 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. @@ -338,60 +265,49 @@ Return Value: // 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 + 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); + status = umss_sync_submit_urb(pdev_ext, &urb); - if ( status != STATUS_SUCCESS ) + if (status != STATUS_SUCCESS) { - usb_dbg_print( DBGLVL_MINIMUM,("umss_bulkonly_reset_recovery(): Reset Recovery failed!\n")); + 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 - ); + 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")); + 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 - ); + 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")); + usb_dbg_print(DBGLVL_MINIMUM, + ("umss_bulkonly_reset_recovery(): Unable to clear Bulk-out endpoint\n")); } } - umss_complete_request( pdev_ext, status ); + umss_complete_request(pdev_ext, status); } - -VOID -umss_bulkonly_transfer_data( -PUMSS_DEVICE_EXTENSION pdev_ext -) /*++ Routine Description: @@ -406,12 +322,13 @@ 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; + NTSTATUS status; + UCHAR trans_dir; // Steps for data phase // 1. Get data buffer fragment (either SGD list, flat buffer, or none). @@ -420,157 +337,141 @@ Return Value: // 4. Move to status phase. // Get next data buffer element, if any - data_buf = umss_get_buffer( pdev_ext, &data_buf_length); + 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 ); + 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 ); - } + 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; + return; } - -VOID -umss_bulkonly_transfer_data_complete( -PURB purb, -PVOID reference -) /*++ 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; + 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 ); + dev_mgr_remove_irp(pdev_ext->dev_mgr, pdev_ext->io_packet.pirp); - if ( status != STATUS_SUCCESS ) + 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 ); + // + // 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 ) ) + if (usb_halted(status)) { - PULONG buf; - buf = usb_alloc_mem( NonPagedPool, 32 ); - buf[ 0 ] = ( ULONG )pdev_ext; - buf[ 1 ] = ( ULONG )purb->endp_handle; + PULONG buf; + buf = usb_alloc_mem(NonPagedPool, 32); + 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_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")); + 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 ); + umss_complete_request(pdev_ext, status); } } - else - { - //finish our request - 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 ); + umss_bulkonly_get_status(pdev_ext); + //umss_complete_request( pdev_ext, status ); } - usb_free_mem( purb ); - purb = NULL; + usb_free_mem(purb); + purb = NULL; - return; // STATUS_MORE_PROCESSING_REQUIRED; + return; // STATUS_MORE_PROCESSING_REQUIRED; } VOID -umss_bulkonly_reset_pipe_and_get_status( -IN PVOID reference -) +umss_bulkonly_reset_pipe_and_get_status(IN PVOID reference) { - PUMSS_DEVICE_EXTENSION pdev_ext; - DEV_HANDLE endp_handle; - NTSTATUS status; + 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") ); + 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; + 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; - } + 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 ); + 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 -) +umss_bulkonly_get_status(PUMSS_DEVICE_EXTENSION pdev_ext) { - NTSTATUS status; + 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 ); - } + 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); + } } - -VOID -umss_bulkonly_get_status_complete( -IN PURB purb, -IN PVOID context -) /*++ Routine Description: @@ -587,112 +488,112 @@ 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; + pdev_ext = (PUMSS_DEVICE_EXTENSION) context; + status = purb->status; - dev_mgr_remove_irp( pdev_ext->dev_mgr, pdev_ext->io_packet.pirp ); + 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 ) ) ) + csw = &(pdev_ext->csw); + if (status == STATUS_SUCCESS && + ((csw->dCSWSignature == CSW_SIGNATURE) || OLYMPUS_CSW(pdev_ext, csw->dCSWSignature))) { - if ( csw->bCSWStatus == CSW_STATUS_PASSED ) + 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 ); + 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 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 ); - } + 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 ) ) + else if ((status != STATUS_SUCCESS) && (usb_halted(status)) && (pdev_ext->retry)) { // Device stalled CSW transfer, retry once before failing - PULONG buf; + PULONG buf; pdev_ext->retry = FALSE; - buf = usb_alloc_mem( NonPagedPool, 32 ); - buf[ 0 ] = ( ULONG )pdev_ext; - buf[ 1 ] = ( ULONG )purb->endp_handle; + buf = usb_alloc_mem(NonPagedPool, 32); + 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 ) ) + 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")); + 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 ); + umss_complete_request(pdev_ext, status); } } - else if( status != STATUS_CANCELLED ) + 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 ) ) + 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")); + 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 ); + 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 ); - } + 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; + usb_free_mem(purb); + purb = NULL; - return; + return; } - -CHAR -umss_bulkonly_get_maxlun( -IN PUMSS_DEVICE_EXTENSION pdev_ext -) /*++ Routine Description: @@ -707,132 +608,118 @@ 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; + PURB purb = NULL; CHAR max_lun; NTSTATUS status; - purb = usb_alloc_mem( NonPagedPool, sizeof( URB ) ); + 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")); + 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); + 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); + status = umss_sync_submit_urb(pdev_ext, purb); - if ( status != STATUS_PENDING ) + if (status != STATUS_PENDING) { - usb_dbg_print( DBGLVL_MINIMUM,("umss_bulkonly_get_maxlun(): Get Max LUN command failed, setting max LUN to 0!\n")); + 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 ); + if (purb) + usb_free_mem(purb); - usb_dbg_print( DBGLVL_MINIMUM,("umss_bulkonly_get_maxlun(): Max LUN = %x\n", max_lun)); + 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 -) +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; - } + 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; + } - return buffer; + return buffer; } BOOL -umss_bulkonly_build_sense_cdb( -PUMSS_DEVICE_EXTENSION pdev_ext, -PCOMMAND_BLOCK_WRAPPER cbw -) +umss_bulkonly_build_sense_cdb(PUMSS_DEVICE_EXTENSION pdev_ext, PCOMMAND_BLOCK_WRAPPER cbw) { - UCHAR sub_class; - PUCHAR cdb; + UCHAR sub_class; + PUCHAR cdb; - if( pdev_ext == NULL || cbw == NULL ) - return FALSE; + if (pdev_ext == NULL || cbw == NULL) + return FALSE; - cdb = cbw->CBWCB; - RtlZeroMemory( cdb, MAX_CDB_LENGTH ); - sub_class = pdev_ext->pif_desc->bInterfaceSubClass; + 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; + 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; + 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 -) +umss_bulkonly_send_sense_req(PUMSS_DEVICE_EXTENSION pdev_ext) { - PCOMMAND_BLOCK_WRAPPER cbw; - NTSTATUS status; + 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; + 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 ) ); - 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 = usb_alloc_mem(NonPagedPool, sizeof(COMMAND_BLOCK_WRAPPER)); + 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; @@ -840,74 +727,68 @@ PUMSS_DEVICE_EXTENSION pdev_ext 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; - } + 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 - ); + 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; + if (status != STATUS_PENDING) + { + usb_free_mem(cbw); + cbw = NULL; + } + return status; } BOOL -umss_clear_pass_through_length( -PIO_PACKET io_packet -) +umss_clear_pass_through_length(PIO_PACKET io_packet) { - // - // clear the respective data length to meet request of scsi pass through requirement. - // + // + // clear the respective data length to meet request of scsi pass through requirement. + // - BOOL sense_stage; - ULONG ctrl_code; - PIO_STACK_LOCATION cur_stack; - PSCSI_PASS_THROUGH pass_through; - PSCSI_PASS_THROUGH_DIRECT pass_through_direct; + BOOL 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 == NULL) + return FALSE; - if( ( io_packet->flags & IOP_FLAG_SCSI_CTRL_TRANSFER ) == 0 ) - 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; + 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; + 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; + return TRUE; } diff --git a/reactos/drivers/usb/nt4compat/usbdriver/cbi.c b/reactos/drivers/usb/nt4compat/usbdriver/cbi.c index 0911f85ba38..0b8a675c4b8 100644 --- a/reactos/drivers/usb/nt4compat/usbdriver/cbi.c +++ b/reactos/drivers/usb/nt4compat/usbdriver/cbi.c @@ -23,187 +23,143 @@ #include "debug.h" #include "umss.h" -VOID -umss_cbi_send_adsc_complete( -PURB purb, -PVOID context -); +VOID umss_cbi_send_adsc_complete(PURB purb, PVOID context); -VOID -umss_cbi_transfer_data( -PUMSS_DEVICE_EXTENSION pdev_ext -); +VOID umss_cbi_transfer_data(PUMSS_DEVICE_EXTENSION pdev_ext); -VOID -umss_cbi_get_status( -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_transfer_data_complete(PURB purb, PVOID context); -VOID -umss_cbi_get_status_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 -) +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; + NTSTATUS status; - purb = usb_alloc_mem( NonPagedPool, sizeof( URB ) ); - // 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 ); + purb = usb_alloc_mem(NonPagedPool, sizeof(URB)); + // 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; + 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 -) +umss_cbi_startio(IN PUMSS_DEVICE_EXTENSION pdev_ext, IN PIO_PACKET io_packet) { - NTSTATUS status; + NTSTATUS status; - status = STATUS_NOT_SUPPORTED; - return status; + status = STATUS_NOT_SUPPORTED; + return status; - RtlCopyMemory( &pdev_ext->io_packet, io_packet, sizeof( pdev_ext->io_packet ) ); + 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 - ); + 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; + return status; } VOID -umss_cbi_send_adsc_complete( -PURB purb, -PVOID context -) +umss_cbi_send_adsc_complete(PURB purb, PVOID context) { NTSTATUS status; PIO_STACK_LOCATION irpStack; PUMSS_DEVICE_EXTENSION pdev_ext; PIO_PACKET io_packet; - ULONG bytes_to_transfer; - PUCHAR buf; + ULONG bytes_to_transfer; + PUCHAR buf; pdev_ext = (PUMSS_DEVICE_EXTENSION) context; io_packet = &pdev_ext->io_packet; - status = purb->status; + status = purb->status; - dev_mgr_remove_irp( pdev_ext->dev_mgr, pdev_ext->io_packet.pirp ); + dev_mgr_remove_irp(pdev_ext->dev_mgr, pdev_ext->io_packet.pirp); - if (!usb_success( status ) ) + if (!usb_success(status)) { - usb_dbg_print( DBGLVL_MINIMUM,("umss_cbi_send_adsc_complete(): Command Block Failure!!!\n")); + 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 ); + umss_complete_request(pdev_ext, STATUS_IO_DEVICE_ERROR); } - else if ( io_packet->data_length ) + 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 ); + 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) + else if (pdev_ext->pif_desc->bInterfaceProtocol == PROTOCOL_CBI) { // Device supports interrupt pipe, so get status - umss_cbi_get_status( pdev_ext ); + umss_cbi_get_status(pdev_ext); } else { // Device does not report status, so complete request - umss_complete_request( pdev_ext, STATUS_SUCCESS ); + umss_complete_request(pdev_ext, STATUS_SUCCESS); } - - usb_free_mem( purb ); - purb = NULL; + + usb_free_mem(purb); + purb = NULL; } VOID -umss_cbi_reset_pipe( -IN PVOID reference -) - +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 ) - ); + 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 ); + umss_complete_request(pdev_ext, USB_STATUS_STALL_PID); } -VOID -umss_cbi_transfer_data( -PUMSS_DEVICE_EXTENSION pdev_ext -) +VOID +umss_cbi_transfer_data(PUMSS_DEVICE_EXTENSION pdev_ext) { PVOID buffer; ULONG buffer_length; - + // Get next data buffer element, if any. - buffer = umss_get_buffer( pdev_ext, &buffer_length ); + buffer = umss_get_buffer(pdev_ext, &buffer_length); if (NULL == buffer) { //Done with data phase, so move to status phase if (supported) @@ -222,101 +178,87 @@ PUMSS_DEVICE_EXTENSION pdev_ext 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 - ); + 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 -) +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 ) ) + 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 (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 ) ) + 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")); + 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 ); + umss_complete_request(pdev_ext, STATUS_IO_DEVICE_ERROR); } } else { - umss_complete_request( pdev_ext, STATUS_IO_DEVICE_ERROR ); + 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; + umss_complete_request(pdev_ext, STATUS_SUCCESS); + return; } VOID -umss_cbi_get_status_complete( -PURB purb, -PVOID context -) +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; @@ -325,39 +267,41 @@ PVOID context pdev_ext = (PUMSS_DEVICE_EXTENSION) context; status = purb->status; - dev_mgr_remove_irp( pdev_ext->dev_mgr, pdev_ext->io_packet.pirp ); + dev_mgr_remove_irp(pdev_ext->dev_mgr, pdev_ext->io_packet.pirp); - usb_free_mem( purb ); - purb = NULL; + usb_free_mem(purb); + purb = NULL; - if ( !usb_success( status ) ) + if (!usb_success(status)) { // Device failed Data Transfer // Check if we need to clear stalled pipe - if ( usb_halted( status ) ) + if (usb_halted(status)) { - if ( !umss_schedule_workitem( (PVOID)pdev_ext, umss_cbi_reset_pipe, pdev_ext->dev_mgr, pdev_ext->dev_handle ) ) + 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")); + 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; } } - 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 ) ) ) + if ((0 != idb->bType) || (0 != (idb->bValue & 0x3))) { - umss_complete_request( pdev_ext, STATUS_IO_DEVICE_ERROR ); + umss_complete_request(pdev_ext, STATUS_IO_DEVICE_ERROR); } else { - umss_complete_request( pdev_ext, STATUS_SUCCESS ); + umss_complete_request(pdev_ext, STATUS_SUCCESS); } } diff --git a/reactos/drivers/usb/nt4compat/usbdriver/compdrv.c b/reactos/drivers/usb/nt4compat/usbdriver/compdrv.c index 732a77c2ac4..6a8c2a2a929 100644 --- a/reactos/drivers/usb/nt4compat/usbdriver/compdrv.c +++ b/reactos/drivers/usb/nt4compat/usbdriver/compdrv.c @@ -28,530 +28,481 @@ #include "hub.h" #include "debug.h" -VOID -compdev_set_cfg_completion( -PURB purb, -PVOID context -); +VOID compdev_set_cfg_completion(PURB purb, PVOID context); -VOID -compdev_select_driver( -PUSB_DEV_MANAGER dev_mgr, -DEV_HANDLE dev_handle -); +VOID compdev_select_driver(PUSB_DEV_MANAGER dev_mgr, DEV_HANDLE dev_handle); + +BOOL compdev_connect(PCONNECT_DATA param, DEV_HANDLE dev_handle); + +BOOL compdev_stop(PUSB_DEV_MANAGER dev_mgr, DEV_HANDLE dev_handle); + +BOOL compdev_disconnect(PUSB_DEV_MANAGER dev_mgr, DEV_HANDLE dev_handle); BOOL -compdev_connect( -PCONNECT_DATA param, -DEV_HANDLE dev_handle -); - -BOOL -compdev_stop( -PUSB_DEV_MANAGER dev_mgr, -DEV_HANDLE dev_handle -); - -BOOL -compdev_disconnect( -PUSB_DEV_MANAGER dev_mgr, -DEV_HANDLE dev_handle -); - -BOOL -compdev_driver_init( -PUSB_DEV_MANAGER dev_mgr, -PUSB_DRIVER pdriver -) +compdev_driver_init(PUSB_DEV_MANAGER dev_mgr, PUSB_DRIVER pdriver) { - if( dev_mgr == NULL || pdriver == NULL ) - return FALSE; + 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.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.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. + 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; + //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; + 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; + return TRUE; } BOOL -compdev_driver_destroy( -PUSB_DEV_MANAGER dev_mgr, -PUSB_DRIVER pdriver -) +compdev_driver_destroy(PUSB_DEV_MANAGER dev_mgr, PUSB_DRIVER pdriver) { - return TRUE; + return TRUE; } BOOL -compdev_connect( -PCONNECT_DATA param, -DEV_HANDLE dev_handle -) +compdev_connect(PCONNECT_DATA param, DEV_HANDLE dev_handle) { - PURB purb; - PUSB_CTRL_SETUP_PACKET psetup; - NTSTATUS status; - PUCHAR buf; - LONG credit, i, j, match; - PUSB_CONFIGURATION_DESC pconfig_desc; - PUSB_INTERFACE_DESC pif_desc; - PUSB_DEV_MANAGER dev_mgr; + PURB purb; + PUSB_CTRL_SETUP_PACKET psetup; + NTSTATUS status; + PUCHAR buf; + LONG credit, i, j, match; + PUSB_CONFIGURATION_DESC pconfig_desc; + PUSB_INTERFACE_DESC pif_desc; + PUSB_DEV_MANAGER dev_mgr; - if( param == NULL || dev_handle == 0 ) - return FALSE; + if (param == NULL || dev_handle == 0) + return FALSE; - dev_mgr = param->dev_mgr; + dev_mgr = param->dev_mgr; - // let's set the configuration - purb = usb_alloc_mem( NonPagedPool, sizeof( URB ) ); - if( purb == NULL ) - return FALSE; + // 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; - } + 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; + // 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; - } + 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; - } + // 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; + 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; - } + 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; - } + 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; + //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 ); + 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_PENDING) + { + usb_free_mem(purb); - if( status == STATUS_SUCCESS ) - return TRUE; + if (status == STATUS_SUCCESS) + return TRUE; - return FALSE; - } + return FALSE; + } - return TRUE; + return TRUE; } VOID -compdev_event_select_if_driver( -PUSB_DEV pdev, -ULONG event, -ULONG context, -ULONG param -) +compdev_event_select_if_driver(PUSB_DEV pdev, ULONG event, ULONG context, ULONG param) { - PUSB_DEV_MANAGER dev_mgr; - DEV_HANDLE dev_handle; - PUMSS_CREATE_DATA cd; + PUSB_DEV_MANAGER dev_mgr; + DEV_HANDLE dev_handle; + PUMSS_CREATE_DATA cd; - if( pdev == NULL ) - return; + 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; + // + // 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; } BOOL -compdev_post_event_select_driver( -PUSB_DEV_MANAGER dev_mgr, -DEV_HANDLE dev_handle -) +compdev_post_event_select_driver(PUSB_DEV_MANAGER dev_mgr, DEV_HANDLE dev_handle) { - PUSB_EVENT pevent; - BOOL bret; - PUSB_DEV pdev; + PUSB_EVENT pevent; + BOOL bret; + PUSB_DEV pdev; - USE_IRQL; + USE_IRQL; - if( dev_mgr == NULL || dev_handle == 0 ) - return FALSE; + if (dev_mgr == NULL || dev_handle == 0) + return FALSE; - if( usb_query_and_lock_dev( dev_mgr, dev_handle, &pdev ) != STATUS_SUCCESS ) - 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 ); + KeAcquireSpinLockAtDpcLevel(&dev_mgr->event_list_lock); + lock_dev(pdev, TRUE); - if( dev_state( pdev ) == USB_DEV_STATE_ZOMB ) - { - bret = FALSE; - goto LBL_OUT; - } + 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; + 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; + 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: + LBL_OUT: - unlock_dev( pdev, TRUE ); - KeReleaseSpinLockFromDpcLevel( &dev_mgr->event_list_lock ); - usb_unlock_dev( pdev ); - return bret; + 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 -) +compdev_set_cfg_completion(PURB purb, PVOID context) { - DEV_HANDLE dev_handle; - PUSB_DEV_MANAGER dev_mgr; - PWORK_QUEUE_ITEM pwork_item; - PUSB_DRIVER pdriver; - NTSTATUS status; - PUSB_DEV pdev; + DEV_HANDLE dev_handle; + PUSB_DEV_MANAGER dev_mgr; + PWORK_QUEUE_ITEM pwork_item; + PUSB_DRIVER pdriver; + NTSTATUS status; + PUSB_DEV pdev; - USE_IRQL; + USE_IRQL; - if( purb == NULL || context == NULL ) - return; + if (purb == NULL || context == NULL) + return; - dev_handle = purb->endp_handle & ~0xffff; - dev_mgr = ( PUSB_DEV_MANAGER ) context; - pdriver = ( PUSB_DRIVER )purb->reference; + 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; - } + if (purb->status != STATUS_SUCCESS) + { + usb_free_mem(purb); + return; + } - usb_free_mem( purb ); - purb = NULL; + 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 ); + // 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; - } + 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; + 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 ); + //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 ); + // + // 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; + return; } VOID -compdev_select_driver( -PUSB_DEV_MANAGER dev_mgr, -DEV_HANDLE dev_handle -) +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; + 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; + PUSB_CTRL_SETUP_PACKET psetup; + PUSB_INTERFACE_DESC pif_desc; + PUSB_CONFIGURATION_DESC pconfig_desc; + PUSB_DEV pdev; - USE_IRQL; + USE_IRQL; - usb_dbg_print( DBGLVL_MAXIMUM, ( "compdev_select_driver(): entering...\n" ) ); + usb_dbg_print(DBGLVL_MAXIMUM, ("compdev_select_driver(): entering...\n")); - dev_id = dev_handle >> 16; + dev_id = dev_handle >> 16; - buf = usb_alloc_mem( NonPagedPool, 512 ); + buf = usb_alloc_mem(NonPagedPool, 512); - if( buf == NULL ) - return; + 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; + // 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(); - } + status = usb_submit_urb(dev_mgr, &urb); + if (status == STATUS_PENDING) + { + TRAP(); + } - // 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_dbg_print( DBGLVL_MAXIMUM, ( "compdev_select_driver(): error, bad configuration desc\n" ) ); - return; - } - pif_desc = ( PUSB_INTERFACE_DESC )&pconfig_desc[ 1 ]; + // 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_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; - } + 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; + } - 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; - } + 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 - CONNECT_DATA param; + if (credit) + { + // ok, we find one + CONNECT_DATA param; - if( pcand->disp_tbl.dev_connect ) - { - param.dev_mgr = dev_mgr; - param.pdriver = pcand; - param.dev_handle = 0; - 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 (pcand->disp_tbl.dev_connect) + { + param.dev_mgr = dev_mgr; + param.pdriver = pcand; + param.dev_handle = 0; + 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; + if (buf) + { + usb_free_mem(buf); + buf = NULL; + } + return; } BOOL -compdev_stop( -PUSB_DEV_MANAGER dev_mgr, -DEV_HANDLE dev_handle -) +compdev_stop(PUSB_DEV_MANAGER dev_mgr, DEV_HANDLE dev_handle) { - PUSB_DEV pdev; - LONG i; - ULONG dev_id; - PUSB_DRIVER pdrv; - NTSTATUS status; + PUSB_DEV pdev; + LONG i; + ULONG dev_id; + PUSB_DRIVER pdrv; + NTSTATUS status; - if( dev_mgr == NULL || dev_handle == 0 ) - return FALSE; + 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; + 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; } BOOL -compdev_disconnect( -PUSB_DEV_MANAGER dev_mgr, -DEV_HANDLE dev_handle -) +compdev_disconnect(PUSB_DEV_MANAGER dev_mgr, DEV_HANDLE dev_handle) { - PUSB_DEV pdev; - LONG i; - ULONG dev_id; - PUSB_DRIVER pdrv; - NTSTATUS status; + PUSB_DEV pdev; + LONG i; + ULONG dev_id; + PUSB_DRIVER pdrv; + NTSTATUS status; - if( dev_mgr == NULL || dev_handle == 0 ) - return FALSE; + 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; + 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: diff --git a/reactos/drivers/usb/nt4compat/usbdriver/dmgrdisp.c b/reactos/drivers/usb/nt4compat/usbdriver/dmgrdisp.c index e1395235046..0c943ddd200 100644 --- a/reactos/drivers/usb/nt4compat/usbdriver/dmgrdisp.c +++ b/reactos/drivers/usb/nt4compat/usbdriver/dmgrdisp.c @@ -26,494 +26,485 @@ #include "hub.h" VOID -disp_urb_completion( -PURB purb, -PVOID context -) +disp_urb_completion(PURB purb, PVOID context) { - PUSB_CTRL_SETUP_PACKET psetup; - PUSB_DEV_MANAGER dev_mgr; - ULONG ctrl_code; - NTSTATUS status; - PDEVEXT_HEADER dev_hdr; + PUSB_CTRL_SETUP_PACKET psetup; + PUSB_DEV_MANAGER dev_mgr; + ULONG ctrl_code; + NTSTATUS status; + PDEVEXT_HEADER dev_hdr; - if( purb == NULL ) - return; + 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 ); + ctrl_code = (ULONG) purb->reference; + dev_mgr = (PUSB_DEV_MANAGER) purb->context; - status = purb->status; - irp_stack = IoGetCurrentIrpStackLocation( purb->pirp ); + // 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); - 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; + 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 -) +disp_noio_urb_completion(PURB purb, PVOID context) { - PUSB_CTRL_SETUP_PACKET psetup; - PURB purb2; - PUSB_DEV_MANAGER dev_mgr; - NTSTATUS status; - PIO_STACK_LOCATION irp_stack; - PDEVEXT_HEADER dev_hdr; + PUSB_CTRL_SETUP_PACKET psetup; + PURB purb2; + PUSB_DEV_MANAGER dev_mgr; + NTSTATUS status; + PIO_STACK_LOCATION irp_stack; + PDEVEXT_HEADER dev_hdr; - if( purb == NULL ) - return; + 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; + psetup = (PUSB_CTRL_SETUP_PACKET) purb->setup_packet; - if( purb2->pirp == NULL ) - return; + if ((psetup->bmRequestType == 0x2) && + (psetup->bRequest == USB_REQ_CLEAR_FEATURE) && + (psetup->wIndex == 0)) //reset pipe + { + purb2 = (PURB) context; + } + else + { + purb2 = purb; + } - dev_mgr = ( PUSB_DEV_MANAGER )purb2->context; + if (purb2->pirp == NULL) + return; - dev_mgr_remove_irp( dev_mgr, purb2->pirp ); + dev_mgr = (PUSB_DEV_MANAGER) purb2->context; - 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; + 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; } -NTSTATUS -dev_mgr_dispatch( -IN PUSB_DEV_MANAGER dev_mgr, -IN PIRP irp -) //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_IRQL; + PIO_STACK_LOCATION irp_stack; + NTSTATUS status; + ULONG ctrl_code; + USE_IRQL; - if( dev_mgr == NULL || irp == NULL ) - { - EXIT_DISPATCH( STATUS_INVALID_PARAMETER, irp ); - } - - status = STATUS_SUCCESS; - irp_stack = IoGetCurrentIrpStackLocation (irp); - ctrl_code = irp_stack->Parameters.DeviceIoControl.IoControlCode; + if (dev_mgr == NULL || irp == NULL) + { + EXIT_DISPATCH(STATUS_INVALID_PARAMETER, irp); + } - 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; + status = STATUS_SUCCESS; + irp_stack = IoGetCurrentIrpStackLocation(irp); + ctrl_code = irp_stack->Parameters.DeviceIoControl.IoControlCode; - irp->IoStatus.Information = 0; - if( irp_stack->Parameters.DeviceIoControl.OutputBufferLength < sizeof( LONG ) ) - { - EXIT_DISPATCH( STATUS_INVALID_PARAMETER, irp ); - } + 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; - 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; - PUSB_DEV pdev; - PENUM_DEV_ARRAY peda; + irp->IoStatus.Information = 0; + if (irp_stack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(LONG)) + { + EXIT_DISPATCH(STATUS_INVALID_PARAMETER, irp); + } - 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 ); + 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); - 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; - KIRQL old_irql; - PUSB_DEV pdev; - LONG buf_size; - - if( irp_stack->Parameters.DeviceIoControl.InputBufferLength < sizeof( GET_DEV_DESC_REQ ) ) - { - EXIT_DISPATCH( STATUS_INVALID_PARAMETER, irp ); - } + *((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; + PUSB_DEV pdev; + PENUM_DEV_ARRAY peda; - 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 ); - } + 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); - 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; - } + 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( 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 ); + 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; - 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; - } + lock_dev(pdev, FALSE); + if (dev_state(pdev) == USB_DEV_STATE_ZOMB) + { + unlock_dev(pdev, FALSE); + continue; + } - pusb_config_desc = usb_find_config_desc_by_idx( - ( PUCHAR )&pdev->pusb_dev_desc[ 1 ], - gddr.desc_idx, - pdev->pusb_dev_desc->bNumConfigurations ); + if (dev_state(pdev) < USB_DEV_STATE_ADDRESSED) + { + unlock_dev(pdev, FALSE); + continue; + } - 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 ); + 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 = - 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: - { - LONG buf_size; - PURB purb; - KIRQL old_irql; - ULONG endp_idx, if_idx, user_buffer_length; - PUCHAR user_buffer; - PUSB_DEV pdev; - DEV_HANDLE endp_handle; - PUSB_ENDPOINT pendp; - - PUSB_CTRL_SETUP_PACKET psetup; + 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; + KIRQL old_irql; + PUSB_DEV pdev; + LONG buf_size; - if( irp_stack->Parameters.DeviceIoControl.InputBufferLength < sizeof( URB ) ) - { - EXIT_DISPATCH( STATUS_INVALID_PARAMETER, irp ); - } + if (irp_stack->Parameters.DeviceIoControl.InputBufferLength < sizeof(GET_DEV_DESC_REQ)) + { + EXIT_DISPATCH(STATUS_INVALID_PARAMETER, irp); + } - purb = ( PURB )irp->AssociatedIrp.SystemBuffer; - endp_handle = purb->endp_handle; + if (irp_stack->Parameters.DeviceIoControl.OutputBufferLength < 8) + { + EXIT_DISPATCH(STATUS_INVALID_PARAMETER, irp); + } - 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; - } + 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_idx = if_idx_from_handle( endp_handle ); - endp_idx = endp_idx_from_handle( endp_handle ); + if (gddr.desc_type != USB_DT_CONFIG && gddr.desc_type != USB_DT_DEVICE) + { + EXIT_DISPATCH(STATUS_INVALID_DEVICE_REQUEST, irp); + } - //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 (usb_query_and_lock_dev(dev_mgr, gddr.dev_handle, &pdev) != STATUS_SUCCESS) + { + EXIT_DISPATCH(STATUS_IO_DEVICE_ERROR, irp); + } - 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 ); + 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; + } - purb->data_buffer = user_buffer; - purb->data_length = user_buffer_length; - purb->completion = disp_urb_completion; - } - else - { - purb->completion = disp_noio_urb_completion; - } + if (pdev->pusb_dev_desc == NULL) + { + status = STATUS_DEVICE_NOT_READY; + goto ERROR_OUT; + } - unlock_dev( pdev, FALSE ); + 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); - // 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 ); + 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: + { + LONG buf_size; + PURB purb; + KIRQL old_irql; + ULONG endp_idx, if_idx, user_buffer_length; + PUCHAR user_buffer; + PUSB_DEV pdev; + DEV_HANDLE endp_handle; + PUSB_ENDPOINT pendp; + + PUSB_CTRL_SETUP_PACKET psetup; + + 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 ) diff --git a/reactos/drivers/usb/nt4compat/usbdriver/ehci.c b/reactos/drivers/usb/nt4compat/usbdriver/ehci.c index e49c9944b83..f184028b6fc 100644 --- a/reactos/drivers/usb/nt4compat/usbdriver/ehci.c +++ b/reactos/drivers/usb/nt4compat/usbdriver/ehci.c @@ -259,1343 +259,1160 @@ //declarations typedef struct { - union - { - PUHCI_DEV uhci; - PEHCI_DEV ehci; - }; - PVOID context; - ULONG ret; + 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 -); +ehci_alloc(PDRIVER_OBJECT drvr_obj, PUNICODE_STRING reg_path, ULONG bus_addr, PUSB_DEV_MANAGER dev_mgr); -BOOL -ehci_init_schedule( -PEHCI_DEV ehci, -PADAPTER_OBJECT padapter -); +BOOL ehci_init_schedule(PEHCI_DEV ehci, PADAPTER_OBJECT padapter); -BOOL -ehci_release( -PDEVICE_OBJECT pdev -); +BOOL ehci_release(PDEVICE_OBJECT pdev); -static VOID -ehci_stop( -PEHCI_DEV ehci -); +static VOID ehci_stop(PEHCI_DEV ehci); -BOOL -ehci_destroy_schedule( -PEHCI_DEV ehci -); +BOOL ehci_destroy_schedule(PEHCI_DEV ehci); -BOOLEAN -ehci_sync_insert_urb_schedule( -PVOID context -); +BOOLEAN ehci_sync_insert_urb_schedule(PVOID context); -VOID -ehci_init_hcd_interface( -PEHCI_DEV ehci -); +VOID ehci_init_hcd_interface(PEHCI_DEV ehci); -NTSTATUS -ehci_rh_submit_urb( -PUSB_DEV rh, -PURB purb -); +NTSTATUS ehci_rh_submit_urb(PUSB_DEV rh, PURB purb); -NTSTATUS -ehci_dispatch_irp( -IN PDEVICE_OBJECT DeviceObject, -IN PIRP irp -); +NTSTATUS ehci_dispatch_irp(IN PDEVICE_OBJECT DeviceObject, IN PIRP irp); -VOID -ehci_generic_urb_completion( -PURB purb, -PVOID context -); +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_bulk(PEHCI_DEV ehci, PURB purb); -static NTSTATUS -ehci_internal_submit_int( -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_ctrl(PEHCI_DEV ehci, PURB purb); -static NTSTATUS -ehci_internal_submit_iso( -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 -); +static ULONG ehci_scan_iso_error(PEHCI_DEV ehci, PURB purb); -BOOL -ehci_claim_bandwidth( -PEHCI_DEV ehci, -PURB purb, -BOOL claim_bw -);//true to claim band-width, false to free band-width +BOOL ehci_claim_bandwidth(PEHCI_DEV ehci, PURB purb, BOOL claim_bw); //true to claim band-width, false to free band-width -static VOID -ehci_insert_bulk_schedule( -PEHCI_DEV ehci, -PURB purb -); +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_int_schedule(PEHCI_DEV ehci, PURB purb); -static VOID -ehci_insert_iso_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_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 -); +PDEVICE_OBJECT ehci_create_device(PDRIVER_OBJECT drvr_obj, PUSB_DEV_MANAGER dev_mgr); -BOOL -ehci_delete_device( -PDEVICE_OBJECT pdev -); +BOOL ehci_delete_device(PDEVICE_OBJECT pdev); -VOID -ehci_get_capabilities( -PEHCI_DEV ehci, -PBYTE base -); +VOID ehci_get_capabilities(PEHCI_DEV ehci, PBYTE base); -BOOLEAN -ehci_isr( -PKINTERRUPT interrupt, -PVOID context -); +BOOLEAN ehci_isr(PKINTERRUPT interrupt, PVOID context); -BOOL -ehci_start( -PHCD hcd -); +BOOL ehci_start(PHCD hcd); -extern VOID -rh_timer_svc_reset_port_completion( -PUSB_DEV dev, -PVOID context -); +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 VOID rh_timer_svc_int_completion(PUSB_DEV dev, PVOID context); -extern USB_DEV_MANAGER g_dev_mgr; +extern USB_DEV_MANAGER g_dev_mgr; #ifndef INCLUDE_EHCI -ULONG debug_level = DBGLVL_MAXIMUM; -PDRIVER_OBJECT usb_driver_obj = NULL; +ULONG debug_level = DBGLVL_MAXIMUM; +PDRIVER_OBJECT usb_driver_obj = NULL; //pending endpoint pool funcs VOID -ehci_wait_ms( -PEHCI_DEV ehci, -LONG ms -) +ehci_wait_ms(PEHCI_DEV ehci, LONG ms) { LARGE_INTEGER lms; - if( ms <= 0 ) - return; + if (ms <= 0) + return; lms.QuadPart = -10 * ms; - KeSetTimer( &ehci->reset_timer, lms, NULL ); + KeSetTimer(&ehci->reset_timer, lms, NULL); - KeWaitForSingleObject( - &ehci->reset_timer, - Executive, - KernelMode, - FALSE, - NULL ); + KeWaitForSingleObject(&ehci->reset_timer, Executive, KernelMode, FALSE, NULL); - return; + return; } BOOL -init_pending_endp_pool( -PUHCI_PENDING_ENDP_POOL pool -) +init_pending_endp_pool(PUHCI_PENDING_ENDP_POOL pool) { - int i; - if( pool == NULL ) - return FALSE; + 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 ); + 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] ); - } + for(i = 0; i < MAX_TIMER_SVCS; i++) + { + free_pending_endp(pool, &pool->pending_endp_array[i]); + } - return TRUE; + return TRUE; } BOOL -free_pending_endp( -PUHCI_PENDING_ENDP_POOL pool, -PUHCI_PENDING_ENDP pending_endp -) +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++; + if (pool == NULL || pending_endp == NULL) + { + return FALSE; + } - return TRUE; + 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) +alloc_pending_endp(PUHCI_PENDING_ENDP_POOL pool, LONG count) { - PUHCI_PENDING_ENDP new; - if( pool == NULL || count != 1 ) - return NULL; + PUHCI_PENDING_ENDP new; + if (pool == NULL || count != 1) + return NULL; - if( pool->free_count <= 0 ) - return NULL; + if (pool->free_count <= 0) + return NULL; - new = ( PUHCI_PENDING_ENDP )RemoveHeadList( &pool->free_que ); - pool->free_count --; - return new; + new = (PUHCI_PENDING_ENDP) RemoveHeadList(&pool->free_que); + pool->free_count--; + return new; } BOOL -destroy_pending_endp_pool( -PUHCI_PENDING_ENDP_POOL pool -) +destroy_pending_endp_pool(PUHCI_PENDING_ENDP_POOL pool) { - if( pool == NULL ) - return FALSE; + 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; + 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; + return TRUE; } #else #define ehci_wait_ms uhci_wait_ms -extern VOID -uhci_wait_ms( -PEHCI_DEV ehci, -LONG ms -); +extern VOID uhci_wait_ms(PEHCI_DEV ehci, LONG ms); -extern BOOL -init_pending_endp_pool( -PUHCI_PENDING_ENDP_POOL pool -); +extern BOOL init_pending_endp_pool(PUHCI_PENDING_ENDP_POOL pool); -extern BOOL -free_pending_endp( -PUHCI_PENDING_ENDP_POOL pool, -PUHCI_PENDING_ENDP pending_endp -); +extern BOOL 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 PUHCI_PENDING_ENDP alloc_pending_endp(PUHCI_PENDING_ENDP_POOL pool, LONG count); -extern BOOL -destroy_pending_endp_pool( -PUHCI_PENDING_ENDP_POOL pool -); +extern BOOL destroy_pending_endp_pool(PUHCI_PENDING_ENDP_POOL pool); #endif //end of pending endpoint pool funcs static VOID -ehci_cancel_pending_endp_urb( -IN PVOID Parameter -) +ehci_cancel_pending_endp_urb(IN PVOID Parameter) { - PLIST_ENTRY abort_list; - PUSB_DEV pdev; - PURB purb; - USE_IRQL; + PLIST_ENTRY abort_list; + PUSB_DEV pdev; + PURB purb; + USE_IRQL; - abort_list = ( PLIST_ENTRY )Parameter; - - if( abort_list == NULL ) - return; + abort_list = (PLIST_ENTRY) Parameter; - 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 + if (abort_list == NULL) + return; - ehci_generic_urb_completion( purb, purb->context ); - - lock_dev( pdev, FALSE ); - pdev->ref_count--; - unlock_dev( pdev, FALSE ); - } - usb_free_mem( abort_list ); - 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 BOOL -ehci_process_pending_endp( -PEHCI_DEV ehci -) +ehci_process_pending_endp(PEHCI_DEV ehci) { - PUSB_DEV pdev; - LIST_ENTRY temp_list, abort_list; - PLIST_ENTRY pthis; - PURB purb; - PUSB_ENDPOINT pendp; - BOOL can_submit; - PWORK_QUEUE_ITEM pwork_item; - PLIST_ENTRY cancel_list; - PUSB_DEV pparent; - UCHAR port_idx; - BOOL tt_needed; - UCHAR hub_addr; - PURB_HS_CONTEXT_CONTENT phcc; - USE_IRQL; + PUSB_DEV pdev; + LIST_ENTRY temp_list, abort_list; + PLIST_ENTRY pthis; + PURB purb; + PUSB_ENDPOINT pendp; + BOOL can_submit; + PWORK_QUEUE_ITEM pwork_item; + PLIST_ENTRY cancel_list; + PUSB_DEV pparent; + UCHAR port_idx; + BOOL tt_needed; + UCHAR hub_addr; + PURB_HS_CONTEXT_CONTENT phcc; + USE_IRQL; - if( ehci == NULL ) - return FALSE; + if (ehci == NULL) + return FALSE; - InitializeListHead( &temp_list ); - InitializeListHead( &abort_list ); + InitializeListHead(&temp_list); + InitializeListHead(&abort_list); - purb = NULL; - ehci_dbg_print( DBGLVL_MEDIUM, ("ehci_process_pending_endp(): entering..., ehci=0x%x\n", ehci ) ); + 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 ) - { + 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 ); + ehci_dbg_print(DBGLVL_MAXIMUM, ("ehci_process_pending_endp(): pending_endp_list=0x%x\n", + &ehci->pending_endp_list)); - 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 ); + tt_needed = FALSE; + pthis = RemoveHeadList(&ehci->pending_endp_list); + pendp = ((PUHCI_PENDING_ENDP) pthis)->pendp; + pdev = dev_from_endp(pendp); + lock_dev(pdev, TRUE); - // pparent won't be removed when pending_endp_list_lock is acquired. - get_parent_hs_hub( pdev, pparent, port_idx ); + 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); - 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; - } + // pparent won't be removed when pending_endp_list_lock is acquired. + get_parent_hs_hub(pdev, pparent, port_idx); - 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; - } + 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; + } - // backup the hub address for future use - hub_addr = pparent->dev_addr; + 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; + } - 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 - } + // backup the hub address for future use + hub_addr = pparent->dev_addr; - 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; - } + 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( 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 (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 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 (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( can_submit == STATUS_NO_MORE_ENTRIES ) - { - //no enough bandwidth or tds - InsertHeadList( &pendp->urb_list, ( PLIST_ENTRY )purb ); - 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 (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( 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 ); + // 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; + } + } - ListFirst( &abort_list, pthis ); - RemoveEntryList( &abort_list ); - InsertTailList( pthis, cancel_list ); - - pwork_item = ( PWORK_QUEUE_ITEM )&cancel_list[ 1 ]; + if (can_submit == STATUS_NO_MORE_ENTRIES) + { + //no enough bandwidth or tds + InsertHeadList(&pendp->urb_list, (PLIST_ENTRY) purb); + InsertTailList(&temp_list, pthis); + } + else + { + // otherwise error or success + free_pending_endp(&ehci->pending_endp_pool, struct_ptr(pthis, UHCI_PENDING_ENDP, endp_link)); - // 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; + 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; } BOOL -ehci_submit_urb( -PEHCI_DEV ehci, -PUSB_DEV pdev, -PUSB_ENDPOINT pendp, -PURB purb -) +ehci_submit_urb(PEHCI_DEV ehci, PUSB_DEV pdev, PUSB_ENDPOINT pendp, PURB purb) { - int i; - PLIST_ENTRY pthis, pnext; - PUHCI_PENDING_ENDP pending_endp; - NTSTATUS status; - USE_IRQL; + int i; + PLIST_ENTRY pthis, pnext; + PUHCI_PENDING_ENDP pending_endp; + NTSTATUS status; + USE_IRQL; - if( ehci == NULL ) - return STATUS_INVALID_PARAMETER; + 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; - } + 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 ); + 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_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_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( dev_from_endp( purb->pendp ) != pdev ) - { - status = purb->status = STATUS_INVALID_PARAMETER; - goto LBL_OUT; - } + if (pendp) + purb->pendp = pendp; + else + purb->pendp = &pdev->default_endp; - if( endp_state( purb->pendp ) == USB_ENDP_FLAG_STALL ) - { - status = purb->status = USB_STATUS_ENDPOINT_HALTED; - goto LBL_OUT; - } + if (dev_from_endp(purb->pendp) != pdev) + { + status = purb->status = STATUS_INVALID_PARAMETER; + goto LBL_OUT; + } - if( ( pdev->flags & USB_DEV_FLAG_HIGH_SPEED ) == 0 ) - { - // wait one ms - usb_wait_ms_dpc( 1 ); - } + 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 ((pdev->flags & USB_DEV_FLAG_HIGH_SPEED) == 0) + { + // wait one ms + usb_wait_ms_dpc(1); + } - 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; + purb->pdev = pdev; + purb->rest_bytes = 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; + 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 ); + i = IsListEmpty(&pendp->urb_list); + InsertTailList(&pendp->urb_list, &purb->urb_link); - pdev->ref_count ++; //for purb reference + 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 ) - { + 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; - } + //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 = 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, ( PLIST_ENTRY )pending_endp ); + pending_endp->pendp = purb->pendp; + InsertTailList(&ehci->pending_endp_list, (PLIST_ENTRY) pending_endp); - unlock_dev( pdev, TRUE ); - unlock_pending_endp_list( &ehci->pending_endp_list_lock ); + unlock_dev(pdev, TRUE); + unlock_pending_endp_list(&ehci->pending_endp_list_lock); - ehci_process_pending_endp( ehci ); - return STATUS_PENDING; + ehci_process_pending_endp(ehci); + return STATUS_PENDING; -LBL_OUT2: - pdev->ref_count --; - RemoveEntryList( ( PLIST_ENTRY )purb ); + LBL_OUT2: + pdev->ref_count--; + RemoveEntryList((PLIST_ENTRY) purb); -LBL_OUT: - unlock_dev( pdev, TRUE ); - unlock_pending_endp_list( &ehci->pending_endp_list_lock ); - ehci_process_pending_endp( ehci ); - return status; + 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 -) +ehci_set_error_code(PURB purb, ULONG raw_status) { - PURB_HS_PIPE_CONTENT pipe_content; + PURB_HS_PIPE_CONTENT pipe_content; - pipe_content = ( PURB_HS_PIPE_CONTENT )&purb->pipe; + 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; + //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 ) - { + 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; + 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_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_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_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 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 + 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_BABBLE) + purb->status = USB_STATUS_BABBLE_DETECTED; - else if( raw_status & ITD_STS_XACTERR ) // Xact Err - purb->status = USB_STATUS_CRC; + else if (raw_status & ITD_STS_XACTERR) // Xact Err + purb->status = USB_STATUS_CRC; - else - purb->status = STATUS_UNSUCCESSFUL; + 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_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_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_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_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 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; + 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; } BOOLEAN -ehci_sync_remove_urb_finished( -PVOID context -) +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; + PEHCI_DEV ehci; + PLIST_ENTRY pthis, pnext, ptemp; + PURB purb; + PSYNC_PARAM pparam; - if( ehci == NULL ) - { - return ( UCHAR )pparam->ret = FALSE; - } - - ListFirst( &ehci->urb_list, pthis ); - while( pthis ) - { + 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; + ListNext(&ehci->urb_list, pthis, pnext); + purb = (PURB) pthis; - if( ( purb->flags & URB_FLAG_IN_SCHEDULE ) == 0 ) - { + 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; + RemoveEntryList(pthis); + InsertTailList(ptemp, pthis); + } + pthis = pnext; + } + pparam->ret = TRUE; + return (UCHAR) TRUE; } VOID -ehci_dpc_callback( -PKDPC dpc, -PVOID context, -PVOID sysarg1, -PVOID sysarg2 -) +ehci_dpc_callback(PKDPC dpc, PVOID context, PVOID sysarg1, PVOID sysarg2) { - PEHCI_DEV ehci; + PEHCI_DEV ehci; - LIST_HEAD temp_list; - PLIST_ENTRY pthis, pnext; - PURB purb; - PEHCI_QH pqh; - PEHCI_QTD ptd; - PUHCI_PENDING_ENDP pending_endp; - PEHCI_FSTN pfstn; - PUSB_DEV pdev; - PUSB_ENDPOINT pendp; + LIST_HEAD temp_list; + PLIST_ENTRY pthis, pnext; + PURB purb; + PEHCI_QH pqh; + PEHCI_QTD ptd; + PUHCI_PENDING_ENDP pending_endp; + PEHCI_FSTN pfstn; + PUSB_DEV pdev; + PUSB_ENDPOINT pendp; - BOOL finished; - LONG i; - ULONG ehci_status, urb_status, toggle = 0; + BOOL finished; + LONG i; + ULONG ehci_status, urb_status, toggle = 0; - SYNC_PARAM sync_param; - UCHAR ep_type; - USE_IRQL; + SYNC_PARAM sync_param; + UCHAR ep_type; + USE_IRQL; - ehci = ( PEHCI_DEV ) context; - if( ehci == NULL ) - return; + ehci = (PEHCI_DEV) context; + if (ehci == NULL) + return; - ehci_status = ( ULONG )sysarg1; + 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 ); + 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 + 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 ); + 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 ); - } + 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 ); + //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; - PEHCI_ITD_CONTENT pitdc; - PEHCI_SITD_CONTENT psitdc; + 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; + PEHCI_ITD_CONTENT pitdc; + PEHCI_SITD_CONTENT psitdc; - em_type = ( UCHAR )elem_type( pthis, TRUE ); + 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; - } + // 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 ); - } + // 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 ); + ListFirst(&purb->trasac_list, pthis); + RemoveEntryList(&purb->trasac_list); - // free the tds - elem_safe_free( pthis, FALSE ); + // free the tds + elem_safe_free(pthis, FALSE); - //termination condition - InitializeListHead( &purb->trasac_list ); - purb->last_finished_td = NULL; - } - } + //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 + 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 ); + KeReleaseSpinLockFromDpcLevel(&ehci->pending_endp_list_lock); - pdev = dev_from_endp( purb->pendp ); - pendp = purb->pendp; + ehci_set_error_code(purb, urb_status); - // 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; + pdev = dev_from_endp(purb->pendp); + pendp = purb->pendp; - get_parent_hs_hub( pdev, phub, port_idx ); - pipe_content = ( PURB_HS_PIPE_CONTENT )&purb->pipe; + // 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; - 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 + 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 ); - } + 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 ); + } - //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 (ehci_status & STS_HALT) //&& !ehci->is_suspended + { + ehci_start(&ehci->hcd_interf); + } - 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 ); + //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( finished ) - pdev->ref_count--; + 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 + } + } - 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; - } + KeAcquireSpinLockAtDpcLevel(&ehci->pending_endp_list_lock); + lock_dev(pdev, TRUE); - if( dev_state( pdev )== USB_DEV_STATE_ZOMB ) - { - unlock_dev( pdev, TRUE); - KeReleaseSpinLockFromDpcLevel( &ehci->pending_endp_list_lock ); - if( finished == FALSE ) - { + if (finished) + pdev->ref_count--; - purb->status = STATUS_DEVICE_DOES_NOT_EXIST; - ehci_generic_urb_completion( purb, purb->context ); + 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; + } - 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 ) - { + 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; - } - } + 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; + 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; + //the purb is not finished + purb->flags &= ~URB_FLAG_STATE_MASK; + purb->flags |= URB_FLAG_STATE_PENDING; - InsertHeadList( &pendp->urb_list, ( PLIST_ENTRY )purb ); - } + InsertHeadList(&pendp->urb_list, (PLIST_ENTRY) purb); + } - pending_endp = alloc_pending_endp( &ehci->pending_endp_pool, 1 ); - pending_endp->pendp = pendp; - InsertTailList( &ehci->pending_endp_list, &pending_endp->endp_link ); + pending_endp = alloc_pending_endp(&ehci->pending_endp_pool, 1); + pending_endp->pendp = pendp; + InsertTailList(&ehci->pending_endp_list, &pending_endp->endp_link); - unlock_dev( pdev, TRUE); - KeReleaseSpinLockFromDpcLevel( &ehci->pending_endp_list_lock ); - } + 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; + //ah...exhausted, let's find some in the pending_endp_list to rock + ehci_process_pending_endp(ehci); + return; } BOOLEAN -ehci_sync_cancel_urbs_dev( -PVOID context -) +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; + //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; + 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 (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; + if (count) + { + // signal an int for further process + press_doorbell(ehci); + } + return (UCHAR) sync_param->ret = TRUE; } BOOL -ehci_remove_device( -PEHCI_DEV ehci, -PUSB_DEV dev -) +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_IRQL; + PUHCI_PENDING_ENDP ppending_endp; + PLIST_ENTRY pthis, pnext; + PURB purb; + LIST_HEAD temp_list; + int i, j, k; + SYNC_PARAM sync_param; - if( ehci == NULL || dev == NULL ) - return FALSE; + USE_IRQL; - InitializeListHead( &temp_list ); + if (ehci == NULL || dev == NULL) + return FALSE; - //free pending endp that has purb queued from pending endp list - lock_pending_endp_list( &ehci->pending_endp_list_lock ); + InitializeListHead(&temp_list); - ListFirst( &ehci->pending_endp_list, pthis ); + //free pending endp that has purb queued from pending endp list + lock_pending_endp_list(&ehci->pending_endp_list_lock); - 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 ); + ListFirst(&ehci->pending_endp_list, pthis); - //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 ); + 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 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 ); + //cancel all the urbs in the purb-list + sync_param.ehci = ehci; + sync_param.context = (PVOID) dev; - RemoveEntryList( pthis ); - InsertHeadList( &temp_list, pthis ); - pthis = pnext; - k++; - } + KeSynchronizeExecution(ehci->pdev_ext->ehci_int, ehci_sync_cancel_urbs_dev, &sync_param); - } - } - } - ListFirst( &dev->default_endp.urb_list, pthis ); - - while( pthis ) - { - ListNext( &dev->default_endp.urb_list, - pthis, - pnext ); + //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++; - } - unlock_dev( dev, FALSE ); + RemoveEntryList(pthis); + InsertHeadList(&temp_list, pthis); + pthis = pnext; + k++; + } - 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 ); - } - } - } + } + } + } + ListFirst(&dev->default_endp.urb_list, pthis); - lock_dev( dev, FALSE ) - dev->ref_count -= k; - unlock_dev( dev, FALSE ); + while (pthis) + { + ListNext(&dev->default_endp.urb_list, pthis, pnext); - return TRUE; + 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 BOOL -ehci_insert_urb_schedule( -PEHCI_DEV ehci, -PURB purb -) +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; + PURB_HS_PIPE_CONTENT pipe_content; - if( ehci == NULL || purb == NULL ) - return FALSE; + 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; - } + 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, ( PLIST_ENTRY )purb ); + purb->flags &= ~URB_FLAG_STATE_MASK; + purb->flags |= URB_FLAG_STATE_IN_PROCESS | URB_FLAG_IN_SCHEDULE; + InsertTailList(&ehci->urb_list, (PLIST_ENTRY) purb); - return TRUE; + return TRUE; } static BOOL -ehci_insert_tds_qh( -PEHCI_DEV ehci, -PEHCI_QH pqh, -PEHCI_QTD td_chain -) +ehci_insert_tds_qh(PEHCI_DEV ehci, PEHCI_QH pqh, PEHCI_QTD td_chain) { - if( pqh == NULL || td_chain == NULL ) - return FALSE; + if (pqh == NULL || td_chain == NULL) + return FALSE; - 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; - 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; + ehci; } static BOOL -ehci_insert_qh_urb( -PURB purb, -PEHCI_QH pqh -) +ehci_insert_qh_urb(PURB purb, PEHCI_QH pqh) { - PLIST_ENTRY pthis, pnext; - if( pqh == NULL || purb == NULL ) - return FALSE; + 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; + 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 ) \ @@ -1633,107 +1450,99 @@ PEHCI_QH pqh } static BOOL -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 -) +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; + 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; + 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; + 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; + 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; - } + 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; + 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; + 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; + 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 ); + // 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; + 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; + ptdc->bytes_to_transfer = (USHORT) data_load; + ptd->bytes_to_transfer = (USHORT) data_load; - data_load -= ( PAGE_SIZE < data_load ? PAGE_SIZE : 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; + 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 -) +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. @@ -1744,3046 +1553,2865 @@ PURB purb { LONG max_packet_size, td_count, offset, bytes_to_transfer, data_load; - PBYTE start_addr; - PEHCI_QTD ptd; - PEHCI_QH pqh; - LIST_ENTRY td_list, *pthis, *pnext; + PBYTE start_addr; + PEHCI_QTD ptd; + PEHCI_QH pqh; + LIST_ENTRY td_list, *pthis, *pnext; BOOL old_toggle, toggle, ret; - UCHAR pid; - LONG i, j, k; - PURB_HS_PIPE_CONTENT pipe_content; - PEHCI_QTD_CONTENT ptdc; - PEHCI_QH_CONTENT pqhc; - PEHCI_ELEM_LINKS pelnk; + UCHAR pid; + LONG i, j, k; + PURB_HS_PIPE_CONTENT pipe_content; + PEHCI_QTD_CONTENT ptdc; + PEHCI_QH_CONTENT pqhc; + PEHCI_ELEM_LINKS pelnk; - if( ehci == NULL || purb == NULL ) - return STATUS_INVALID_PARAMETER; + 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; - } + 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 ); + 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 ); + 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 ); + 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 ); + InitializeListHead(&td_list); + InsertTailList(&ptd->elem_head_link->elem_link, &td_list); - ListFirst( &td_list, pthis ); - ListNext( &td_list, pthis, pnext ); + 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 ) ); + 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 ) + for(i = 1; i < 16; i++) { - ptd = qtd_from_list_entry( pthis ); - ptdc = ( PEHCI_QTD_CONTENT ) ptd; + if ((max_packet_size >> i) == 0) + break; + } + i--; + i &= 0xf; - // ptdc->alt_terminal = 1; - // ptdc->alt_qtd = 0; - ptd->hw_alt_next = EHCI_PTR_TERM; - ptdc->pid = pid; + 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; - // 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; + pid = (((ULONG) purb->pendp->pusb_endp_desc->bEndpointAddress & USB_DIR_IN) ? QTD_PID_IN : QTD_PID_OUT); - if( pnext ) - { - ptd->hw_next = qtd_from_list_entry( pnext )->phys_addr; - } - else - { + 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; - } - } + 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; + pthis = pnext; - if( pthis ) - ListNext( &td_list, pthis, pnext ); - } + if (pthis) + ListNext(&td_list, pthis, pnext); + } - ListFirst( &td_list, pthis ); - RemoveEntryList( &td_list ); + ListFirst(&td_list, pthis); + RemoveEntryList(&td_list); - elem_pool_lock( qh_pool, TRUE ); - pqh = ( PEHCI_QH )( ( ULONG )elem_pool_alloc_elem( qh_pool )->phys_part & PHYS_PART_ADDR_MASK ); - elem_pool_unlock( qh_pool, TRUE); + elem_pool_lock(qh_pool, TRUE); + pqh = (PEHCI_QH) ((ULONG) elem_pool_alloc_elem(qh_pool)->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; + 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; + 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; + 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 + 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; - } + 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 ); + 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); - RemoveEntryList( &purb->trasac_list ); - RemoveEntryList( &pqh->elem_head_link->elem_link ); //remove qh from td_chain + if (ret == FALSE) + { + // undo all we have done + ListFirst(&pqh->elem_head_link->elem_link, pthis); - elem_safe_free( pthis, FALSE ); - elem_safe_free( &pqh->elem_head_link->elem_link, TRUE ); + RemoveEntryList(&purb->trasac_list); + RemoveEntryList(&pqh->elem_head_link->elem_link); //remove qh from td_chain - 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; + 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 -) +ehci_internal_submit_ctrl(PEHCI_DEV ehci, PURB purb) { LIST_ENTRY td_list, *pthis, *pnext; - LONG i, j, td_count; - LONG toggle; - LONG max_packet_size, bytes_to_transfer, bytes_rest, start_idx; + LONG i, j, 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; - BOOL 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; + PEHCI_QTD ptd; + PEHCI_QH pqh; + PEHCI_QH_CONTENT pqhc; + UCHAR dev_addr; + BOOL ret; + PURB_HS_PIPE_CONTENT pipe_content; + PEHCI_QTD_CONTENT ptdc; + PEHCI_ELEM_LINKS pelnk; + PUSB_DEV pdev; - 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; + if (ehci == NULL || purb == NULL) + return STATUS_INVALID_PARAMETER; - calc_td_count( purb, start_idx, td_count ); - td_count += 2; // add setup td and handshake td + 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; - elem_pool_lock( qtd_pool, TRUE ); - pelnk = elem_pool_alloc_elems( qtd_pool, td_count ); - elem_pool_unlock( qtd_pool, TRUE ); + calc_td_count(purb, start_idx, td_count); + td_count += 2; // add setup td and handshake td - if( pelnk == NULL ) - { - return STATUS_NO_MORE_ENTRIES; - } + elem_pool_lock(qtd_pool, TRUE); + pelnk = elem_pool_alloc_elems(qtd_pool, td_count); + elem_pool_unlock(qtd_pool, TRUE); - InsertTailList( &pelnk->elem_link, &td_list ); - ListFirst( &td_list, pthis ); - ListNext( &td_list, pthis, pnext ); + if (pelnk == NULL) + { + return STATUS_NO_MORE_ENTRIES; + } - 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; + InsertTailList(&pelnk->elem_link, &td_list); + ListFirst(&td_list, pthis); + ListNext(&td_list, pthis, pnext); - for( i = 1; i < 16; i++ ) - { - if( ( max_packet_size >> i ) == 0 ) - break; - } - i--; - i &= 0xf; + ptd = qtd_from_list_entry(pthis); - 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; + pdev = dev_from_endp(purb->pendp); + dev_addr = pdev->dev_addr; - pthis = pnext; - ListNext( &td_list, pthis, pnext ); + if (dev_state(pdev) <= USB_DEV_STATE_RESET) //only valid for control transfer + dev_addr = 0; - // 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 ); + usb_dbg_print(DBGLVL_MAXIMUM, ("ehci_internal_submit_ctrl(): dev_addr =0x%x\n", dev_addr)); - for( i = 0; ( ( i < td_count - 2 ) && pthis ); i++ ) - { + // 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; + 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; + 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 ); - } + pthis = pnext; + if (pthis) + ListNext(&td_list, pthis, pnext); + } - if( pthis ) - ptd->hw_next = qtd_from_list_entry( pthis )->phys_addr; - else - TRAP(); + if (pthis) + ptd->hw_next = qtd_from_list_entry(pthis)->phys_addr; + else + TRAP(); - // ListFirstPrev( &td_list, pthis ); - ptd = qtd_from_list_entry( pthis ); + // 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 = (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; + 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 ); + 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); + 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; + 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 = (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; + 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 ); + 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; + 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 ); + 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; + if (pipe_content->speed_high == 0) + pqhc->is_ctrl_endp = 1; + else + pqhc->is_ctrl_endp = 0; - pqhc->reload_counter = EHCI_NAK_RL_COUNT; + pqhc->reload_counter = EHCI_NAK_RL_COUNT; - // DWORD 2 - pqh->hw_info2 = 0; - pqhc->mult = 1; + // 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; - } + 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; + purb->td_count = td_count; - ehci_insert_tds_qh( ehci, pqh, ptd ); - ehci_insert_qh_urb( purb, pqh ); + 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 ); + 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 ); + 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 ); + 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; + 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 -) +ehci_internal_submit_int(PEHCI_DEV ehci, PURB purb) { LIST_ENTRY td_list, *pthis, *pnext; - LONG i, max_packet_size; - PEHCI_QTD ptd; - BOOL 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; + LONG i, max_packet_size; + PEHCI_QTD ptd; + BOOL 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; + 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 ); + 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 (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; + 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; - } + 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 ) == USB_DIR_IN ? 1 : 0; // 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; + 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) == USB_DIR_IN ? 1 : 0; // 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 + // 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; + 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 ) + 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; - } + 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 ); + // 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; - } + 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 ); + 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; + 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 ); + 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; + 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; + 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; + // 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; - } + 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; + // DWORD 3 + purb->td_count = 1; - InitializeListHead( &purb->trasac_list ); - ehci_insert_tds_qh( ehci, pqh, ptd ); - ehci_insert_qh_urb( purb, pqh ); + 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 ); + purb->pendp->flags = (purb->pendp->flags & ~USB_ENDP_FLAG_DATATOGGLE) | (toggle << 31); + usb_endp_busy_count_inc(purb->pendp); - 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 ); + ehci_insert_urb_to_schedule(ehci, purb, ret); - InitializeListHead( &purb->trasac_list ); - ehci_claim_bandwidth( ehci, purb, FALSE ); + if (ret == FALSE) + { + RemoveEntryList(&purb->trasac_list); + RemoveEntryList(&pqh->elem_head_link->elem_link); - purb->pendp->flags = ( purb->pendp->flags & ~USB_ENDP_FLAG_DATATOGGLE ) | ( ( toggle ^ 1 ) << 31 ); - // usb_endp_busy_count_dec( purb->pendp ); + 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); - return STATUS_UNSUCCESSFUL; - } - - return STATUS_SUCCESS; + 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 -) +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; - BOOL toggle, ret; - KIRQL old_irql; - 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 ) == USB_DIR_IN ? 1 : 0; // 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, n2; - // 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; + 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; + BOOL toggle, ret; + KIRQL old_irql; + 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) == USB_DIR_IN ? 1 : 0; // 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, n2; + // 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 -ehci_sync_insert_urb_schedule( -PVOID context -) +ehci_sync_insert_urb_schedule(PVOID context) //this function used as the KeSynchronizeExecution param to delegate control to ehci_insert_urb_schedule -{ - PSYNC_PARAM sync_param; - PEHCI_DEV ehci; - PURB purb; +{ + PSYNC_PARAM sync_param; + PEHCI_DEV ehci; + PURB purb; - sync_param = ( PSYNC_PARAM ) context; - if( sync_param == NULL ) - return FALSE; + sync_param = (PSYNC_PARAM) context; + if (sync_param == NULL) + return FALSE; - ehci = sync_param->ehci; - purb = ( PURB )sync_param->context; + ehci = sync_param->ehci; + purb = (PURB) sync_param->context; - if( ehci == NULL || purb == NULL ) - return ( UCHAR )sync_param->ret = FALSE; + if (ehci == NULL || purb == NULL) + return (UCHAR) sync_param->ret = FALSE; - return ( UCHAR )( sync_param->ret = ehci_insert_urb_schedule( ehci, purb ) ); + return (UCHAR) (sync_param->ret = ehci_insert_urb_schedule(ehci, purb)); } BOOLEAN -ehci_sync_cancel_urb( -PVOID context -) +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; - BOOL found = FALSE; - - if( context == NULL ) - return FALSE; + //cancel a single purb + PEHCI_DEV ehci; + PSYNC_PARAM sync_param; + PURB purb2, dest_urb; + PLIST_ENTRY pthis, pnext; + BOOL found = FALSE; - sync_param = ( PSYNC_PARAM )context; - ehci = sync_param->ehci; - dest_urb = ( PURB )sync_param->context; + if (context == NULL) + return FALSE; - 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; - } + sync_param = (PSYNC_PARAM) context; + ehci = sync_param->ehci; + dest_urb = (PURB) sync_param->context; - if( found ) - { - press_doorbell( ehci ); - } - return ( UCHAR )( sync_param->ret = found ); + 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 -) +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 { - NTSTATUS status; - PLIST_ENTRY pthis, pnext; - BOOL found; - PURB purb2; - - SYNC_PARAM sync_param; - - USE_IRQL; + NTSTATUS status; + PLIST_ENTRY pthis, pnext; + BOOL found; + PURB purb2; - if( ehci == NULL || purb == NULL || pdev == NULL || pendp == NULL ) - return STATUS_INVALID_PARAMETER; + SYNC_PARAM sync_param; - lock_dev( pdev, FALSE ); + USE_IRQL; - 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 (ehci == NULL || purb == NULL || pdev == NULL || pendp == NULL) + return STATUS_INVALID_PARAMETER; - if( dev_from_endp( pendp ) != pdev ) - { - unlock_dev( pdev, FALSE ); - return STATUS_INVALID_PARAMETER; - } + lock_dev(pdev, FALSE); - 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; - } + 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; + } - 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 (dev_from_endp(pendp) != pdev) + { + unlock_dev(pdev, FALSE); + return STATUS_INVALID_PARAMETER; + } - if( found ) - { - purb->status = STATUS_CANCELLED; - - ehci_generic_urb_completion( purb, purb->context ); + 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; + } - lock_dev( pdev, FALSE ); - pdev->ref_count --; - unlock_dev( pdev, FALSE ); - return STATUS_SUCCESS; - } + 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); - // 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 ); + if (found) + { + purb->status = STATUS_CANCELLED; - found = sync_param.ret; - - if( found ) - return USB_STATUS_CANCELING; + ehci_generic_urb_completion(purb, purb->context); - return STATUS_INVALID_PARAMETER; + 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 -) +ehci_generic_urb_completion(PURB purb, PVOID context) { - PUSB_DEV pdev; - KIRQL cur_irql; - BOOL is_ctrl; - USE_IRQL; + PUSB_DEV pdev; + KIRQL cur_irql; + BOOL is_ctrl; + USE_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; + old_irql = KeGetCurrentIrql(); + if (old_irql > DISPATCH_LEVEL) + TRAP(); - if( pdev == NULL ) - goto LBL_LOWER_IRQL; + if (old_irql < DISPATCH_LEVEL) + KeRaiseIrql(DISPATCH_LEVEL, &old_irql); - lock_dev( pdev, TRUE ); + pdev = purb->pdev; + if (purb == NULL) + goto LBL_LOWER_IRQL; - 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 (pdev == NULL) + goto LBL_LOWER_IRQL; - 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; - - } + lock_dev(pdev, TRUE); - is_ctrl = FALSE; - if( endp_type( purb->pendp ) == USB_ENDPOINT_XFER_CONTROL ) - is_ctrl = 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++; + } - unlock_dev( pdev, TRUE ); + 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; -LBL_CLIENT_PROCESS: - if( !is_ctrl ) - { - if( purb->completion ) - purb->completion( purb, context ); - } - else - { - PCTRL_REQ_STACK pstack; - 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 ); + is_ctrl = FALSE; + if (endp_type(purb->pendp) == USB_ENDPOINT_XFER_CONTROL) + is_ctrl = TRUE; - return; + unlock_dev(pdev, TRUE); + + LBL_CLIENT_PROCESS: + if (!is_ctrl) + { + if (purb->completion) + purb->completion(purb, context); + } + else + { + PCTRL_REQ_STACK pstack; + 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 -) +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; + 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_IRQL; - if( pdev == NULL || purb == NULL ) - return STATUS_INVALID_PARAMETER; + USE_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; - } + dev_mgr = dev_mgr_from_dev(pdev); - ehci = ehci_from_hcd( pdev->hcd ); - psetup = ( PUSB_CTRL_SETUP_PACKET ) purb->setup_packet; + 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; + } - 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; - } + ehci = ehci_from_hcd(pdev->hcd); + psetup = (PUSB_CTRL_SETUP_PACKET) purb->setup_packet; - 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; + hub_ext = ((PHUB2_EXTENSION) pdev->dev_ext); + port_count = (UCHAR) ((PEHCI_HCS_CONTENT) & ehci->ehci_caps.hcs_params)->port_count; - 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; - } + 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; - 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; + status = EHCI_READ_PORT_ULONG((PULONG) (ehci->port_base + i)); + ps = &hub_ext->rh_port_status[psetup->wIndex]; - i = EHCI_PORTSC + 4 * ( psetup->wIndex - 1 ); // USBPORTSC1; - - ptimer = alloc_timer_svc( &dev_mgr->timer_svc_pool, 1 ); - 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; + psret = (PUSB_PORT_STATUS) purb->data_buffer; + ps->wPortStatus = 0; - //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 ); - ptimer->threshold = RH_INTERVAL; - ptimer->context = ( ULONG )purb; - ptimer->pdev = pdev; - ptimer->func = rh_timer_svc_int_completion; + 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; + } - //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 + //always power on + ps->wPortStatus |= USB_PORT_STAT_POWER; - 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; + //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); + 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); + 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 BOOL -ehci_rh_reset_port( -PHCD hcd, -UCHAR port_idx -) +ehci_rh_reset_port(PHCD hcd, UCHAR port_idx) { - ULONG i; - PEHCI_DEV ehci; - ULONG status; - UCHAR port_count; + ULONG i; + PEHCI_DEV ehci; + ULONG status; + UCHAR port_count; - if( hcd == NULL ) - return FALSE; + if (hcd == NULL) + return FALSE; - ehci = ehci_from_hcd( hcd ); - port_count = ( UCHAR )( ( PEHCI_HCS_CONTENT )&ehci->ehci_caps.hcs_params )->port_count; + 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 ) ); + if (port_idx < 1 || port_idx > port_count) + return FALSE; - // assert the reset signal,(implicitly disable the port) - SET_RH2_PORTSTAT( i, PORT_PR ); + i = (ULONG) (EHCI_PORTSC + 4 * (port_idx - 1)); - usb_wait_ms_dpc( 50 ); - // clear the reset signal, delay port enable till clearing port feature - CLR_RH2_PORTSTAT( i, PORT_PR ); + // assert the reset signal,(implicitly disable the port) + SET_RH2_PORTSTAT(i, PORT_PR); - // wait the port stable - usb_wait_ms_dpc( 2 ); + usb_wait_ms_dpc(50); + // clear the reset signal, delay port enable till clearing port feature + CLR_RH2_PORTSTAT(i, PORT_PR); - 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 ); + // wait the port stable + usb_wait_ms_dpc(2); - //recovery time 10ms - usb_wait_ms_dpc( 10 ); + 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 ); - // clear PORT_PEC and PORT_PCC - SET_RH2_PORTSTAT( i, 0x0a ); + //recovery time 10ms + usb_wait_ms_dpc(10); - 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; + // 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 -) +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; + PEHCI_DEVICE_EXTENSION pdev_ext; + PUSB_DEV_MANAGER dev_mgr; + PEHCI_DEV ehci; - dev_mgr = ehci->hcd_interf.hcd_get_dev_mgr( &ehci->hcd_interf ); - return dev_mgr_dispatch( dev_mgr, irp ); + 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 -) - +ehci_set_dev_mgr(PHCD hcd, PUSB_DEV_MANAGER dev_mgr) { - hcd->dev_mgr = dev_mgr; + hcd->dev_mgr = dev_mgr; } PUSB_DEV_MANAGER -ehci_get_dev_mgr( -PHCD hcd -) +ehci_get_dev_mgr(PHCD hcd) { - return hcd->dev_mgr; + return hcd->dev_mgr; } -ULONG -ehci_get_type( -PHCD hcd -) +ULONG +ehci_get_type(PHCD hcd) { - return HCD_TYPE_EHCI; // ( hcd->flags & HCD_TYPE_MASK ); + return HCD_TYPE_EHCI; // ( hcd->flags & HCD_TYPE_MASK ); } VOID -ehci_set_id( -PHCD hcd, -UCHAR id -) +ehci_set_id(PHCD hcd, UCHAR id) { - hcd->flags &= ~HCD_ID_MASK; - hcd->flags |= ( HCD_ID_MASK & id ); + hcd->flags &= ~HCD_ID_MASK; + hcd->flags |= (HCD_ID_MASK & id); } UCHAR -ehci_get_id( -PHCD hcd -) +ehci_get_id(PHCD hcd) { - return ( UCHAR )( hcd->flags & HCD_ID_MASK ); + return (UCHAR) (hcd->flags & HCD_ID_MASK); } UCHAR -ehci_alloc_addr( -PHCD hcd -) +ehci_alloc_addr(PHCD hcd) { - LONG i; - if( hcd == NULL ) - return 0; + 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; - } - } + 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; + if (i >= MAX_DEVS) + return 0xff; - hcd->dev_addr_map[ i >> 3 ] |= ( 1 << ( i & 7 ) ); - hcd->conn_count++; - return ( BYTE )i; + 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; +ehci_free_addr(PHCD hcd, UCHAR addr) +{ + if (addr & 0x80) + return; - if( hcd == NULL ) - return; + if (hcd == NULL) + return; + + hcd->dev_addr_map[addr >> 3] &= ~(1 << (addr & 7)); + 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 ) +ehci_submit_urb2(PHCD hcd, PUSB_DEV pdev, PUSB_ENDPOINT pendp, PURB purb) { - return ehci_submit_urb( ehci_from_hcd( hcd ), pdev, pendp, purb ); + return ehci_submit_urb(ehci_from_hcd(hcd), pdev, pendp, purb); } PUSB_DEV -ehci_get_root_hub( -PHCD hcd -) +ehci_get_root_hub(PHCD hcd) { - return ehci_from_hcd( hcd )->root_hub; + return ehci_from_hcd(hcd)->root_hub; } + VOID -ehci_set_root_hub( -PHCD hcd, -PUSB_DEV root_hub -) +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; + if (hcd == NULL || root_hub == NULL) + return; + ehci_from_hcd(hcd)->root_hub = root_hub; + return; } BOOL -ehci_remove_device2( -PHCD hcd, -PUSB_DEV pdev -) +ehci_remove_device2(PHCD hcd, PUSB_DEV pdev) { - if( hcd == NULL || pdev == NULL ) - return FALSE; + if (hcd == NULL || pdev == NULL) + return FALSE; - return ehci_remove_device( ehci_from_hcd( hcd ), pdev ); + return ehci_remove_device(ehci_from_hcd(hcd), pdev); } BOOL -ehci_hcd_release( -PHCD hcd -) +ehci_hcd_release(PHCD hcd) { - PEHCI_DEV ehci; - PEHCI_DEVICE_EXTENSION pdev_ext; + 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 ); + if (hcd == NULL) + return FALSE; + + ehci = ehci_from_hcd(hcd); + pdev_ext = ehci->pdev_ext; + return ehci_release(pdev_ext->pdev_obj); } NTSTATUS -ehci_cancel_urb2( -PHCD hcd, -PUSB_DEV pdev, -PUSB_ENDPOINT pendp, -PURB purb -) +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 ); + PEHCI_DEV ehci; + if (hcd == NULL) + return STATUS_INVALID_PARAMETER; + + ehci = ehci_from_hcd(hcd); + return ehci_cancel_urb(ehci, pdev, pendp, purb); } + BOOL -ehci_rh_get_dev_change( -PHCD hcd, -PBYTE buf -) //must have the rh dev_lock acquired +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; + PEHCI_DEV ehci; + LONG port_count, i; + ULONG status; - if( hcd == NULL ) - return FALSE; + 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 ) ); + 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; + 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 -) +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; + 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 +// EHCI routines follows // -VOID -ehci_init_int8_qh( -PEHCI_QH_CONTENT qh -); +VOID ehci_init_int8_qh(PEHCI_QH_CONTENT qh); BOOLEAN -ehci_cal_cpu_freq( -PVOID context -) +ehci_cal_cpu_freq(PVOID context) { - usb_cal_cpu_freq(); - return TRUE; + usb_cal_cpu_freq(); + return TRUE; } PDEVICE_OBJECT -ehci_probe( -PDRIVER_OBJECT drvr_obj, -PUNICODE_STRING reg_path, -PUSB_DEV_MANAGER dev_mgr -) +ehci_probe(PDRIVER_OBJECT drvr_obj, PUNICODE_STRING reg_path, PUSB_DEV_MANAGER dev_mgr) { - LONG bus, i, j, ret; - 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 bus, i, j, ret; + PCI_SLOT_NUMBER slot_num; + PPCI_COMMON_CONFIG pci_config; + PDEVICE_OBJECT pdev; + BYTE buffer[sizeof(PCI_COMMON_CONFIG)]; + PEHCI_DEVICE_EXTENSION pdev_ext; - slot_num.u.AsULONG = 0; - pci_config = ( PPCI_COMMON_CONFIG ) buffer; - pdev = NULL; + slot_num.u.AsULONG = 0; + pci_config = (PPCI_COMMON_CONFIG) buffer; + pdev = NULL; - //scan the bus to find ehci 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; + //scan the bus to find ehci 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 ); + ret = HalGetBusData(PCIConfiguration, + bus, slot_num.u.AsULONG, pci_config, PCI_COMMON_HDR_LENGTH); - if( ret == 0 ) /*no this bus*/ - break; + if (ret == 0) /*no this bus */ + break; - if( ret == 2 ) /*no device on the slot*/ - 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 (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 ) - continue; - } - } + if (!pdev) + continue; + } + } - if( ret == 0 ) - break; - } - } + if (ret == 0) + break; + } + } - 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 NULL; + 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 NULL; } PDEVICE_OBJECT -ehci_alloc( -PDRIVER_OBJECT drvr_obj, -PUNICODE_STRING reg_path, -ULONG bus_addr, -PUSB_DEV_MANAGER dev_mgr -) +ehci_alloc(PDRIVER_OBJECT drvr_obj, PUNICODE_STRING reg_path, ULONG bus_addr, PUSB_DEV_MANAGER dev_mgr) { - LONG frd_num, prd_num; - UCHAR buffer[ PCI_COMMON_HDR_LENGTH ]; - PDEVICE_OBJECT pdev; - PEHCI_DEVICE_EXTENSION pdev_ext; - ULONG vector, addr_space; - LONG bus, i; - KIRQL irql; - KAFFINITY affinity; - UCHAR hcd_id; + LONG frd_num, prd_num; + UCHAR buffer[PCI_COMMON_HDR_LENGTH]; + PDEVICE_OBJECT pdev; + PEHCI_DEVICE_EXTENSION pdev_ext; + ULONG vector, addr_space; + LONG bus, i; + KIRQL irql; + KAFFINITY affinity; + UCHAR hcd_id; - DEVICE_DESCRIPTION dev_desc; - CM_PARTIAL_RESOURCE_DESCRIPTOR *pprd; - PCI_SLOT_NUMBER slot_num; - NTSTATUS status; + DEVICE_DESCRIPTION dev_desc; + CM_PARTIAL_RESOURCE_DESCRIPTOR *pprd; + PCI_SLOT_NUMBER slot_num; + NTSTATUS status; - pdev = ehci_create_device( drvr_obj, dev_mgr ); + pdev = ehci_create_device(drvr_obj, dev_mgr); - if( pdev == NULL ) - return NULL; + if (pdev == NULL) + return NULL; - pdev_ext = pdev->DeviceExtension; + 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 ); + pdev_ext->pci_addr = bus_addr; + bus = (bus_addr >> 8); - //now create adapter object - RtlZeroMemory( &dev_desc, sizeof( dev_desc ) ); + slot_num.u.AsULONG = 0; + slot_num.u.bits.DeviceNumber = ((bus_addr & 0xff) >> 3); + slot_num.u.bits.FunctionNumber = (bus_addr & 0x07); - 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; + //now create adapter object + RtlZeroMemory(&dev_desc, sizeof(dev_desc)); - pdev_ext->map_regs = 2; // we do not use it seriously + 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->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 ); - return NULL; - } + pdev_ext->map_regs = 2; // we do not use it seriously - DbgPrint("ehci_alloc(): reg_path=0x%x, \n \ + 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); + 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 ); - return NULL; - } + 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); - //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 ) ); + //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); + return NULL; + } - } - 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 ) ); - } - } - } + //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)); - //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 ); - return NULL; - } + } + 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)); + } + } + } - 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 ); - 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; + //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); + return NULL; + } - //init ehci_caps - // i = ( ( PEHCI_HCS_CONTENT )( &pdev_ext->ehci->ehci_caps.hcs_params ) )->length; + DbgPrint("ehci_alloc(): address space=0x%x\n, reg_base=0x%x\n", + addr_space, pdev_ext->ehci->ehci_reg_base.u.LowPart); - 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 (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); - 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; - } + //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); + return NULL; + } + } + else + { + //io space + pdev_ext->ehci->port_mapped = FALSE; + pdev_ext->ehci->port_base = (PBYTE) pdev_ext->ehci->ehci_reg_base.LowPart; + } - 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 ); + //before we connect the interrupt, we have to init ehci + pdev_ext->ehci->pdev_ext = pdev_ext; - KeInitializeTimer( &pdev_ext->ehci->reset_timer ); + //init ehci_caps + // i = ( ( PEHCI_HCS_CONTENT )( &pdev_ext->ehci->ehci_caps.hcs_params ) )->length; - vector = HalGetInterruptVector( - PCIBus, - bus, - pdev_ext->res_interrupt.level, - pdev_ext->res_interrupt.vector, - &irql, - &affinity); + ehci_get_capabilities(pdev_ext->ehci, pdev_ext->ehci->port_base); + i = pdev_ext->ehci->ehci_caps.length; + pdev_ext->ehci->port_base += i; - //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 ); - return NULL; - } + 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; + } - KeInitializeDpc( &pdev_ext->ehci_dpc, - ehci_dpc_callback, - ( PVOID )pdev_ext->ehci ); + InitializeListHead(&pdev_ext->ehci->urb_list); + KeInitializeSpinLock(&pdev_ext->ehci->pending_endp_list_lock); + InitializeListHead(&pdev_ext->ehci->pending_endp_list); - return pdev; + 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); + + //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); + return NULL; + } + + KeInitializeDpc(&pdev_ext->ehci_dpc, ehci_dpc_callback, (PVOID) pdev_ext->ehci); + + return pdev; } PDEVICE_OBJECT -ehci_create_device( -PDRIVER_OBJECT drvr_obj, -PUSB_DEV_MANAGER dev_mgr -) +ehci_create_device(PDRIVER_OBJECT drvr_obj, PUSB_DEV_MANAGER dev_mgr) { - NTSTATUS status; - PDEVICE_OBJECT pdev; - PEHCI_DEVICE_EXTENSION pdev_ext; + NTSTATUS status; + PDEVICE_OBJECT pdev; + PEHCI_DEVICE_EXTENSION pdev_ext; - UNICODE_STRING dev_name; - UNICODE_STRING symb_name; + UNICODE_STRING dev_name; + UNICODE_STRING symb_name; - STRING string, another_string; - CHAR str_dev_name[ 64 ], str_symb_name[ 64 ]; - UCHAR hcd_id; + STRING string, another_string; + CHAR str_dev_name[64], str_symb_name[64]; + UCHAR hcd_id; - if( drvr_obj == NULL ) - return NULL; + 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 ); + //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); + RtlInitString(&string, str_dev_name); + RtlAnsiStringToUnicodeString(&dev_name, &string, TRUE); - 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 = NULL; + status = IoCreateDevice(drvr_obj, + sizeof(EHCI_DEVICE_EXTENSION) + sizeof(EHCI_DEV), + &dev_name, FILE_EHCI_DEV_TYPE, 0, FALSE, &pdev); - 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; + 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->ehci = ( PEHCI_DEV ) &( pdev_ext[ 1 ] ); + pdev_ext = pdev->DeviceExtension; + RtlZeroMemory(pdev_ext, sizeof(EHCI_DEVICE_EXTENSION) + sizeof(EHCI_DEV)); - RtlInitString( &another_string, str_symb_name ); - RtlAnsiStringToUnicodeString( &symb_name, &another_string, TRUE ); - //RtlInitUnicodeString( &symb_name, DOS_DEVICE_NAME ); + 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; - IoCreateSymbolicLink( &symb_name, &dev_name ); + pdev_ext->pdev_obj = pdev; + pdev_ext->pdrvr_obj = drvr_obj; - 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 ) ); + pdev_ext->ehci = (PEHCI_DEV) & (pdev_ext[1]); - 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; + 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_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.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 + ehci->hcd_interf.flags = HCD_TYPE_EHCI; //hcd types | hcd id } BOOL -ehci_init_schedule( -PEHCI_DEV ehci, -PADAPTER_OBJECT padapter -) +ehci_init_schedule(PEHCI_DEV ehci, PADAPTER_OBJECT padapter) { - PEHCI_DEVICE_EXTENSION pdev_ext; - BOOL ret; - LONG i; - PEHCI_QH_CONTENT pqh_content; - PEHCI_QH pqh; - PEHCI_QTD ptd; - PEHCI_ELEM_LINKS pelnk; - PEHCI_FSTN pfstn; + PEHCI_DEVICE_EXTENSION pdev_ext; + BOOL ret; + LONG i; + PEHCI_QH_CONTENT pqh_content; + PEHCI_QH pqh; + PEHCI_QTD ptd; + PEHCI_ELEM_LINKS pelnk; + PEHCI_FSTN pfstn; - if( ehci == NULL ) - return FALSE; + if (ehci == NULL) + return FALSE; - pdev_ext = ehci->pdev_ext; - if( pdev_ext == 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; + // 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; - } + // 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; - } + 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; + // 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 ); + 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; + 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 < (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 ] ); - } + 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; + InitializeListHead(&ehci->async_list_cpu); - 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; + // 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; - // 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; + 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; - pqh_content = ( PEHCI_QH_CONTENT )( ( ULONG )pelnk->phys_part & PHYS_PART_ADDR_MASK ); - ehci_init_int8_qh( pqh_content ); + // 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; - // chain qh to the shadow list - InsertTailList( &ehci->periodic_list_cpu[ EHCI_SCHED_INT8_INDEX ], &pelnk->sched_link ); + pqh_content = (PEHCI_QH_CONTENT) ((ULONG) pelnk->phys_part & PHYS_PART_ADDR_MASK); + ehci_init_int8_qh(pqh_content); - // chain it to the periodic schedule, we use it as a docking point - // for req of 8- uframes request - pqh = ( PEHCI_QH )pqh_content; + // chain qh to the shadow list + InsertTailList(&ehci->periodic_list_cpu[EHCI_SCHED_INT8_INDEX], &pelnk->sched_link); - for( i = 0; i < ( LONG )ehci->frame_count; i++ ) - { - ehci->frame_list[ i ] = pqh->phys_addr; - } + // chain it to the periodic schedule, we use it as a docking point + // for req of 8- uframes request + pqh = (PEHCI_QH) pqh_content; - // allocate fstn - /*if( ( pelnk = elem_pool_alloc_elem( &ehci->elem_pools[ EHCI_FSTN_POOL_IDX ] ) ) == NULL ) - goto ERROR_OUT; + for(i = 0; i < (LONG) ehci->frame_count; i++) + { + ehci->frame_list[i] = pqh->phys_addr; + } - 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 fstn + /*if( ( pelnk = elem_pool_alloc_elem( &ehci->elem_pools[ EHCI_FSTN_POOL_IDX ] ) ) == NULL ) + goto ERROR_OUT; - // allocate for async list head - if( ( pelnk = elem_pool_alloc_elem( &ehci->elem_pools[ EHCI_QH_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; */ - // 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; + // allocate for async list head + if ((pelnk = elem_pool_alloc_elem(&ehci->elem_pools[EHCI_QH_POOL_IDX])) == NULL) + goto ERROR_OUT; -ERROR_OUT: - ehci_destroy_schedule( ehci ); - return FALSE; + // 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; } BOOL -ehci_destroy_schedule( -PEHCI_DEV ehci -) +ehci_destroy_schedule(PEHCI_DEV ehci) { - LONG i; - if( ehci == NULL ) - return FALSE; + LONG i; + if (ehci == NULL) + return FALSE; - if( ehci->frame_bw ) - usb_free_mem( ehci->frame_bw ); - ehci->frame_bw = NULL; + 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_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 ); + 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; + 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 ] ); + for(i = 0; i < 5; i++) + elem_pool_destroy_pool(&ehci->elem_pools[i]); - return TRUE; + return TRUE; } VOID -ehci_init_int8_qh( -PEHCI_QH_CONTENT qh -) +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; + 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 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 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 + // 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; + // 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 -) +ehci_get_capabilities(PEHCI_DEV ehci, PBYTE base) // fetch capabilities register from ehci { - NTSTATUS status; - PEHCI_CAPS pcap; - PEHCI_HCS_CONTENT phcs; - LONG i; + NTSTATUS status; + PEHCI_CAPS pcap; + PEHCI_HCS_CONTENT phcs; + LONG i; - if( ehci == NULL ) - return; + 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 ) ); + 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; -} - -BOOL -ehci_delete_device( -PDEVICE_OBJECT pdev -) -{ - 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 ); - - 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 ); -} - -BOOL -ehci_release( -PDEVICE_OBJECT pdev -) -{ - PEHCI_DEVICE_EXTENSION pdev_ext; - PEHCI_DEV ehci; - KIRQL disp_level; - KIRQL old_level; - - 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 ) + phcs = (PEHCI_HCS_CONTENT) & pcap->hcs_params; + if (phcs->port_rout_rules) { - IoDisconnectInterrupt( pdev_ext->ehci_int ); - pdev_ext->ehci_int = NULL; + for(i = 0; i < 8; i++) + pcap->portroute[i] = EHCI_READ_PORT_UCHAR((PUCHAR) (base + 12 + i)); } - else - TRAP(); - destroy_pending_endp_pool( &pdev_ext->ehci->pending_endp_pool ); + return; +} - ehci_destroy_schedule( ehci ); +BOOL +ehci_delete_device(PDEVICE_OBJECT pdev) +{ + STRING string; + UNICODE_STRING symb_name; + CHAR str_symb_name[64]; + PEHCI_DEVICE_EXTENSION pdev_ext; - release_adapter( pdev_ext->padapter ); - pdev_ext->padapter = NULL; + if (pdev == NULL) + return FALSE; - ehci_delete_device( pdev ); + pdev_ext = pdev->DeviceExtension; - return FALSE; + 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); + + 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); +} + +BOOL +ehci_release(PDEVICE_OBJECT pdev) +{ + PEHCI_DEVICE_EXTENSION pdev_ext; + PEHCI_DEV ehci; + KIRQL disp_level; + KIRQL old_level; + + 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); + + return FALSE; } BOOL -ehci_start( -PHCD hcd -) +ehci_start(PHCD hcd) { - ULONG tmp; - PBYTE base; - LONG i; - PEHCI_USBCMD_CONTENT usbcmd; - LARGE_INTEGER interval; - PEHCI_DEV ehci; + ULONG tmp; + PBYTE base; + LONG i; + PEHCI_USBCMD_CONTENT usbcmd; + LARGE_INTEGER interval; + PEHCI_DEV ehci; - if( hcd == NULL ) - return FALSE; + if (hcd == NULL) + return FALSE; - ehci = struct_ptr( hcd, EHCI_DEV, hcd_interf ); - base = ehci->port_base; + 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 ); + // 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 ); + // 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 ); + // 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; - } + 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 ); + // 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 ); + // 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 ) ); + 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 ); + 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 ); + // 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 ); + // 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 ); + // enable the list traversaling + usbcmd->async_enable = 1; + usbcmd->periodic_enable = 1; + EHCI_WRITE_PORT_ULONG((PULONG) (base + EHCI_USBCMD), tmp); - return TRUE; + return TRUE; } VOID -ehci_run_stop( -PEHCI_DEV ehci, -BOOL start -) +ehci_run_stop(PEHCI_DEV ehci, BOOL start) { - PEHCI_USBCMD_CONTENT usbcmd; - PEHCI_USBSTS_CONTENT usbsts; - ULONG tmp; - PBYTE base; + PEHCI_USBCMD_CONTENT usbcmd; + PEHCI_USBSTS_CONTENT usbsts; + ULONG tmp; + PBYTE base; - if( ehci == NULL ) - return; + if (ehci == NULL) + return; - base = ehci->port_base; - usbcmd = ( PEHCI_USBCMD_CONTENT )&tmp; - usbsts = ( PEHCI_USBSTS_CONTENT )&tmp; + 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 + 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 -) +ehci_find_min_bandwidth(PEHCI_DEV ehci) { - LONG i; - if( ehci == NULL ) - return; + 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; + 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; } BOOL -ehci_claim_bw_for_int( -PEHCI_DEV ehci, -PURB purb, -BOOL release -) +ehci_claim_bw_for_int(PEHCI_DEV ehci, PURB purb, BOOL 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; - BOOL bw_avail; - ULONG max_packet_size; + PURB_HS_PIPE_CONTENT pipe_content; + LONG i, j; + ULONG interval, bus_time, ss_time, cs_time; + BOOL bw_avail; + ULONG max_packet_size; - if( ehci == NULL || purb == NULL ) - return FALSE; + if (ehci == NULL || purb == NULL) + return FALSE; - if( purb->pipe == 0 ) - 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; - } + 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 ); + 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 + 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 ) - ); + 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; + // 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; + 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; - } - } + 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; + 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 ); - } - } - } - } + 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; - } + LBL_OUT: + if (!release) + return bw_avail; + else + { + ehci_find_min_bandwidth(ehci); + return TRUE; + } } LONG -ehci_get_cache_policy( -PEHCI_DEV ehci -) +ehci_get_cache_policy(PEHCI_DEV ehci) { - PEHCI_HCC_CONTENT hcc_content; + 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; + 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; } @@ -4798,1926 +4426,1876 @@ PEHCI_DEV ehci #define iso_uframes_data_load( dir, data_load, uf_cnt ) BOOL -ehci_claim_bw_for_iso( -PEHCI_DEV ehci, -PURB purb, -BOOL release -) +ehci_claim_bw_for_iso(PEHCI_DEV ehci, PURB purb, BOOL release) { - PURB_HS_PIPE_CONTENT pipe_content; - LONG i, j, k; - ULONG interval, bus_time, ss_time, cs_time, remainder; - BOOL bw_avail; - ULONG cur_uframe, start_uframe, max_time, max_packet_size; - PBYTE base; - if( ehci == NULL || purb == NULL ) - return FALSE; + PURB_HS_PIPE_CONTENT pipe_content; + LONG i, j, k; + ULONG interval, bus_time, ss_time, cs_time, remainder; + BOOL bw_avail; + ULONG cur_uframe, start_uframe, 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; + 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 ); + 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; + 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; - } + 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 (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 (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 (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; + if (max_packet_size > 1023) + return FALSE; - remainder = 0; + 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 - // + // + // 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; - } - } + 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 ); + 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; - } + 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 ); - } + // 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 ); + // 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 ); - } + 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 - { - BOOL large; - long temp, base; + // 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 + { + BOOL large; + long temp, base; - for( j = ( cur_uframe >> 3 ) + 2; j != ( LONG )( cur_uframe >> 3 ); j = ( j + 1 ) % ehci->frame_count ) - { - temp = 0; + 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; + 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 (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; + 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; + 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; + // 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 (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; + 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; - } - } + 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; - } + 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; + 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; } BOOL -ehci_claim_bandwidth( -PEHCI_DEV ehci, -PURB purb, -BOOL claim_bw )//true to claim band-width, false to free band-width +ehci_claim_bandwidth(PEHCI_DEV ehci, PURB purb, BOOL 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; - BOOL ret; + PURB_HS_PIPE_CONTENT pipe_content; + BOOL ret; - if( ehci == NULL || purb == NULL ) - return FALSE; + 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; + 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; } BOOL -ehci_can_remove( -PURB purb, -BOOL door_bell_rings, -ULONG cur_frame -) +ehci_can_remove(PURB purb, BOOL 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; + PURB_HS_PIPE_CONTENT pipe_content; + ULONG interval; - pipe_content = ( PURB_HS_PIPE_CONTENT )&purb->pipe; - interval = REAL_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; + 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 -); +NTSTATUS ehci_remove_urb_from_schedule(PEHCI_DEV ehci, PURB purb); static VOID -ehci_deactivate_urb( -PURB purb -) +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; + 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; + if (purb == NULL) + return; - }while( pthis ); - break; - } - case USB_ENDPOINT_XFER_ISOC: - { - // fall through - } - default: - TRAP(); - } - 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 -) +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; - PEHCI_QTD ptd; - PLIST_ENTRY pthis, pprev, pnext; + PLIST_ENTRY list_head; + PEHCI_QH pqh, pqhprev, pqhnext; + PEHCI_QTD ptd; + PLIST_ENTRY pthis, pprev, pnext; - if( ehci == NULL || purb == NULL ) - return; + if (ehci == NULL || purb == NULL) + return; - list_head = &purb->trasac_list; - ListFirst( list_head, pthis ); - if( pthis == 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; + 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 ); + 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 ); + // 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; + 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 -) +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_QTD ptd; - PEHCI_QH_CONTENT pqhc; - PLIST_ENTRY pthis, pprev, pnext; + PLIST_ENTRY list_head; + PEHCI_QH pqh, pqhprev, pqhnext; + PEHCI_QTD ptd; + PEHCI_QH_CONTENT pqhc; + PLIST_ENTRY pthis, pprev, pnext; - if( ehci == NULL || purb == NULL ) - return; + 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; + 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(); + if (pqhc->is_async_head) + TRAP(); - ListFirst( &pqh->elem_head_link->sched_link, pnext ); - ListFirstPrev( &pqh->elem_head_link->sched_link, pprev ); + 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; + 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 -) +ehci_insert_fstn_schedule(PEHCI_DEV ehci, PURB purb) { - PURB_HS_PIPE_CONTENT pipe_content, pc; - PLIST_ENTRY pthis, list_head, pnext, pprev; - PEHCI_ELEM_LINKS elem_link; - PEHCI_QH pqh, pqhprev, pqhnext; - PEHCI_FSTN pfstn; - PURB purb1; + PURB_HS_PIPE_CONTENT pipe_content, pc; + PLIST_ENTRY pthis, list_head, pnext, pprev; + PEHCI_ELEM_LINKS elem_link; + PEHCI_QH pqh, pqhprev, pqhnext; + PEHCI_FSTN pfstn; + PURB purb1; - ULONG interval, start_frame, start_uframe; - LONG i; + ULONG interval, start_frame, start_uframe; + LONG i; - if( ehci == NULL || purb == NULL ) - return; + 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; + 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(); + if ((start_frame << 3) >= interval) + TRAP(); - ListFirstPrev( list_head, pprev ); + ListFirstPrev(list_head, pprev); - if( elem_type_list_entry( pprev ) != INIT_LIST_FLAG_FSTN ) - { - TRAP(); - return; - } + if (elem_type_list_entry(pprev) != INIT_LIST_FLAG_FSTN) + { + TRAP(); + return; + } - pfstn = fstn_from_list_entry( pprev ); + pfstn = fstn_from_list_entry(pprev); - if( interval == 8 ) - { - ListFirst( &ehci->periodic_list_cpu[ EHCI_SCHED_INT8_INDEX ], pthis ); + 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; + // 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 ); + 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; - } + 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; + 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; + 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(); + if (purb1 == NULL) + TRAP(); - pc = ( PURB_HS_PIPE_CONTENT )&purb1->pipe; - u = 1 << ( pc->speed_high ? ( 1 << pc->interval ) : ( 1 << ( pc->interval + 3 ) ) ); + 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 (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; + 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 ); + // 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 ); - } + 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; - } - } + 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 -) +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; - PURB purb1; + PURB_HS_PIPE_CONTENT pipe_content; + PLIST_ENTRY pthis, list_head, pnext, pprev; + PEHCI_FSTN pfstn; + PURB purb1; - ULONG interval, start_frame, start_uframe; - LONG i; + ULONG interval, start_frame, start_uframe; + LONG i; - if( ehci == NULL || purb == NULL ) - return; + 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; + 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++; + if ((start_frame << 3) >= interval) + TRAP(); + start_frame++; - ListFirstPrev( list_head, pprev ); - if( elem_type_list_entry( pprev ) != INIT_LIST_FLAG_FSTN ) - { - TRAP(); - return; - } + 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; + 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 -) +ehci_insert_int_schedule(PEHCI_DEV ehci, PURB purb) { - PURB_HS_PIPE_CONTENT pipe_content, pc; - PLIST_ENTRY pthis, list_head, pnext, pprev; - PEHCI_ELEM_LINKS elem_link; - PEHCI_QH pqh, pqhprev, pqhnext; - PURB purb1; + PURB_HS_PIPE_CONTENT pipe_content, pc; + PLIST_ENTRY pthis, list_head, pnext, 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; + ULONG interval, u, start_frame, start_uframe; + LONG i; + UCHAR need_fstn; - if( ehci == NULL || purb == NULL ) - return; + 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; + 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; + ListFirst(list_head, pthis); + if (pthis == NULL) + return; - pqh = qh_from_list_entry( pthis ); + 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 (!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 < 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(); + 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 ); + 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; - } + 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 + 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; + 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(); + if (purb1 == NULL) + TRAP(); - pc = ( PURB_HS_PIPE_CONTENT )&purb1->pipe; - u = 1 << ( pc->speed_high ? ( 1 << pc->interval ) : ( 1 << ( pc->interval + 3 ) ) ); + 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; + 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 ); + // 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 ); - } + 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; - } - } + 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 ); + if (need_fstn) + ehci_insert_fstn_schedule(ehci, purb); - return; + return; } static VOID -ehci_remove_int_from_schedule( -PEHCI_DEV ehci, -PURB purb -) +ehci_remove_int_from_schedule(PEHCI_DEV ehci, PURB purb) { - PURB_HS_PIPE_CONTENT pipe_content, pc; - PLIST_ENTRY pthis, list_head, pnext, pprev, pcur; - PEHCI_ELEM_LINKS elem_link; - PEHCI_QH pqh, pqhprev, pqhnext; - PURB purb1; + PURB_HS_PIPE_CONTENT pipe_content, pc; + PLIST_ENTRY pthis, list_head, pnext, pprev, pcur; + PEHCI_ELEM_LINKS elem_link; + PEHCI_QH pqh, pqhprev, pqhnext; + PURB purb1; - ULONG interval, start_frame, start_uframe, u; - LONG i; + ULONG interval, start_frame, start_uframe, u; + LONG i; - if( ehci == NULL || purb == NULL ) - return; + 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; + 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; + ListFirst(&purb->trasac_list, pthis); + if (pthis == NULL) + return; - pqh = qh_from_list_entry( pthis ); - list_head = &purb->trasac_list; + pqh = qh_from_list_entry(pthis); + list_head = &purb->trasac_list; - if( IsListEmpty( list_head ) ) - { - TRAP(); - return; - } + if (IsListEmpty(list_head)) + { + TRAP(); + return; + } - if( !pipe_content->speed_high ) - { - interval = ( interval << 3 ); - } + if (!pipe_content->speed_high) + { + interval = (interval << 3); + } - if( interval >= 256 * 8 ) - return; + 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; + 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; - } + 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(); - } - } - } + 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; + 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 -) +ehci_insert_iso_schedule(PEHCI_DEV ehci, PURB purb) { - PURB_HS_PIPE_CONTENT pipe_content; - PLIST_ENTRY pthis, list_head, pnext, pprev, pcur; + PURB_HS_PIPE_CONTENT pipe_content; + PLIST_ENTRY pthis, list_head, pnext, pprev, pcur; - ULONG interval, start_frame; - LONG i; + ULONG interval, start_frame; + LONG i; - if( ehci == NULL || purb == NULL ) - return; + if (ehci == NULL || purb == NULL) + return; - pipe_content = ( PURB_HS_PIPE_CONTENT )&purb->pipe; + pipe_content = (PURB_HS_PIPE_CONTENT) & purb->pipe; - interval = 8; - if( pipe_content->speed_high ) - interval = REAL_INTERVAL; + interval = 8; + if (pipe_content->speed_high) + interval = REAL_INTERVAL; - start_frame = purb->iso_start_frame; + start_frame = purb->iso_start_frame; - ListFirst( &purb->trasac_list, pthis ); - if( pthis == NULL ) - { - TRAP(); - return; - } + ListFirst(&purb->trasac_list, pthis); + if (pthis == NULL) + { + TRAP(); + return; + } - list_head = &purb->trasac_list; - if( IsListEmpty( list_head ) ) - { - 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 ]; + 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] = 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; - } + 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; + ListNext(list_head, pthis, pnext); + pthis = pnext; - if( interval <= 8 ) - i++; - else - i += ( interval >> 3 ); - } - return; + if (interval <= 8) + i++; + else + i += (interval >> 3); + } + return; } static VOID -ehci_remove_iso_from_schedule( -PEHCI_DEV ehci, -PURB purb -) +ehci_remove_iso_from_schedule(PEHCI_DEV ehci, PURB purb) { - PURB_HS_PIPE_CONTENT pipe_content; - PLIST_ENTRY pthis, list_head, pnext, pprev, pcur; + PURB_HS_PIPE_CONTENT pipe_content; + PLIST_ENTRY pthis, list_head, pnext, pprev, pcur; - ULONG interval, start_frame; - LONG i; + ULONG interval, start_frame; + LONG i; - if( ehci == NULL || purb == NULL ) - return; + if (ehci == NULL || purb == NULL) + return; - pipe_content = ( PURB_HS_PIPE_CONTENT )&purb->pipe; + pipe_content = (PURB_HS_PIPE_CONTENT) & purb->pipe; - interval = 8; - if( pipe_content->speed_high ) - interval = REAL_INTERVAL; + interval = 8; + if (pipe_content->speed_high) + interval = REAL_INTERVAL; - start_frame = purb->iso_start_frame; + start_frame = purb->iso_start_frame; - ListFirst( &purb->trasac_list, pthis ); - if( pthis == NULL ) - { - TRAP(); - return; - } + ListFirst(&purb->trasac_list, pthis); + if (pthis == NULL) + { + TRAP(); + return; + } - list_head = &purb->trasac_list; - if( IsListEmpty( list_head ) ) - { - 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; - } + 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; + 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; + ListNext(list_head, pthis, pnext); + pthis = pnext; - if( interval <= 8 ) - i++; - else - i += ( interval >> 3 ); - } - return; + if (interval <= 8) + i++; + else + i += (interval >> 3); + } + return; } NTSTATUS -ehci_isr_removing_urb( -PEHCI_DEV ehci, -PURB purb, -BOOL doorbell_rings, -ULONG cur_frame -) +ehci_isr_removing_urb(PEHCI_DEV ehci, PURB purb, BOOL doorbell_rings, ULONG cur_frame) { - UCHAR type; - PLIST_ENTRY pthis, plast; - 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; + UCHAR type; + PLIST_ENTRY pthis, plast; + 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 == NULL || ehci == NULL) + return STATUS_INVALID_PARAMETER; - if( ( purb->flags & URB_FLAG_STATE_MASK ) == URB_FLAG_STATE_FINISHED ) - return STATUS_SUCCESS; + if ((purb->flags & URB_FLAG_STATE_MASK) == URB_FLAG_STATE_FINISHED) + return STATUS_SUCCESS; type = 0; - pipe_content = ( PURB_HS_PIPE_CONTENT )&purb->pipe; + 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(); + 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 + } // end of not force cancel - if( type == 0 ) - return STATUS_SUCCESS; + 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(); + 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; + 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; + // 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 ); + 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_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; + purb->flags &= ~URB_FLAG_STATE_MASK; + purb->flags |= URB_FLAG_STATE_DOORBELL; - press_doorbell( ehci ); + press_doorbell(ehci); - } - else // unknown transfer or iso transfer - DO_NOTHING; - purb->status = 0; - return STATUS_SUCCESS; - } - default: - TRAP(); - } - } - case URB_FLAG_STATE_DOORBELL: - { - if( doorbell_rings == FALSE ) - return STATUS_SUCCESS; + } + else // unknown transfer or iso transfer + DO_NOTHING; + purb->status = 0; + return STATUS_SUCCESS; + } + default: + TRAP(); + } + } + 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; + 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 -) +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; + 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; + 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; - } + 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; + 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; + return purb->status = psitd_content->status; + } + ListNext(&purb->trasac_list, pthis, pnext); + pthis = pnext; + } + } + return 0; } BOOLEAN -ehci_isr( -PKINTERRUPT interrupt, -PVOID context -) +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, urb_count; - PLIST_ENTRY pthis, pnext; - PURB purb; - BOOL 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; + PEHCI_DEV ehci; + ULONG status, urb_count; + PLIST_ENTRY pthis, pnext; + PURB purb; + BOOL 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_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; - } + 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 ); + /* 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 - } + 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")); + } - door_bell_rings = ( ( status & STS_IAA ) != 0 ); + if (status & STS_FATAL) + { + DbgPrint("ehci_isr(): host system error, PCI problems?\n"); + for(;;); - // scan to remove those due + } + + 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 #ifdef DBG - urb_count = dbg_count_list( &ehci->urb_list ); - ehci_dbg_print( DBGLVL_MAXIMUM, ("ehci_isr(): urb# in process is %d\n", urb_count ) ); + 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; - } + 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; + KeInsertQueueDpc(&ehci->pdev_ext->ehci_dpc, (PVOID) status, 0); + return TRUE; } #ifndef INCLUDE_EHCI VOID -ehci_unload( -IN PDRIVER_OBJECT DriverObject -) +ehci_unload(IN PDRIVER_OBJECT DriverObject) { - PDEVICE_OBJECT pdev; - PEHCI_DEVICE_EXTENSION pdev_ext; - PUSB_DEV_MANAGER dev_mgr; - LONG i; + 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; + pdev = DriverObject->DeviceObject; - dev_mgr = &g_dev_mgr; - if( dev_mgr == NULL ) - return; - // - // set the termination flag - // - dev_mgr->term_flag = TRUE; + if (pdev == NULL) + return; + + pdev_ext = pdev->DeviceExtension; + if (pdev_ext == NULL) + return; + + dev_mgr = &g_dev_mgr; + if (dev_mgr == NULL) + return; // - // 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; + // 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; + dev_mgr_release_hcd(dev_mgr); + return; } NTSTATUS -generic_dispatch_irp( -IN PDEVICE_OBJECT dev_obj, -IN PIRP irp -) +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 ); + 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 -) +generic_start_io(IN PDEVICE_OBJECT dev_obj, IN PIRP irp) { - PDEVEXT_HEADER dev_ext; - - KIRQL old_irql; + PDEVEXT_HEADER dev_ext; - IoAcquireCancelSpinLock( &old_irql ); - if (irp != dev_obj->CurrentIrp || irp->Cancel) - { - IoReleaseCancelSpinLock(old_irql); - return; - } - else - { - IoSetCancelRoutine(irp, NULL); - IoReleaseCancelSpinLock(old_irql); - } + KIRQL 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 ); + 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 -DriverEntry( - IN PDRIVER_OBJECT DriverObject, - IN PUNICODE_STRING RegistryPath - ) +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. + // 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 + // L"DebugLevel", // REG_DWORD ValueName + // &gDebugLevel ); // Value receiver - // debug_level = DBGLVL_MAXIMUM; + // debug_level = DBGLVL_MAXIMUM; #endif - ehci_dbg_print_cond( DBGLVL_MINIMUM , DEBUG_UHCI, ("Entering DriverEntry(), RegistryPath=\n %ws\n", RegistryPath->Buffer )); + 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->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; + 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_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_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; + RtlZeroMemory(&g_dev_mgr, sizeof(USB_DEV_MANAGER)); + g_dev_mgr.usb_driver_obj = DriverObject; - ehci_probe( DriverObject, RegistryPath, &g_dev_mgr ); + 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; + 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 diff --git a/reactos/drivers/usb/nt4compat/usbdriver/etd.c b/reactos/drivers/usb/nt4compat/usbdriver/etd.c index c15e34d777c..531c96fe0e1 100644 --- a/reactos/drivers/usb/nt4compat/usbdriver/etd.c +++ b/reactos/drivers/usb/nt4compat/usbdriver/etd.c @@ -67,332 +67,269 @@ 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 -); +VOID elem_list_destroy_elem_list(PEHCI_ELEM_LIST plist); -PLIST_ENTRY -elem_list_get_list_head( -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_total_count(PEHCI_ELEM_LIST plist); -LONG -elem_list_get_elem_size( -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_get_link_offset(PEHCI_ELEM_LIST plist); -LONG -elem_list_add_ref( -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_release_ref(PEHCI_ELEM_LIST plist); -LONG -elem_list_get_ref( -PEHCI_ELEM_LIST plist -); +LONG elem_list_get_ref(PEHCI_ELEM_LIST plist); BOOL -elem_pool_lock( -PEHCI_ELEM_POOL pool, -BOOL at_dpc -) +elem_pool_lock(PEHCI_ELEM_POOL pool, BOOL at_dpc) { - return TRUE; + return TRUE; } + BOOL -elem_pool_unlock( -PEHCI_ELEM_POOL pool, -BOOL at_dpc -) +elem_pool_unlock(PEHCI_ELEM_POOL pool, BOOL at_dpc) { - return TRUE; + return TRUE; } + LONG -get_elem_phys_part_size( -ULONG type -) +get_elem_phys_part_size(ULONG type) { - // type is INIT_LIST_FLAG_XXX - LONG size; + // 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; + 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; } -BOOL -elem_list_init_elem_list( -PEHCI_ELEM_LIST plist, -LONG init_flags, -PVOID context, -LONG count -) +BOOL +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; + 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; - if( plist == NULL || context == NULL ) - return FALSE; + if (plist == NULL || context == NULL) + return FALSE; - RtlZeroMemory( plist, sizeof( EHCI_ELEM_LIST ) ); + RtlZeroMemory(plist, sizeof(EHCI_ELEM_LIST)); - pinit_ctx = context; + 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; + 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 ); + 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; - } + 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->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 ); + 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; - } + 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 ); + 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); + 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; - 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); - if( plist->phys_addrs != NULL ) - usb_free_mem( plist->phys_addrs ); - - RtlZeroMemory( plist, sizeof( EHCI_ELEM_LIST ) ); - return FALSE; + RtlZeroMemory(plist, sizeof(EHCI_ELEM_LIST)); + return FALSE; } VOID -elem_list_destroy_elem_list( -PEHCI_ELEM_LIST plist -) +elem_list_destroy_elem_list(PEHCI_ELEM_LIST plist) { - LONG i, pages; + LONG i, pages; - if( plist == NULL ) - return; + 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 ); + 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 ) ); + usb_free_mem(plist->phys_addrs); + RtlZeroMemory(plist, sizeof(EHCI_ELEM_LIST)); } PLIST_ENTRY -elem_list_get_list_head( -PEHCI_ELEM_LIST plist -) +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; + if (plist == NULL) + return NULL; + return &plist->free_list; } LONG -elem_list_get_link_offset( -PEHCI_ELEM_LIST plist -) +elem_list_get_total_count(PEHCI_ELEM_LIST plist) { - if( plist == NULL ) - return 0; - - return get_elem_phys_part_size( plist->flags & 0xf ); + if (plist == NULL) + return 0; + return plist->total_count;; } LONG -elem_list_add_ref( -PEHCI_ELEM_LIST plist -) +elem_list_get_elem_size(PEHCI_ELEM_LIST plist) { - plist->reference++; - return plist->reference; + if (plist == NULL) + return 0; + return plist->elem_size; } LONG -elem_list_release_ref( -PEHCI_ELEM_LIST plist -) +elem_list_get_link_offset(PEHCI_ELEM_LIST plist) { - plist->reference--; - return plist->reference; + if (plist == NULL) + return 0; + + return get_elem_phys_part_size(plist->flags & 0xf); } LONG -elem_list_get_ref( -PEHCI_ELEM_LIST plist -) +elem_list_add_ref(PEHCI_ELEM_LIST plist) { - return plist->reference; + 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; } // @@ -400,334 +337,300 @@ PEHCI_ELEM_LIST plist // BOOL -elem_pool_init_pool( -PEHCI_ELEM_POOL pool, -LONG flags, -PVOID context -) +elem_pool_init_pool(PEHCI_ELEM_POOL pool, LONG flags, PVOID context) { - PADAPTER_OBJECT padapter; - INIT_ELEM_LIST_CONTEXT init_ctx; + PADAPTER_OBJECT padapter; + INIT_ELEM_LIST_CONTEXT init_ctx; - if( pool == NULL || context == NULL ) - return FALSE; + if (pool == NULL || context == NULL) + return FALSE; - RtlZeroMemory( pool, sizeof( EHCI_ELEM_POOL ) ); + RtlZeroMemory(pool, sizeof(EHCI_ELEM_POOL)); - init_ctx.pool = pool; - init_ctx.padapter = context; + init_ctx.pool = pool; + init_ctx.padapter = context; - pool->elem_lists[ 0 ] = usb_alloc_mem( NonPagedPool, sizeof( EHCI_ELEM_LIST ) ); + pool->elem_lists[0] = usb_alloc_mem(NonPagedPool, sizeof(EHCI_ELEM_LIST)); - if( pool->elem_lists[ 0 ] == NULL ) - return FALSE; + 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; + 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; + return TRUE; } LONG -elem_pool_get_link_offset( -PEHCI_ELEM_POOL elem_pool -) +elem_pool_get_link_offset(PEHCI_ELEM_POOL elem_pool) { - return elem_pool->link_offset; + return elem_pool->link_offset; } LONG -elem_pool_get_total_count( -PEHCI_ELEM_POOL elem_pool -) +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; + 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 -) +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; + 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 -) +elem_pool_alloc_elem(PEHCI_ELEM_POOL pool) { - LONG i; - PEHCI_ELEM_LIST pel; - PLIST_HEAD lh; - PEHCI_ELEM_LINKS elnk; + LONG i; + PEHCI_ELEM_LIST pel; + PLIST_HEAD lh; + PEHCI_ELEM_LINKS elnk; - if( pool == NULL ) - return NULL; + 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 ]; - } + 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 ); + 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--; + pel->add_ref(pel); + pool->free_count--; - return elnk; + return elnk; } VOID -elem_pool_free_elem( -PEHCI_ELEM_LINKS elem_link -) +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, ( PLIST_ENTRY )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; + 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, (PLIST_ENTRY) 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; } BOOL -elem_pool_is_empty( -PEHCI_ELEM_POOL pool -) +elem_pool_is_empty(PEHCI_ELEM_POOL pool) { - PEHCI_ELEM_LIST pel; + PEHCI_ELEM_LIST pel; - if( pool == NULL ) - return TRUE; - pel = pool->elem_lists[ 0 ]; - return ( pool->list_count == 1 && pool->free_count == pel->get_total_count( pel ) ); + if (pool == NULL) + return TRUE; + pel = pool->elem_lists[0]; + return (pool->list_count == 1 && pool->free_count == pel->get_total_count(pel)); } LONG -elem_pool_get_free_count( -PEHCI_ELEM_POOL pool -) +elem_pool_get_free_count(PEHCI_ELEM_POOL pool) { - if( pool == NULL ) - return 0; - return pool->free_count; + if (pool == NULL) + return 0; + return pool->free_count; } PEHCI_ELEM_LINKS -elem_pool_alloc_elems( -PEHCI_ELEM_POOL pool, -LONG count -) +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 + 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; + 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; + 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; + 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; + 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; } BOOL -elem_pool_free_elems( -PEHCI_ELEM_LINKS elem_chains -) +elem_pool_free_elems(PEHCI_ELEM_LINKS elem_chains) { - // note: no list head exists. - LIST_HEAD lh; - PEHCI_ELEM_LINKS elnk; + // 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; + 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 -) +elem_pool_get_type(PEHCI_ELEM_POOL pool) { - if( pool == NULL ) - return -1; - return ( pool->flags & 0xf ); + if (pool == NULL) + return -1; + return (pool->flags & 0xf); } BOOL -elem_pool_expand_pool( -PEHCI_ELEM_POOL pool, -LONG elem_count -) +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; + 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; + 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; + 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 ); + 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; + 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; - } + 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; - } + 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; + // update pool + pool->free_count += elem_cnt_list * list_count; + pool->list_count += list_count; + return TRUE; } BOOL -elem_pool_collect_garbage( -PEHCI_ELEM_POOL pool -) +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; + LONG i, j, k, fl; + LONG free_elem_lists[EHCI_MAX_LISTS_POOL - 1]; + PEHCI_ELEM_LIST pel; - if( pool == NULL ) - return FALSE; + 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(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; + 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; } BOOL -elem_pool_can_transfer( -PEHCI_ELEM_POOL pool, -LONG td_count -) +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; + 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/usbdriver/gendrv.c b/reactos/drivers/usb/nt4compat/usbdriver/gendrv.c index 64a0aec7858..d246541a1fd 100644 --- a/reactos/drivers/usb/nt4compat/usbdriver/gendrv.c +++ b/reactos/drivers/usb/nt4compat/usbdriver/gendrv.c @@ -31,7 +31,7 @@ #include "stdio.h" #define if_dev( dev_obj ) \ -( ( ( ( PGENDRV_DEVICE_EXTENSION)dev_obj->DeviceExtension )->pdriver->driver_desc.flags & USB_DRIVER_FLAG_IF_CAPABLE ) != 0 ) +( ( ( ( PGENDRV_DEVICE_EXTENSION)dev_obj->DeviceExtension )->pdriver->driver_desc.flags & USB_DRIVER_FLAG_IF_CAPABLE ) != 0 ) #define GENDRV_EXIT_DISPATCH( dev_OBJ, staTUS, iRp ) \ {\ @@ -59,1578 +59,1372 @@ extern POBJECT_TYPE NTSYSAPI IoDriverObjectType; -extern VOID -disp_urb_completion( -PURB purb, -PVOID context -); +extern VOID disp_urb_completion(PURB purb, PVOID context); -VOID -disp_noio_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 -ZwLoadDriver( -IN PUNICODE_STRING DriverServiceName -); +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); -NTSYSAPI -NTSTATUS -NTAPI -ZwClose( -IN HANDLE Handle -); +BOOL gendrv_if_driver_destroy(PUSB_DEV_MANAGER dev_mgr, PUSB_DRIVER pdriver); -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 gendrv_set_cfg_completion(PURB purb, PVOID context); -BOOL -gendrv_if_driver_destroy( -PUSB_DEV_MANAGER dev_mgr, -PUSB_DRIVER pdriver -); +BOOL gendrv_connect(PCONNECT_DATA param, DEV_HANDLE dev_handle); -VOID -gendrv_set_cfg_completion( -PURB purb, -PVOID context -); +BOOL gendrv_stop(PUSB_DEV_MANAGER dev_mgr, DEV_HANDLE dev_handle); -BOOL -gendrv_connect( -PCONNECT_DATA param, -DEV_HANDLE dev_handle -); +BOOL gendrv_disconnect(PUSB_DEV_MANAGER dev_mgr, DEV_HANDLE dev_handle); -BOOL -gendrv_stop( -PUSB_DEV_MANAGER dev_mgr, -DEV_HANDLE dev_handle -); +VOID gendrv_startio(IN PDEVICE_OBJECT dev_obj, IN PIRP irp); -BOOL -gendrv_disconnect( -PUSB_DEV_MANAGER dev_mgr, -DEV_HANDLE dev_handle -); +VOID gendrv_cancel_queued_irp(PDEVICE_OBJECT pdev_obj, PIRP pirp); -VOID -gendrv_startio( -IN PDEVICE_OBJECT dev_obj, -IN PIRP irp -); +VOID gendrv_release_ext_drvr_entry(PGENDRV_DRVR_EXTENSION pdrvr_ext, PGENDRV_EXT_DRVR_ENTRY pentry); -VOID -gendrv_cancel_queued_irp( -PDEVICE_OBJECT pdev_obj, -PIRP pirp -); +VOID gendrv_clean_up_queued_irps(PDEVICE_OBJECT dev_obj); -VOID -gendrv_release_ext_drvr_entry( -PGENDRV_DRVR_EXTENSION pdrvr_ext, -PGENDRV_EXT_DRVR_ENTRY pentry -); +PGENDRV_EXT_DRVR_ENTRY gendrv_alloc_ext_drvr_entry(PGENDRV_DRVR_EXTENSION pdrvr_ext); -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 -); +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 -); +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 -); +gendrv_open_reg_key(OUT PHANDLE handle, + IN HANDLE base_handle OPTIONAL, + IN PUNICODE_STRING keyname, IN ACCESS_MASK desired_access, IN BOOLEAN create); + +BOOL gendrv_do_disconnect(PUSB_DEV_MANAGER dev_mgr, DEV_HANDLE if_handle, BOOL is_if); + +BOOL gendrv_do_stop(PUSB_DEV_MANAGER dev_mgr, DEV_HANDLE dev_handle, BOOL is_if); + +NTSTATUS gendrv_send_pnp_msg(ULONG msg, PDEVICE_OBJECT pdev_obj, PVOID pctx); + +BOOL 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); BOOL -gendrv_do_disconnect( -PUSB_DEV_MANAGER dev_mgr, -DEV_HANDLE if_handle, -BOOL is_if -); - -BOOL -gendrv_do_stop( -PUSB_DEV_MANAGER dev_mgr, -DEV_HANDLE dev_handle, -BOOL is_if -); - -NTSTATUS -gendrv_send_pnp_msg( -ULONG msg, -PDEVICE_OBJECT pdev_obj, -PVOID pctx -); - -BOOL -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 -); - -BOOL -gendrv_driver_init( -PUSB_DEV_MANAGER dev_mgr, -PUSB_DRIVER pdriver -) +gendrv_driver_init(PUSB_DEV_MANAGER dev_mgr, PUSB_DRIVER pdriver) { - PGENDRV_DRVR_EXTENSION pdrvr_ext; + PGENDRV_DRVR_EXTENSION pdrvr_ext; - if( dev_mgr == NULL || pdriver == NULL ) - return FALSE; + 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.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.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_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 ) ); - pdriver->driver_ext_size = sizeof( GENDRV_DRVR_EXTENSION ); + pdriver->driver_ext = usb_alloc_mem(NonPagedPool, sizeof(GENDRV_DRVR_EXTENSION)); + pdriver->driver_ext_size = sizeof(GENDRV_DRVR_EXTENSION); - RtlZeroMemory( pdriver->driver_ext, pdriver->driver_ext_size ); - pdrvr_ext = ( PGENDRV_DRVR_EXTENSION )pdriver->driver_ext; + 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 ); + // 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; + 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; + return TRUE; } BOOL -gendrv_driver_destroy( -PUSB_DEV_MANAGER dev_mgr, -PUSB_DRIVER pdriver -) +gendrv_driver_destroy(PUSB_DEV_MANAGER dev_mgr, PUSB_DRIVER pdriver) { - return gendrv_if_driver_destroy( dev_mgr, pdriver ); + return gendrv_if_driver_destroy(dev_mgr, pdriver); } BOOL -gendrv_connect( -PCONNECT_DATA param, -DEV_HANDLE dev_handle -) +gendrv_connect(PCONNECT_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; + 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; + if (param == NULL || dev_handle == 0) + return FALSE; - dev_mgr = param->dev_mgr; + dev_mgr = param->dev_mgr; - // let's set the configuration - purb = usb_alloc_mem( NonPagedPool, sizeof( URB ) ); - if( purb == NULL ) - return FALSE; + // 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; - } + 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; + // 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; - } + 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; - } + // 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; + 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; + //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 ); + 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_PENDING) + { + usb_free_mem(purb); - if( status == STATUS_SUCCESS ) - return TRUE; + if (status == STATUS_SUCCESS) + return TRUE; - return FALSE; - } + return FALSE; + } - return TRUE; + return TRUE; } BOOL -gendrv_event_select_driver( -PUSB_DEV pdev, //always null. we do not use this param -ULONG event, -ULONG context, -ULONG param -) +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; + // + // 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; + PDEVICE_OBJECT pdev_obj; + PDRIVER_OBJECT pdrvr_obj; + PLIST_ENTRY pthis, pnext; - USE_BASIC_NON_PENDING_IRQL; + USE_BASIC_NON_PENDING_IRQL; - if( pdev == NULL ) - return FALSE; + if (pdev == NULL) + return FALSE; - usb_dbg_print( DBGLVL_MAXIMUM, ( "gendrv_event_select_driver(): entering...\n" ) ); + usb_dbg_print(DBGLVL_MAXIMUM, ("gendrv_event_select_driver(): entering...\n")); - pdrvr = ( PUSB_DRIVER )param; - pconfig_desc = ( PUSB_CONFIGURATION_DESC )pdev->desc_buf[ sizeof( USB_DEVICE_DESC ) ]; - pdrvr_ext = ( PGENDRV_DRVR_EXTENSION )pdrvr->driver_ext; + pdrvr = (PUSB_DRIVER) param; + 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; - } + // + // 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; - } + 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; - } + 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; - } + 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; - } + if (pdev->usb_config) + { + pdev->dev_obj = pdev_obj; + } - unlock_dev( pdev, FALSE ); + unlock_dev(pdev, FALSE); - pdev_ext = ( PGENDRV_DEVICE_EXTENSION )pdev_obj->DeviceExtension; - pdev_ext->desc_buf = usb_alloc_mem( NonPagedPool, 512 ); - RtlCopyMemory( pdev_ext->desc_buf, pconfig_desc, 512 ); + pdev_ext = (PGENDRV_DEVICE_EXTENSION) pdev_obj->DeviceExtension; + pdev_ext->desc_buf = usb_alloc_mem(NonPagedPool, 512); + 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 ); + // 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; + // 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: + ERROR_OUT: - usb_unlock_dev( pdev ); - return FALSE; + usb_unlock_dev(pdev); + return FALSE; } VOID -gendrv_set_cfg_completion( -PURB purb, -PVOID context -) +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; + 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; + if (purb == NULL || context == NULL) + return; - dev_handle = purb->endp_handle & ~0xffff; - dev_mgr = ( PUSB_DEV_MANAGER ) context; - pdriver = ( PUSB_DRIVER )purb->reference; + 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; - } + if (purb->status != STATUS_SUCCESS) + { + usb_free_mem(purb); + return; + } - usb_free_mem( purb ); - purb = NULL; + usb_free_mem(purb); + purb = NULL; - // set the dev state - status = usb_query_and_lock_dev( dev_mgr, purb->endp_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 + // set the dev state + status = usb_query_and_lock_dev(dev_mgr, purb->endp_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 ); + 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_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; - } + 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; + //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 ); - } + pevent = alloc_event(&dev_mgr->event_pool, 1); + if (pevent == NULL) + { + unlock_dev(pdev, TRUE); + KeReleaseSpinLockFromDpcLevel(&dev_mgr->event_list_lock); + } - 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; + 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 ); + 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; + return; } BOOL -gendrv_stop( -PUSB_DEV_MANAGER dev_mgr, -DEV_HANDLE dev_handle -) +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 ); + if (dev_mgr == NULL) + return FALSE; + return gendrv_do_stop(dev_mgr, dev_handle, FALSE); } BOOL -gendrv_disconnect( -PUSB_DEV_MANAGER dev_mgr, -DEV_HANDLE dev_handle -) +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 ); + if (dev_mgr == NULL) + return FALSE; + return gendrv_do_disconnect(dev_mgr, dev_handle, FALSE); } BOOL -gendrv_build_reg_string( -PUSB_DESC_HEADER pdesc, -PUNICODE_STRING pus -) +gendrv_build_reg_string(PUSB_DESC_HEADER pdesc, PUNICODE_STRING pus) { - CHAR desc_str[ 128 ]; - STRING atemp; + 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; + if (pdesc == NULL || pus == NULL) + return FALSE; - RtlInitString( &atemp, desc_str ); - RtlAnsiStringToUnicodeString( pus, &atemp, TRUE ); - return TRUE; + 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 -) +gendrv_make_key(PUSB_DESC_HEADER pdesc) { - PUSB_DEVICE_DESC pdev_desc; - PUSB_INTERFACE_DESC pif_desc; + 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; + 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 -) +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; + 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 ); + 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; + return NULL; } PDRIVER_OBJECT -gendrv_load_ext_drvr( -PGENDRV_DRVR_EXTENSION pdrvr_ext, -PUSB_DESC_HEADER pdesc -) +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; + 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; + 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 ); - 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; - } + // 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); + 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; + 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 ); + 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 ); + 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; + 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; + 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 ); + 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; + // 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 ); + 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 ); + if (handle) + ZwClose(handle); - return NULL; + return NULL; } VOID -gendrv_release_drvr( -PGENDRV_DRVR_EXTENSION pdrvr_ext, -PDRIVER_OBJECT pdrvr_obj -) +gendrv_release_drvr(PGENDRV_DRVR_EXTENSION pdrvr_ext, PDRIVER_OBJECT pdrvr_obj) { - PLIST_ENTRY pthis, pnext; - PGENDRV_EXT_DRVR_ENTRY pentry; + 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 ); + 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 -) +gendrv_send_pnp_msg(ULONG msg, PDEVICE_OBJECT pdev_obj, PVOID pctx) { - if( pdev_obj == NULL ) - return STATUS_INVALID_PARAMETER; + 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; + 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; + 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; } BOOL -gendrv_if_connect( -PCONNECT_DATA params, -DEV_HANDLE if_handle -) +gendrv_if_connect(PCONNECT_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; + // + // 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; + 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" ) ); + pdev = NULL; + usb_dbg_print(DBGLVL_MAXIMUM, ("gendrv_if_connect(): entering...\n")); - if( params == NULL ) - return FALSE; + if (params == NULL) + return FALSE; - dev_mgr = params->dev_mgr; - pdrvr = params->pdriver; - pdrvr_ext = ( PGENDRV_DRVR_EXTENSION )pdrvr->driver_ext; + 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; + 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 ] ); + 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; + 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; - } + // + // 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; - } + 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; - } + 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; - } + 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; - } + 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 ); + unlock_dev(pdev, FALSE); - pdev_ext = ( PGENDRV_DEVICE_EXTENSION )pdev_obj->DeviceExtension; - pdev_ext->desc_buf = usb_alloc_mem( NonPagedPool, 512 ); - 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 ]; + pdev_ext = (PGENDRV_DEVICE_EXTENSION) pdev_obj->DeviceExtension; + pdev_ext->desc_buf = usb_alloc_mem(NonPagedPool, 512); + 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 ); + // 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; + // 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: + ERROR_OUT: - usb_unlock_dev( pdev ); - return FALSE; + usb_unlock_dev(pdev); + return FALSE; } BOOL -gendrv_do_stop( -PUSB_DEV_MANAGER dev_mgr, -DEV_HANDLE dev_handle, -BOOL is_if -) +gendrv_do_stop(PUSB_DEV_MANAGER dev_mgr, DEV_HANDLE dev_handle, BOOL is_if) { - PUSB_DEV pdev; - PDEVICE_OBJECT pdev_obj; - ULONG if_idx; + PUSB_DEV pdev; + PDEVICE_OBJECT pdev_obj; + ULONG if_idx; - if( dev_mgr == NULL ) - return FALSE; + 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; + // 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 ); + 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 ); + // send message to class drivers. + gendrv_send_pnp_msg(GENDRV_MSG_STOPDEVICE, pdev_obj, NULL); - return TRUE; + return TRUE; } BOOL -gendrv_if_stop( -PUSB_DEV_MANAGER dev_mgr, -DEV_HANDLE dev_handle -) +gendrv_if_stop(PUSB_DEV_MANAGER dev_mgr, DEV_HANDLE dev_handle) { - if( dev_mgr == NULL ) - return FALSE; + if (dev_mgr == NULL) + return FALSE; - return gendrv_do_stop( dev_mgr, dev_handle, TRUE ); + return gendrv_do_stop(dev_mgr, dev_handle, TRUE); } BOOL -gendrv_do_disconnect( -PUSB_DEV_MANAGER dev_mgr, -DEV_HANDLE if_handle, -BOOL is_if -) +gendrv_do_disconnect(PUSB_DEV_MANAGER dev_mgr, DEV_HANDLE if_handle, BOOL 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; + 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; - } - 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 ); + 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; + } + pdrvr_ext = (PGENDRV_DRVR_EXTENSION) pdrvr->driver_ext; + pdev_ext = (PGENDRV_DEVICE_EXTENSION) dev_obj->DeviceExtension; + } + else + TRAP(); + pdev = NULL; - // 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; + // 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; } BOOL -gendrv_if_disconnect( -PUSB_DEV_MANAGER dev_mgr, -DEV_HANDLE if_handle -) +gendrv_if_disconnect(PUSB_DEV_MANAGER dev_mgr, DEV_HANDLE if_handle) { - return gendrv_do_disconnect( dev_mgr, if_handle, TRUE ); + return gendrv_do_disconnect(dev_mgr, if_handle, TRUE); } BOOL -gendrv_if_driver_init( -PUSB_DEV_MANAGER dev_mgr, -PUSB_DRIVER pdriver -) +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; + 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.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.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. + 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 + //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->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 ) ); - pdriver->driver_ext_size = sizeof( GENDRV_DRVR_EXTENSION ); + pdriver->driver_ext = usb_alloc_mem(NonPagedPool, sizeof(GENDRV_DRVR_EXTENSION)); + pdriver->driver_ext_size = sizeof(GENDRV_DRVR_EXTENSION); - RtlZeroMemory( pdriver->driver_ext, pdriver->driver_ext_size ); - pdrvr_ext = ( PGENDRV_DRVR_EXTENSION )pdriver->driver_ext; + 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 ); + // 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; + return TRUE; } BOOL -gendrv_if_driver_destroy( -PUSB_DEV_MANAGER dev_mgr, -PUSB_DRIVER pdriver -) +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; + 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; - } + 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; + 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 -) +gendrv_open_ext_driver(PUNICODE_STRING unicode_string) { - NTSTATUS status; - OBJECT_ATTRIBUTES oa; - HANDLE drvr_handle; - UNICODE_STRING oname; - PDRIVER_OBJECT pdrvr = NULL; + 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 ); + 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 ); + 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; + 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; } BOOL -gendrv_close_ext_driver( PDRIVER_OBJECT pdrvr ) +gendrv_close_ext_driver(PDRIVER_OBJECT pdrvr) { - if( pdrvr == NULL ) - return FALSE; - ObDereferenceObject( pdrvr ); - return TRUE; + if (pdrvr == NULL) + return FALSE; + ObDereferenceObject(pdrvr); + return TRUE; } NTSTATUS -gendrv_dispatch( -PDEVICE_OBJECT dev_obj, -PIRP irp -) +gendrv_dispatch(PDEVICE_OBJECT dev_obj, PIRP irp) { - IO_STACK_LOCATION *irpstack; - PUSB_DEV_MANAGER dev_mgr; - PDEVEXT_HEADER ext_hdr; - NTSTATUS status; + 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; + if (dev_obj == NULL || irp == NULL) + return STATUS_INVALID_PARAMETER; - ext_hdr = dev_obj->DeviceExtension; - dev_mgr = ext_hdr->dev_mgr; + 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->MinorFunction == IOCTL_SUBMIT_URB_RD || - irpstack->MinorFunction == IOCTL_SUBMIT_URB_WR || - irpstack->MinorFunction == IOCTL_SUBMIT_URB_NOIO ) - { - PURB purb; - DEV_HANDLE endp_handle; - PGENDRV_DEVICE_EXTENSION pdev_ext; + 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->MinorFunction == IOCTL_SUBMIT_URB_RD || + irpstack->MinorFunction == IOCTL_SUBMIT_URB_WR || + irpstack->MinorFunction == 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 ); - } + 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->MinorFunction != 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 ); - } + purb = (PURB) irp->AssociatedIrp.SystemBuffer; + endp_handle = purb->endp_handle; + if (purb->data_buffer == NULL || purb->data_length == 0) + { + if (irpstack->MinorFunction != 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->MinorFunction == IOCTL_GET_DEV_DESC ) - { - // this is a synchronous call, route to dev_mgr_dispatch - return dev_mgr_dispatch( dev_mgr, irp ); - } - else if( irpstack->MinorFunction == 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 ); + GENDRV_EXIT_DISPATCH(dev_obj, STATUS_PENDING, irp); + } + else if (irpstack->MinorFunction == IOCTL_GET_DEV_DESC) + { + // this is a synchronous call, route to dev_mgr_dispatch + return dev_mgr_dispatch(dev_mgr, irp); + } + else if (irpstack->MinorFunction == 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->MinorFunction == IOCTL_SUBMIT_URB_RD || - irpstack->MinorFunction == IOCTL_SUBMIT_URB_WR || - irpstack->MinorFunction == IOCTL_SUBMIT_URB_NOIO ) - { - PURB purb; - DEV_HANDLE endp_handle; - PGENDRV_DEVICE_EXTENSION pdev_ext; + *((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->MinorFunction == IOCTL_SUBMIT_URB_RD || + irpstack->MinorFunction == IOCTL_SUBMIT_URB_WR || + irpstack->MinorFunction == 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 ); - } + 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 ); - } + 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->MinorFunction == IOCTL_GET_DEV_DESC ) - { - // this is a synchronous call, route to dev_mgr_dispatch - return dev_mgr_dispatch( dev_mgr, irp ); - } - else if( irpstack->MinorFunction == 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 ); + GENDRV_EXIT_DISPATCH(dev_obj, STATUS_PENDING, irp); + } + else if (irpstack->MinorFunction == IOCTL_GET_DEV_DESC) + { + // this is a synchronous call, route to dev_mgr_dispatch + return dev_mgr_dispatch(dev_mgr, irp); + } + else if (irpstack->MinorFunction == 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 ); + *((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; + return STATUS_NOT_SUPPORTED; } -BOOL -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; +BOOL +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 -) +gendrv_create_device(PUSB_DEV_MANAGER dev_mgr, PUSB_DRIVER gen_drvr, DEV_HANDLE dev_handle) { - BOOL 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; + BOOL 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; + 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 ); + 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 ); + 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; + 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); + 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; + 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->Flags &= ~DO_DEVICE_INITIALIZING; + pdev->StackSize = 2; //one for fdo, one for file device obj - pdev_ext = ( PGENDRV_DEVICE_EXTENSION )pdev->DeviceExtension; + pdev_ext = (PGENDRV_DEVICE_EXTENSION) pdev->DeviceExtension; - //may be accessed by other thread + //may be accessed by other thread - gendrv_init_dev_ext_hdr( pdev, dev_mgr ); + 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; + 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 ); + 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 ); + 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; + } + RtlFreeUnicodeString(&name_string); + return pdev; } VOID -gendrv_deferred_delete_device( -PVOID context -) +gendrv_deferred_delete_device(PVOID context) { - PDEVICE_OBJECT dev_obj; - PGENDRV_DEVICE_EXTENSION pdev_ext; - PGENDRV_DRVR_EXTENSION pdrvr_ext; - LARGE_INTEGER interval; + PDEVICE_OBJECT dev_obj; + PGENDRV_DEVICE_EXTENSION pdev_ext; + PGENDRV_DRVR_EXTENSION pdrvr_ext; + LARGE_INTEGER interval; - if( context == NULL ) - return; + if (context == NULL) + return; - dev_obj = ( PDEVICE_OBJECT )context; - pdev_ext = dev_obj->DeviceExtension; - pdrvr_ext = ( PGENDRV_DRVR_EXTENSION )pdev_ext->pdriver->driver_ext; + 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 + 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 ) ); + 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 ); + 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; + IoDeleteDevice(dev_obj); + return; } BOOL -gendrv_delete_device( -PUSB_DEV_MANAGER dev_mgr, -PDEVICE_OBJECT dev_obj -) +gendrv_delete_device(PUSB_DEV_MANAGER dev_mgr, PDEVICE_OBJECT dev_obj) { - BOOL is_if; - PUSB_DRIVER pdrvr; - PGENDRV_DEVICE_EXTENSION pdev_ext; - UCHAR dev_name[ 64 ]; - STRING string; - UNICODE_STRING symb_link; - PGENDRV_DRVR_EXTENSION pdrvr_ext; + BOOL is_if; + PUSB_DRIVER pdrvr; + PGENDRV_DEVICE_EXTENSION pdev_ext; + UCHAR dev_name[64]; + STRING string; + UNICODE_STRING symb_link; + PGENDRV_DRVR_EXTENSION pdrvr_ext; - if( dev_mgr == NULL || dev_obj == 0 ) - return FALSE; + 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 = 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 ); + pdev_ext = (PGENDRV_DEVICE_EXTENSION) dev_obj->DeviceExtension; + pdrvr = pdev_ext->pdriver; + pdrvr_ext = (PGENDRV_DRVR_EXTENSION) pdrvr->driver_ext; + is_if = 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 ); + 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 (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 ); + 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; - } + IoDeleteDevice(dev_obj); + return TRUE; + } - // borrow from umss's work routine - return umss_schedule_workitem( dev_obj, gendrv_deferred_delete_device, NULL, 0 ); + // 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 -) +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; + 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 -) +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; + 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 -) - +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: @@ -1657,7 +1451,6 @@ Return Value: The function value is the final status of the operation. --*/ - { OBJECT_ATTRIBUTES object_attr; ULONG disposition; @@ -1666,11 +1459,8 @@ Return Value: // Initialize the object for the key. // - InitializeObjectAttributes( &object_attr, - keyname, - OBJ_CASE_INSENSITIVE, - base_handle, - (PSECURITY_DESCRIPTOR) NULL ); + 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 @@ -1678,31 +1468,20 @@ Return Value: // if (create) - { - return ZwCreateKey( handle, - desired_access, - &object_attr, - 0, - (PUNICODE_STRING) NULL, - REG_OPTION_VOLATILE, - &disposition ); + { + return ZwCreateKey(handle, + desired_access, + &object_attr, 0, (PUNICODE_STRING) NULL, REG_OPTION_VOLATILE, &disposition); } - else - { - return ZwOpenKey( handle, - desired_access, - &object_attr ); + else + { + return ZwOpenKey(handle, desired_access, &object_attr); } - return STATUS_INVALID_PARAMETER; + return STATUS_INVALID_PARAMETER; } NTSTATUS -gendrv_get_key_value( -IN HANDLE KeyHandle, -IN PWSTR ValueName, -OUT PKEY_VALUE_FULL_INFORMATION *Information -) - +gendrv_get_key_value(IN HANDLE KeyHandle, IN PWSTR ValueName, OUT PKEY_VALUE_FULL_INFORMATION * Information) /*++ Routine Description: @@ -1727,7 +1506,6 @@ Return Value: The function value is the final status of the query operation. --*/ - { UNICODE_STRING unicodeString; NTSTATUS status; @@ -1736,21 +1514,17 @@ Return Value: PAGED_CODE(); - RtlInitUnicodeString( &unicodeString, ValueName ); + 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) { + status = ZwQueryValueKey(KeyHandle, + &unicodeString, KeyValueFullInformation, (PVOID) NULL, 0, &keyValueLength); + if (status != STATUS_BUFFER_OVERFLOW && status != STATUS_BUFFER_TOO_SMALL) + { return status; } @@ -1758,8 +1532,9 @@ Return Value: // Allocate a buffer large enough to contain the entire key data value. // - infoBuffer = usb_alloc_mem( NonPagedPool, keyValueLength ); - if (!infoBuffer) { + infoBuffer = usb_alloc_mem(NonPagedPool, keyValueLength); + if (!infoBuffer) + { return STATUS_INSUFFICIENT_RESOURCES; } @@ -1767,14 +1542,12 @@ Return Value: // Query the data for the key value. // - status = ZwQueryValueKey( KeyHandle, - &unicodeString, - KeyValueFullInformation, - infoBuffer, - keyValueLength, - &keyValueLength ); - if (!NT_SUCCESS( status )) { - usb_free_mem( infoBuffer ); + status = ZwQueryValueKey(KeyHandle, + &unicodeString, + KeyValueFullInformation, infoBuffer, keyValueLength, &keyValueLength); + if (!NT_SUCCESS(status)) + { + usb_free_mem(infoBuffer); return status; } @@ -1788,270 +1561,259 @@ Return Value: } VOID -gendrv_startio( -IN PDEVICE_OBJECT dev_obj, -IN PIRP irp -) +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; + PIO_STACK_LOCATION irp_stack; + ULONG ctrl_code; + PUSB_DEV_MANAGER dev_mgr; + USE_NON_PENDING_IRQL; - if( dev_obj == NULL || irp == NULL ) - return; + 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 - { - 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; + // 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 + { + IoSetCancelRoutine(irp, NULL); + } + IoReleaseCancelSpinLock(old_irql); - 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 ); - } + irp->IoStatus.Information = 0; - 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; + irp_stack = IoGetCurrentIrpStackLocation(irp); + ctrl_code = irp_stack->Parameters.DeviceIoControl.IoControlCode; + dev_mgr = ((PDEVEXT_HEADER) dev_obj->DeviceExtension)->dev_mgr; - if( irp_stack->Parameters.DeviceIoControl.InputBufferLength < sizeof( URB ) ) - { - GENDRV_COMPLETE_START_IO( dev_obj, STATUS_INVALID_PARAMETER, irp ); - } + 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); + } - 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; - } + 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; - if_idx = if_idx_from_handle( endp_handle ); - endp_idx = endp_idx_from_handle( endp_handle ); + NTSTATUS status; - //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 ); + if (irp_stack->Parameters.DeviceIoControl.InputBufferLength < sizeof(URB)) + { + GENDRV_COMPLETE_START_IO(dev_obj, STATUS_INVALID_PARAMETER, irp); + } - // 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; + 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; + } + } - 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; - } + purb->reference = 0; + endp_handle = purb->endp_handle; - unlock_dev( pdev, FALSE ); + 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); + } - // - // 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; + lock_dev(pdev, FALSE); + if (dev_state(pdev) == USB_DEV_STATE_ZOMB || (dev_state(pdev) < USB_DEV_STATE_ADDRESSED)) -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 ); + { + 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 -) +gendrv_clean_up_queued_irps(PDEVICE_OBJECT dev_obj) { - // called when device may not function or about to be removed, need cleanup + // 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; + LIST_ENTRY cancel_irps, *pthis; - // - // cancel all the irps in the queue - // - if( dev_obj == NULL ) - return; + // + // cancel all the irps in the queue + // + if (dev_obj == NULL) + return; - InitializeListHead( &cancel_irps ); + 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 ); + // 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 ); + 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 ); + // 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; + 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 -gendrv_cancel_queued_irp( -PDEVICE_OBJECT dev_obj, -PIRP pirp -) +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; + // 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; + 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; - } + 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 ); + 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; + 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/usbdriver/hub.c b/reactos/drivers/usb/nt4compat/usbdriver/hub.c index a01608e64c2..14503d5bf32 100644 --- a/reactos/drivers/usb/nt4compat/usbdriver/hub.c +++ b/reactos/drivers/usb/nt4compat/usbdriver/hub.c @@ -67,2902 +67,2601 @@ BOOL -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. -) +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_IRQL; + ULONG i; + USE_IRQL; - if( dev_mgr == NULL || if_handle == 0 || pdriver == NULL ) - return FALSE; + 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; - } + 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; + 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; + 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; } BOOL -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 -) +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_IRQL; + USE_IRQL; - if( dev_mgr == NULL || dev_handle == 0 || pdriver == NULL ) - return FALSE; + 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 (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; + 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 ); + 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; + return TRUE; } -USB_DRIVER g_driver_list[ DEVMGR_MAX_DRIVERS ]; -USB_DEV_MANAGER g_dev_mgr; +USB_DRIVER g_driver_list[DEVMGR_MAX_DRIVERS]; +USB_DEV_MANAGER g_dev_mgr; extern ULONG cpu_clock_freq; -BOOL -hub_check_reset_port_status( -PUSB_DEV pdev, -LONG port_idx -); +BOOL hub_check_reset_port_status(PUSB_DEV pdev, LONG port_idx); + +BOOL hub_start_next_reset_port(PUSB_DEV_MANAGER dev_mgr, BOOL from_dpc); + +VOID hub_reexamine_port_status_queue(PUSB_DEV hub_dev, ULONG port_idx, BOOL 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); + +BOOL hub_remove_reset_event(PUSB_DEV pdev, ULONG port_idx, BOOL from_dpc); + +BOOL hub_driver_init(PUSB_DEV_MANAGER dev_mgr, PUSB_DRIVER pdriver); + +BOOL hub_driver_destroy(PUSB_DEV_MANAGER dev_mgr, PUSB_DRIVER pdriver); + +BOOL hub_connect(PCONNECT_DATA init_param, DEV_HANDLE dev_handle); + +BOOL hub_disconnect(PUSB_DEV_MANAGER dev_mgr, DEV_HANDLE dev_handle); + +BOOL 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); + +BOOL dev_mgr_start_config_dev(PUSB_DEV pdev); + +BOOL 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); + +BOOL dev_mgr_start_select_driver(PUSB_DEV pdev); + +VOID dev_mgr_cancel_irp(PDEVICE_OBJECT pdev_obj, PIRP pirp); BOOL -hub_start_next_reset_port( -PUSB_DEV_MANAGER dev_mgr, -BOOL from_dpc -); - -VOID -hub_reexamine_port_status_queue( -PUSB_DEV hub_dev, -ULONG port_idx, -BOOL 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 -); - -BOOL -hub_remove_reset_event( -PUSB_DEV pdev, -ULONG port_idx, -BOOL from_dpc -); - -BOOL -hub_driver_init( -PUSB_DEV_MANAGER dev_mgr, -PUSB_DRIVER pdriver -); - -BOOL -hub_driver_destroy( -PUSB_DEV_MANAGER dev_mgr, -PUSB_DRIVER pdriver -); - -BOOL -hub_connect( -PCONNECT_DATA init_param, -DEV_HANDLE dev_handle -); - -BOOL -hub_disconnect( -PUSB_DEV_MANAGER dev_mgr, -DEV_HANDLE dev_handle -); - -BOOL -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 -); - -BOOL -dev_mgr_start_config_dev( -PUSB_DEV pdev -); - -BOOL -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 -); - -BOOL -dev_mgr_start_select_driver( -PUSB_DEV pdev -); - -VOID -dev_mgr_cancel_irp( -PDEVICE_OBJECT pdev_obj, -PIRP pirp -); - -BOOL -init_event_pool( -PUSB_EVENT_POOL pool -) +init_event_pool(PUSB_EVENT_POOL pool) { - int i; + int i; - if( pool == NULL ) - return FALSE; + if (pool == NULL) + return FALSE; - if( ( pool->event_array = usb_alloc_mem( - NonPagedPool, - sizeof( USB_EVENT ) * MAX_EVENTS ) ) - == 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; + 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 ] ); - } + for(i = 0; i < MAX_EVENTS; i++) + { + free_event(pool, &pool->event_array[i]); + } - return TRUE; + return TRUE; } BOOL -free_event( -PUSB_EVENT_POOL pool, -PUSB_EVENT pevent -) +free_event(PUSB_EVENT_POOL pool, PUSB_EVENT pevent) { - if( pool == NULL || pevent == NULL ) - { - return FALSE; - } + if (pool == NULL || pevent == NULL) + { + return FALSE; + } - RtlZeroMemory( pevent, sizeof( USB_EVENT ) ); - InsertTailList( &pool->free_que, (PLIST_ENTRY) pevent ); - pool->free_count++; - usb_dbg_print( DBGLVL_MAXIMUM + 1, ( "free_event(): alloced=0x%x, addr=0x%x\n", MAX_EVENTS - pool->free_count, pevent ) ); + RtlZeroMemory(pevent, sizeof(USB_EVENT)); + InsertTailList(&pool->free_que, (PLIST_ENTRY) pevent); + 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; + return TRUE; } +//null if failed PUSB_EVENT -alloc_event( -PUSB_EVENT_POOL pool, -LONG count -) //null if failed +alloc_event(PUSB_EVENT_POOL pool, LONG count) { - PUSB_EVENT new; - if( pool == NULL || count != 1) - return NULL; + PUSB_EVENT NewEvent; + if (pool == NULL || count != 1) + return NULL; - if( pool->free_count == 0 ) - return NULL; + if (pool->free_count == 0) + return NULL; - new = ( PUSB_EVENT )RemoveHeadList( &pool->free_que ); - pool->free_count --; + 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, new ) ); - return new; + usb_dbg_print(DBGLVL_MAXIMUM + 1, + ("alloc_event(): alloced=0x%x, addr=0x%x\n", MAX_EVENTS - pool->free_count, NewEvent)); + return NewEvent; } BOOL -destroy_event_pool( -PUSB_EVENT_POOL pool -) +destroy_event_pool(PUSB_EVENT_POOL pool) { - if( pool == NULL ) - return FALSE; + 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; + InitializeListHead(&pool->free_que); + pool->free_count = pool->total_count = 0; + usb_free_mem(pool->event_array); + pool->event_array = NULL; - return TRUE; + return TRUE; } VOID -event_list_default_process_event( -PUSB_DEV pdev, -ULONG event, -ULONG context, -ULONG param -) -{} +event_list_default_process_event(PUSB_DEV pdev, ULONG event, ULONG context, ULONG param) +{ +} //---------------------------------------------------------- //timer_svc pool routines BOOL -init_timer_svc_pool( -PTIMER_SVC_POOL pool -) +init_timer_svc_pool(PTIMER_SVC_POOL pool) { - int i; - if( pool == NULL ) - return FALSE; + int i; - 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 ); + if (pool == NULL) + return FALSE; - for( i = 0; i < MAX_TIMER_SVCS; i++ ) - { - free_timer_svc( pool, &pool->timer_svc_array[ i ] ); - } + 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); - return TRUE; + for(i = 0; i < MAX_TIMER_SVCS; i++) + { + free_timer_svc(pool, &pool->timer_svc_array[i]); + } + + return TRUE; } BOOL -free_timer_svc( -PTIMER_SVC_POOL pool, -PTIMER_SVC ptimer -) +free_timer_svc(PTIMER_SVC_POOL pool, PTIMER_SVC ptimer) { - if( pool == NULL || ptimer == NULL ) - return FALSE; + if (pool == NULL || ptimer == NULL) + return FALSE; - RtlZeroMemory( ptimer, sizeof( TIMER_SVC ) ); - InsertTailList( &pool->free_que, ( PLIST_ENTRY )&ptimer->timer_svc_link ); - pool->free_count ++; + RtlZeroMemory(ptimer, sizeof(TIMER_SVC)); + InsertTailList(&pool->free_que, (PLIST_ENTRY) & ptimer->timer_svc_link); + pool->free_count++; - return TRUE; + return TRUE; } +//null if failed PTIMER_SVC -alloc_timer_svc( -PTIMER_SVC_POOL pool, -LONG count -) //null if failed +alloc_timer_svc(PTIMER_SVC_POOL pool, LONG count) { - PTIMER_SVC new; - if( pool == NULL || count != 1 ) - return NULL; + PTIMER_SVC NewTimer; - if( pool->free_count <= 0 ) - return NULL; + if (pool == NULL || count != 1) + return NULL; - new = ( PTIMER_SVC )RemoveHeadList( &pool->free_que ); - pool->free_count --; - return new; + if (pool->free_count <= 0) + return NULL; + + NewTimer = (PTIMER_SVC) RemoveHeadList(&pool->free_que); + pool->free_count--; + return NewTimer; } BOOL -destroy_timer_svc_pool( -PTIMER_SVC_POOL pool -) +destroy_timer_svc_pool(PTIMER_SVC_POOL pool) { - if( pool == NULL ) - return FALSE; + 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; + 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; + return TRUE; } BOOL -dev_mgr_post_event( -PUSB_DEV_MANAGER dev_mgr, -PUSB_EVENT event -) +dev_mgr_post_event(PUSB_DEV_MANAGER dev_mgr, PUSB_EVENT event) { - KIRQL old_irql; + KIRQL old_irql; - if( dev_mgr == NULL || event == NULL ) - return FALSE; + 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 ); + 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; + KeSetEvent(&dev_mgr->wake_up_event, 0, FALSE); + 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 -) +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 + //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; + 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; + RemoveEntryList(&usb_event->event_link); + RtlCopyMemory(out_event, usb_event, sizeof(USB_EVENT)); + free_event(event_pool, usb_event); + return; } BOOL -psq_enqueue( -PPORT_STATUS_QUEUE psq, -ULONG status -) +psq_enqueue(PPORT_STATUS_QUEUE psq, ULONG status) { - if( psq == NULL ) - return FALSE; + if (psq == NULL) + return FALSE; - if( psq_is_full( psq ) ) - 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->port_status[psq->status_count].wPortChange = HIWORD(status); + psq->port_status[psq->status_count].wPortStatus = LOWORD(status); - psq->status_count++; + 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; + 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 -) +psq_init(PPORT_STATUS_QUEUE psq) { - RtlZeroMemory( psq, sizeof( PORT_STATUS_QUEUE ) ); - psq->port_flags = STATE_IDLE | USB_PORT_FLAG_DISABLE; + 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 -) //return 0xffffffff if no element +psq_outqueue(PPORT_STATUS_QUEUE psq) { - ULONG status; + ULONG status; - if( psq == NULL ) - return 0; + if (psq == NULL) + return 0; - if( psq_is_empty( psq ) ) - 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--; + 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; + return status; } BOOL -psq_push( -PPORT_STATUS_QUEUE psq, -ULONG status -) +psq_push(PPORT_STATUS_QUEUE psq, ULONG status) { - if( psq == NULL ) - return FALSE; + 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 ]; + 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; + ((PULONG) & psq->port_status)[0] = status; - psq->status_count++; - psq->status_count = ( ( 4 > psq->status_count ) ? psq->status_count : 4 ); + psq->status_count++; + psq->status_count = ((4 > psq->status_count) ? psq->status_count : 4); - return TRUE; + return TRUE; } VOID -dev_mgr_driver_entry_init( -PUSB_DEV_MANAGER dev_mgr, -PUSB_DRIVER pdrvr -) +dev_mgr_driver_entry_init(PUSB_DEV_MANAGER dev_mgr, PUSB_DRIVER pdrvr) { - // Device Info + // Device Info - RtlZeroMemory( pdrvr, sizeof( USB_DRIVER ) * DEVMGR_MAX_DRIVERS ); + 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[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[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[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[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_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[GEN_IF_DRIVER_IDX].driver_init = gendrv_if_driver_init; + pdrvr[GEN_IF_DRIVER_IDX].driver_destroy = gendrv_if_driver_destroy; } BOOL -dev_mgr_strobe( -PUSB_DEV_MANAGER dev_mgr -) +dev_mgr_strobe(PUSB_DEV_MANAGER dev_mgr) { - PUSB_EVENT pevent; - HANDLE thread_handle; + PUSB_EVENT pevent; + HANDLE thread_handle; - if( dev_mgr == NULL ) - return FALSE; - if( dev_mgr->hcd_count == 0 ) - return FALSE; + if (dev_mgr == NULL) + return FALSE; + if (dev_mgr->hcd_count == 0) + return FALSE; - dev_mgr->term_flag = FALSE; + dev_mgr->term_flag = FALSE; - if( dev_mgr->hcd_count == 0 ) - return 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 ); + 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 = 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->flags = USB_EVENT_FLAG_ACTIVE; + pevent->event = USB_EVENT_INIT_DEV_MGR; - pevent->process_queue = event_list_default_process_queue; - pevent->process_event = dev_mgr_event_init; + pevent->process_queue = event_list_default_process_queue; + pevent->process_event = dev_mgr_event_init; - pevent->context = ( ULONG )dev_mgr; + pevent->context = (ULONG) dev_mgr; - KeInitializeEvent( &dev_mgr->wake_up_event, - SynchronizationEvent, - FALSE ); + KeInitializeEvent(&dev_mgr->wake_up_event, SynchronizationEvent, FALSE); - InsertTailList( &dev_mgr->event_list, &pevent->event_link ); + 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; - } + 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); + ObReferenceObjectByHandle(thread_handle, + THREAD_ALL_ACCESS, NULL, KernelMode, (PVOID *) & dev_mgr->pthread, NULL); - ZwClose( thread_handle ); + ZwClose(thread_handle); - return TRUE; + return TRUE; } BOOL -dev_mgr_event_init( -PUSB_DEV pdev, //always null. we do not use this param -ULONG event, -ULONG context, -ULONG param -) +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; + 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; + 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; + if (event != USB_EVENT_INIT_DEV_MGR) + return FALSE; //dev_mgr->root_hub = NULL; - KeInitializeTimer( &dev_mgr->dev_mgr_timer ); + KeInitializeTimer(&dev_mgr->dev_mgr_timer); - KeInitializeDpc( &dev_mgr->dev_mgr_timer_dpc, - dev_mgr_timer_dpc_callback, - ( PVOID )dev_mgr ); + 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; + 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 ); + init_irp_list(&dev_mgr->irp_list); - KeInitializeSpinLock( &dev_mgr->dev_list_lock ); - InitializeListHead( &dev_mgr->dev_list ); + KeInitializeSpinLock(&dev_mgr->dev_list_lock); + InitializeListHead(&dev_mgr->dev_list); - dev_mgr->hub_count = 0; - InitializeListHead( &dev_mgr->hub_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->conn_count = 0; + dev_mgr->driver_list = g_driver_list; - dev_mgr_driver_entry_init( dev_mgr, dev_mgr->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; + 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 ); + 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 ); + KeSetTimerEx(&dev_mgr->dev_mgr_timer, + due_time, DEV_MGR_TIMER_INTERVAL_MS, &dev_mgr->dev_mgr_timer_dpc); - return TRUE; - } + return TRUE; + } - i--; + 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 ] ); - } + 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 ); - 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 ); + KeCancelTimer(&dev_mgr->dev_mgr_timer); + KeRemoveQueueDpc(&dev_mgr->dev_mgr_timer_dpc); + return FALSE; } VOID -dev_mgr_thread( -PVOID context -) +dev_mgr_destroy(PUSB_DEV_MANAGER dev_mgr) { - PUSB_DEV_MANAGER dev_mgr; - PUSB_EVENT pevent; - PLIST_ENTRY pthis, pnext; - USB_EVENT usb_event; - LARGE_INTEGER time_out; - NTSTATUS status; - BOOL dev_mgr_inited; - KIRQL old_irql; - LONG i; + LONG i; + // oops... + KeCancelTimer(&dev_mgr->dev_mgr_timer); + KeRemoveQueueDpc(&dev_mgr->dev_mgr_timer_dpc); - 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; + for(i = DEVMGR_MAX_DRIVERS - 1; i >= 0; i--) + dev_mgr->driver_list[i].driver_destroy(dev_mgr, &dev_mgr->driver_list[i]); - //usb_dbg_print( DBGLVL_MAXIMUM + 1, ( "dev_mgr_thread(): current uhci status=0x%x\n", uhci_status( dev_mgr->pdev_ext->uhci ) ) ); + destroy_irp_list(&dev_mgr->irp_list); + destroy_timer_svc_pool(&dev_mgr->timer_svc_pool); + destroy_event_pool(&dev_mgr->event_pool); - 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 -dev_mgr_timer_dpc_callback( -PKDPC Dpc, -PVOID context, -PVOID SystemArgument1, -PVOID SystemArgument2 -) +dev_mgr_thread(PVOID context) { - PUSB_DEV_MANAGER dev_mgr; - LIST_HEAD templist; - PLIST_ENTRY pthis, pnext; - static ULONG ticks = 0; + PUSB_DEV_MANAGER dev_mgr; + PUSB_EVENT pevent; + PLIST_ENTRY pthis, pnext; + USB_EVENT usb_event; + LARGE_INTEGER time_out; + NTSTATUS status; + BOOL dev_mgr_inited; + KIRQL old_irql; + LONG i; - ticks++; - dev_mgr = ( PUSB_DEV_MANAGER ) context; - if( dev_mgr == NULL ) - return; + 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; - dev_mgr->timer_click ++; - InitializeListHead( &templist ); + //usb_dbg_print( DBGLVL_MAXIMUM + 1, ( "dev_mgr_thread(): current uhci status=0x%x\n", uhci_status( dev_mgr->pdev_ext->uhci ) ) ); - KeAcquireSpinLockAtDpcLevel( &dev_mgr->timer_svc_list_lock ); - if( IsListEmpty( &dev_mgr->timer_svc_list ) == TRUE ) - { - KeReleaseSpinLockFromDpcLevel( &dev_mgr->timer_svc_list_lock ); - return; - } + 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; + } - 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; - } + // usb_dbg_print( DBGLVL_MAXIMUM, ( "dev_mgr_thread(): current element in event list is 0x%x\n", \ + // dbg_count_list( &dev_mgr->event_list ) ) ); - KeReleaseSpinLockFromDpcLevel( &dev_mgr->timer_svc_list_lock ); + 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 +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 ); - } + 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); + } } BOOL -dev_mgr_request_timer_svc( -PUSB_DEV_MANAGER dev_mgr, -PUSB_DEV pdev, -ULONG context, -ULONG due_time, -TIMER_SVC_HANDLER handler -) +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; + PTIMER_SVC timer_svc; + KIRQL old_irql; - if( dev_mgr == NULL || pdev == NULL || due_time == 0 || handler == NULL ) - return FALSE; + 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; + 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; + 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 -) +dev_mgr_alloc_addr(PUSB_DEV_MANAGER dev_mgr, PHCD hcd) { - // alloc a usb addr for the device within 1-128 - ULONG i; - if( dev_mgr == NULL || hcd == NULL ) - return 0xff; + // alloc a usb addr for the device within 1-128 + ULONG i; + if (dev_mgr == NULL || hcd == NULL) + return 0xff; - return hcd->hcd_alloc_addr( hcd ); + return hcd->hcd_alloc_addr(hcd); } BOOL -dev_mgr_free_addr( -PUSB_DEV_MANAGER dev_mgr, -PUSB_DEV pdev, -BYTE addr -) +dev_mgr_free_addr(PUSB_DEV_MANAGER dev_mgr, PUSB_DEV pdev, BYTE addr) { - PHCD hcd; - if( addr & 0x80 ) - return FALSE; + PHCD hcd; + if (addr & 0x80) + return FALSE; - if( dev_mgr == NULL || pdev == NULL ) - 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; + 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 -) +dev_mgr_alloc_device(PUSB_DEV_MANAGER dev_mgr, PHCD hcd) { - BYTE addr; - PUSB_DEV pdev; + BYTE addr; + PUSB_DEV pdev; - if( ( addr = dev_mgr_alloc_addr( dev_mgr, hcd ) ) == 0xff ) - return NULL; + 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; + pdev = usb_alloc_mem(NonPagedPool, sizeof(USB_DEV)); + if (pdev == NULL) + return NULL; - RtlZeroMemory( pdev, sizeof( USB_DEV ) ); + RtlZeroMemory(pdev, sizeof(USB_DEV)); - KeInitializeSpinLock( &pdev->dev_lock ); - dev_mgr->conn_count++; + 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->flags = USB_DEV_STATE_RESET; //class | cur_state | low speed + pdev->ref_count = 0; + pdev->dev_addr = addr; - pdev->hcd = hcd; + pdev->hcd = hcd; - pdev->dev_id = dev_mgr->conn_count; //will be used to compose dev_handle + 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 + 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; + return pdev; } VOID -dev_mgr_free_device( -PUSB_DEV_MANAGER dev_mgr, -PUSB_DEV pdev -) +dev_mgr_free_device(PUSB_DEV_MANAGER dev_mgr, PUSB_DEV pdev) { - if( pdev == NULL || dev_mgr == NULL ) - return; + 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; + 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; } BOOL -rh_driver_destroy( -PUSB_DEV_MANAGER dev_mgr, -PUSB_DRIVER pdriver -) +rh_driver_destroy(PUSB_DEV_MANAGER dev_mgr, PUSB_DRIVER pdriver) { - LONG i; - PHCD hcd; + LONG i; + PHCD hcd; - if( dev_mgr == NULL ) - return FALSE; + 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; + 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; } BOOL -rh_driver_init( -PUSB_DEV_MANAGER dev_mgr, -PUSB_DRIVER pdriver -) +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; - PTIMER_SVC ptimer; - PURB purb; - NTSTATUS status; - PHCD hcd; - LONG i; + 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; + PTIMER_SVC ptimer; + PURB purb; + NTSTATUS status; + PHCD hcd; + LONG i; - if( dev_mgr == NULL || pdriver == NULL ) - return FALSE; + 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 + //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.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_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_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; + 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; + 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; + 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; + 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; + if (usb2(hcd)) + rh->flags |= USB_DEV_FLAG_HIGH_SPEED; - rh->dev_driver = pdriver; + 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_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 ); + 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 ); + 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 = (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; + 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 = (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->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->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; + 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; + 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; + 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 ]; + 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->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; + pif->if_ext_size = 0; + pif->if_ext = NULL; - phub_ext = ( PHUB2_EXTENSION )&pconfig[ 1 ]; - phub_ext->port_count = 2; + 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 ); - } + 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 ) ); - } - } + { + 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; + 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->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; + 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; + 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; + //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; } -BOOL -rh_destroy( -PUSB_DEV pdev -) //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 +BOOL +rh_destroy(PUSB_DEV pdev) { - PUSB_DEV rh; - PLIST_ENTRY pthis, pnext; - PUSB_DEV_MANAGER dev_mgr; + PUSB_DEV rh; + PLIST_ENTRY pthis, pnext; + PUSB_DEV_MANAGER dev_mgr; - if( pdev == NULL ) - return FALSE; + if (pdev == NULL) + return FALSE; - dev_mgr = dev_mgr_from_dev( pdev ); + 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; - } + //??? + 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; + return TRUE; } VOID -rh_timer_svc_int_completion( -PUSB_DEV pdev, -PVOID context -) +rh_timer_svc_int_completion(PUSB_DEV pdev, PVOID context) { - PUSB_EVENT pevent; - PURB purb; - ULONG status, i; - PHCD hcd; - USE_IRQL; + PUSB_EVENT pevent; + PURB purb; + ULONG status, i; + PHCD hcd; + USE_IRQL; - if( pdev == NULL || context == NULL ) - return; + if (pdev == NULL || context == NULL) + return; - purb = ( PURB )context; + purb = (PURB) context; - lock_dev( pdev, TRUE ); + 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; - } + 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; - } + 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 ); + 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 ); + 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_MAXIMUM, ( "rh_timer_svc_int_completion(): rh's ref_count=0x%x\n", pdev->ref_count ) ); - unlock_dev( pdev, TRUE ); - usb_dbg_print( DBGLVL_MAXIMUM, ( "rh_timer_svc_int_completion(): exitiing...\n" ) ); - return; + 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_MAXIMUM, ("rh_timer_svc_int_completion(): rh's ref_count=0x%x\n", pdev->ref_count)); + unlock_dev(pdev, TRUE); + usb_dbg_print(DBGLVL_MAXIMUM, ("rh_timer_svc_int_completion(): exitiing...\n")); + return; } VOID -rh_timer_svc_reset_port_completion( -PUSB_DEV pdev, -PVOID context -) +rh_timer_svc_reset_port_completion(PUSB_DEV pdev, PVOID context) { - PURB purb; - ULONG i; - USHORT port_num; - PHUB2_EXTENSION hub_ext; - PLIST_ENTRY pthis, pnext; - PUSB_DEV_MANAGER dev_mgr; - PUSB_CTRL_SETUP_PACKET psetup; + PURB purb; + ULONG i; + USHORT port_num; + PHUB2_EXTENSION hub_ext; + PLIST_ENTRY pthis, pnext; + PUSB_DEV_MANAGER dev_mgr; + PUSB_CTRL_SETUP_PACKET psetup; - USE_IRQL; + USE_IRQL; - if( pdev == NULL || context == NULL ) - return; + if (pdev == NULL || context == NULL) + return; - dev_mgr = dev_mgr_from_dev( pdev ); //readonly and hold ref_count + 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; - } + //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 ); + 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; + 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 ); + 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; - } + 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 ); + i = pdev->hcd->hcd_rh_reset_port(pdev->hcd, (UCHAR) psetup->wIndex); - hub_ext = hub_ext_from_dev( pdev ); + 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; - } - } + { + 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 ); + //???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 + 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 ); + 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; - } + //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 ); + 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; + lock_dev(pdev, TRUE); + pdev->ref_count--; + unlock_dev(pdev, TRUE); + return; } -VOID -dev_mgr_disconnect_dev( -PUSB_DEV pdev -) //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; - PUSB_CONFIGURATION pconfig; - PUSB_INTERFACE pif; - PUSB_DEV_MANAGER dev_mgr; - PHCD hcd; - BOOL is_hub, found; - ULONG dev_id; + PLIST_ENTRY pthis, pnext; + PHUB2_EXTENSION phub_ext; + PUSB_CONFIGURATION pconfig; + PUSB_INTERFACE pif; + PUSB_DEV_MANAGER dev_mgr; + PHCD hcd; + BOOL is_hub, found; + ULONG dev_id; + int i; - int i; - USE_IRQL; + USE_IRQL; - if( pdev == NULL ) - return; + if (pdev == NULL) + return; - found = FALSE; + 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 ); + 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 ) ); + // 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 ); + //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; + if (dev_mgr == NULL) + return; - hcd->hcd_remove_device( hcd, pdev ); + 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; - } - } - } - } + //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; + pconfig = pdev->usb_config; - //remove event belong to the dev - is_hub = ( ( pdev->flags & USB_DEV_CLASS_MASK ) == USB_DEV_CLASS_HUB ); + //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; - } - } + 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 ); + //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 ); + // 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 ); + // 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 ); - } + // 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; + // 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 ); - } + 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 ) ); + 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 ); + // 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 - } + 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; + return; } BOOL -hub_driver_init( -PUSB_DEV_MANAGER dev_mgr, -PUSB_DRIVER pdriver -) +hub_driver_init(PUSB_DEV_MANAGER dev_mgr, PUSB_DRIVER pdriver) { - //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 + //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.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_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_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->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; + 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; + return TRUE; } BOOL -hub_driver_destroy( -PUSB_DEV_MANAGER dev_mgr, -PUSB_DRIVER pdriver -) +hub_driver_destroy(PUSB_DEV_MANAGER dev_mgr, PUSB_DRIVER pdriver) { - pdriver->driver_ext = NULL; - return TRUE; + pdriver->driver_ext = NULL; + return TRUE; } + void - -hub_reset_pipe_completion( -PURB purb, //only for reference, can not be released -PVOID context -) +hub_reset_pipe_completion(PURB purb, //only for reference, can not be released + PVOID context) { - PUSB_DEV pdev; - PUSB_ENDPOINT pendp; - NTSTATUS status; + PUSB_DEV pdev; + PUSB_ENDPOINT pendp; + NTSTATUS status; - USE_IRQL; + USE_IRQL; - if( purb == NULL ) - { - return; - } + if (purb == NULL) + { + return; + } - pdev = purb->pdev; - pendp = purb->pendp; + pdev = purb->pdev; + pendp = purb->pendp; - lock_dev( pdev, TRUE ); - if( dev_state( pdev ) == USB_DEV_STATE_ZOMB ) - { - unlock_dev( pdev, TRUE ); - return; - } + 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 ); + 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; + pdev = purb->pdev; + hub_start_int_request(pdev); + return; } NTSTATUS -hub_start_int_request( -PUSB_DEV pdev -) +hub_start_int_request(PUSB_DEV pdev) { - PURB purb; - PUSB_INTERFACE pif; - PHUB2_EXTENSION hub_ext; - NTSTATUS status; - PHCD hcd; - USE_IRQL; + PURB purb; + PUSB_INTERFACE pif; + PHUB2_EXTENSION hub_ext; + NTSTATUS status; + PHCD hcd; + USE_IRQL; - if( pdev == NULL ) - return STATUS_INVALID_PARAMETER; + 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 ) ); - RtlZeroMemory( purb, sizeof( URB ) ); + 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)); + RtlZeroMemory(purb, sizeof(URB)); - if( purb == NULL ) - { - unlock_dev( pdev, FALSE ); - return STATUS_NO_MEMORY; - } + if (purb == NULL) + { + unlock_dev(pdev, FALSE); + return STATUS_NO_MEMORY; + } 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; + 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_MAXIMUM, ( "hub_start_int_request(): pdev=0x%x, pif=0x%x\n", pdev, pif ) ); - purb->pendp = &pif->endp[ 0 ]; - purb->pdev = pdev; + hub_if_from_dev(pdev, pif); + usb_dbg_print(DBGLVL_MAXIMUM, ("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 ); + 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; - } + status = hcd->hcd_submit_urb(hcd, pdev, purb->pendp, purb); + if (status != STATUS_PENDING) + { + usb_free_mem(purb); + purb = NULL; + } - return status; + return status; } void -hub_int_completion( -PURB purb, -PVOID pcontext -) +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; + PUSB_DEV pdev; + PHUB2_EXTENSION hub_ext; + ULONG port_idx; + PUSB_CTRL_SETUP_PACKET psetup; + NTSTATUS status; + LONG i; + PHCD hcd; - USE_IRQL; + USE_IRQL; - if( purb == NULL ) - return; + if (purb == NULL) + return; - if( pcontext == NULL ) - { - usb_free_mem( purb ); - return; - } + if (pcontext == NULL) + { + usb_free_mem(purb); + return; + } - usb_dbg_print( DBGLVL_MAXIMUM, ("hub_int_completion(): entering...\n" ) ); + usb_dbg_print(DBGLVL_MAXIMUM, ("hub_int_completion(): entering...\n")); - pdev = purb->pdev; - hub_ext = pcontext; + 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; - } + lock_dev(pdev, TRUE); + if (dev_state(pdev) == USB_DEV_STATE_ZOMB) + { + unlock_dev(pdev, TRUE); + usb_free_mem(purb); + return; + } - hcd = pdev->hcd; + hcd = pdev->hcd; - if( purb->status == STATUS_SUCCESS ) - { + 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; - } + 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; + 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; + //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->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; + 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 = (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; + 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 ); + 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 ); - } + 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; + usb_free_mem(purb); + purb = NULL; + } + return; } VOID -hub_get_port_status_completion( -PURB purb, -PVOID context -) +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; + PUSB_DEV pdev; + PUSB_ENDPOINT pendp; + BYTE port_idx; + PHUB2_EXTENSION hub_ext; + PUSB_CTRL_SETUP_PACKET psetup; + NTSTATUS status; + PHCD hcd; - USE_IRQL; + USE_IRQL; - if( purb == NULL || context == NULL ) - return; + if (purb == NULL || context == NULL) + return; - usb_dbg_print( DBGLVL_MAXIMUM, ("hub_get_port_feature_completion(): entering...\n" ) ); + usb_dbg_print(DBGLVL_MAXIMUM, ("hub_get_port_feature_completion(): entering...\n")); - pdev = purb->pdev; - pendp = purb->pendp; + 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; - } + 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 ); + hcd = pdev->hcd; + if (usb_error(purb->status)) + { + unlock_dev(pdev, TRUE); - purb->status = 0; + 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 ); + 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; - } + } + 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; + 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 ) ) ); + 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 ) ); + psq_enqueue(&hub_ext->port_status_queue[port_idx], *((PULONG) purb->data_buffer)); - //reuse the urb to clear the feature - RtlZeroMemory( purb, sizeof( URB ) ); + //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->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; + 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 = (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; + 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 ); + 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 ); + 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; + // 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 -) +hub_clear_port_feature_completion(PURB purb, PVOID context) { - BYTE port_idx; - LONG i; - BOOL bReset, event_post, brh; - ULONG pc; - PHCD hcd; - NTSTATUS status; - PUSB_DEV pdev, pdev2; - PUSB_EVENT pevent; - PUSB_ENDPOINT pendp; - PUSB_INTERFACE pif; - PHUB2_EXTENSION hub_ext; - PUSB_DEV_MANAGER dev_mgr; + BYTE port_idx; + LONG i; + BOOL bReset, event_post, brh; + ULONG pc; + PHCD hcd; + NTSTATUS status; + PUSB_DEV pdev, pdev2; + PUSB_EVENT pevent; + PUSB_ENDPOINT pendp; + PUSB_INTERFACE pif; + PHUB2_EXTENSION hub_ext; + PUSB_DEV_MANAGER dev_mgr; - PUSB_CTRL_SETUP_PACKET psetup; + PUSB_CTRL_SETUP_PACKET psetup; - USE_IRQL; + USE_IRQL; - if( purb == NULL ) - return; + if (purb == NULL) + return; - if( context == NULL ) - { - usb_free_mem( purb ); - return; - } + if (context == NULL) + { + usb_free_mem(purb); + return; + } - usb_dbg_print( DBGLVL_MAXIMUM, ("hub_clear_port_feature_completion(): entering...\n" ) ); + usb_dbg_print(DBGLVL_MAXIMUM, ("hub_clear_port_feature_completion(): entering...\n")); - pdev = purb->pdev; - port_idx = ( BYTE )purb->reference; + pdev = purb->pdev; + port_idx = (BYTE) purb->reference; - lock_dev( pdev, TRUE ); - dev_mgr = dev_mgr_from_dev( pdev ); - hcd = pdev->hcd; - brh = ( dev_class( pdev ) == USB_DEV_CLASS_ROOT_HUB ); + lock_dev(pdev, TRUE); + dev_mgr = dev_mgr_from_dev(pdev); + hcd = pdev->hcd; + brh = (dev_class(pdev) == USB_DEV_CLASS_ROOT_HUB); - if( usb_error( purb->status ) ) - { - unlock_dev( pdev, TRUE ); + if (usb_error(purb->status)) + { + unlock_dev(pdev, TRUE); - purb->status = 0; + 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 - // - // usb_free_mem( purb ); - // - goto LBL_SCAN_PORT_STAT; - } - } - return; - } + // 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 + // + // usb_free_mem( purb ); + // + goto LBL_SCAN_PORT_STAT; + } + } + return; + } - if( dev_state( pdev ) == USB_DEV_STATE_ZOMB ) - { - unlock_dev( pdev, TRUE ); - usb_free_mem( purb ); - return; - } + if (dev_state(pdev) == USB_DEV_STATE_ZOMB) + { + unlock_dev(pdev, TRUE); + usb_free_mem(purb); + return; + } - pc = ( ( PUSB_PORT_STATUS ) context )->wPortChange; + 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; + 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 ); + hub_ext = hub_ext_from_dev(pdev); - if( pc ) - { + if (pc) + { //some other status change on the port still active - psetup = ( PUSB_CTRL_SETUP_PACKET )purb->setup_packet; + 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 ); + 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_stataus_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 ) ); + 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_stataus_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 ) ); + 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; - } + // 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; - } - } + 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 ); + //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; - } - } + //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; + 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; + //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; + 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 = (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; + 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; + purb->pirp = NULL; - unlock_dev( pdev, TRUE ); + 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; - } + 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 ); + unlock_dev(pdev, TRUE); LBL_SCAN_PORT_STAT: - //all status changes are cleared - if( purb ) - usb_free_mem( purb ); + //all status changes are cleared + if (purb) + usb_free_mem(purb); - purb = NULL; + purb = NULL; - KeAcquireSpinLockAtDpcLevel( &dev_mgr->event_list_lock ); - lock_dev( pdev, TRUE ); + 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; - } + 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; - } - } - } + //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 ); + unlock_dev(pdev, TRUE); + KeReleaseSpinLockFromDpcLevel(&dev_mgr->event_list_lock); - if( port_idx ) - hub_check_reset_port_status( - pdev, - port_idx ); + 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 ); + //reinitialize the int request, here to reduce some uncertainty of concurrency + hub_start_int_request(pdev); - return; + return; } VOID -hub_event_examine_status_que( -PUSB_DEV pdev, -ULONG event, -ULONG context, //hub_ext -ULONG param //port_idx -) +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; + PHUB2_EXTENSION hub_ext; + USB_PORT_STATUS ps; + PUSB_DEV pchild_dev; + PTIMER_SVC ptimer; + PUSB_DEV_MANAGER dev_mgr; - USE_IRQL; + USE_IRQL; - if( pdev == NULL || context == 0 || param == 0 ) - return; + 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; - } + 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 ); + 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; - } + 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 ] ); + *((ULONG *) & ps) = psq_outqueue(&hub_ext->port_status_queue[param]); - pchild_dev = hub_ext->child_dev[ param ]; - hub_ext->child_dev[ param ] = 0; + 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 ) ); + 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 ); + unlock_dev(pdev, FALSE); - if( pchild_dev != NULL ) - dev_mgr_disconnect_dev( pchild_dev ); + 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 ) ); + 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; + 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 - { - usb_dbg_print( DBGLVL_MAXIMUM, ("hub_event_examine_status_queue(): unknown error\n" ) ); - 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; + return; } VOID -hub_timer_wait_dev_stable( -PUSB_DEV pdev, -PVOID context //port-index -) +hub_timer_wait_dev_stable(PUSB_DEV pdev, + PVOID context //port-index + ) { - PHUB2_EXTENSION hub_ext; - PUSB_INTERFACE pif; - PUSB_EVENT pevent; - ULONG param; - PUSB_DEV_MANAGER dev_mgr; + PHUB2_EXTENSION hub_ext; + PUSB_INTERFACE pif; + PUSB_EVENT pevent; + ULONG param; + PUSB_DEV_MANAGER dev_mgr; - USE_IRQL; + USE_IRQL; - if( pdev == NULL || context == 0 ) - return; + 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 ); + dev_mgr = dev_mgr_from_dev(pdev); + param = (ULONG) context; + KeAcquireSpinLockAtDpcLevel(&dev_mgr->event_list_lock); + lock_dev(pdev, TRUE); - pdev->ref_count--; + pdev->ref_count--; - if( dev_state( pdev ) == USB_DEV_STATE_ZOMB ) - { - goto LBL_OUT; - } + if (dev_state(pdev) == USB_DEV_STATE_ZOMB) + { + goto LBL_OUT; + } - hub_ext = hub_ext_from_dev( pdev ); + 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 ); + 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_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 ); + hub_post_esq_event(pdev, (BYTE) param, hub_event_dev_stable); - } + } - LBL_OUT: - unlock_dev( pdev, TRUE ); - KeReleaseSpinLockFromDpcLevel( &dev_mgr->event_list_lock ); - return; +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 -) +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; - BOOL que_exist; - PHCD hcd; - PUSB_DEV_MANAGER dev_mgr; - NTSTATUS status; - PURB purb; - PUSB_CTRL_SETUP_PACKET psetup; + PHUB2_EXTENSION hub_ext; + PUSB_EVENT pevent, pevent1; + PLIST_ENTRY pthis, pnext; + BOOL que_exist; + PHCD hcd; + PUSB_DEV_MANAGER dev_mgr; + NTSTATUS status; + PURB purb; + PUSB_CTRL_SETUP_PACKET psetup; - USE_IRQL; + USE_IRQL; - if( pdev == NULL || context == 0 || param == 0 ) - return; + 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 ); + 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; + if (dev_state(pdev) == USB_DEV_STATE_ZOMB) + goto LBL_OUT; - hub_ext = hub_ext_from_dev( pdev ); - hcd = pdev->hcd; + 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 = 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; + 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; + 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; + 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; - } + 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 ) ); - RtlZeroMemory( purb, sizeof( URB ) ); + 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)); + RtlZeroMemory(purb, sizeof(URB)); - purb->data_buffer = NULL; - purb->data_length = 0; - purb->pendp = &pdev->default_endp; + 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; + 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 = (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; + 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 ); + 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 ); + 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; - } + 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; +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 -) +hub_start_reset_port_completion(PURB purb, PVOID context) { - PUSB_DEV pdev; - PUSB_ENDPOINT pendp; - PUSB_DEV_MANAGER dev_mgr; - NTSTATUS status; - ULONG port_idx; - PHCD hcd; + PUSB_DEV pdev; + PUSB_ENDPOINT pendp; + PUSB_DEV_MANAGER dev_mgr; + NTSTATUS status; + ULONG port_idx; + PHCD hcd; - USE_IRQL; - if( purb == NULL ) - return; + USE_IRQL; + if (purb == NULL) + return; - if( context == NULL ) - { - //fatal error no retry. - usb_free_mem( purb ); - return; - } + if (context == NULL) + { + //fatal error no retry. + usb_free_mem(purb); + return; + } - pdev = purb->pdev; - pendp = purb->pendp; - port_idx = purb->reference; + pdev = purb->pdev; + pendp = purb->pendp; + port_idx = purb->reference; - lock_dev( pdev, TRUE ); + lock_dev(pdev, TRUE); - if( dev_state( pdev ) == USB_DEV_STATE_ZOMB ) - { - unlock_dev( pdev, TRUE ); - usb_free_mem( purb ); - goto LBL_FREE_EVENT; - } + 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 ); + hcd = pdev->hcd; + dev_mgr = dev_mgr_from_dev(pdev); + unlock_dev(pdev, TRUE); - status = purb->status; - usb_free_mem( purb ); + status = purb->status; + usb_free_mem(purb); - if( !usb_error( status ) ) - { - return; - } + 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; +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 -) +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; + PUSB_DEV pdev, hub_dev; + PUSB_ENDPOINT pendp; + PUSB_DEV_MANAGER dev_mgr; + NTSTATUS status; + ULONG port_idx; + PHCD hcd; - USE_IRQL; + USE_IRQL; - if( purb == NULL ) - return; + if (purb == NULL) + return; - if( context == NULL ) - { - //fatal error no retry. - usb_free_mem( purb ); - return; - } + if (context == NULL) + { + //fatal error no retry. + usb_free_mem(purb); + return; + } - pdev = purb->pdev; - pendp = purb->pendp; - port_idx = purb->reference; + pdev = purb->pdev; + pendp = purb->pendp; + port_idx = purb->reference; - lock_dev( pdev, TRUE ); + lock_dev(pdev, TRUE); - hcd = pdev->hcd; - dev_mgr = dev_mgr_from_dev( pdev ); - hub_dev = pdev->parent_dev; - port_idx = pdev->port_idx; + 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; - } + 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; + pdev->flags &= ~USB_DEV_STATE_MASK; + pdev->flags |= USB_DEV_STATE_ADDRESSED; - unlock_dev( pdev, TRUE ); - status = purb->status; + 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; - } + 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 ); + usb_free_mem(purb); + //let address settle + usb_wait_ms_dpc(10); - //let's config the dev - dev_mgr_start_config_dev( pdev ); + //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; +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 -) +hub_disable_port_completion(PURB purb, PVOID pcontext) { - PHUB2_EXTENSION hub_ext; - PUSB_DEV pdev; - PUSB_DEV_MANAGER dev_mgr; - UCHAR port_idx; - PUSB_ENDPOINT pendp; - PUSB_CTRL_SETUP_PACKET psetup; + PHUB2_EXTENSION hub_ext; + PUSB_DEV pdev; + PUSB_DEV_MANAGER dev_mgr; + UCHAR port_idx; + PUSB_ENDPOINT pendp; + PUSB_CTRL_SETUP_PACKET psetup; - if( purb == NULL ) - return; + if (purb == NULL) + return; - pdev = purb->pdev; - pendp = purb->pendp; - psetup = ( PUSB_CTRL_SETUP_PACKET )purb->setup_packet; - port_idx = ( UCHAR )psetup->wIndex; + 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 ); + dev_mgr = dev_mgr_from_dev(pdev); - usb_free_mem( purb ); + 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 ); + 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; + return; } -NTSTATUS -hub_disable_port_request( -PUSB_DEV pdev, -UCHAR port_idx -) //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_IRQL; + PURB purb; + PUSB_ENDPOINT pendp; + PHUB2_EXTENSION hub_ext; + PUSB_CTRL_SETUP_PACKET psetup; + NTSTATUS status; + PHCD hcd; + USE_IRQL; - if( pdev == NULL || port_idx == 0 ) - return STATUS_INVALID_PARAMETER; + 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; - } + 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; - } + purb = usb_alloc_mem(NonPagedPool, sizeof(URB)); + if (purb == NULL) + { + unlock_dev(pdev, FALSE); + return STATUS_NO_MEMORY; + } - RtlZeroMemory( purb, sizeof( URB ) ); + RtlZeroMemory(purb, sizeof(URB)); - purb->flags = 0; - purb->status = STATUS_SUCCESS; + purb->flags = 0; + purb->status = STATUS_SUCCESS; - hub_ext = hub_ext_from_dev( pdev ); + hub_ext = hub_ext_from_dev(pdev); - purb->data_buffer = NULL; + purb->data_buffer = NULL; purb->data_length = 0; - pendp = purb->pendp = &pdev->default_endp; - purb->pdev = pdev; + pendp = purb->pendp = &pdev->default_endp; + purb->pdev = pdev; purb->completion = hub_disable_port_completion; purb->context = hub_ext; @@ -2970,1032 +2669,977 @@ UCHAR port_idx purb->pirp = NULL; purb->reference = 0; - psetup = ( PUSB_CTRL_SETUP_PACKET )purb->setup_packet; + 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; + 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 ); + 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; + status = hcd->hcd_submit_urb(hcd, pdev, pendp, purb); + if (status == STATUS_PENDING) + return status; - usb_free_mem( purb ); - return status; + usb_free_mem(purb); + return status; } - BOOL -hub_remove_reset_event( -PUSB_DEV pdev, -ULONG port_idx, -BOOL from_dpc -) +hub_remove_reset_event(PUSB_DEV pdev, ULONG port_idx, BOOL from_dpc) { - PUSB_DEV_MANAGER dev_mgr; - PLIST_ENTRY pthis, pnext; - PUSB_EVENT pevent, pnext_event; - BOOL found; + PUSB_DEV_MANAGER dev_mgr; + PLIST_ENTRY pthis, pnext; + PUSB_EVENT pevent, pnext_event; + BOOL found; - KIRQL old_irql; + KIRQL old_irql; - if( pdev == NULL ) - return FALSE; + if (pdev == NULL) + return FALSE; - if( port_idx == 0 ) - return FALSE; + if (port_idx == 0) + return FALSE; - dev_mgr = dev_mgr_from_dev( pdev ); - found = 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 ); + 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 ); + 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 ); + if (pnext_event) + InsertHeadList(&dev_mgr->event_list, &pnext_event->event_link); - found = TRUE; - break; - } - } - ListNext( &dev_mgr->event_list, pthis, pnext ); - pthis = pnext; - } + 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; + if (from_dpc) + KeReleaseSpinLockFromDpcLevel(&dev_mgr->event_list_lock); + else + KeReleaseSpinLock(&dev_mgr->event_list_lock, old_irql); + return found; } BOOL -hub_start_next_reset_port( -PUSB_DEV_MANAGER dev_mgr, -BOOL from_dpc -) +hub_start_next_reset_port(PUSB_DEV_MANAGER dev_mgr, BOOL from_dpc) { - PLIST_ENTRY pthis, pnext; - PUSB_EVENT pevent, pnext_event; - PUSB_DEV pdev; - PHUB2_EXTENSION hub_ext; - BOOL bret; - PURB purb; - BOOL processed; - PUSB_CTRL_SETUP_PACKET psetup; - PHCD hcd; + PLIST_ENTRY pthis, pnext; + PUSB_EVENT pevent, pnext_event; + PUSB_DEV pdev; + PHUB2_EXTENSION hub_ext; + BOOL bret; + PURB purb; + BOOL processed; + PUSB_CTRL_SETUP_PACKET psetup; + PHCD hcd; - USE_IRQL; + USE_IRQL; - if( dev_mgr == NULL ) - return FALSE; + if (dev_mgr == NULL) + return FALSE; - bret = FALSE; - processed = FALSE; + bret = FALSE; + processed = FALSE; - if( from_dpc ) - KeAcquireSpinLockAtDpcLevel( &dev_mgr->event_list_lock ); - else - KeAcquireSpinLock( &dev_mgr->event_list_lock, &old_irql ); + if (from_dpc) + KeAcquireSpinLockAtDpcLevel(&dev_mgr->event_list_lock); + else + KeAcquireSpinLock(&dev_mgr->event_list_lock, &old_irql); - ListFirst( &dev_mgr->event_list, pthis); + 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 ) - { + 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; + processed = TRUE; - pdev = pevent->pdev; - lock_dev( pdev, 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; - } + 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 ) ); - RtlZeroMemory( purb, sizeof( URB ) ); + purb = usb_alloc_mem(NonPagedPool, sizeof(URB)); + RtlZeroMemory(purb, sizeof(URB)); - purb->data_buffer = NULL; - purb->data_length = 0; - purb->pendp = &pdev->default_endp; + 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; + 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 = (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; + 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 ); + 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; - } + bret = TRUE; + break; + } - if( !processed ) - { - ListNext( &dev_mgr->event_list, pthis, pnext ); - pthis = pnext; - } - else - 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 (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 (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; + if (pthis == NULL) + bret = TRUE; - return bret; + 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 -) +hub_post_esq_event(PUSB_DEV pdev, BYTE port_idx, PROCESS_EVENT pe) { - PUSB_DEV_MANAGER dev_mgr; - PUSB_EVENT pevent; + PUSB_DEV_MANAGER dev_mgr; + PUSB_EVENT pevent; - if( pdev == NULL || port_idx == 0 || pe == NULL ) - return; + if (pdev == NULL || port_idx == 0 || pe == NULL) + return; - dev_mgr = dev_mgr_from_dev( pdev ); + dev_mgr = dev_mgr_from_dev(pdev); - pevent = alloc_event( &dev_mgr->event_pool, 1 ); - 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; + pevent = alloc_event(&dev_mgr->event_pool, 1); + 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; } -BOOL -hub_check_reset_port_status( -PUSB_DEV pdev, -LONG port_idx -) // called only in hub_clear_port_feature_completion +BOOL +hub_check_reset_port_status(PUSB_DEV pdev, LONG port_idx) { - PUSB_DEV_MANAGER dev_mgr; - PHUB2_EXTENSION hub_ext; - BOOL bReset; - USB_PORT_STATUS port_status; - PUSB_DEV pdev2; - PURB purb2; - PHCD hcd; + PUSB_DEV_MANAGER dev_mgr; + PHUB2_EXTENSION hub_ext; + BOOL bReset; + USB_PORT_STATUS port_status; + PUSB_DEV pdev2; + PURB purb2; + PHCD hcd; - PUSB_CTRL_SETUP_PACKET psetup; - ULONG status; - LARGE_INTEGER delay; + PUSB_CTRL_SETUP_PACKET psetup; + ULONG status; + LARGE_INTEGER delay; - USE_IRQL; + USE_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 ); + //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; + 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; - } + 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 ); + 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; + bReset = FALSE; + if (port_status.wPortChange & USB_PORT_STAT_C_RESET) + bReset = TRUE; - pdev2 = NULL; - purb2 = NULL; + 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 ); + 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; + //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++; + pdev2->parent_dev = pdev; + pdev2->port_idx = (UCHAR) port_idx; + pdev2->ref_count++; - RtlZeroMemory( purb2, sizeof( URB ) ); + RtlZeroMemory(purb2, sizeof(URB)); - purb2->pdev = pdev2; - purb2->pendp = &pdev2->default_endp; - purb2->context = hub_ext; - purb2->completion = hub_set_address_completion; + 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; + 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; - } - } - } + 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 ); + 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 ); + unlock_dev(pdev, TRUE); + KeReleaseSpinLockFromDpcLevel(&dev_mgr->dev_list_lock); - status = hcd->hcd_submit_urb( hcd, pdev2, purb2->pendp, purb2 ); + 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 ); + 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; - } + 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 ); + 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); + //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; + return FALSE; } VOID -hub_reexamine_port_status_queue( -PUSB_DEV hub_dev, -ULONG port_idx, -BOOL from_dpc -) +hub_reexamine_port_status_queue(PUSB_DEV hub_dev, ULONG port_idx, BOOL from_dpc) { - PHUB2_EXTENSION hub_ext; - PUSB_DEV_MANAGER dev_mgr; + PHUB2_EXTENSION hub_ext; + PUSB_DEV_MANAGER dev_mgr; - USE_IRQL; + USE_IRQL; - if( hub_dev == NULL || port_idx == 0 ) - return; + 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 ); + 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 ) - { + 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 ); + 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 ); + } + 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 ); + 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; + if (from_dpc) + KeReleaseSpinLockFromDpcLevel(&dev_mgr->event_list_lock); + else + KeReleaseSpinLock(&dev_mgr->event_list_lock, old_irql); + return; } -BOOL -dev_mgr_start_config_dev( -PUSB_DEV pdev -) //called in hub_set_address_completion +BOOL +dev_mgr_start_config_dev(PUSB_DEV pdev) { - PUSB_DEV_MANAGER dev_mgr; - PBYTE data_buf; - PUSB_CTRL_SETUP_PACKET psetup; - PURB purb; - PHCD hcd; + PUSB_DEV_MANAGER dev_mgr; + PBYTE data_buf; + PUSB_CTRL_SETUP_PACKET psetup; + PURB purb; + PHCD hcd; - USE_IRQL; + USE_IRQL; - if( pdev == NULL ) - return FALSE; + if (pdev == NULL) + return FALSE; - lock_dev( pdev, TRUE ); - if( dev_state( pdev ) == USB_DEV_STATE_ZOMB ) - { - unlock_dev( pdev, TRUE ); - return FALSE; - } + lock_dev(pdev, TRUE); + if (dev_state(pdev) == USB_DEV_STATE_ZOMB) + { + unlock_dev(pdev, TRUE); + return FALSE; + } - hcd = pdev->hcd; + hcd = pdev->hcd; - //first, get device descriptor - purb = usb_alloc_mem( NonPagedPool, sizeof( URB ) ); - data_buf = usb_alloc_mem( NonPagedPool, 512 ); - if( purb == NULL ) - { - unlock_dev( pdev, TRUE ); - return FALSE; - } + //first, get device descriptor + purb = usb_alloc_mem(NonPagedPool, sizeof(URB)); + data_buf = usb_alloc_mem(NonPagedPool, 512); + if (purb == NULL) + { + unlock_dev(pdev, TRUE); + return FALSE; + } - RtlZeroMemory( purb, sizeof( URB ) ); - RtlZeroMemory( data_buf, 512 ); + RtlZeroMemory(purb, sizeof(URB)); + RtlZeroMemory(data_buf, 512); - psetup = ( PUSB_CTRL_SETUP_PACKET )purb->setup_packet; + psetup = (PUSB_CTRL_SETUP_PACKET) purb->setup_packet; - purb->data_buffer = data_buf; // user data - purb->data_length = 8; // get partial desc + purb->data_buffer = data_buf; // user data + purb->data_length = 8; // get partial desc - pdev->desc_buf = data_buf; - pdev->desc_buf_size = 512; + pdev->desc_buf = data_buf; + pdev->desc_buf_size = 512; - purb->pdev = pdev; - purb->pendp = &pdev->default_endp; //pipe for current transfer + purb->pdev = pdev; + purb->pendp = &pdev->default_endp; //pipe for current transfer purb->completion = dev_mgr_get_desc_completion; - purb->reference = 0; + purb->reference = 0; - InitializeListHead( &purb->trasac_list ); + 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 ); + 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; + 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 -) +dev_mgr_get_desc_completion(PURB purb, PVOID context) { - PUSB_DEV pdev; + PUSB_DEV pdev; PUSB_CONFIGURATION_DESC pconfig_desc; - PUSB_ENDPOINT pendp; - PUSB_DEV_MANAGER dev_mgr; - NTSTATUS status; - PUSB_CTRL_SETUP_PACKET psetup; - LONG i; - PHCD hcd; + PUSB_ENDPOINT pendp; + PUSB_DEV_MANAGER dev_mgr; + NTSTATUS status; + PUSB_CTRL_SETUP_PACKET psetup; + LONG i; + PHCD hcd; - USE_IRQL; + USE_IRQL; - if( purb == NULL ) - return; + if (purb == NULL) + return; - pdev = purb->pdev; - pendp = purb->pendp; + pdev = purb->pdev; + pendp = purb->pendp; - if( pdev == NULL || pendp == NULL ) - { - usb_free_mem( purb ); - purb = NULL; - return; - } + 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; - } + 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; + 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; - } + 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; + 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 ); + 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 ); + //get the complete dev_desc + purb->reference = 1; + purb->status = 0; + purb->data_length = sizeof(USB_DEVICE_DESC); - unlock_dev( pdev, TRUE ); + 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; - } + 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; + 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 ); + psetup->wValue = (USB_DT_CONFIG << 8) | 0; + psetup->wLength = 8; + unlock_dev(pdev, TRUE); - status = hcd->hcd_submit_urb( hcd, pdev, pendp, purb ); + 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 (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; + 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; + } + 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 ); + 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; - dev_mgr_start_select_driver( pdev ); - } - } - return; - } - } + 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; + dev_mgr_start_select_driver(pdev); + } + } + return; + } + } - LBL_OUT: - usb_free_mem( purb ); - purb = NULL; +LBL_OUT: + 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 ); + 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; + return; } BOOL -dev_mgr_start_select_driver( -PUSB_DEV pdev -) +dev_mgr_start_select_driver(PUSB_DEV pdev) { - PUSB_DEV_MANAGER dev_mgr; - PUSB_EVENT pevent; - BOOL bret; + PUSB_DEV_MANAGER dev_mgr; + PUSB_EVENT pevent; + BOOL bret; - USE_IRQL; + USE_IRQL; - if( pdev == NULL ) - return FALSE; + if (pdev == NULL) + return FALSE; - dev_mgr = dev_mgr_from_dev( pdev ); - KeAcquireSpinLockAtDpcLevel( &dev_mgr->event_list_lock ); - lock_dev( pdev, TRUE ); + 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; - } + 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; + 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; + 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; +LBL_OUT: + unlock_dev(pdev, TRUE); + KeReleaseSpinLockFromDpcLevel(&dev_mgr->event_list_lock); + return bret; } BOOL -dev_mgr_connect_to_dev( -PVOID Parameter -) +dev_mgr_connect_to_dev(PVOID Parameter) { - PUSB_DEV pdev; - DEV_HANDLE dev_handle; - NTSTATUS status; - PUSB_DRIVER pdriver; - PCONNECT_DATA pcd = ( PCONNECT_DATA )Parameter; - PUSB_DEV_MANAGER dev_mgr; - CONNECT_DATA param; + PUSB_DEV pdev; + DEV_HANDLE dev_handle; + NTSTATUS status; + PUSB_DRIVER pdriver; + PCONNECT_DATA pcd = (PCONNECT_DATA) Parameter; + PUSB_DEV_MANAGER dev_mgr; + CONNECT_DATA param; - USE_IRQL; + USE_IRQL; - if( pcd == NULL ) - return FALSE; - dev_handle = pcd->dev_handle; - pdriver = pcd->pdriver; - dev_mgr = pcd->dev_mgr; + 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 + 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; + 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; + 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 -) +dev_mgr_event_select_driver(PUSB_DEV pdev, ULONG event, ULONG context, ULONG param) { - PUSB_DEV_MANAGER dev_mgr; - PLIST_ENTRY pthis, pnext; - PUSB_DRIVER pdriver, pcand; - LONG credit, match, i; - DEV_HANDLE handle; - CONNECT_DATA cd; + PUSB_DEV_MANAGER dev_mgr; + PLIST_ENTRY pthis, pnext; + PUSB_DRIVER pdriver, pcand; + LONG credit, match, i; + DEV_HANDLE handle; + CONNECT_DATA cd; - USE_IRQL; + USE_IRQL; - if( pdev == NULL ) - return; + 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 ); + 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 ]; + 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 (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) + { + // we set class driver here + // pdev->dev_driver = pcand; + handle = usb_make_handle(pdev->dev_id, 0, 0); + } + unlock_dev(pdev, FALSE); - if( match ) - { + if (match) + { - cd.dev_handle = handle; - cd.pdriver = pcand; - cd.dev_mgr = dev_mgr; + cd.dev_handle = handle; + cd.pdriver = pcand; + cd.dev_mgr = dev_mgr; - if( dev_mgr_connect_to_dev( &cd ) ) - return; + 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; + // 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; } BOOL -dev_mgr_build_usb_endp( -PUSB_INTERFACE pif, -PUSB_ENDPOINT pendp, -PUSB_ENDPOINT_DESC pendp_desc -) +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; + if (pendp == NULL || pif == NULL || pendp_desc == NULL) + return FALSE; pendp->flags = 0; - InitializeListHead( &pendp->urb_list ); //pending urb queue - pendp->pusb_if = pif; + InitializeListHead(&pendp->urb_list); //pending urb queue + pendp->pusb_if = pif; pendp->pusb_endp_desc = pendp_desc; - return TRUE; + return TRUE; } BOOL -dev_mgr_build_usb_if( -PUSB_CONFIGURATION pcfg, -PUSB_INTERFACE pif, -PUSB_INTERFACE_DESC pif_desc, -BOOL alt_if -) +dev_mgr_build_usb_if(PUSB_CONFIGURATION pcfg, PUSB_INTERFACE pif, PUSB_INTERFACE_DESC pif_desc, BOOL alt_if) { - LONG i; - PUSB_ENDPOINT_DESC pendp_desc; + LONG i; + PUSB_ENDPOINT_DESC pendp_desc; - if( pcfg == NULL || pif == NULL || pif_desc == NULL ) - return FALSE; + 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; - - pendp_desc = ( PUSB_ENDPOINT_DESC )( &( ( PBYTE )pif_desc )[ sizeof( USB_INTERFACE_DESC ) ] ); - - for( i = 0; i < pif->endp_count; i++, pendp_desc++ ) - { - dev_mgr_build_usb_endp( pif, &pif->endp[ i ], pendp_desc ); - } - } - else - { - PUSB_INTERFACE paltif; - PLIST_ENTRY pthis, pnext; - - pif->altif_count++; - paltif = usb_alloc_mem( NonPagedPool, sizeof( USB_INTERFACE ) ); - 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 ); - } - - } - 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 (alt_if == FALSE) { - if( pif_desc->bAlternateSetting == 0) - { - dev_mgr_build_usb_if( pcfg, &pcfg->interf[ i ], pif_desc, FALSE ); - } - else - { - i--; - pif = &pcfg->interf[ i ]; - dev_mgr_build_usb_if( pcfg, pif, pif_desc, TRUE ); - } - } - return STATUS_SUCCESS; + 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; + + pendp_desc = (PUSB_ENDPOINT_DESC) (&((PBYTE) pif_desc)[sizeof(USB_INTERFACE_DESC)]); + + for(i = 0; i < pif->endp_count; i++, pendp_desc++) + { + dev_mgr_build_usb_endp(pif, &pif->endp[i], pendp_desc); + } + } + else + { + PUSB_INTERFACE paltif; + PLIST_ENTRY pthis, pnext; + + pif->altif_count++; + paltif = usb_alloc_mem(NonPagedPool, sizeof(USB_INTERFACE)); + 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); + } + + } + return TRUE; } NTSTATUS -dev_mgr_destroy_usb_config( -PUSB_CONFIGURATION pcfg -) +dev_mgr_build_usb_config(PUSB_DEV pdev, PBYTE pbuf, ULONG config_val, LONG config_count) { - long i; - PLIST_ENTRY pthis, pnext; - PUSB_INTERFACE pif; + PUSB_CONFIGURATION pcfg; + PUSB_INTERFACE_DESC pif_desc; + PUSB_INTERFACE pif; + int i; + LONG if_count; - if( pcfg == NULL ) - return FALSE; + if (pdev == NULL || pbuf == NULL) + return STATUS_INVALID_PARAMETER; - 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; + pdev->usb_config = usb_alloc_mem(NonPagedPool, sizeof(USB_CONFIGURATION)); + pcfg = pdev->usb_config; - ListFirst( &pif->altif_list, pthis ); - } - } - } - usb_free_mem( pcfg ); - return TRUE; + 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 + { + i--; + pif = &pcfg->interf[i]; + 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, pnext; + 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 ) \ @@ -4003,71 +3647,61 @@ PUSB_CONFIGURATION pcfg && ( 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 -) +dev_mgr_score_driver_for_dev(PUSB_DEV_MANAGER dev_mgr, PUSB_DRIVER pdriver, PUSB_DEVICE_DESC pdev_desc) { - LONG credit = 0; + LONG credit = 0; - //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; - } - } + //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; + if (is_dev_product_match(pdriver, pdev_desc)) + credit += 20; - return credit; + return credit; } LONG -dev_mgr_score_driver_for_if( -PUSB_DEV_MANAGER dev_mgr, -PUSB_DRIVER pdriver, -PUSB_INTERFACE_DESC pif_desc -) +dev_mgr_score_driver_for_if(PUSB_DEV_MANAGER dev_mgr, PUSB_DRIVER pdriver, PUSB_INTERFACE_DESC pif_desc) { - LONG credit; + LONG credit; - if( pdriver == NULL - || !( pdriver->driver_desc.flags & USB_DRIVER_FLAG_IF_CAPABLE ) - || pif_desc == NULL - || dev_mgr == NULL ) - return 0; + 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; - } + 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; + 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; + return credit; } #define is_equal_driver( pd1, pd2, ret ) \ @@ -4087,1098 +3721,991 @@ PUSB_INTERFACE_DESC pif_desc }\ } -UCHAR -dev_mgr_register_hcd( -PUSB_DEV_MANAGER dev_mgr, -PHCD hcd -) //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 == NULL || hcd == NULL) + return 0xff; - if( dev_mgr->hcd_count >= MAX_HCDS ) - 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; + dev_mgr->hcd_array[dev_mgr->hcd_count++] = hcd; + return dev_mgr->hcd_count - 1; } BOOL -dev_mgr_register_irp( -PUSB_DEV_MANAGER dev_mgr, -PIRP pirp, -PURB purb -) +dev_mgr_register_irp(PUSB_DEV_MANAGER dev_mgr, PIRP pirp, PURB purb) { - KIRQL old_irql; - if( dev_mgr == NULL ) - return FALSE; + KIRQL old_irql; + if (dev_mgr == NULL) + return FALSE; - if( add_irp_to_list( &dev_mgr->irp_list, pirp, purb ) ) - { - return TRUE; - } - TRAP(); - return FALSE; + if (add_irp_to_list(&dev_mgr->irp_list, pirp, purb)) + { + return TRUE; + } + TRAP(); + return FALSE; } -PURB -dev_mgr_remove_irp( -PUSB_DEV_MANAGER dev_mgr, -PIRP pirp -) //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; - KIRQL old_irql; - if( dev_mgr == NULL ) - return NULL; + PURB purb; + KIRQL old_irql; + if (dev_mgr == NULL) + return NULL; - purb = remove_irp_from_list( &dev_mgr->irp_list, pirp, NULL ); - return purb; + purb = remove_irp_from_list(&dev_mgr->irp_list, pirp, NULL); + return purb; } VOID -dev_mgr_cancel_irp( -PDEVICE_OBJECT dev_obj, -PIRP pirp -) +dev_mgr_cancel_irp(PDEVICE_OBJECT dev_obj, PIRP pirp) { - PUSB_DEV_MANAGER dev_mgr; - PDEVEXT_HEADER pdev_ext_hdr; - ULONG i; + PUSB_DEV_MANAGER dev_mgr; + PDEVEXT_HEADER pdev_ext_hdr; + ULONG i; - pdev_ext_hdr = ( PDEVEXT_HEADER )dev_obj->DeviceExtension; - dev_mgr = pdev_ext_hdr->dev_mgr; + 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 ); + 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; - } + 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; + // + // 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; } -VOID -dev_mgr_release_hcd( -PUSB_DEV_MANAGER dev_mgr -) // 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; + 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 -) +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; + LONG i; + PHCD hcd; + for(i = 0; i < dev_mgr->hcd_count; i++) + { + hcd = dev_mgr->hcd_array[i]; + hcd->hcd_start(hcd); + } + return; } BOOL -hub_connect( -PCONNECT_DATA param, -DEV_HANDLE dev_handle -) +hub_connect(PCONNECT_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; - PUSB_DEV_MANAGER dev_mgr; - PUSB_DEV pdev; - USE_IRQL; + 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; + PUSB_DEV_MANAGER dev_mgr; + PUSB_DEV pdev; + USE_IRQL; - if( param == NULL || dev_handle == 0 ) - return FALSE; + if (param == NULL || dev_handle == 0) + return FALSE; - dev_mgr = param->dev_mgr; + 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 ); + 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; + 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 ); + 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_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; + 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 ); + 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 (found) + break; - if( usb_skip_one_config( ( PBYTE* )&pcfg_desc ) == FALSE ) - { - 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; + } + 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 ) ); + 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; + 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; - } + status = usb_submit_urb(dev_mgr, purb); + if (status != STATUS_PENDING) + { + usb_free_mem(purb); + return FALSE; + } + return TRUE; + } - return FALSE; + 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, if_alt_idx; + PUSB_DEV pdev; + PUSB_INTERFACE pif; + BOOL high_speed, multiple_tt; + NTSTATUS status; + USE_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 -); - -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, if_alt_idx; - PUSB_DEV pdev; - PUSB_INTERFACE pif; - BOOL high_speed, multiple_tt; - NTSTATUS status; - USE_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 -) +hub_set_interface_completion(PURB purb, PVOID pcontext) { - PUSB_ENDPOINT pendp; - NTSTATUS status; - PUSB_CTRL_SETUP_PACKET psetup; - PUSB_DEV_MANAGER dev_mgr; - PBYTE dev_ext; - DEV_HANDLE endp_handle; - PUSB_DRIVER pdriver; + PUSB_ENDPOINT pendp; + 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; + if (purb == NULL || pcontext == NULL) + return; - //pdev = NULL; - dev_mgr = ( PUSB_DEV_MANAGER )pcontext; - endp_handle = purb->endp_handle; - pdriver = ( PUSB_DRIVER )purb->reference; + //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; - } + 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; - } + 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 ); + // + //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; + 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 ); + 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; - PUSB_DEV pdev; - 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 ) ); - } + if (status != STATUS_PENDING) + { + usb_free_mem(dev_ext); + goto LBL_OUT; + } + return; LBL_OUT: - usb_free_mem( purb ); - return; + //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; + PUSB_DEV pdev; + 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 -) +hub_power_on_port(PUSB_DEV pdev, UCHAR port_idx) { + PUSB_ENDPOINT pendp; + NTSTATUS status; + PUSB_CTRL_SETUP_PACKET psetup; + PUSB_DEV_MANAGER dev_mgr; + PBYTE dev_ext; + DEV_HANDLE endp_handle; + PURB purb; + PHCD hcd; - PUSB_ENDPOINT pendp; - NTSTATUS status; - PUSB_CTRL_SETUP_PACKET psetup; - PUSB_DEV_MANAGER dev_mgr; - PBYTE dev_ext; - DEV_HANDLE endp_handle; - PURB purb; - PHCD hcd; + USE_IRQL; + if (pdev == NULL || port_idx == 0) + return STATUS_INVALID_PARAMETER; - USE_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; - purb = usb_alloc_mem( NonPagedPool, sizeof( URB ) ); - if( purb == NULL ) - return STATUS_NO_MEMORY; + urb_init(purb); - 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; - 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; - 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; - 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); - unlock_dev( pdev, FALSE ); + status = hcd->hcd_submit_urb(hcd, pdev, purb->pendp, purb); - 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; + 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 -) +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; - ULONG status; - LONG port_count; - PUSB_DRIVER pdriver; - DEV_HANDLE dev_handle; + PUSB_DEV_MANAGER dev_mgr; + PHUB2_EXTENSION hub_ext; + PUSB_DEV pdev; + LONG i; + PUSB_INTERFACE pif; + ULONG status; + LONG port_count; + PUSB_DRIVER pdriver; + DEV_HANDLE dev_handle; - USE_IRQL; + USE_IRQL; - if( purb == NULL ) - { - return; - } + 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; + 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 (pcontext == NULL || purb->reference == 0) + goto LBL_OUT; - if( purb->status != STATUS_SUCCESS ) - { - 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 ); + // 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; - } + 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; + //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 ); + 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 ); - } + 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 ); + hub_ext->multiple_tt = (pif->pusb_if_desc->bInterfaceProtocol == 2); - unlock_dev( pdev, TRUE ); - usb_free_mem( purb ); + unlock_dev(pdev, TRUE); + usb_free_mem(purb); - hub_start_int_request( pdev ); + hub_start_int_request(pdev); - for( i = 0; i < port_count; i ++ ) - { - hub_power_on_port( pdev, ( UCHAR )( i + 1 ) ); - } - return; + for(i = 0; i < port_count; i++) + { + hub_power_on_port(pdev, (UCHAR) (i + 1)); + } + return; - LBL_OUT: - if( purb ) - usb_free_mem( purb ); +LBL_OUT: + if (purb) + usb_free_mem(purb); - if( hub_ext ) - usb_free_mem( hub_ext ); - return; + if (hub_ext) + usb_free_mem(hub_ext); + return; } BOOL -hub_stop( -PUSB_DEV_MANAGER dev_mgr, -DEV_HANDLE dev_handle -) +hub_stop(PUSB_DEV_MANAGER dev_mgr, DEV_HANDLE dev_handle) { - return TRUE; + return TRUE; } BOOL -hub_disconnect( -PUSB_DEV_MANAGER dev_mgr, -DEV_HANDLE dev_handle -) +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 ); - } - } + 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; + return TRUE; } static BOOL -hub_lock_unlock_tt( -PUSB_DEV pdev, -UCHAR port_idx, -UCHAR type, -BOOL lock -) +hub_lock_unlock_tt(PUSB_DEV pdev, UCHAR port_idx, UCHAR type, BOOL lock) { - PUSB_INTERFACE pif; - PHUB2_EXTENSION dev_ext; - PULONG pmap; + PUSB_INTERFACE pif; + PHUB2_EXTENSION dev_ext; + PULONG pmap; - USE_IRQL; + USE_IRQL; - if( pdev == NULL || port_idx > 127 ) - return FALSE; + 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; - } + 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; - } + 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 ); - } + 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; + unlock_dev(pdev, FALSE); + return TRUE; } BOOL -hub_lock_tt( -PUSB_DEV pdev, -UCHAR port_idx, -UCHAR type // transfer type -) +hub_lock_tt(PUSB_DEV pdev, + UCHAR port_idx, + UCHAR type // transfer type + ) { - return hub_lock_unlock_tt( pdev, port_idx, type, TRUE ); + return hub_lock_unlock_tt(pdev, port_idx, type, TRUE); } BOOL -hub_unlock_tt( -PUSB_DEV pdev, -UCHAR port_idx, -UCHAR type -) +hub_unlock_tt(PUSB_DEV pdev, UCHAR port_idx, UCHAR type) { - return hub_lock_unlock_tt( pdev, port_idx, type, FALSE ); + return hub_lock_unlock_tt(pdev, port_idx, type, FALSE); } VOID -hub_clear_tt_buffer_completion( -PURB purb, -PVOID context -) +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; + PUSB_CTRL_SETUP_PACKET psetup; + PURB_HS_PIPE_CONTENT pipe_content; + PHUB2_EXTENSION hub_ext; + PHCD hcd; - if( purb == NULL || context == NULL ) - return; + 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; + 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 ); + // 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; + return; } -BOOL -hub_clear_tt_buffer( -PUSB_DEV pdev, -URB_HS_PIPE_CONTENT pipe_content, -UCHAR port_idx -) // send CLEAR_TT_BUFFER to the hub +BOOL +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_IRQL; + PURB purb; + PUSB_CTRL_SETUP_PACKET psetup; + PHUB2_EXTENSION hub_ext; + PHCD hcd; + NTSTATUS status; + USE_IRQL; - if( pdev == NULL ) - return FALSE; + if (pdev == NULL) + return FALSE; - if( pipe_content.speed_high ) - 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; - } + 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 ) ); - RtlZeroMemory( purb, sizeof( URB ) ); + hub_ext = hub_ext_from_dev(pdev); + if (hub_ext == NULL) + { + unlock_dev(pdev, FALSE); + return FALSE; + } + purb = usb_alloc_mem(NonPagedPool, sizeof(URB)); + RtlZeroMemory(purb, sizeof(URB)); - if( purb == NULL ) - { - unlock_dev( pdev, FALSE ); - return STATUS_NO_MEMORY; - } + if (purb == NULL) + { + unlock_dev(pdev, FALSE); + return STATUS_NO_MEMORY; + } purb->flags = 0; - purb->status = STATUS_SUCCESS; - purb->data_buffer = NULL; - purb->data_length = 0; // ( hub_ext->port_count + 7 ) / 8; + 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; + // 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->reference = *((PLONG) & pipe_content); purb->pirp = NULL; - hcd = pdev->hcd; + 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 ) ); + 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; + if (hub_ext->multiple_tt) + { + psetup->wIndex = (USHORT) port_idx; + } + else + psetup->wIndex = 1; - psetup->wLength = 0; - unlock_dev( pdev, FALSE ); + 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; + status = hcd->hcd_submit_urb(hcd, pdev, purb->pendp, purb); + if (status != STATUS_PENDING) + { + usb_free_mem(purb); + purb = NULL; + return FALSE; + } + return TRUE; } BOOL -hub_event_clear_tt_buffer( -PUSB_DEV pdev, //always null. we do not use this param -ULONG event, -ULONG context, -ULONG param -) +hub_event_clear_tt_buffer(PUSB_DEV pdev, //always null. we do not use this param + ULONG event, + ULONG context, + ULONG param) { - hub_clear_tt_buffer( pdev, *( ( PURB_HS_PIPE_CONTENT )&context ), ( UCHAR )param ); - return TRUE; + hub_clear_tt_buffer(pdev, *((PURB_HS_PIPE_CONTENT) & context), (UCHAR) param); + return TRUE; } VOID -hub_post_clear_tt_event( -PUSB_DEV pdev, -BYTE port_idx, -ULONG pipe -) +hub_post_clear_tt_event(PUSB_DEV pdev, BYTE port_idx, ULONG pipe) { - PUSB_DEV_MANAGER dev_mgr; - PUSB_EVENT pevent; - USE_IRQL; + PUSB_DEV_MANAGER dev_mgr; + PUSB_EVENT pevent; + USE_IRQL; - dev_mgr = dev_mgr_from_dev( pdev ); + 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; - } + 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 ); + 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); - KeSetEvent( &dev_mgr->wake_up_event, 0, FALSE ); - return; + unlock_dev(pdev, TRUE); + KeReleaseSpinLock(&dev_mgr->event_list_lock, old_irql); + + KeSetEvent(&dev_mgr->wake_up_event, 0, FALSE); + return; } BOOL -init_irp_list( -PIRP_LIST irp_list -) +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 ); + 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; + 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; + 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 -) +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; + 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; } BOOL -add_irp_to_list( -PIRP_LIST irp_list, -PIRP pirp, -PURB purb -) +add_irp_to_list(PIRP_LIST irp_list, PIRP pirp, PURB purb) { - KIRQL old_irql; - PIRP_LIST_ELEMENT pile; + KIRQL old_irql; + PIRP_LIST_ELEMENT pile; - if( irp_list == NULL || pirp == NULL || purb == NULL ) - return FALSE; + if (irp_list == NULL || pirp == NULL || purb == NULL) + return FALSE; - IoAcquireCancelSpinLock( &old_irql ); - KeAcquireSpinLockAtDpcLevel( &irp_list->irp_list_lock ); + 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 ); + 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; + pile->pirp = pirp; + pile->purb = purb; - irp_list->irp_free_list_count--; - InsertTailList( &irp_list->irp_busy_list, &pile->irp_link ); - IoSetCancelRoutine( pirp, dev_mgr_cancel_irp ); + irp_list->irp_free_list_count--; + InsertTailList(&irp_list->irp_busy_list, &pile->irp_link); + IoSetCancelRoutine(pirp, dev_mgr_cancel_irp); - KeReleaseSpinLockFromDpcLevel( &irp_list->irp_list_lock ); - IoReleaseCancelSpinLock( old_irql ); - return TRUE; + 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 -) +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; + PIRP_LIST_ELEMENT pile; + PLIST_ENTRY pthis, pnext; + PURB purb; + DEV_HANDLE endp_handle; + PUSB_DEV pdev; + PUSB_ENDPOINT pendp; + PHCD hcd; - USE_IRQL; + USE_IRQL; - if( irp_list == NULL || pirp == NULL ) - return NULL; + if (irp_list == NULL || pirp == NULL) + return NULL; - KeAcquireSpinLock( &irp_list->irp_list_lock, &old_irql ); + 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; - } + 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; - } + 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; - } + 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 ); + 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 (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; + 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; - } + 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; + 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; } BOOL -irp_list_empty( -PIRP_LIST irp_list -) +irp_list_empty(PIRP_LIST irp_list) { - KIRQL old_irql; - BOOL ret; - KeAcquireSpinLock( &irp_list->irp_list_lock, &old_irql ); - ret = ( irp_list->irp_free_list_count == MAX_IRP_LIST_SIZE ); - KeReleaseSpinLock( &irp_list->irp_list_lock, old_irql ); - return ret; + KIRQL old_irql; + BOOL ret; + KeAcquireSpinLock(&irp_list->irp_list_lock, &old_irql); + ret = (irp_list->irp_free_list_count == MAX_IRP_LIST_SIZE); + KeReleaseSpinLock(&irp_list->irp_list_lock, old_irql); + return ret; } BOOL -irp_list_full( -PIRP_LIST irp_list -) +irp_list_full(PIRP_LIST irp_list) { - KIRQL old_irql; - BOOL ret; - KeAcquireSpinLock( &irp_list->irp_list_lock, &old_irql ); - ret = ( irp_list->irp_free_list_count == 0 ); - KeReleaseSpinLock( &irp_list->irp_list_lock, old_irql ); - return ret; + KIRQL old_irql; + BOOL ret; + KeAcquireSpinLock(&irp_list->irp_list_lock, &old_irql); + ret = (irp_list->irp_free_list_count == 0); + KeReleaseSpinLock(&irp_list->irp_list_lock, old_irql); + return ret; } - - -VOID -zzz() -{}; diff --git a/reactos/drivers/usb/nt4compat/usbdriver/td.c b/reactos/drivers/usb/nt4compat/usbdriver/td.c index c20f60c71da..77e9becefff 100644 --- a/reactos/drivers/usb/nt4compat/usbdriver/td.c +++ b/reactos/drivers/usb/nt4compat/usbdriver/td.c @@ -24,664 +24,583 @@ #define UHCI_MIN_TD_POOLS 4 -BOOL -free_td_to_pool( -PUHCI_TD_POOL ptd_pool, -PUHCI_TD ptd -); //add tds till pnext == NULL +BOOL 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 +PUHCI_QH alloc_qh(PUHCI_QH_POOL pqh_pool); //null if failed BOOL -init_td_pool( -PUHCI_TD_POOL ptd_pool -) +init_td_pool(PUHCI_TD_POOL ptd_pool) { int i, pages; - PTD_EXTENSION ptde; - PHYSICAL_ADDRESS phys_addr; - + PTD_EXTENSION ptde; + PHYSICAL_ADDRESS phys_addr; + if (ptd_pool == NULL) return FALSE; - if( ptd_pool->padapter == 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 ) ); + 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; - } + 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); - 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 < pages; i++) + { + RtlZeroMemory(ptd_pool->td_array[i], PAGE_SIZE); + } - for( i = 0; i < UHCI_MAX_POOL_TDS; i++ ) + 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 ]); - + 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; + 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; - } - } +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); + 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(); - 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; + return FALSE; } +//add tds till pnext == NULL BOOL -free_td_to_pool( -PUHCI_TD_POOL ptd_pool, -PUHCI_TD ptd -) //add tds till pnext == NULL +free_td_to_pool(PUHCI_TD_POOL ptd_pool, PUHCI_TD ptd) { - if( ptd_pool == NULL || ptd == NULL ) - { - return FALSE; - } + if (ptd_pool == NULL || ptd == NULL) + { + return FALSE; + } - ptd->link = ptd->status = ptd->info = ptd->buffer = 0; - ptd->purb = NULL; - ptd_pool->free_count++; + 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); + InsertTailList(&ptd_pool->free_que, &ptd->ptde->vert_link); + + return TRUE; - return TRUE; - } + // qh routines + +//null if failed PUHCI_TD -alloc_td_from_pool( -PUHCI_TD_POOL ptd_pool -) //null if failed +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 ); + PTD_EXTENSION ptde; + PLIST_ENTRY temp; - if( temp == NULL ) - return FALSE; + if (ptd_pool == NULL) + return FALSE; - ptde = struct_ptr( temp, TD_EXTENSION, vert_link ); + if (IsListEmpty(&ptd_pool->free_que)) + return FALSE; - ptd_pool->free_count--; - - InitializeListHead( &ptde->vert_link ); - InitializeListHead( &ptde->hori_link ); + temp = RemoveHeadList(&ptd_pool->free_que); - return ptde->ptd; + 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 BOOL -is_pool_free( -PUHCI_TD_POOL pool -) //test whether the pool is all free +is_pool_free(PUHCI_TD_POOL pool) { - if( pool == NULL ) - return FALSE; + if (pool == NULL) + return FALSE; - if( pool->free_count == pool->total_count ) - return TRUE; + if (pool->free_count == pool->total_count) + return TRUE; - return FALSE; + return FALSE; } BOOL -is_pool_empty( -PUHCI_TD_POOL pool -) +is_pool_empty(PUHCI_TD_POOL pool) { - if( pool == NULL ) - return FALSE; + if (pool == NULL) + return FALSE; - return ( pool->free_count == 0 ); + return (pool->free_count == 0); } BOOL -destroy_td_pool( -PUHCI_TD_POOL ptd_pool -) +destroy_td_pool(PUHCI_TD_POOL ptd_pool) { int i, pages; - PADAPTER_OBJECT padapter; //we need this garbage for allocation + 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 ) + + 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; + 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; + return TRUE; } BOOL -init_td_pool_list( -PUHCI_TD_POOL_LIST pool_list, -PADAPTER_OBJECT padapter -) +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 ); + 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; + 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); - } + 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 ); + KeInitializeSpinLock(&pool_list->pool_lock); + return expand_pool_list(pool_list, UHCI_MIN_TD_POOLS); } BOOL -destroy_td_pool_list( -PUHCI_TD_POOL_LIST pool_list -) +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 ); - } + 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; + RtlZeroMemory(pool_list, sizeof(UHCI_TD_POOL_LIST)); + return TRUE; } BOOL -expand_pool_list( -PUHCI_TD_POOL_LIST pool_list, -LONG pool_count -) //private +expand_pool_list(PUHCI_TD_POOL_LIST pool_list, LONG pool_count) //private { - PUHCI_TD_POOL pool; - int i; + PUHCI_TD_POOL pool; + int i; - if( IsListEmpty( &pool_list->free_pools) == TRUE ) - return FALSE; + 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 (pool_list->free_count < pool_count) + return FALSE; - if( init_td_pool( pool ) == FALSE ) - { - //reverse the allocation - InsertHeadList( &pool_list->free_pools, &pool->pool_link ); - // collect_garbage( pool_list ); - return FALSE; - } + for(i = 0; i < pool_count; i++) + { + pool = (PUHCI_TD_POOL) RemoveHeadList(&pool_list->free_pools); - InsertTailList( &pool_list->busy_pools, &pool->pool_link ); - pool_list->free_tds += UHCI_MAX_POOL_TDS; - pool_list->free_count--; - } - return TRUE; + 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; } BOOL -collect_garbage( -PUHCI_TD_POOL_LIST pool_list -) +collect_garbage(PUHCI_TD_POOL_LIST pool_list) { - PLIST_ENTRY prev, next; + PLIST_ENTRY prev, next; - // no garbage - if( pool_list->free_count >= UHCI_MAX_TD_POOLS - UHCI_MIN_TD_POOLS ) - return TRUE; + // 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); + 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; + 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 -) +get_num_free_tds(PUHCI_TD_POOL_LIST pool_list) { - return pool_list->free_tds; + return pool_list->free_tds; } -//private +//private LONG -get_max_free_tds( -PUHCI_TD_POOL_LIST pool_list -) +get_max_free_tds(PUHCI_TD_POOL_LIST pool_list) { - return pool_list->free_tds + pool_list->free_count * UHCI_MAX_POOL_TDS; + return pool_list->free_tds + pool_list->free_count * UHCI_MAX_POOL_TDS; } +//add tds till pnext == NULL BOOL -free_td( -PUHCI_TD_POOL_LIST pool_list, -PUHCI_TD ptd -) //add tds till pnext == NULL +free_td(PUHCI_TD_POOL_LIST pool_list, PUHCI_TD ptd) { - if( pool_list == NULL || ptd == NULL ) - return FALSE; + if (pool_list == NULL || ptd == NULL) + return FALSE; - if( free_td_to_pool( ptd->pool, ptd ) == FALSE ) - return FALSE; + if (free_td_to_pool(ptd->pool, ptd) == FALSE) + return FALSE; - pool_list->free_tds++; + pool_list->free_tds++; - if( is_pool_free( ptd->pool ) ) - { - collect_garbage( pool_list ); - } - return TRUE; + 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 -) //null if failed +alloc_td(PUHCI_TD_POOL_LIST pool_list) { - PLIST_ENTRY prev, next; - PUHCI_TD new_td; + PLIST_ENTRY prev, next; + PUHCI_TD new_td; - if( pool_list == NULL ) - return NULL; + if (pool_list == NULL) + return NULL; - if( pool_list->free_tds == 0 ) - { - if( expand_pool_list( pool_list, 1 ) == FALSE ) - return NULL; - } + if (pool_list->free_tds == 0) + { + if (expand_pool_list(pool_list, 1) == FALSE) + return NULL; + } - ListFirst( &pool_list->busy_pools, prev ); + 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 ); + 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(); + if (new_td == NULL) + TRAP(); - pool_list->free_tds--; + pool_list->free_tds--; - return new_td; - } + return new_td; + } - ListNext( &pool_list->busy_pools, prev, next); + ListNext(&pool_list->busy_pools, prev, next); prev = next; - } + } - return NULL; + return NULL; } PUHCI_TD -alloc_tds( -PUHCI_TD_POOL_LIST pool_list, -LONG count -) +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; + LONG i; + PUHCI_TD ptd, pnext; - if( pool_list == NULL || count <= 0 ) - return NULL; + if (pool_list == NULL || count <= 0) + return NULL; - if( count >= get_max_free_tds( pool_list ) ) - return NULL; + if (count >= get_max_free_tds(pool_list)) + return NULL; - ptd = alloc_td( pool_list ); + ptd = alloc_td(pool_list); - for( i = 1; i < count; i ++ ) - { - pnext = alloc_td( pool_list ); - - if( pnext ) + for(i = 1; i < count; i++) + { + pnext = alloc_td(pool_list); + + if (pnext) { - InsertTailList( &ptd->ptde->vert_link, &pnext->ptde->vert_link ); + InsertTailList(&ptd->ptde->vert_link, &pnext->ptde->vert_link); } - else - TRAP(); - } + 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; + 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 -) +free_tds(PUHCI_TD_POOL_LIST pool_list, PUHCI_TD ptd) { - PUHCI_TD ptofree; - PLIST_ENTRY pthis; + PUHCI_TD ptofree; + PLIST_ENTRY pthis; - if( pool_list == NULL || ptd == NULL ) - return; + 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 ); - } + 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; + free_td(pool_list, ptd); + return; } BOOL -can_transfer( -PUHCI_TD_POOL_LIST pool_list, -LONG td_count -) +can_transfer(PUHCI_TD_POOL_LIST pool_list, LONG td_count) { - if( td_count > get_max_free_tds( pool_list ) ) - return FALSE; + if (td_count > get_max_free_tds(pool_list)) + return FALSE; - return TRUE; + return TRUE; } VOID -lock_td_pool( -PUHCI_TD_POOL_LIST pool_list, -BOOL at_dpc -) +lock_td_pool(PUHCI_TD_POOL_LIST pool_list, BOOL at_dpc) { - //if( !at_dpc ) - // KeAcquireSpinLock( &pool_list->pool_lock ); - //else - // KeAcquireSpinLockAtDpcLevel( &pool_list->pool_lock ); + //if( !at_dpc ) + // KeAcquireSpinLock( &pool_list->pool_lock ); + //else + // KeAcquireSpinLockAtDpcLevel( &pool_list->pool_lock ); } VOID -unlock_td_pool( -PUHCI_TD_POOL_LIST pool_list, -BOOL at_dpc -) +unlock_td_pool(PUHCI_TD_POOL_LIST pool_list, BOOL at_dpc) { - //if( !at_dpc ) - // KeReleaseSpinLock( &pool_list->pool_lock ); - //else - // KeReleaseSpinLockFromDpcLevel( &pool_list->pool_lock ); + //if( !at_dpc ) + // KeReleaseSpinLock( &pool_list->pool_lock ); + //else + // KeReleaseSpinLockFromDpcLevel( &pool_list->pool_lock ); } -BOOL -init_qh_pool( -PUHCI_QH_POOL pqh_pool, -PADAPTER_OBJECT padapter -) +BOOL +init_qh_pool(PUHCI_QH_POOL pqh_pool, PADAPTER_OBJECT padapter) { - PQH_EXTENSION pqhe; - LONG i; + PQH_EXTENSION pqhe; + LONG i; - if( pqh_pool == NULL || padapter == NULL ) - return FALSE; + 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); - + + 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); + 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; - } + 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); - 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]; + 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; + 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; + //always breadth first + pqhe[i].flags = UHCI_ITEM_FLAG_QH; + + free_qh(pqh_pool, &pqh_pool->qh_array[i]); - free_qh( pqh_pool, &pqh_pool->qh_array[i] ); - } - return TRUE; - + return TRUE; + } +//add qhs till pnext == NULL BOOL -free_qh( -PUHCI_QH_POOL pqh_pool, -PUHCI_QH pqh -) //add qhs till pnext == NULL +free_qh(PUHCI_QH_POOL pqh_pool, PUHCI_QH pqh) { - if( pqh_pool == NULL || pqh == NULL) - return FALSE; - + 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; + 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 -) //null if failed +alloc_qh(PUHCI_QH_POOL pqh_pool) { - PQH_EXTENSION pqhe; + 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; - 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; - } BOOL -destroy_qh_pool( -PUHCI_QH_POOL pqh_pool -) +destroy_qh_pool(PUHCI_QH_POOL pqh_pool) { int i; - if(pqh_pool) + if (pqh_pool) { - usb_free_mem(pqh_pool->qhe_array); + 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); + 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 ) ); + RtlZeroMemory(pqh_pool, sizeof(UHCI_QH_POOL)); - } - else - return FALSE; + } + else + return FALSE; - return TRUE; + return TRUE; } VOID -lock_qh_pool( -PUHCI_QH_POOL pool, -BOOL at_dpc -) +lock_qh_pool(PUHCI_QH_POOL pool, BOOL at_dpc) { - //if( !at_dpc ) - // KeAcquireSpinLock( &pool->pool_lock ); - //else - // KeAcquireSpinLockAtDpcLevel( &pool->pool_lock ); + //if( !at_dpc ) + // KeAcquireSpinLock( &pool->pool_lock ); + //else + // KeAcquireSpinLockAtDpcLevel( &pool->pool_lock ); } VOID -unlock_qh_pool( -PUHCI_QH_POOL pool, -BOOL at_dpc -) +unlock_qh_pool(PUHCI_QH_POOL pool, BOOL at_dpc) { - //if( !at_dpc ) - // KeReleaseSpinLock( &pool->pool_lock ); - //else - // KeReleaseSpinLockFromDpcLevel( &pool->pool_lock ); + //if( !at_dpc ) + // KeReleaseSpinLock( &pool->pool_lock ); + //else + // KeReleaseSpinLockFromDpcLevel( &pool->pool_lock ); } - diff --git a/reactos/drivers/usb/nt4compat/usbdriver/uhci.c b/reactos/drivers/usb/nt4compat/usbdriver/uhci.c index 9b19ea2de5a..82d1aa11183 100644 --- a/reactos/drivers/usb/nt4compat/usbdriver/uhci.c +++ b/reactos/drivers/usb/nt4compat/usbdriver/uhci.c @@ -36,12 +36,7 @@ #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 -); +extern PDEVICE_OBJECT ehci_probe(PDRIVER_OBJECT drvr_obj, PUNICODE_STRING reg_path, PUSB_DEV_MANAGER dev_mgr); #endif @@ -106,176 +101,119 @@ PUSB_DEV_MANAGER dev_mgr //declarations typedef struct { - PUHCI_DEV uhci; - PVOID context; - ULONG ret; - + 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 -); +uhci_alloc(PDRIVER_OBJECT drvr_obj, PUNICODE_STRING reg_path, ULONG bus_addr, PUSB_DEV_MANAGER dev_mgr); -BOOL -uhci_init_schedule( -PUHCI_DEV uhci, -PADAPTER_OBJECT padapter -); +BOOL uhci_init_schedule(PUHCI_DEV uhci, PADAPTER_OBJECT padapter); -BOOL -uhci_release( -PDEVICE_OBJECT pdev -); +BOOL uhci_release(PDEVICE_OBJECT pdev); -static VOID -uhci_stop( -PUHCI_DEV uhci -); +static VOID uhci_stop(PUHCI_DEV uhci); -BOOL -uhci_destroy_schedule( -PUHCI_DEV uhci -); +BOOL uhci_destroy_schedule(PUHCI_DEV uhci); -BOOLEAN -uhci_sync_insert_urb_schedule( -PVOID context -); +BOOLEAN uhci_sync_insert_urb_schedule(PVOID context); -VOID -uhci_init_hcd_interface( -PUHCI_DEV uhci -); +VOID uhci_init_hcd_interface(PUHCI_DEV uhci); -NTSTATUS -uhci_rh_submit_urb( -PUSB_DEV rh, -PURB purb -); +NTSTATUS uhci_rh_submit_urb(PUSB_DEV rh, PURB purb); -NTSTATUS -uhci_dispatch_irp( -IN PDEVICE_OBJECT DeviceObject, -IN PIRP irp -); +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_reset_port_completion(PUSB_DEV dev, PVOID context); -extern VOID -rh_timer_svc_int_completion( -PUSB_DEV dev, -PVOID context -); +extern VOID rh_timer_svc_int_completion(PUSB_DEV dev, PVOID context); -ULONG debug_level = DBGLVL_MAXIMUM; -PDRIVER_OBJECT usb_driver_obj = NULL; -extern USB_DEV_MANAGER g_dev_mgr; +ULONG debug_level = 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 -) +uhci_wait_ms(PUHCI_DEV uhci, LONG ms) { LARGE_INTEGER lms; - if( ms <= 0 ) - return; + if (ms <= 0) + return; lms.QuadPart = -10 * ms; - KeSetTimer( &uhci->reset_timer, lms, NULL ); + KeSetTimer(&uhci->reset_timer, lms, NULL); - KeWaitForSingleObject( - &uhci->reset_timer, - Executive, - KernelMode, - FALSE, - NULL ); + KeWaitForSingleObject(&uhci->reset_timer, Executive, KernelMode, FALSE, NULL); - return; + return; } BOOL -init_pending_endp_pool( -PUHCI_PENDING_ENDP_POOL pool -) +init_pending_endp_pool(PUHCI_PENDING_ENDP_POOL pool) { - int i; - if( pool == NULL ) - return FALSE; + 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 ); + 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] ); - } + for(i = 0; i < MAX_TIMER_SVCS; i++) + { + free_pending_endp(pool, &pool->pending_endp_array[i]); + } - return TRUE; + return TRUE; } BOOL -free_pending_endp( -PUHCI_PENDING_ENDP_POOL pool, -PUHCI_PENDING_ENDP pending_endp -) +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++; + if (pool == NULL || pending_endp == NULL) + { + return FALSE; + } - return TRUE; + 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) +alloc_pending_endp(PUHCI_PENDING_ENDP_POOL pool, LONG count) { - PUHCI_PENDING_ENDP new; - if( pool == NULL || count != 1 ) - return NULL; + PUHCI_PENDING_ENDP new; + if (pool == NULL || count != 1) + return NULL; - if( pool->free_count <= 0 ) - return NULL; + if (pool->free_count <= 0) + return NULL; - new = ( PUHCI_PENDING_ENDP )RemoveHeadList( &pool->free_que ); - pool->free_count --; - return new; + new = (PUHCI_PENDING_ENDP) RemoveHeadList(&pool->free_que); + pool->free_count--; + return new; } BOOL -destroy_pending_endp_pool( -PUHCI_PENDING_ENDP_POOL pool -) +destroy_pending_endp_pool(PUHCI_PENDING_ENDP_POOL pool) { - if( pool == NULL ) - return FALSE; + 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; + 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; + return TRUE; } @@ -283,1837 +221,1662 @@ PUHCI_PENDING_ENDP_POOL pool //end of pending endpoint pool funcs static void -uhci_fill_td( -PUHCI_TD td, -ULONG status, -ULONG info, -ULONG buffer) +uhci_fill_td(PUHCI_TD td, ULONG status, ULONG info, ULONG buffer) { - td->status = status; - td->info = info; - td->buffer = buffer; + td->status = status; + td->info = info; + td->buffer = buffer; } BOOL -uhci_insert_td_fl( -PUHCI_TD prev_td, -PUHCI_TD ptd -) +uhci_insert_td_fl(PUHCI_TD prev_td, PUHCI_TD ptd) { - ULONG temp; - PLIST_ENTRY temp_entry; + ULONG temp; + PLIST_ENTRY temp_entry; - if( prev_td == NULL || ptd == NULL ) - return FALSE; + if (prev_td == NULL || ptd == NULL) + return FALSE; - temp_entry = &prev_td->ptde->hori_link; + 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; + 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; + InsertHeadList(&prev_td->ptde->hori_link, &ptd->ptde->hori_link); + return TRUE; } BOOL -uhci_remove_td_fl( -PUHCI_TD ptd -) +uhci_remove_td_fl(PUHCI_TD ptd) { - PUHCI_TD prev_td; + PUHCI_TD prev_td; - if( ptd == NULL ) - return FALSE; + 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; + 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 ); + RemoveEntryList(&ptd->ptde->hori_link); - return FALSE; + return FALSE; } BOOL -uhci_insert_qh_fl( -PVOID prev_item, -PUHCI_QH pqh -) +uhci_insert_qh_fl(PVOID prev_item, PUHCI_QH pqh) { - //only horizontal link allowed - PUHCI_QH pprev_qh; - PUHCI_TD pprev_td; - ULONG temp; - PLIST_ENTRY temp_entry; + //only horizontal link allowed + PUHCI_QH pprev_qh; + PUHCI_TD pprev_td; + ULONG temp; + PLIST_ENTRY temp_entry; - if( prev_item == NULL || pqh == NULL ) - return FALSE; + 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; + 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 ); + 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; + 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 ); - } + InsertHeadList(&pprev_td->ptde->hori_link, &pqh->pqhe->hori_link); + } - return FALSE; + return FALSE; } BOOL -uhci_remove_qh_fl( -PUHCI_QH pqh -) +uhci_remove_qh_fl(PUHCI_QH pqh) { - PVOID prev_item; - PUHCI_QH pprevqh; - PUHCI_TD pprevtd; + PVOID prev_item; + PUHCI_QH pprevqh; + PUHCI_TD pprevtd; - if( pqh == NULL ) - return FALSE; + if (pqh == NULL) + return FALSE; - prev_item = ( struct_ptr( pqh->pqhe->hori_link.Blink, TD_EXTENSION, hori_link ) )->ptd; + 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; - } + 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 ); + RemoveEntryList(&pqh->pqhe->hori_link); - pqh->link = UHCI_PTR_TERM; - pqh->pqhe->hori_link.Flink = pqh->pqhe->hori_link.Blink = NULL; + pqh->link = UHCI_PTR_TERM; + pqh->pqhe->hori_link.Flink = pqh->pqhe->hori_link.Blink = NULL; - return TRUE; + return TRUE; } BOOL -uhci_init_frame_list( -PUHCI_DEV uhci, -PADAPTER_OBJECT padapter -) +uhci_init_frame_list(PUHCI_DEV uhci, PADAPTER_OBJECT padapter) { - int i; - if( uhci == NULL || padapter == NULL ) - return FALSE; + int i; + if (uhci == NULL || padapter == NULL) + return FALSE; //note: frame_list_lock will be connected to interrupt - KeInitializeSpinLock( &uhci->frame_list_lock ); + KeInitializeSpinLock(&uhci->frame_list_lock); - uhci->io_buf = \ - HalAllocateCommonBuffer( - padapter, - 4096, - &uhci->io_buf_logic_addr, - FALSE); + 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->io_buf == NULL) + return FALSE; - if( uhci->frame_list == NULL ) - return FALSE; + uhci->frame_list = + HalAllocateCommonBuffer(padapter, + sizeof(ULONG) * UHCI_MAX_FRAMES, &uhci->frame_list_logic_addr, FALSE); - RtlZeroMemory( uhci->frame_list, - sizeof( ULONG ) * UHCI_MAX_FRAMES ); + if (uhci->frame_list == NULL) + return FALSE; - uhci->frame_list_cpu = usb_alloc_mem( - NonPagedPool, - sizeof( FRAME_LIST_CPU_ENTRY ) * UHCI_MAX_FRAMES ); + RtlZeroMemory(uhci->frame_list, sizeof(ULONG) * UHCI_MAX_FRAMES); - if( uhci->frame_list_cpu == NULL ) - return FALSE; + uhci->frame_list_cpu = usb_alloc_mem(NonPagedPool, sizeof(FRAME_LIST_CPU_ENTRY) * UHCI_MAX_FRAMES); - for( i = 0; i < UHCI_MAX_FRAMES; i++ ) - InitializeListHead( &uhci->frame_list_cpu[ i ].td_link ); + if (uhci->frame_list_cpu == NULL) + return FALSE; - uhci->frame_bw = usb_alloc_mem( NonPagedPool, - sizeof( LONG ) * UHCI_MAX_FRAMES ); + for(i = 0; i < UHCI_MAX_FRAMES; i++) + InitializeListHead(&uhci->frame_list_cpu[i].td_link); - if( uhci->frame_bw == NULL ) - return FALSE; + uhci->frame_bw = usb_alloc_mem(NonPagedPool, sizeof(LONG) * UHCI_MAX_FRAMES); - for( i = 0; i < UHCI_MAX_FRAMES; i++ ) - { - uhci->frame_bw[ i ] = FRAME_TIME_MAX_USECS_ALLOC; - } - uhci->fsbr_cnt = 0; - - return TRUE; + 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; } BOOL -uhci_destroy_frame_list( -PUHCI_DEV uhci -) +uhci_destroy_frame_list(PUHCI_DEV uhci) { + if (uhci == NULL) + return FALSE; - 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); - 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 = 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 ); + if (uhci->frame_list_cpu) + usb_free_mem(uhci->frame_list_cpu); - uhci->frame_list_cpu = NULL; + uhci->frame_list_cpu = NULL; - if( uhci->frame_bw ) - usb_free_mem( uhci->frame_bw ); + if (uhci->frame_bw) + usb_free_mem(uhci->frame_bw); - uhci->frame_bw = NULL; + uhci->frame_bw = NULL; - return TRUE; + return TRUE; } PDEVICE_OBJECT -uhci_create_device( -PDRIVER_OBJECT drvr_obj, -PUSB_DEV_MANAGER dev_mgr -) +uhci_create_device(PDRIVER_OBJECT drvr_obj, PUSB_DEV_MANAGER dev_mgr) { - NTSTATUS status; - PDEVICE_OBJECT pdev; - PDEVICE_EXTENSION pdev_ext; + NTSTATUS status; + PDEVICE_OBJECT pdev; + PDEVICE_EXTENSION pdev_ext; - UNICODE_STRING dev_name; - UNICODE_STRING symb_name; + UNICODE_STRING dev_name; + UNICODE_STRING symb_name; - STRING string, another_string; - CHAR str_dev_name[ 64 ], str_symb_name[ 64 ]; - UCHAR hcd_id; + STRING string, another_string; + CHAR str_dev_name[64], str_symb_name[64]; + UCHAR hcd_id; - if( drvr_obj == NULL ) - return NULL; + if (drvr_obj == NULL) + return NULL; - ASSERT( dev_mgr != 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 ); + //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 ); + 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); + 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; -} - -BOOL -uhci_delete_device( -PDEVICE_OBJECT pdev -) -{ - 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 ); - - 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; -} - -BOOLEAN -uhci_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 urb->pipe in uhci_internal_submit_XXX. - -{ - - PUHCI_DEV uhci; - USHORT status; - PLIST_ENTRY pthis, pnext; - PURB purb; - - - /* - * 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 -uhci_cal_cpu_freq( -PVOID 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; - 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 bus to find uhci 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 ); - - 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 ) - { - // well, we find our usb host controller, create device -#ifdef _MULTI_UHCI - { - pdev = uhci_alloc( drvr_obj, reg_path, ( ( bus << 8 ) | ( i << 3 ) | j ), dev_mgr ); - count++; - if( !pdev ) - return NULL; - } -#else - pdev = uhci_alloc( drvr_obj, reg_path, ( ( bus << 8 ) | ( i << 3 ) | j ), dev_mgr ); - if( pdev ) - goto LBL_LOOPOUT; -#endif - } - } - if( ret == 0 ) - break; - } - } -LBL_LOOPOUT: - 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 NULL; -} - -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; - UCHAR buffer[ PCI_COMMON_HDR_LENGTH ]; - PDEVICE_OBJECT pdev; - PDEVICE_EXTENSION pdev_ext; - ULONG vector, addr_space; - LONG bus; - KIRQL irql; - KAFFINITY affinity; - UCHAR hcd_id; - - DEVICE_DESCRIPTION dev_desc; - CM_PARTIAL_RESOURCE_DESCRIPTOR *pprd; - PCI_SLOT_NUMBER slot_num; - NTSTATUS status; - - - pdev = uhci_create_device( drvr_obj, dev_mgr ); - 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 ); - - if( pdev == NULL ) - return pdev; - - //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 ); - return NULL; - } - - DbgPrint("uhci_alloc(): reg_path=0x%x, \n \ - uhci_alloc(): PCIBus=0x%x, bus=0x%x, bus_addr=0x%x \n \ - uhci_alloc(): slot_num=0x%x, &res_list=0x%x \n", \ - ( DWORD )reg_path, \ - ( DWORD )PCIBus, \ - ( DWORD )bus, \ - ( DWORD )bus_addr,\ - ( DWORD )slot_num.u.AsULONG, \ - ( DWORD )&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 ); - 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 ); - 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 ); - 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 ); - 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); - - //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 ); - return NULL; - } - - KeInitializeDpc( &pdev_ext->uhci_dpc, - uhci_dpc_callback, - ( PVOID )pdev_ext->uhci ); - - return pdev; -} - -BOOL -uhci_release( -PDEVICE_OBJECT pdev -) -{ - PDEVICE_EXTENSION pdev_ext; - PUHCI_DEV uhci; - KIRQL disp_level; - KIRQL old_level; - - 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 ) + if (status != STATUS_SUCCESS || pdev == NULL) { - IoDisconnectInterrupt( pdev_ext->uhci_int ); - pdev_ext->uhci_int = NULL; + RtlFreeUnicodeString(&dev_name); + return NULL; } - else - TRAP(); - destroy_pending_endp_pool( &pdev_ext->uhci->pending_endp_pool ); - //pdev_ext->uhci->pending_endp_pool = NULL; - uhci_destroy_schedule( uhci ); + pdev_ext = pdev->DeviceExtension; + RtlZeroMemory(pdev_ext, sizeof(DEVICE_EXTENSION) + sizeof(UHCI_DEV)); - release_adapter( pdev_ext->padapter ); - pdev_ext->padapter = NULL; + 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; - uhci_delete_device( pdev ); + pdev_ext->pdev_obj = pdev; + pdev_ext->pdrvr_obj = drvr_obj; - return FALSE; + 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; } BOOL -uhci_start( -PHCD hcd -) +uhci_delete_device(PDEVICE_OBJECT pdev) { + 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); + + 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 +uhci_isr(PKINTERRUPT interrupt, PVOID context) +{ + PUHCI_DEV uhci; + USHORT status; + PLIST_ENTRY pthis, pnext; + PURB purb; + + /* + * 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 +uhci_cal_cpu_freq(PVOID 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; + 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 bus to find uhci 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); + + 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) + { + // well, we find our usb host controller, create device +#ifdef _MULTI_UHCI + { + pdev = uhci_alloc(drvr_obj, reg_path, ((bus << 8) | (i << 3) | j), dev_mgr); + count++; + if (!pdev) + return NULL; + } +#else + pdev = uhci_alloc(drvr_obj, reg_path, ((bus << 8) | (i << 3) | j), dev_mgr); + if (pdev) + goto LBL_LOOPOUT; +#endif + } + } + if (ret == 0) + break; + } + } + +LBL_LOOPOUT: + 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 NULL; +} + +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; + UCHAR buffer[PCI_COMMON_HDR_LENGTH]; + PDEVICE_OBJECT pdev; + PDEVICE_EXTENSION pdev_ext; + ULONG vector, addr_space; + LONG bus; + KIRQL irql; + KAFFINITY affinity; + UCHAR hcd_id; + + DEVICE_DESCRIPTION dev_desc; + CM_PARTIAL_RESOURCE_DESCRIPTOR *pprd; + PCI_SLOT_NUMBER slot_num; + NTSTATUS status; + + + pdev = uhci_create_device(drvr_obj, dev_mgr); + 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); + + if (pdev == NULL) + return pdev; + + //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); + return NULL; + } + + DbgPrint("uhci_alloc(): reg_path=0x%x, \n \ + uhci_alloc(): PCIBus=0x%x, bus=0x%x, bus_addr=0x%x \n \ + uhci_alloc(): slot_num=0x%x, &res_list=0x%x \n", (DWORD) reg_path, (DWORD) PCIBus, (DWORD) bus, + (DWORD) bus_addr, (DWORD) slot_num.u.AsULONG, (DWORD) & 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); + 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); + 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); + 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); + 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); + + //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); + return NULL; + } + + KeInitializeDpc(&pdev_ext->uhci_dpc, uhci_dpc_callback, (PVOID) pdev_ext->uhci); + + return pdev; +} + +BOOL +uhci_release(PDEVICE_OBJECT pdev) +{ + PDEVICE_EXTENSION pdev_ext; + PUHCI_DEV uhci; + KIRQL disp_level; + KIRQL old_level; + + 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); + + return FALSE; + +} + // send cmds to start the uhc // shamelessly copied from linux's uhci.c - PUHCI_DEV uhci; - PBYTE io_addr; - int timeout = 10000; +BOOL +uhci_start(PHCD hcd) +{ + PUHCI_DEV uhci; + PBYTE io_addr; + int timeout = 10000; - uhci = uhci_from_hcd( hcd ); - io_addr = uhci->port_base; + 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; - } - } + /* + * 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 - ); + /* 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 ); + /* 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 ) ); - - return TRUE; + /* 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)); + + return TRUE; } VOID -uhci_stop( -PUHCI_DEV uhci -) +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 ); + 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 -) +uhci_reset(PUHCI_DEV uhci) { - PUSB_DEV_MANAGER dev_mgr; - PLIST_ENTRY pthis, pnext; - PBYTE io_addr = uhci->port_base; + PUSB_DEV_MANAGER dev_mgr; + PLIST_ENTRY pthis, pnext; + 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 ); + 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 ); + WRITE_PORT_USHORT((PUSHORT) (io_addr + USBCMD), 0); + //uhci_wait_ms( uhci, 10 ); + usb_wait_ms_dpc(10); } static VOID -uhci_suspend( -PUHCI_DEV uhci -) +uhci_suspend(PUHCI_DEV uhci) { - PBYTE io_addr = uhci->port_base; + PBYTE io_addr = uhci->port_base; - //uhci->is_suspended = 1; - WRITE_PORT_USHORT( ( PUSHORT )( io_addr + USBCMD ), USBCMD_EGSM ); + //uhci->is_suspended = 1; + WRITE_PORT_USHORT((PUSHORT) (io_addr + USBCMD), USBCMD_EGSM); } static VOID -uhci_wakeup( -PUHCI_DEV uhci -) +uhci_wakeup(PUHCI_DEV uhci) { - PBYTE io_addr; - unsigned int status; + PBYTE io_addr; + unsigned int status; - io_addr = uhci->port_base; + 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 ) ); + WRITE_PORT_USHORT((PUSHORT) (io_addr + USBCMD), 0); - //uhci->is_suspended = 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)); - /* Run and mark it configured with a 64-byte max packet */ - WRITE_PORT_USHORT( - ( PUSHORT )( io_addr + USBCMD ), - USBCMD_RS | USBCMD_CF | USBCMD_MAXP - ); + //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); } BOOL -uhci_init_schedule( -PUHCI_DEV uhci, -PADAPTER_OBJECT padapter -) +uhci_init_schedule(PUHCI_DEV uhci, PADAPTER_OBJECT padapter) { - int i, irq; + int i, irq; - uhci_dbg_print( DBGLVL_MAXIMUM, ( "uhci_init_schedule(): entering..., uhci=0x%x\n", uhci ) ); - if( uhci == NULL || padapter == NULL ) - return FALSE; + 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; - } + 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 ); + //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; - } - } + 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 = 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; - } + 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_qh[i]->element = UHCI_PTR_TERM; + } - uhci->skel_int1_td->link = uhci->skel_ls_control_qh->phy_addr; - - 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_int1_td->link = uhci->skel_ls_control_qh->phy_addr; - uhci->skel_term_qh->link = UHCI_PTR_TERM; - uhci->skel_term_qh->element = uhci->skel_term_td->phy_addr; + 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; - InsertTailList( &uhci->skel_term_qh->pqhe->vert_link, &uhci->skel_term_td->ptde->vert_link ); + uhci->skel_term_qh->link = UHCI_PTR_TERM; + uhci->skel_term_qh->element = uhci->skel_term_td->phy_addr; - /*for( i = 0; i < UHCI_MAX_SKELQHS; i++ ) - { - InsertTailList( &uhci->skel_int256_td->ptde->hori_link, - &uhci->skel_qh[ i ]->pqhe->hori_link ); - }*/ + InsertTailList(&uhci->skel_term_qh->pqhe->vert_link, &uhci->skel_term_td->ptde->vert_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 + /*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++; - } - } - } - } - } - } + 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; + /* Only place we don't use the frame list routines */ + uhci->frame_list[i] = uhci->skel_td[irq]->phy_addr; + } + return TRUE; } BOOL -uhci_destroy_schedule( -PUHCI_DEV uhci -) +uhci_destroy_schedule(PUHCI_DEV uhci) { - BOOL ret; + BOOL ret; - ret = uhci_destroy_frame_list( uhci ); - ret = destroy_qh_pool( &uhci->qh_pool ); - ret = destroy_td_pool_list( &uhci->td_pool ); + ret = uhci_destroy_frame_list(uhci); + ret = destroy_qh_pool(&uhci->qh_pool); + ret = destroy_td_pool_list(&uhci->td_pool); - return ret; + return ret; } static VOID -uhci_cancel_pending_endp_urb( -IN PVOID Parameter -) +uhci_cancel_pending_endp_urb(IN PVOID Parameter) { - PLIST_ENTRY abort_list; - PUSB_DEV pdev; - PURB purb; - USE_IRQL; + PLIST_ENTRY abort_list; + PUSB_DEV pdev; + PURB purb; + USE_IRQL; - abort_list = ( PLIST_ENTRY )Parameter; - - if( abort_list == NULL ) - return; + abort_list = (PLIST_ENTRY) Parameter; - 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 + if (abort_list == NULL) + return; - uhci_generic_urb_completion( purb, purb->context ); - - lock_dev( pdev, FALSE ); - pdev->ref_count--; - unlock_dev( pdev, FALSE ); - } - usb_free_mem( abort_list ); - 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; } static BOOL -uhci_process_pending_endp( -PUHCI_DEV uhci -) +uhci_process_pending_endp(PUHCI_DEV uhci) { - PUSB_DEV pdev; - LIST_ENTRY temp_list, abort_list; - PLIST_ENTRY pthis; - PURB purb; - PUSB_ENDPOINT pendp; - BOOL can_submit; - PWORK_QUEUE_ITEM pwork_item; - PLIST_ENTRY cancel_list; - USE_IRQL; + PUSB_DEV pdev; + LIST_ENTRY temp_list, abort_list; + PLIST_ENTRY pthis; + PURB purb; + PUSB_ENDPOINT pendp; + BOOL can_submit; + PWORK_QUEUE_ITEM pwork_item; + PLIST_ENTRY cancel_list; + USE_IRQL; - if( uhci == NULL ) - return FALSE; + if (uhci == NULL) + return FALSE; - InitializeListHead( &temp_list ); - InitializeListHead( &abort_list ); + InitializeListHead(&temp_list); + InitializeListHead(&abort_list); - purb = NULL; - uhci_dbg_print( DBGLVL_MEDIUM, ("uhci_process_pending_endp(): entering..., uhci=0x%x\n", uhci ) ); + 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 ) - { + 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 ); + uhci_dbg_print(DBGLVL_MAXIMUM, ("uhci_process_pending_endp(): pending_endp_list=0x%x\n", + &uhci->pending_endp_list)); - lock_dev( pdev, TRUE ); + pthis = RemoveHeadList(&uhci->pending_endp_list); + pendp = ((PUHCI_PENDING_ENDP) pthis)->pendp; + pdev = dev_from_endp(pendp); - 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 remiving the urb queue on the endpoint - continue; - } + lock_dev(pdev, TRUE); - 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 (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 remiving 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 - switch( endp_type( pendp ) ) - { - case USB_ENDPOINT_XFER_BULK: - { + 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 + switch (endp_type(pendp)) + { + case USB_ENDPOINT_XFER_BULK: + { #ifdef DEMO - can_submit = STATUS_UNSUCCESSFUL; + can_submit = STATUS_UNSUCCESSFUL; #else - can_submit = uhci_internal_submit_bulk( uhci, purb ); + 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; - } - } + 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, ( PLIST_ENTRY )purb ); - 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 ); - purb->status = can_submit; - } + if (can_submit == STATUS_NO_MORE_ENTRIES) + { + //no enough bandwidth or tds + InsertHeadList(&pendp->urb_list, (PLIST_ENTRY) purb); + InsertTailList(&temp_list, pthis); + } + else + { + // other error or success + free_pending_endp(&uhci->pending_endp_pool, struct_ptr(pthis, UHCI_PENDING_ENDP, endp_link)); - } - unlock_dev( pdev, TRUE ); - } + if (can_submit != STATUS_SUCCESS) + { + //abort these URBs + InsertTailList(&abort_list, (LIST_ENTRY *) purb); + purb->status = can_submit; + } - 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 ); + } + unlock_dev(pdev, TRUE); + } - ListFirst( &abort_list, pthis ); - RemoveEntryList( &abort_list ); - InsertTailList( pthis, cancel_list ); - - pwork_item = ( PWORK_QUEUE_ITEM )&cancel_list[ 1 ]; + 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); - // 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; + 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; } BOOL -uhci_submit_urb( -PUHCI_DEV uhci, -PUSB_DEV pdev, -PUSB_ENDPOINT pendp, -PURB purb -) +uhci_submit_urb(PUHCI_DEV uhci, PUSB_DEV pdev, PUSB_ENDPOINT pendp, PURB purb) { - int i; - PLIST_ENTRY pthis, pnext; - PUHCI_PENDING_ENDP pending_endp; - NTSTATUS status; - USE_IRQL; + int i; + PLIST_ENTRY pthis, pnext; + PUHCI_PENDING_ENDP pending_endp; + NTSTATUS status; + USE_IRQL; - if( uhci == NULL || pdev == NULL || pendp == NULL || purb == NULL ) - return STATUS_INVALID_PARAMETER; + if (uhci == NULL || pdev == NULL || pendp == NULL || purb == NULL) + return STATUS_INVALID_PARAMETER; - lock_pending_endp_list( &uhci->pending_endp_list_lock ); - lock_dev( pdev, TRUE ); + 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_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_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( dev_from_endp( purb->pendp ) != pdev ) - { - status = purb->status = STATUS_INVALID_PARAMETER; - goto LBL_OUT; - } + if (pendp) + purb->pendp = pendp; + else + purb->pendp = &pdev->default_endp; - if( endp_state( purb->pendp ) == USB_ENDP_FLAG_STALL ) - { - status = purb->status = USB_STATUS_ENDPOINT_HALTED; - goto LBL_OUT; - } + if (dev_from_endp(purb->pendp) != pdev) + { + status = purb->status = STATUS_INVALID_PARAMETER; + goto LBL_OUT; + } - purb->pdev = pdev; - purb->rest_bytes = purb->data_length; + if (endp_state(purb->pendp) == USB_ENDP_FLAG_STALL) + { + status = purb->status = USB_STATUS_ENDPOINT_HALTED; + goto LBL_OUT; + } - 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; + purb->pdev = pdev; + purb->rest_bytes = 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; + 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 ); + i = IsListEmpty(&pendp->urb_list); + InsertTailList(&pendp->urb_list, &purb->urb_link); - pdev->ref_count ++; //for urb reference + 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 ) - { + 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; - } + //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 = 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, ( PLIST_ENTRY )pending_endp ); + pending_endp->pendp = purb->pendp; + InsertTailList(&uhci->pending_endp_list, (PLIST_ENTRY) pending_endp); - unlock_dev( pdev, TRUE ); - unlock_pending_endp_list( &uhci->pending_endp_list_lock ); + unlock_dev(pdev, TRUE); + unlock_pending_endp_list(&uhci->pending_endp_list_lock); - uhci_process_pending_endp( uhci ); - return STATUS_PENDING; + uhci_process_pending_endp(uhci); + return STATUS_PENDING; LBL_OUT2: - pdev->ref_count --; - RemoveEntryList( ( PLIST_ENTRY )purb ); + pdev->ref_count--; + RemoveEntryList((PLIST_ENTRY) purb); LBL_OUT: - unlock_dev( pdev, TRUE ); - unlock_pending_endp_list( &uhci->pending_endp_list_lock ); - return status; + unlock_dev(pdev, TRUE); + unlock_pending_endp_list(&uhci->pending_endp_list_lock); + return status; } static NTSTATUS -uhci_set_error_code( -PURB urb, -ULONG raw_status -) +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; + 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_STALLED ) - urb->status = USB_STATUS_STALL_PID; + else if (raw_status & TD_CTRL_BABBLE) + urb->status = USB_STATUS_DATA_OVERRUN; - else if( raw_status & TD_CTRL_DBUFERR ) - urb->status = USB_STATUS_BUFFER_OVERRUN; + else if (raw_status & TD_CTRL_STALLED) + urb->status = USB_STATUS_STALL_PID; - else if( raw_status & TD_CTRL_CRCTIMEO ) - urb->status = USB_STATUS_CRC; + else if (raw_status & TD_CTRL_DBUFERR) + urb->status = USB_STATUS_BUFFER_OVERRUN; - else if( raw_status & TD_CTRL_BITSTUFF ) - urb->status = USB_STATUS_BTSTUFF; + else if (raw_status & TD_CTRL_CRCTIMEO) + urb->status = USB_STATUS_CRC; - else - urb->status = STATUS_UNSUCCESSFUL; + else if (raw_status & TD_CTRL_BITSTUFF) + urb->status = USB_STATUS_BTSTUFF; - return urb->status; + else + urb->status = STATUS_UNSUCCESSFUL; + + return urb->status; } BOOLEAN -uhci_sync_remove_urb_finished( -PVOID context -) +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; + PUHCI_DEV uhci; + PLIST_ENTRY pthis, pnext, ptemp; + PURB purb; + PSYNC_PARAM pparam; - if( uhci == NULL ) - { - return ( UCHAR )pparam->ret = FALSE; - } - - ListFirst( &uhci->urb_list, pthis ); - while( pthis ) - { + 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; + ListNext(&uhci->urb_list, pthis, pnext); + purb = (PURB) pthis; - if( ( purb->flags & URB_FLAG_IN_SCHEDULE ) == 0 ) - { + 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; + 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 -) +uhci_drop_fsbr(PUHCI_DEV uhci) { + if (uhci == NULL) + return (UCHAR) FALSE; - if( uhci == NULL ) - return ( UCHAR )FALSE; + uhci->fsbr_cnt--; - uhci->fsbr_cnt--; - - if( uhci->fsbr_cnt <= 0 ) - { - uhci->skel_term_qh->link = UHCI_PTR_TERM; - uhci->fsbr_cnt = 0; - } - - return ( UCHAR )TRUE; + if (uhci->fsbr_cnt <= 0) + { + uhci->skel_term_qh->link = UHCI_PTR_TERM; + uhci->fsbr_cnt = 0; + } + + return (UCHAR) TRUE; } + VOID -uhci_dpc_callback( -PKDPC dpc, -PVOID context, -PVOID sysarg1, -PVOID sysarg2 -) +uhci_dpc_callback(PKDPC dpc, PVOID context, PVOID sysarg1, PVOID sysarg2) { - PUHCI_DEV uhci; + PUHCI_DEV uhci; - LIST_HEAD temp_list; - PLIST_ENTRY pthis, pnext; - PURB purb; - PQH_EXTENSION pqhe; - PTD_EXTENSION ptde; - PUHCI_PENDING_ENDP pending_endp; - PUSB_DEV pdev; - PUSB_ENDPOINT pendp; + LIST_HEAD temp_list; + PLIST_ENTRY pthis, pnext; + PURB purb; + PQH_EXTENSION pqhe; + PTD_EXTENSION ptde; + PUHCI_PENDING_ENDP pending_endp; + PUSB_DEV pdev; + PUSB_ENDPOINT pendp; - BOOL finished; - LONG i, j; - ULONG uhci_status, urb_status, toggle = 0; + BOOL finished; + LONG i, j; + ULONG uhci_status, urb_status, toggle = 0; - SYNC_PARAM sync_param; - USE_IRQL; + SYNC_PARAM sync_param; + USE_IRQL; - uhci = ( PUHCI_DEV ) context; - if( uhci == NULL ) - return; + uhci = (PUHCI_DEV) context; + if (uhci == NULL) + return; - uhci_status = ( ULONG )sysarg1; + 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 ); + 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 + 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; + 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 ); + //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 ((((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)); - 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; - } - } + } + ListNext(&purb->trasac_list, pthis, pnext); + pthis = pnext; + } - 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 + 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; + } + } - 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 + 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 ); - } + pdev = dev_from_endp(purb->pendp); + pendp = purb->pendp; - //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 (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); + } - 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 ); + //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( finished ) - pdev->ref_count--; + 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 + } + } - 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; - } + KeAcquireSpinLockAtDpcLevel(&uhci->pending_endp_list_lock); + lock_dev(pdev, TRUE); - if( dev_state( pdev )== USB_DEV_STATE_ZOMB ) - { - unlock_dev( pdev, TRUE); - KeReleaseSpinLockFromDpcLevel( &uhci->pending_endp_list_lock ); - if( finished == FALSE ) - { + if (finished) + pdev->ref_count--; - purb->status = STATUS_DEVICE_DOES_NOT_EXIST; - uhci_generic_urb_completion( purb, purb->context ); + 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; + } - 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 ) - { + 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; - } - } + 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; + 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; + //the urb is not finished + purb->flags &= ~URB_FLAG_STATE_MASK; + purb->flags |= URB_FLAG_STATE_PENDING; - InsertHeadList( &pendp->urb_list, ( PLIST_ENTRY )purb ); - } + InsertHeadList(&pendp->urb_list, (PLIST_ENTRY) purb); + } - pending_endp = alloc_pending_endp( &uhci->pending_endp_pool, 1 ); - pending_endp->pendp = pendp; - InsertTailList( &uhci->pending_endp_list, &pending_endp->endp_link ); + pending_endp = alloc_pending_endp(&uhci->pending_endp_pool, 1); + pending_endp->pendp = pendp; + InsertTailList(&uhci->pending_endp_list, &pending_endp->endp_link); - unlock_dev( pdev, TRUE); - KeReleaseSpinLockFromDpcLevel( &uhci->pending_endp_list_lock ); - } + 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; + //ah...exhausted, let's find some in the pending_endp_list to rock + uhci_process_pending_endp(uhci); + return; } BOOL -uhci_add_device( -PUHCI_DEV uhci, -PUSB_DEV dev -) +uhci_add_device(PUHCI_DEV uhci, PUSB_DEV dev) { - if( dev == NULL || uhci == NULL ) - return FALSE; - - return TRUE; + if (dev == NULL || uhci == NULL) + return FALSE; + return TRUE; } BOOLEAN -uhci_sync_cancel_urbs_dev( -PVOID context -) +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; + //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; + 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; + 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; } BOOL -uhci_remove_device( -PUHCI_DEV uhci, -PUSB_DEV dev -) +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_IRQL; + PUHCI_PENDING_ENDP ppending_endp; + PLIST_ENTRY pthis, pnext; + PURB purb; + LIST_HEAD temp_list; + int i, j, k; + SYNC_PARAM sync_param; - if( uhci == NULL || dev == NULL ) - return FALSE; + USE_IRQL; - InitializeListHead( &temp_list ); + if (uhci == NULL || dev == NULL) + return FALSE; - //free pending endp that has urb queued from pending endp list - lock_pending_endp_list( &uhci->pending_endp_list_lock ); + InitializeListHead(&temp_list); - ListFirst( &uhci->pending_endp_list, pthis ); + //free pending endp that has urb queued from pending endp list + lock_pending_endp_list(&uhci->pending_endp_list_lock); - 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 ); + ListFirst(&uhci->pending_endp_list, pthis); - //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 ); + 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 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 ); + //cancel all the urbs in the urb-list + sync_param.uhci = uhci; + sync_param.context = (PVOID) dev; - RemoveEntryList( pthis ); - InsertHeadList( &temp_list, pthis ); - pthis = pnext; - k++; - } + KeSynchronizeExecution(uhci->pdev_ext->uhci_int, uhci_sync_cancel_urbs_dev, &sync_param); - } - } - } - ListFirst( &dev->default_endp.urb_list, pthis ); - - while( pthis ) - { - ListNext( &dev->default_endp.urb_list, - pthis, - pnext ); + //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++; - } - unlock_dev( dev, FALSE ); + RemoveEntryList(pthis); + InsertHeadList(&temp_list, pthis); + pthis = pnext; + k++; + } - 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 ); - } - } - } + } + } + } + ListFirst(&dev->default_endp.urb_list, pthis); - lock_dev( dev, FALSE ) - dev->ref_count -= k; - unlock_dev( dev, FALSE ); + while (pthis) + { + ListNext(&dev->default_endp.urb_list, pthis, pnext); - return TRUE; + 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; } -static NTSTATUS -uhci_internal_submit_bulk( -PUHCI_DEV uhci, -PURB urb -) // // assume that the urb has its rest_bytes and bytes_to_transfer set // and bytes_transfered is zeroed. @@ -2121,2094 +1884,1965 @@ PURB urb // urb comes from dev's endpoint urb-list. it is already removed from // the endpoint urb-list. // +static 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; + PBYTE start_addr; + PUHCI_TD ptd; + PUHCI_QH pqh; + LIST_ENTRY td_list, *pthis, *pnext; BOOL old_toggle, toggle, ret; - UCHAR pid; + UCHAR pid; - if( uhci == NULL || urb == NULL ) - return STATUS_INVALID_PARAMETER; + 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; - } + 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; - } + td_count = (urb->bytes_to_transfer + max_packet_size - 1) / max_packet_size; - ptd = alloc_tds( &uhci->td_pool, td_count ); - unlock_td_pool( &uhci->td_pool, TRUE ); + 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; + } - if( ptd == NULL ) - { - return STATUS_UNSUCCESSFUL; - } + ptd = alloc_tds(&uhci->td_pool, td_count); + unlock_td_pool(&uhci->td_pool, TRUE); - InitializeListHead( &td_list ); - InsertTailList( &ptd->ptde->vert_link, &td_list ); + if (ptd == NULL) + { + return STATUS_UNSUCCESSFUL; + } - ListFirst( &td_list, pthis ); - ListNext( &td_list, pthis, pnext ); + InitializeListHead(&td_list); + InsertTailList(&ptd->ptde->vert_link, &td_list); - start_addr = &urb->data_buffer[ urb->data_length - urb->rest_bytes ]; + 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; + 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; + 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 ) + 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; - -} - -static 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; - BOOL 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; -} - -static NTSTATUS -uhci_internal_submit_int( -PUHCI_DEV uhci, -PURB urb -) -{ - LIST_ENTRY td_list, *pthis, *pnext; - LONG i; - LONG toggle = 0; - LONG max_packet_size; - PUHCI_TD ptd; - BOOL ret; - - if( uhci == NULL || urb == NULL ) - 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 ) - { - 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; -} - - -static NTSTATUS -uhci_internal_submit_iso( -PUHCI_DEV uhci, -PURB urb -) -{ - PUHCI_TD ptd; - LIST_ENTRY td_list, *pthis, *pnext; - int i; - BOOL toggle, ret; - KIRQL old_irql; - - 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; -} - -static BOOL -uhci_is_xfer_finished( -PURB urb -) -// runs in uhci_isr -{ - PLIST_ENTRY pthis, pnext; - PUHCI_TD ptd; - PUHCI_QH pqh; - BOOL ret; - 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; -} - -static BOOL -uhci_remove_urb_from_schedule( -PUHCI_DEV uhci, -PURB urb -) -// 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 -{ - BOOL 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; -} - -static BOOL -uhci_remove_bulk_from_schedule( -PUHCI_DEV uhci, -PURB urb -) -// 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 -{ - - 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; -} - -static BOOL -uhci_remove_iso_from_schedule( -PUHCI_DEV uhci, -PURB urb -) -{ - PUHCI_TD ptd, pnext_td, 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; - } + 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 - { - pprev_td = struct_ptr( pprev, TD_EXTENSION, hori_link )->ptd; - pprev_td->link = ptd->link; - } + { + //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; + } + } - RemoveEntryList( &ptd->ptde->hori_link ); - ListNext( &urb->trasac_list, pthis, pnext ); - pthis = pnext; - } - - urb->flags &= ~URB_FLAG_IN_SCHEDULE; - return TRUE; -} - -static BOOL -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; -} - -static BOOL -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; -} - -static BOOL -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; -} - -static BOOL -uhci_insert_urb_schedule( -PUHCI_DEV uhci, -PURB urb -) -// must have dev_lock and frame_list_lock acquired -{ - 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, ( PLIST_ENTRY )urb ); - - 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; -} - -BOOLEAN -uhci_sync_insert_urb_schedule( -PVOID context -) -//this function used as the KeSynchronizeExecution param to delegate control to uhci_insert_urb_schedule -{ - 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 ) ); -} - -static BOOL -uhci_claim_bandwidth( -PUHCI_DEV uhci, -PURB urb, -BOOL claim_bw //true to claim band-width, false to free band-width -) -// be sure pending_endp_list_lock acuqired -{ - - UCHAR type; - BOOL 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; - } - } + pthis = pnext; + toggle ^= 1; + if (pthis) + ListNext(&td_list, pthis, pnext); } - 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 ); - } + ListFirst(&td_list, pthis); + RemoveEntryList(&td_list); - 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; - } - } + lock_qh_pool(&uhci->qh_pool, TRUE); + pqh = alloc_qh(&uhci->qh_pool); + unlock_qh_pool(&uhci->qh_pool, TRUE); - if( !can_alloc ) - { - return FALSE; - } + if (pqh == NULL) + { + lock_td_pool(&uhci->td_pool, TRUE); - 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; - } - } + if (pthis) + free_tds(&uhci->td_pool, ((PTD_EXTENSION) pthis)->ptd); - } + unlock_td_pool(&uhci->td_pool, TRUE); + return STATUS_NO_MORE_ENTRIES; - return TRUE; + } + + 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; +} + +static 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; + BOOL 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; +} + +static NTSTATUS +uhci_internal_submit_int(PUHCI_DEV uhci, PURB urb) +{ + LIST_ENTRY td_list, *pthis, *pnext; + LONG i; + LONG toggle = 0; + LONG max_packet_size; + PUHCI_TD ptd; + BOOL ret; + + if (uhci == NULL || urb == NULL) + 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) + { + 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; } +static NTSTATUS +uhci_internal_submit_iso(PUHCI_DEV uhci, PURB urb) +{ + PUHCI_TD ptd; + LIST_ENTRY td_list, *pthis, *pnext; + int i; + BOOL toggle, ret; + KIRQL old_irql; + + 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 +static BOOL +uhci_is_xfer_finished(PURB urb) +{ + PLIST_ENTRY pthis, pnext; + PUHCI_TD ptd; + PUHCI_QH pqh; + BOOL ret; + 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 +static BOOL +uhci_remove_urb_from_schedule(PUHCI_DEV uhci, PURB urb) +{ + BOOL 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 +static BOOL +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; +} + +static BOOL +uhci_remove_iso_from_schedule(PUHCI_DEV uhci, PURB urb) +{ + PUHCI_TD ptd, pnext_td, 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; +} + +static BOOL +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; +} + +static BOOL +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; +} + +static BOOL +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 +static BOOL +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, (PLIST_ENTRY) urb); + + 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 -uhci_sync_cancel_urb( -PVOID context -) +uhci_sync_insert_urb_schedule(PVOID context) { - //cancel a single urb - PUHCI_DEV uhci; - PSYNC_PARAM sync_param; - PURB purb2, dest_urb; - PLIST_ENTRY pthis, pnext; - BOOL found = FALSE; - - if( context == NULL ) - return FALSE; + PSYNC_PARAM sync_param; + PUHCI_DEV uhci; + PURB purb; - sync_param = ( PSYNC_PARAM )context; - uhci = sync_param->uhci; - dest_urb = ( PURB )sync_param->context; + sync_param = (PSYNC_PARAM) context; + if (sync_param == NULL) + return FALSE; - 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; + uhci = sync_param->uhci; + purb = (PURB) sync_param->context; - return ( UCHAR )( sync_param->ret = found ); + if (uhci == NULL || purb == NULL) + return (UCHAR) sync_param->ret = FALSE; + return (UCHAR) (sync_param->ret = uhci_insert_urb_schedule(uhci, purb)); } -NTSTATUS -uhci_cancel_urb( -PUHCI_DEV uhci, -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 +// be sure pending_endp_list_lock acquired +static BOOL +uhci_claim_bandwidth(PUHCI_DEV uhci, + PURB urb, + BOOL claim_bw //true to claim bandwidth, false to free bandwidth + ) { - NTSTATUS status; - PLIST_ENTRY pthis, pnext; - BOOL found; - PURB purb2; - - SYNC_PARAM sync_param; - - USE_IRQL; + UCHAR type; + BOOL ls, can_alloc; + LONG bus_time, us; + LONG i, idx, j, start_frame, interval; - if( uhci == NULL || purb == NULL || pdev == NULL || pendp == NULL ) - return STATUS_INVALID_PARAMETER; + if (urb == NULL) + return FALSE; - lock_dev( pdev, FALSE ); + can_alloc = TRUE; - 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; - } + type = (UCHAR) (urb->pipe & USB_ENDPOINT_XFERTYPE_MASK); + if (type == USB_ENDPOINT_XFER_BULK || type == USB_ENDPOINT_XFER_CONTROL) + { + return FALSE; + } - if( dev_from_endp( pendp ) != pdev ) - { - unlock_dev( pdev, FALSE ); - return STATUS_INVALID_PARAMETER; - } + ls = (urb->pipe & USB_DEV_FLAG_LOW_SPEED) ? TRUE : FALSE; - 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; - } + 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); - 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 ); + i = (urb->pipe >> 24); //polling interval - if( found ) - { - purb->status = STATUS_CANCELLED; - - uhci_generic_urb_completion( purb, purb->context ); + for(interval = 0, j = 0; j < 8; j++) + { + if (i & (1 << j)) + { + interval = j; + } + } - lock_dev( pdev, FALSE ); - pdev->ref_count --; - unlock_dev( pdev, FALSE ); - return STATUS_SUCCESS; - } + interval = 1 << interval; + start_frame = interval - 1; - // 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 ); + if (claim_bw) + { - found = sync_param.ret; - - if( found ) - return USB_STATUS_CANCELING; + for(idx = 0; idx < UHCI_MAX_FRAMES; idx += interval) + { + if (uhci->frame_bw[idx] < us) + { + can_alloc = FALSE; + break; + } + } - return STATUS_INVALID_PARAMETER; + 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 +uhci_sync_cancel_urb(PVOID context) +{ + PUHCI_DEV uhci; + PSYNC_PARAM sync_param; + PURB purb2, dest_urb; + PLIST_ENTRY pthis, pnext; + BOOL 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) +{ + + NTSTATUS status; + PLIST_ENTRY pthis, pnext; + BOOL found; + PURB purb2; + + SYNC_PARAM sync_param; + + USE_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 = sync_param.ret; + + if (found) + return USB_STATUS_CANCELING; + + return STATUS_INVALID_PARAMETER; } VOID -uhci_generic_urb_completion( -PURB purb, -PVOID context -) +uhci_generic_urb_completion(PURB purb, PVOID context) { - PUSB_DEV pdev; - KIRQL cur_irql; - USE_IRQL; + PUSB_DEV pdev; + KIRQL cur_irql; + USE_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 ) - return; + old_irql = KeGetCurrentIrql(); + if (old_irql > DISPATCH_LEVEL) + TRAP(); - if( pdev == NULL ) - return; + if (old_irql < DISPATCH_LEVEL) + KeRaiseIrql(DISPATCH_LEVEL, &old_irql); - lock_dev( pdev, TRUE ); + pdev = purb->pdev; + if (purb == NULL) + return; - 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 (pdev == NULL) + return; - 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 ); + lock_dev(pdev, TRUE); - LBL_CLIENT_PROCESS: - if( purb->completion ) - purb->completion( purb, context ); + 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( old_irql < DISPATCH_LEVEL ) - KeLowerIrql( old_irql ); + 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; - return; + } + 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 -) +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; + PUSB_DEV_MANAGER dev_mgr; + PTIMER_SVC ptimer; + PUSB_CTRL_SETUP_PACKET psetup; + PUHCI_DEV uhci; + NTSTATUS status; #ifndef INCLUDE_EHCI - PHUB_EXTENSION hub_ext; + PHUB_EXTENSION hub_ext; #else - PHUB2_EXTENSION hub_ext; + PHUB2_EXTENSION hub_ext; #endif - PUSB_PORT_STATUS ps, psret; - LONG i; + PUSB_PORT_STATUS ps, psret; + LONG i; - USE_IRQL; - if( pdev == NULL || purb == NULL ) - return STATUS_INVALID_PARAMETER; + USE_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; - } + dev_mgr = dev_mgr_from_dev(pdev); - uhci = uhci_from_hcd( pdev->hcd ); - psetup = ( PUSB_CTRL_SETUP_PACKET ) purb->setup_packet; + 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 ); + hub_ext = ((PHUB_EXTENSION) pdev->dev_ext); #else - hub_ext = ( ( PHUB2_EXTENSION )pdev->dev_ext ); + 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; - } - status = READ_PORT_USHORT( ( PUSHORT )( uhci->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; - 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 ); - 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; + 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; + } - //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 ); - ptimer->threshold = RH_INTERVAL; - ptimer->context = ( ULONG )purb; - ptimer->pdev = pdev; - ptimer->func = rh_timer_svc_int_completion; + psret = (PUSB_PORT_STATUS) purb->data_buffer; + ps->wPortStatus = 0; - //start the timer - InsertTailList(&dev_mgr->timer_svc_list, &ptimer->timer_svc_link ); - - usb_dbg_print( DBGLVL_MAXIMUM, ( "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 + 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; + } - 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; + //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; + } + status = READ_PORT_USHORT((PUSHORT)(uhci->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; + 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); + 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); + 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, + ("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 BOOL -uhci_rh_reset_port( -PHCD hcd, -UCHAR port_idx -) +uhci_rh_reset_port(PHCD hcd, UCHAR port_idx) { - LONG i; - PUHCI_DEV uhci; - ULONG status; + LONG i; + PUHCI_DEV uhci; + ULONG status; - if( port_idx != 1 && port_idx != 2 ) - return FALSE; + if (port_idx != 1 && port_idx != 2) + return FALSE; - if( hcd == NULL ) - return FALSE; - - if( port_idx == 1 ) - { - i = USBPORTSC1; - } - else - { - i = USBPORTSC2; - } + if (hcd == NULL) + return FALSE; - 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 ); + if (port_idx == 1) + { + i = USBPORTSC1; + } + else + { + i = USBPORTSC2; + } - 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 ) ); + 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); - return TRUE; + 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 -) +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; + PDEVICE_EXTENSION pdev_ext; + PUSB_DEV_MANAGER dev_mgr; + PUHCI_DEV uhci; - dev_mgr = uhci->hcd_interf.hcd_get_dev_mgr( &uhci->hcd_interf ); - return dev_mgr_dispatch( dev_mgr, irp ); + 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 -uhci_unload( -IN PDRIVER_OBJECT DriverObject -) +uhci_unload(IN PDRIVER_OBJECT DriverObject) { - PDEVICE_OBJECT pdev; - PDEVICE_EXTENSION pdev_ext; - PUSB_DEV_MANAGER dev_mgr; - LONG i; + PDEVICE_OBJECT pdev; + PDEVICE_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; + pdev = DriverObject->DeviceObject; - dev_mgr = &g_dev_mgr; - if( dev_mgr == NULL ) - return; - // - // set the termination flag - // - dev_mgr->term_flag = TRUE; + if (pdev == NULL) + return; + + pdev_ext = pdev->DeviceExtension; + if (pdev_ext == NULL) + return; + + dev_mgr = &g_dev_mgr; + if (dev_mgr == NULL) + return; // - // 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 ); + // set the termination flag + // + dev_mgr->term_flag = TRUE; - return; + // + // 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 ) +uhci_set_dev_mgr(struct _HCD * hcd, PUSB_DEV_MANAGER dev_mgr) { - hcd->dev_mgr = dev_mgr; + hcd->dev_mgr = dev_mgr; } PUSB_DEV_MANAGER -uhci_get_dev_mgr( -struct _HCD* hcd -) +uhci_get_dev_mgr(struct _HCD *hcd) { - return hcd->dev_mgr; + return hcd->dev_mgr; } -ULONG -uhci_get_type( -struct _HCD* hcd -) +ULONG +uhci_get_type(struct _HCD * hcd) { - return ( hcd->flags & HCD_TYPE_MASK ); + return (hcd->flags & HCD_TYPE_MASK); } VOID -uhci_set_id( -struct _HCD* hcd, -UCHAR id -) +uhci_set_id(struct _HCD * hcd, UCHAR id) { - hcd->flags &= ~HCD_ID_MASK; - hcd->flags |= ( HCD_ID_MASK & id ); + hcd->flags &= ~HCD_ID_MASK; + hcd->flags |= (HCD_ID_MASK & id); } UCHAR -uhci_get_id( -struct _HCD* hcd -) +uhci_get_id(struct _HCD *hcd) { - return ( UCHAR )( hcd->flags & HCD_ID_MASK ); + return (UCHAR) (hcd->flags & HCD_ID_MASK); } UCHAR -uhci_alloc_addr( -struct _HCD* hcd -) +uhci_alloc_addr(struct _HCD * hcd) { - LONG i; - if( hcd == NULL ) - return 0; + 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; - } - } + 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; + if (i >= MAX_DEVS) + return 0xff; - hcd->dev_addr_map[ i >> 3 ] |= ( 1 << ( i & 7 ) ); - hcd->conn_count++; - return ( BYTE )i; + 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; +uhci_free_addr(struct _HCD * hcd, UCHAR addr) +{ + if (addr & 0x80) + return; - if( hcd == NULL ) - return; + if (hcd == NULL) + return; + + hcd->dev_addr_map[addr >> 3] &= ~(1 << (addr & 7)); + 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 ) +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 ); + return uhci_submit_urb(uhci_from_hcd(hcd), pdev, pendp, purb); } PUSB_DEV -uhci_get_root_hub( -struct _HCD* hcd -) +uhci_get_root_hub(struct _HCD * hcd) { - return uhci_from_hcd( hcd )->root_hub; + return uhci_from_hcd(hcd)->root_hub; } + VOID -uhci_set_root_hub( -struct _HCD* hcd, -PUSB_DEV root_hub -) +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; + if (hcd == NULL || root_hub == NULL) + return; + uhci_from_hcd(hcd)->root_hub = root_hub; + return; } BOOL -uhci_remove_device2( -struct _HCD* hcd, -PUSB_DEV pdev -) +uhci_remove_device2(struct _HCD * hcd, PUSB_DEV pdev) { - if( hcd == NULL || pdev == NULL ) - return FALSE; + if (hcd == NULL || pdev == NULL) + return FALSE; - return uhci_remove_device( uhci_from_hcd( hcd ), pdev ); -} - -BOOL 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 ); -} - -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 ); + return uhci_remove_device(uhci_from_hcd(hcd), pdev); } BOOL -uhci_rh_get_dev_change( -PHCD hcd, -PBYTE buf -) +uhci_hcd_release(struct _HCD * hcd) { - PUHCI_DEV uhci; - ULONG status; + PUHCI_DEV uhci; + PDEVICE_EXTENSION pdev_ext; - if( hcd == NULL || buf == NULL ) - return FALSE; + if (hcd == NULL) + return FALSE; - uhci = uhci_from_hcd( hcd ); - status = READ_PORT_USHORT( ( PUSHORT )( uhci->port_base + USBPORTSC1 ) ); - usb_dbg_print( DBGLVL_MAXIMUM, ( "uhci_rh_get_dev_change(): rh port1 status=0x%x\n", status ) ); - if( ( status & USBPORTSC_PEC ) || ( status & USBPORTSC_CSC ) ) - { - buf[ 0 ] |= ( 1 << 1 ); - } + uhci = uhci_from_hcd(hcd); + pdev_ext = uhci->pdev_ext; - status = READ_PORT_USHORT( ( PUSHORT )( uhci->port_base + USBPORTSC2 ) ); - usb_dbg_print( DBGLVL_MAXIMUM, ( "rh_timer_svc_int_completion(): rh port2 status=0x%x\n", status ) ); - - if( ( status & USBPORTSC_PEC ) || ( status & USBPORTSC_CSC ) ) - { - buf[ 0 ] |= ( 1 << 2 ); - } - return TRUE; + return uhci_release(pdev_ext->pdev_obj); } NTSTATUS -uhci_dispatch( -PHCD hcd, -LONG disp_code, -PVOID param ) // locking depends on type of code +uhci_cancel_urb2(struct _HCD * hcd, PUSB_DEV pdev, PUSB_ENDPOINT pendp, PURB purb) { - ULONG status; - - 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; + PUHCI_DEV uhci; + if (hcd == NULL) + return STATUS_INVALID_PARAMETER; + uhci = uhci_from_hcd(hcd); + return uhci_cancel_urb(uhci, pdev, pendp, purb); } + +BOOL +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_MAXIMUM, ("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_MAXIMUM, ("rh_timer_svc_int_completion(): 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 +{ + ULONG status; + + 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_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 + 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 -generic_dispatch_irp( -IN PDEVICE_OBJECT dev_obj, -IN PIRP irp -) +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 ); + 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 -) +generic_start_io(IN PDEVICE_OBJECT dev_obj, IN PIRP irp) { - PDEVEXT_HEADER dev_ext; - - KIRQL old_irql; + PDEVEXT_HEADER dev_ext; - IoAcquireCancelSpinLock( &old_irql ); - if (irp != dev_obj->CurrentIrp || irp->Cancel) - { - IoReleaseCancelSpinLock(old_irql); - return; - } - else - { - IoSetCancelRoutine(irp, NULL); - IoReleaseCancelSpinLock(old_irql); - } + KIRQL 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 ); + 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 -DriverEntry( - IN PDRIVER_OBJECT DriverObject, - IN PUNICODE_STRING RegistryPath - ) +DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath) { NTSTATUS ntStatus = STATUS_SUCCESS; PDEVICE_OBJECT dev_obj = NULL; BOOLEAN fRes; #if DBG - // should be done before any debug output is done. + // 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 + // L"DebugLevel", // REG_DWORD ValueName + // &gDebugLevel ); // Value receiver - // debug_level = DBGLVL_MAXIMUM; + // debug_level = DBGLVL_MAXIMUM; #endif - uhci_dbg_print_cond( DBGLVL_MINIMUM , DEBUG_UHCI, ("Entering DriverEntry(), RegistryPath=\n %ws\n", RegistryPath->Buffer )); + 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->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; + 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_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_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; + 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 ); + ehci_probe(DriverObject, RegistryPath, &g_dev_mgr); #endif - uhci_probe( DriverObject, RegistryPath, &g_dev_mgr ); + uhci_probe(DriverObject, RegistryPath, &g_dev_mgr); - if( dev_mgr_strobe( &g_dev_mgr ) == FALSE ) - { + if (dev_mgr_strobe(&g_dev_mgr) == FALSE) + { - dev_mgr_release_hcd( &g_dev_mgr ); - return STATUS_UNSUCCESSFUL; - } + dev_mgr_release_hcd(&g_dev_mgr); + return STATUS_UNSUCCESSFUL; + } - dev_mgr_start_hcd( &g_dev_mgr ); - - uhci_dbg_print_cond( DBGLVL_DEFAULT, DEBUG_UHCI, ("DriverEntry(): exiting... (%x)\n", ntStatus)); - return STATUS_SUCCESS; + dev_mgr_start_hcd(&g_dev_mgr); + + 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 diff --git a/reactos/drivers/usb/nt4compat/usbdriver/umss.c b/reactos/drivers/usb/nt4compat/usbdriver/umss.c index f917d2ecf18..b9ee954f98c 100644 --- a/reactos/drivers/usb/nt4compat/usbdriver/umss.c +++ b/reactos/drivers/usb/nt4compat/usbdriver/umss.c @@ -63,2085 +63,1904 @@ typedef unsigned long ULONG_PTR, *PULONG_PTR; return;\ } -extern VOID -gendrv_startio( -IN PDEVICE_OBJECT dev_obj, -IN PIRP irp -); +extern VOID gendrv_startio(IN PDEVICE_OBJECT dev_obj, IN PIRP irp); + +NTSYSAPI NTSTATUS NTAPI ZwLoadDriver(IN PUNICODE_STRING DriverServiceName); NTSYSAPI NTSTATUS NTAPI -ZwLoadDriver( -IN PUNICODE_STRING DriverServiceName -); +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); -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 umss_start_io(IN PDEVICE_OBJECT dev_obj, IN PIRP irp); -VOID -umss_start_io( -IN PDEVICE_OBJECT dev_obj, -IN PIRP irp -); +NTSTATUS umss_port_dispatch_routine(PDEVICE_OBJECT pdev_obj, PIRP irp); -NTSTATUS -umss_port_dispatch_routine( -PDEVICE_OBJECT pdev_obj, -PIRP irp -); +BOOL umss_connect(PCONNECT_DATA dev_mgr, DEV_HANDLE dev_handle); -BOOL -umss_connect( -PCONNECT_DATA dev_mgr, -DEV_HANDLE dev_handle -); +BOOL umss_disconnect(PUSB_DEV_MANAGER dev_mgr, DEV_HANDLE dev_handle); -BOOL -umss_disconnect( -PUSB_DEV_MANAGER dev_mgr, -DEV_HANDLE dev_handle -); +BOOL umss_stop(PUSB_DEV_MANAGER dev_mgr, DEV_HANDLE dev_handle); -BOOL -umss_stop( -PUSB_DEV_MANAGER dev_mgr, -DEV_HANDLE dev_handle -); +NTSTATUS umss_dispatch_routine(PDEVICE_OBJECT pdev_obj, PIRP irp); -NTSTATUS -umss_dispatch_routine( -PDEVICE_OBJECT pdev_obj, -PIRP irp -); +VOID umss_set_cfg_completion(PURB purb, PVOID pcontext); -VOID -umss_set_cfg_completion( -PURB purb, -PVOID pcontext -); +VOID umss_start_create_device(IN PVOID Parameter); -VOID -umss_start_create_device( -IN PVOID Parameter -); +BOOL umss_delete_device(PUSB_DEV_MANAGER dev_mgr, PUSB_DRIVER pdrvr, PDEVICE_OBJECT dev_obj, BOOL is_if); -BOOL -umss_delete_device( -PUSB_DEV_MANAGER dev_mgr, -PUSB_DRIVER pdrvr, -PDEVICE_OBJECT dev_obj, -BOOL is_if -); +BOOL umss_stop(PUSB_DEV_MANAGER dev_mgr, DEV_HANDLE dev_handle); -BOOL -umss_stop( -PUSB_DEV_MANAGER dev_mgr, -DEV_HANDLE dev_handle -); +NTSTATUS umss_process_srb(PDEVICE_OBJECT dev_obj, PIRP irp); -NTSTATUS -umss_process_srb( -PDEVICE_OBJECT dev_obj, -PIRP irp ); +VOID umss_load_class_driver(PVOID context); -VOID -umss_load_class_driver( -PVOID context -); +BOOL umss_tsc_to_sff(PIO_PACKET io_packet); -BOOL -umss_tsc_to_sff( -PIO_PACKET io_packet -); - -VOID -umss_fix_sff_result( -PIO_PACKET io_packet, -SCSI_REQUEST_BLOCK *srb -); +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 -) +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 - UCHAR dev_name[ 64 ]; - STRING string; - NTSTATUS status; - PDEVICE_OBJECT pdev; - UNICODE_STRING name_string, symb_link; - PUMSS_PORT_DEV_EXT pdev_ext; + // 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 + UCHAR 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 ); + sprintf(dev_name, "\\Device\\usbPort_%d", (int)0); - RtlInitString( &string, dev_name ); - RtlAnsiStringToUnicodeString( &name_string, &string, TRUE ); - pdev = NULL; + 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); + 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; + 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->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 = (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; + 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 ); + 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 ); + RtlInitString(&string, dev_name); + RtlAnsiStringToUnicodeString(&symb_link, &string, TRUE); + IoCreateSymbolicLink(&symb_link, &name_string); + RtlFreeUnicodeString(&symb_link); - } + } - RtlFreeUnicodeString( &name_string ); - return pdev; + RtlFreeUnicodeString(&name_string); + return pdev; } BOOL -umss_delete_port_device( -PDEVICE_OBJECT dev_obj -) +umss_delete_port_device(PDEVICE_OBJECT dev_obj) { - UCHAR dev_name[ 64 ]; - STRING string; - UNICODE_STRING symb_link; + UCHAR dev_name[64]; + STRING string; + UNICODE_STRING symb_link; - if( dev_obj == NULL ) - return FALSE; + 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 ); + // 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; + 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; } -NTSTATUS -umss_port_dispatch_routine( -PDEVICE_OBJECT pdev_obj, -PIRP irp -) // 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. +// not resolved yet. // 2004-03-22 23:12:26 +NTSTATUS +umss_port_dispatch_routine(PDEVICE_OBJECT pdev_obj, PIRP irp) { - KIRQL irql; - ULONG ctrl_code; - NTSTATUS status; - PIO_STACK_LOCATION irp_stack; - PUMSS_PORT_DEV_EXT pdev_ext; - PUMSS_DRVR_EXTENSION pdrvr_ext; + KIRQL irql; + ULONG ctrl_code; + NTSTATUS status; + PIO_STACK_LOCATION irp_stack; + PUMSS_PORT_DEV_EXT pdev_ext; + PUMSS_DRVR_EXTENSION pdrvr_ext; - USE_IRQL; + USE_IRQL; - if( pdev_obj == NULL || irp == NULL ) - return STATUS_INVALID_PARAMETER; + if (pdev_obj == NULL || irp == NULL) + return STATUS_INVALID_PARAMETER; - status = STATUS_SUCCESS; - irp_stack = IoGetCurrentIrpStackLocation( irp ); - ctrl_code = irp_stack->Parameters.DeviceIoControl.IoControlCode; + status = STATUS_SUCCESS; + irp_stack = IoGetCurrentIrpStackLocation(irp); + ctrl_code = irp_stack->Parameters.DeviceIoControl.IoControlCode; - pdev_ext = ( PUMSS_PORT_DEV_EXT )pdev_obj->DeviceExtension; + 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 ); - } + 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 ); - } - } - } - case IRP_MJ_CREATE: - case IRP_MJ_CLOSE: - { - EXIT_DISPATCH( STATUS_SUCCESS, irp ); - } - } - EXIT_DISPATCH( STATUS_INVALID_DEVICE_REQUEST, 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); + } + } + } + case IRP_MJ_CREATE: + case IRP_MJ_CLOSE: + { + EXIT_DISPATCH(STATUS_SUCCESS, irp); + } + } + EXIT_DISPATCH(STATUS_INVALID_DEVICE_REQUEST, irp); } BOOL -umss_driver_init( -PUSB_DEV_MANAGER dev_mgr, -PUSB_DRIVER pdriver -) +umss_driver_init(PUSB_DEV_MANAGER dev_mgr, PUSB_DRIVER pdriver) { - PUMSS_DRVR_EXTENSION pdrvr_ext; - UNICODE_STRING unicode_string; - NTSTATUS status; + PUMSS_DRVR_EXTENSION pdrvr_ext; + UNICODE_STRING unicode_string; + NTSTATUS status; - if( dev_mgr == NULL || pdriver == NULL ) - return FALSE; + 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 + //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.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_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 ) ); - pdriver->driver_ext_size = sizeof( UMSS_DRVR_EXTENSION ); + pdriver->driver_ext = usb_alloc_mem(NonPagedPool, sizeof(UMSS_DRVR_EXTENSION)); + 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 ); + 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; + 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; - } + 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; + 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; } BOOL -umss_driver_destroy( -PUSB_DEV_MANAGER dev_mgr, -PUSB_DRIVER pdriver -) +umss_driver_destroy(PUSB_DEV_MANAGER dev_mgr, PUSB_DRIVER pdriver) { - PUMSS_DRVR_EXTENSION pdrvr_ext; - if( dev_mgr == NULL || pdriver == NULL ) - return FALSE; + 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; + 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; + 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, -BOOL is_if -) +umss_create_device(PUSB_DEV_MANAGER dev_mgr, PUSB_DRIVER umss_drvr, DEV_HANDLE dev_handle, BOOL is_if) { - UCHAR 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; + UCHAR 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; + 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 ); + 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; + 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); + 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; + 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->Flags &= ~DO_DEVICE_INITIALIZING; + pdev->StackSize = 2; //one for fdo, one for file device obj - pdev_ext = ( PUMSS_DEVICE_EXTENSION )pdev->DeviceExtension; + 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 ); + //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; + 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->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; + 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 ); + 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 ); + 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; + } + RtlFreeUnicodeString(&name_string); + return pdev; } BOOL -umss_connect( -PCONNECT_DATA param, -DEV_HANDLE dev_handle -) +umss_connect(PCONNECT_DATA param, DEV_HANDLE dev_handle) { - PURB purb; - NTSTATUS status; - PUSB_CTRL_SETUP_PACKET psetup; - PUSB_DEV_MANAGER dev_mgr; - PUSB_DRIVER pdrvr; + 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" ) ); + usb_dbg_print(DBGLVL_MAXIMUM, ("umss_connect(): entering...\n")); - dev_mgr = param->dev_mgr; - pdrvr = param->pdriver; + dev_mgr = param->dev_mgr; + pdrvr = param->pdriver; - //directly set the configuration - purb = usb_alloc_mem( NonPagedPool, sizeof( URB ) ); - if( purb == NULL ) - return FALSE; + //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 ) ); + 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; + 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; + 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 -) +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; + 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; + if (purb == NULL || pcontext == NULL) + return; - dev_mgr = ( PUSB_DEV_MANAGER ) pcontext; - pdrvr = ( PUSB_DRIVER )purb->reference; - dev_handle = purb->endp_handle & ~0xffff; + 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; - } + if (purb->status != STATUS_SUCCESS) + { + usb_free_mem(purb); + return; + } - buf = usb_alloc_mem( NonPagedPool, 512 ); - if( buf == NULL ) - { - 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; + //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; + 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; - } + 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 = 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 ] ); + 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 ); + ExInitializeWorkItem(pwork_item, umss_start_create_device, (PVOID) pcd); + ExQueueWorkItem(pwork_item, DelayedWorkQueue); } VOID -umss_start_create_device( -IN PVOID Parameter -) +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; + 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_IRQL; + USE_IRQL; - if( Parameter == NULL ) - return; + 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; + 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; - } + 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 ); + 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 ); + 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 ); + if (pdev_obj) + umss_delete_device(dev_mgr, pdrvr, pdev_obj, FALSE); - usb_unlock_dev( pdev ); - return; - } - unlock_dev( pdev, FALSE ); + usb_unlock_dev(pdev); + return; + } + unlock_dev(pdev, FALSE); - pdev_ext = ( PUMSS_DEVICE_EXTENSION )pdev_obj->DeviceExtension; + 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; + 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; - } - } + 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; + 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; } BOOL -umss_stop( -PUSB_DEV_MANAGER dev_mgr, -DEV_HANDLE dev_handle -) +umss_stop(PUSB_DEV_MANAGER dev_mgr, DEV_HANDLE dev_handle) { - return TRUE; + return TRUE; } BOOL -umss_disconnect( -PUSB_DEV_MANAGER dev_mgr, -DEV_HANDLE dev_handle -) +umss_disconnect(PUSB_DEV_MANAGER dev_mgr, DEV_HANDLE dev_handle) { - PDEVICE_OBJECT dev_obj; - NTSTATUS status; - PUSB_DEV pdev; - PUSB_DRIVER pdrvr; + PDEVICE_OBJECT dev_obj; + NTSTATUS status; + PUSB_DEV pdev; + PUSB_DRIVER pdrvr; - if( dev_mgr == NULL || dev_handle == 0 ) - return FALSE; + 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; + 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 ); + return umss_delete_device(dev_mgr, pdrvr, dev_obj, FALSE); } VOID -umss_deferred_delete_device( -PVOID context -) +umss_deferred_delete_device(PVOID context) { - PDEVICE_OBJECT dev_obj; - PUMSS_DEVICE_EXTENSION pdev_ext; - PUMSS_DRVR_EXTENSION pdrvr_ext; - LARGE_INTEGER interval; + PDEVICE_OBJECT dev_obj; + PUMSS_DEVICE_EXTENSION pdev_ext; + PUMSS_DRVR_EXTENSION pdrvr_ext; + LARGE_INTEGER interval; - if( context == NULL ) - return; + if (context == NULL) + return; - dev_obj = ( PDEVICE_OBJECT )context; - pdev_ext = dev_obj->DeviceExtension; - pdrvr_ext = ( PUMSS_DRVR_EXTENSION )pdev_ext->pdriver->driver_ext; + 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 + 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 ) ); + 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 ); + 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; + IoDeleteDevice(dev_obj); + return; } BOOL -umss_delete_device( -PUSB_DEV_MANAGER dev_mgr, -PUSB_DRIVER pdrvr, -PDEVICE_OBJECT dev_obj, -BOOL is_if -) +umss_delete_device(PUSB_DEV_MANAGER dev_mgr, PUSB_DRIVER pdrvr, PDEVICE_OBJECT dev_obj, BOOL is_if) { - UCHAR dev_name[ 64 ]; - STRING string; - UNICODE_STRING symb_link; + UCHAR dev_name[64]; + STRING string; + UNICODE_STRING symb_link; - NTSTATUS status; - PUMSS_DEVICE_EXTENSION pdev_ext; - PUMSS_DRVR_EXTENSION pdrvr_ext; + NTSTATUS status; + PUMSS_DEVICE_EXTENSION pdev_ext; + PUMSS_DRVR_EXTENSION pdrvr_ext; - if( dev_obj == NULL ) - return FALSE; + if (dev_obj == NULL) + return FALSE; - if( pdrvr == NULL || dev_mgr == 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 ); + 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 ); + 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 (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 ); + 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; - } + 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; + // + // 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 -) +umss_submit_io_packet(PDEVICE_OBJECT dev_obj, PIO_PACKET io_packet) { - NTSTATUS status; - PUMSS_DEVICE_EXTENSION pdev_ext; - PUSB_DEV pdev; + NTSTATUS status; + PUMSS_DEVICE_EXTENSION pdev_ext; + PUSB_DEV pdev; - pdev_ext = dev_obj->DeviceExtension; + 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; - } + // 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; + 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 -umss_start_io( -IN PDEVICE_OBJECT dev_obj, -IN PIRP irp -) +umss_start_io(IN PDEVICE_OBJECT dev_obj, IN PIRP irp) { - KIRQL irql; - 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; + KIRQL irql; + 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; - USE_IRQL; + USE_IRQL; - if( dev_obj == NULL || irp == NULL ) - return; + 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; - } + status = STATUS_SUCCESS; - if( irp_stack->MajorFunction != IRP_MJ_DEVICE_CONTROL ) - { - UMSS_COMPLETE_START_IO( dev_obj, STATUS_INVALID_DEVICE_REQUEST, irp ); - } + irp_stack = IoGetCurrentIrpStackLocation(irp); + ctrl_code = irp_stack->Parameters.DeviceIoControl.IoControlCode; + pdev_ext = (PUMSS_DEVICE_EXTENSION) dev_obj->DeviceExtension; - switch( ctrl_code ) - { - case IOCTL_UMSS_SUBMIT_CDB_IN: - case IOCTL_UMSS_SUBMIT_CDB_OUT: - case IOCTL_UMSS_SUBMIT_CDB: - { - PUSB_DEV pdev; - - if( irp_stack->Parameters.DeviceIoControl.InputBufferLength < sizeof( USER_IO_PACKET ) ) - { - UMSS_COMPLETE_START_IO( dev_obj, STATUS_INVALID_PARAMETER, irp ); - } + if (irp_stack->MajorFunction == IRP_MJ_SCSI) + { + umss_process_srb(dev_obj, irp); + return; + } - user_io_packet = ( PUSER_IO_PACKET )irp->AssociatedIrp.SystemBuffer; + if (irp_stack->MajorFunction != IRP_MJ_DEVICE_CONTROL) + { + UMSS_COMPLETE_START_IO(dev_obj, STATUS_INVALID_DEVICE_REQUEST, irp); + } - 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 ); - } + switch (ctrl_code) + { + case IOCTL_UMSS_SUBMIT_CDB_IN: + case IOCTL_UMSS_SUBMIT_CDB_OUT: + case IOCTL_UMSS_SUBMIT_CDB: + { + PUSB_DEV pdev; - RtlZeroMemory( &io_packet, sizeof( io_packet ) ); - io_packet.cdb_length = user_io_packet->cdb_length; - io_packet.lun = user_io_packet->lun; + if (irp_stack->Parameters.DeviceIoControl.InputBufferLength < sizeof(USER_IO_PACKET)) + { + UMSS_COMPLETE_START_IO(dev_obj, STATUS_INVALID_PARAMETER, irp); + } - RtlCopyMemory( io_packet.cdb, user_io_packet->cdb, MAX_CDB_LENGTH ); + user_io_packet = (PUSER_IO_PACKET) irp->AssociatedIrp.SystemBuffer; - if( ctrl_code == IOCTL_UMSS_SUBMIT_CDB_IN ) - io_packet.flags |= USB_DIR_IN; + 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); + } - 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 ); + RtlZeroMemory(&io_packet, sizeof(io_packet)); + io_packet.cdb_length = user_io_packet->cdb_length; + io_packet.lun = user_io_packet->lun; - io_packet.data_buffer = MmGetSystemAddressForMdl( irp->MdlAddress ); - io_packet.data_length = irp_stack->Parameters.DeviceIoControl.OutputBufferLength; + RtlCopyMemory(io_packet.cdb, user_io_packet->cdb, MAX_CDB_LENGTH); - if( io_packet.data_length > MAX_BULK_TRANSFER_LENGTH ) - UMSS_COMPLETE_START_IO( dev_obj, STATUS_BUFFER_TOO_SMALL, irp ); + if (ctrl_code == IOCTL_UMSS_SUBMIT_CDB_IN) + io_packet.flags |= USB_DIR_IN; - //synchronize the buffer - if( io_packet.flags & USB_DIR_IN ) - KeFlushIoBuffers( irp->MdlAddress, TRUE, TRUE ); - else - KeFlushIoBuffers( irp->MdlAddress, FALSE, TRUE ); - } + 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.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; + io_packet.data_buffer = MmGetSystemAddressForMdl(irp->MdlAddress); + io_packet.data_length = irp_stack->Parameters.DeviceIoControl.OutputBufferLength; - if( pass_through->DataTransferLength && - pass_through->DataBufferOffset != sizeof( SCSI_PASS_THROUGH ) ) - UMSS_COMPLETE_START_IO( dev_obj, STATUS_INVALID_PARAMETER, irp ); + if (io_packet.data_length > MAX_BULK_TRANSFER_LENGTH) + UMSS_COMPLETE_START_IO(dev_obj, STATUS_BUFFER_TOO_SMALL, irp); - if( pass_through->SenseInfoLength && - ( pass_through->SenseInfoOffset != - pass_through->DataBufferOffset + pass_through->DataTransferLength ) ) - UMSS_COMPLETE_START_IO( dev_obj, STATUS_INVALID_PARAMETER, irp ); + //synchronize the buffer + if (io_packet.flags & USB_DIR_IN) + KeFlushIoBuffers(irp->MdlAddress, TRUE, TRUE); + else + KeFlushIoBuffers(irp->MdlAddress, FALSE, TRUE); + } - 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 ); + 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; - 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; + pass_through = irp->AssociatedIrp.SystemBuffer; - 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; - } + if (pass_through->DataTransferLength && + pass_through->DataBufferOffset != sizeof(SCSI_PASS_THROUGH)) + UMSS_COMPLETE_START_IO(dev_obj, STATUS_INVALID_PARAMETER, irp); - 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 ); + if (pass_through->SenseInfoLength && + (pass_through->SenseInfoOffset != + pass_through->DataBufferOffset + pass_through->DataTransferLength)) + UMSS_COMPLETE_START_IO(dev_obj, STATUS_INVALID_PARAMETER, irp); - RtlZeroMemory( &io_packet, sizeof( io_packet ) ); + 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); - io_packet.flags |= IOP_FLAG_SCSI_CTRL_TRANSFER; - if( pass_through_direct->DataIn ) - io_packet.flags |= IOP_FLAG_DIR_IN; + RtlZeroMemory(&io_packet, sizeof(io_packet)); - 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.flags |= IOP_FLAG_SCSI_CTRL_TRANSFER; + if (pass_through->DataIn) + io_packet.flags |= IOP_FLAG_DIR_IN; - 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; + 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; } -NTSTATUS -umss_dispatch_routine( -PDEVICE_OBJECT pdev_obj, -PIRP irp -) // 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. -{ - KIRQL irql; - ULONG ctrl_code; - NTSTATUS status; - PIO_STACK_LOCATION irp_stack; - PUMSS_DEVICE_EXTENSION pdev_ext; - - USE_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; - USE_IRQL; - - 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: - { - PUCHAR user_buffer; - ULONG user_buffer_length; - 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; -} - NTSTATUS -umss_reset_pipe( -PUMSS_DEVICE_EXTENSION pdev_ext, -DEV_HANDLE endp_handle -) +umss_dispatch_routine(PDEVICE_OBJECT pdev_obj, PIRP irp) +{ + KIRQL irql; + ULONG ctrl_code; + NTSTATUS status; + PIO_STACK_LOCATION irp_stack; + PUMSS_DEVICE_EXTENSION pdev_ext; + + USE_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; + USE_IRQL; + + 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: + { + PUCHAR user_buffer; + ULONG user_buffer_length; + 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; - PUSB_ENDPOINT pendp; + NTSTATUS status; + PUSB_DEV pdev; + PUSB_ENDPOINT pendp; - if( pdev_ext == NULL ) - return STATUS_INVALID_PARAMETER; + if (pdev_ext == NULL) + return STATUS_INVALID_PARAMETER; - status = usb_query_and_lock_dev( pdev_ext->dev_mgr, pdev_ext->dev_handle, &pdev ); + status = usb_query_and_lock_dev(pdev_ext->dev_mgr, pdev_ext->dev_handle, &pdev); - if( status != STATUS_SUCCESS ) - return STATUS_UNSUCCESSFUL; + if (status != STATUS_SUCCESS) + return STATUS_UNSUCCESSFUL; - status = usb_reset_pipe_ex( - pdev_ext->dev_mgr, - endp_handle, - umss_reset_pipe_completion, - pdev_ext ); + 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; + 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; } BOOL -umss_gen_result_srb( -PIO_PACKET io_packet, -PSCSI_REQUEST_BLOCK srb, -NTSTATUS status -) +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; + if (srb == NULL || io_packet == NULL) + { + return FALSE; + } + if (status == STATUS_SUCCESS) + { + PULONG dest_buf, src_buf; + ULONG i; - srb->SrbStatus = SRB_STATUS_SUCCESS; + 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; + 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 - // + // + // let's build the srb status for class driver + // - srb->SrbStatus |= SRB_STATUS_AUTOSENSE_VALID; - sense_buf = ( PSENSE_DATA )srb->SenseInfoBuffer; + 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; + 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; + 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; + 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; } BOOL -umss_gen_result_ctrl( -PDEVICE_OBJECT dev_obj, -PIRP irp, -NTSTATUS status -) +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; + 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; + if (irp == NULL) + return FALSE; - switch( ctrl_code ) - { - case IOCTL_SCSI_PASS_THROUGH: - { - PSCSI_PASS_THROUGH pass_through; - pass_through = irp->AssociatedIrp.SystemBuffer; - irp->IoStatus.Status = status; + irp->IoStatus.Information = 0; + irp_stack = IoGetCurrentIrpStackLocation(irp); + ctrl_code = irp_stack->Parameters.DeviceIoControl.IoControlCode; + pdev_ext = dev_obj->DeviceExtension; - // 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; + 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; + // 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; + 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; - return TRUE; - } - } - return FALSE; + 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 -) +umss_complete_request(PUMSS_DEVICE_EXTENSION pdev_ext, NTSTATUS status) { - PIRP pirp; - KIRQL old_irql; + PIRP pirp; + KIRQL old_irql; - PDEVICE_OBJECT dev_obj; - PIO_STACK_LOCATION irp_stack; + PDEVICE_OBJECT dev_obj; + PIO_STACK_LOCATION irp_stack; - usb_dbg_print( DBGLVL_MAXIMUM, ( "umss_complete_request(): entering...\n" ) ); + usb_dbg_print(DBGLVL_MAXIMUM, ("umss_complete_request(): entering...\n")); - pirp = pdev_ext->io_packet.pirp; - dev_obj = pdev_ext->pdo; + pirp = pdev_ext->io_packet.pirp; + dev_obj = pdev_ext->pdo; - irp_stack = IoGetCurrentIrpStackLocation ( pirp ); + 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 ); + 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 ) - { - 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 ); + //this device has its irp queued + if (status == STATUS_CANCELLED) + { + 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); - pirp->IoStatus.Status = status; + pirp->IoStatus.Status = status; - if( status != STATUS_SUCCESS ) - pirp->IoStatus.Information = 0; + if (status != STATUS_SUCCESS) + pirp->IoStatus.Information = 0; - IoCompleteRequest( pirp, IO_NO_INCREMENT ); - return; + IoCompleteRequest(pirp, IO_NO_INCREMENT); + return; } BOOL -umss_if_connect( -PCONNECT_DATA params, -DEV_HANDLE if_handle -) +umss_if_connect(PCONNECT_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; + 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_IRQL; - //configuration is already set - purb = NULL; - desc_buf = NULL; - pdev = NULL; + PDEVICE_OBJECT pdev_obj; + USE_IRQL; + //configuration is already set + purb = NULL; + desc_buf = NULL; + pdev = NULL; - usb_dbg_print( DBGLVL_MAXIMUM, ( "umss_if_connect(): entering...\n" ) ); + usb_dbg_print(DBGLVL_MAXIMUM, ("umss_if_connect(): entering...\n")); - if( params == NULL ) - return FALSE; + if (params == NULL) + return FALSE; - dev_mgr = params->dev_mgr; - pdrvr = params->pdriver; + dev_mgr = params->dev_mgr; + pdrvr = params->pdriver; - if_idx = if_idx_from_handle( if_handle ); + if_idx = if_idx_from_handle(if_handle); - purb = usb_alloc_mem( NonPagedPool, sizeof( URB ) ); - if( purb == NULL ) - goto ERROR_OUT; + 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; + 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 ) ); + 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; + // 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; + 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; - } + 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; - } + 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; - } + 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; - } + 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; - } + 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; + 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 ); + unlock_dev(pdev, FALSE); - pdev_ext = ( PUMSS_DEVICE_EXTENSION )pdev_obj->DeviceExtension; + 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 ] ); + 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; + 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; + //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; - } - } + 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 ); + // 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; + usb_unlock_dev(pdev); + return TRUE; ERROR_OUT: + if (desc_buf) + usb_free_mem(desc_buf); - if( desc_buf ) - usb_free_mem( desc_buf ); + if (purb) + usb_free_mem(purb); - if( purb ) - usb_free_mem( purb ); + usb_unlock_dev(pdev); - usb_unlock_dev( pdev ); + desc_buf = NULL; + purb = NULL; - desc_buf = NULL; - purb = NULL; - - return FALSE; + return FALSE; } BOOL -umss_if_disconnect( -PUSB_DEV_MANAGER dev_mgr, -DEV_HANDLE if_handle -) +umss_if_disconnect(PUSB_DEV_MANAGER dev_mgr, DEV_HANDLE if_handle) { - LONG if_idx; - NTSTATUS status; - PUSB_DEV pdev; - PUSB_DRIVER pdrvr; - PDEVICE_OBJECT dev_obj; - PUMSS_DRVR_EXTENSION pdrvr_ext; - PUMSS_DEVICE_EXTENSION pdev_ext; + LONG if_idx; + NTSTATUS status; + PUSB_DEV pdev; + PUSB_DRIVER pdrvr; + PDEVICE_OBJECT dev_obj; + PUMSS_DRVR_EXTENSION pdrvr_ext; + PUMSS_DEVICE_EXTENSION pdev_ext; - if( dev_mgr == NULL || if_handle == 0 ) - return FALSE; + 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; + 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 ); + // 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 ); + // no need to unlock the dev + return umss_delete_device(dev_mgr, pdrvr, dev_obj, TRUE); } BOOL -umss_if_stop( -PUSB_DEV_MANAGER dev_mgr, -DEV_HANDLE if_handle -) +umss_if_stop(PUSB_DEV_MANAGER dev_mgr, DEV_HANDLE if_handle) { - LONG if_idx; - NTSTATUS status; - PUSB_DEV pdev; - PUSB_DRIVER pdrvr; - PDEVICE_OBJECT dev_obj; - PUMSS_DRVR_EXTENSION pdrvr_ext; - PUMSS_DEVICE_EXTENSION pdev_ext; + LONG if_idx; + NTSTATUS status; + PUSB_DEV pdev; + PUSB_DRIVER pdrvr; + PDEVICE_OBJECT dev_obj; + PUMSS_DRVR_EXTENSION pdrvr_ext; + PUMSS_DEVICE_EXTENSION pdev_ext; - USE_IRQL; + USE_IRQL; - if( dev_mgr == NULL || if_handle == 0 ) - return FALSE; + if (dev_mgr == NULL || if_handle == 0) + return FALSE; - pdev = NULL; - if_idx = if_idx_from_handle( if_handle ); + 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; - } + // 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; - } + 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 ); + 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 ); + // 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; + usb_unlock_dev(pdev); + return TRUE; } VOID -umss_load_class_driver( -PVOID context -) +umss_load_class_driver(PVOID context) { - NTSTATUS status; - UNICODE_STRING unicode_string; - - // - // 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 ) ); + NTSTATUS status; + UNICODE_STRING unicode_string; + + // + // 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)); } + BOOL -umss_if_driver_init( -PUSB_DEV_MANAGER dev_mgr, -PUSB_DRIVER pdriver -) +umss_if_driver_init(PUSB_DEV_MANAGER dev_mgr, PUSB_DRIVER pdriver) { - PUMSS_DRVR_EXTENSION pdrvr_ext; - UNICODE_STRING unicode_string; - NTSTATUS status; + PUMSS_DRVR_EXTENSION pdrvr_ext; + UNICODE_STRING unicode_string; + NTSTATUS status; - if( dev_mgr == NULL || pdriver == NULL ) - return FALSE; + if (dev_mgr == NULL || pdriver == NULL) + return FALSE; - //init driver structure, no PNP table functions + //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.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.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_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 ) ); - pdriver->driver_ext_size = sizeof( UMSS_DRVR_EXTENSION ); + pdriver->driver_ext = usb_alloc_mem(NonPagedPool, sizeof(UMSS_DRVR_EXTENSION)); + pdriver->driver_ext_size = sizeof(UMSS_DRVR_EXTENSION); - RtlZeroMemory( pdriver->driver_ext, 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 ); + 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; + 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 - // + 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 ); + // + // 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" ) ); + // 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; + return TRUE; } -PCLASS_DRV_REG_INFO -umss_get_if_driver_info( -PUSB_DEV_MANAGER dev_mgr, -PUSB_DEV pdev, -DEV_HANDLE if_handle -) // 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_IRQL; + PUMSS_DRVR_EXTENSION drvr_ext; + ULONG if_idx; + USE_IRQL; - if_idx = if_idx_from_handle( if_handle ); - if( if_idx >= 4 ) // max interfaces per config supports. defined in td.h - return NULL; + 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 ); + 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; - } + 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; + 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(); + 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 ); + unlock_dev(pdev, FALSE); - if( drvr_ext == NULL ) - { - return NULL; - } + if (drvr_ext == NULL) + { + return NULL; + } - return &drvr_ext->class_driver_info; + return &drvr_ext->class_driver_info; } VOID -umss_worker( -IN PVOID reference -) +umss_worker(IN PVOID reference) { PUMSS_WORKER_PACKET worker_packet; - PUSB_DEV pdev; + 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" ) ); + 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")); } -BOOL -umss_schedule_workitem( -PVOID context, -UMSS_WORKER_ROUTINE completion, -PUSB_DEV_MANAGER dev_mgr, -DEV_HANDLE dev_handle -) /*++ 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. + 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: +Arguments: Routine - Routine to be called when this work-item is processed Context - Value to be passed to worker routine @@ -2151,302 +1970,289 @@ Return Value: FALSE if work item not queued --*/ - +BOOL +umss_schedule_workitem(PVOID context, + UMSS_WORKER_ROUTINE completion, PUSB_DEV_MANAGER dev_mgr, DEV_HANDLE dev_handle) { BOOL 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 ) ); - RtlZeroMemory( worker_packet, sizeof( WORK_QUEUE_ITEM ) + sizeof( UMSS_WORKER_PACKET ) ); + worker_packet = usb_alloc_mem(NonPagedPool, sizeof(WORK_QUEUE_ITEM) + sizeof(UMSS_WORKER_PACKET)); + RtlZeroMemory(worker_packet, sizeof(WORK_QUEUE_ITEM) + sizeof(UMSS_WORKER_PACKET)); - if ( worker_packet ) + if (worker_packet) { - workitem = ( PWORK_QUEUE_ITEM )&worker_packet[ 1 ]; - worker_packet->completion = completion; + 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; - } - } + 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 - ); + ExInitializeWorkItem(workitem, umss_worker, worker_packet); // Schedule the work-item - ExQueueWorkItem( - workitem, - DelayedWorkQueue - ); + ExQueueWorkItem(workitem, DelayedWorkQueue); - usb_dbg_print( DBGLVL_MINIMUM,( "umss_schedule_workitem(): work-item queued\n" ) ); + 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")); + usb_dbg_print(DBGLVL_MINIMUM, ("umss_schedule_workitem(): Failed to allocate work-item\n")); ret_val = FALSE; } - return ret_val; + return ret_val; } NTSTATUS -umss_process_srb( -PDEVICE_OBJECT dev_obj, -PIRP irp -) +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; + 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; + if (dev_obj == NULL || irp == NULL) + return STATUS_INVALID_PARAMETER; - pdev = NULL; - cur_stack = IoGetCurrentIrpStackLocation( irp ); - srb = cur_stack->Parameters.Scsi.Srb; + 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; - } + if (srb == NULL || srb->DataTransferLength > 65536) + { + status = STATUS_INVALID_PARAMETER; + goto ERROR_OUT; + } - irp->IoStatus.Status = STATUS_SUCCESS; - irp->IoStatus.Information = 0; + 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; + 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 - // + // + // 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; + } - 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)); - 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.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; - 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; - 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; + 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; + 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; + io_packet.data_length = srb->DataTransferLength; + } - // 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; + if (io_packet.flags & IOP_FLAG_REQ_SENSE) + { + io_packet.sense_data = srb->SenseInfoBuffer; + io_packet.sense_data_length = srb->SenseInfoBufferLength; + } - usb_dbg_print( DBGLVL_MAXIMUM, ( "umss_process_srb(): error converting to sff proto, 0x%x\n", - status ) ); - srb->SrbStatus = SRB_STATUS_ERROR; - break; - } - } + io_packet.pirp = irp; - 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; - } + // 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; - 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(): error converting to sff proto, 0x%x\n", status)); + srb->SrbStatus = SRB_STATUS_ERROR; + break; + } + } - usb_dbg_print( DBGLVL_MAXIMUM, ( "umss_process_srb(): current srb->Function=0x%x\n", - srb->Function ) ); + 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; + } - status = STATUS_SUCCESS; - srb->SrbStatus = SRB_STATUS_SUCCESS; - break; - } - } + 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_unlock_dev( pdev ); - pdev = NULL; + 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; + 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; } BOOL -umss_tsc_to_sff( -PIO_PACKET io_packet -) +umss_tsc_to_sff(PIO_PACKET io_packet) { - if( io_packet == NULL ) - return FALSE; + 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->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; + 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; + return TRUE; } + VOID -umss_fix_sff_result( -PIO_PACKET io_packet, -SCSI_REQUEST_BLOCK *srb ) +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; + 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/usbdriver/usb.c b/reactos/drivers/usb/nt4compat/usbdriver/usb.c index 21b450d865b..9f0087664c1 100644 --- a/reactos/drivers/usb/nt4compat/usbdriver/usb.c +++ b/reactos/drivers/usb/nt4compat/usbdriver/usb.c @@ -24,1500 +24,1392 @@ #include "hub.h" #include "debug.h" -LONG g_alloc_cnt = 0; -ULONG cpu_clock_freq = 0; +LONG g_alloc_cnt = 0; +ULONG cpu_clock_freq = 0; -NTSTATUS -usb_get_descriptor( -PUSB_DEV pdev, -PURB purb -); +NTSTATUS usb_get_descriptor(PUSB_DEV pdev, PURB purb); -VOID -usb_set_interface_completion( -PURB purb, -PVOID context -); +VOID usb_set_interface_completion(PURB purb, PVOID context); -NTSTATUS -usb_set_interface( -PURB purb -); +NTSTATUS usb_set_interface(PURB purb); PVOID -usb_alloc_mem( -POOL_TYPE pool_type, -LONG size -) +usb_alloc_mem(POOL_TYPE pool_type, LONG size) { - PVOID ret; - g_alloc_cnt++; - ret = ExAllocatePool( pool_type, size ); - usb_dbg_print( DBGLVL_MAXIMUM, ( "usb_alloc_mem(): alloced=0x%x\n", g_alloc_cnt ) ); - return ret; + PVOID ret; + g_alloc_cnt++; + ret = ExAllocatePool(pool_type, size); + usb_dbg_print(DBGLVL_MAXIMUM, ("usb_alloc_mem(): alloced=0x%x\n", g_alloc_cnt)); + return ret; } VOID -usb_free_mem( -PVOID pbuf -) +usb_free_mem(PVOID pbuf) { - g_alloc_cnt--; - usb_dbg_print( DBGLVL_MAXIMUM, ( "usb_free_mem(): alloced=0x%x\n", g_alloc_cnt ) ); - ExFreePool( pbuf); + g_alloc_cnt--; + usb_dbg_print(DBGLVL_MAXIMUM, ("usb_free_mem(): alloced=0x%x\n", g_alloc_cnt)); + ExFreePool(pbuf); } -VOID -usb_config_dev_completion( -PURB purb, -PVOID context -); +VOID usb_config_dev_completion(PURB purb, PVOID context); -LONG -usb_calc_bus_time( -LONG speed, -LONG input_dir, -LONG is_iso, -LONG byte_count -) //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; + 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 */ + 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: */ + /* 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; + 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; } -NTSTATUS -usb_query_and_lock_dev( -PUSB_DEV_MANAGER dev_mgr, -DEV_HANDLE dev_handle, -PUSB_DEV* ppdev -) // // 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; - BOOL valid_dev; + int i; + PLIST_ENTRY pthis, pnext; + PUSB_DEV pdev; + BOOL valid_dev; - USE_NON_PENDING_IRQL; + USE_NON_PENDING_IRQL; - *ppdev = NULL; + *ppdev = NULL; - if( dev_mgr == NULL || dev_handle == 0 ) - return STATUS_INVALID_PARAMETER; + if (dev_mgr == NULL || dev_handle == 0) + return STATUS_INVALID_PARAMETER; - i = dev_id_from_handle( dev_handle ); + i = dev_id_from_handle(dev_handle); - KeAcquireSpinLock( &dev_mgr->dev_list_lock, &old_irql ); - ListFirst( &dev_mgr->dev_list, pthis ); + 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; - } + 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; + valid_dev = TRUE; - lock_dev( pdev, 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 + 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 ); + unlock_dev(pdev, TRUE); - KeReleaseSpinLock( &dev_mgr->dev_list_lock, old_irql ); + KeReleaseSpinLock(&dev_mgr->dev_list_lock, old_irql); - *ppdev = pdev; + *ppdev = pdev; - if( !valid_dev ) - return STATUS_DEVICE_DOES_NOT_EXIST; + if (!valid_dev) + return STATUS_DEVICE_DOES_NOT_EXIST; - return STATUS_SUCCESS; + return STATUS_SUCCESS; } NTSTATUS -usb_unlock_dev( -PUSB_DEV dev -) +usb_unlock_dev(PUSB_DEV dev) { - USE_BASIC_NON_PENDING_IRQL; + USE_BASIC_NON_PENDING_IRQL; - if( dev == NULL ) - return STATUS_INVALID_PARAMETER; + 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; + 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 -) +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; + 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; + 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; + 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; - } + 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_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 (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; - } + 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; + 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 ); + unlock_dev(pdev, FALSE); + usb_unlock_dev(pdev); - return status; + return status; } -NTSTATUS -usb_reset_pipe( -PUSB_DEV pdev, -PUSB_ENDPOINT pendp, -PURBCOMPLETION client_reset_pipe_completion, -PVOID param -) // 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; + PHCD hcd; + PURB purb; + BYTE endp_addr; + NTSTATUS status; + DEV_HANDLE dev_handle; - USE_BASIC_NON_PENDING_IRQL; + USE_BASIC_NON_PENDING_IRQL; - if( pdev == NULL || pendp == NULL ) - return STATUS_INVALID_PARAMETER; + 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; - } + 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 ); + 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 ) ); + purb = (PURB) usb_alloc_mem(NonPagedPool, sizeof(URB) + sizeof(PIRP)); - if( purb == NULL ) - return STATUS_NO_MEMORY; + if (purb == NULL) + return STATUS_NO_MEMORY; - UsbBuildResetPipeRequest( purb, - dev_handle, - endp_addr, - usb_reset_pipe_completion, - pendp, - ( LONG )client_reset_pipe_completion ); + UsbBuildResetPipeRequest(purb, + dev_handle, + endp_addr, + usb_reset_pipe_completion, + pendp, + (LONG)client_reset_pipe_completion); - *( ( PULONG )&purb[ 1 ] ) = ( ULONG )param; + *((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; + 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 -) +usb_reset_pipe_completion(PURB purb, PVOID context) { - PUSB_DEV pdev; - PUSB_ENDPOINT pendp; + PUSB_DEV pdev; + PUSB_ENDPOINT pendp; - USE_BASIC_NON_PENDING_IRQL; + USE_BASIC_NON_PENDING_IRQL; - if( purb == NULL || context == NULL ) - return; + if (purb == NULL || context == NULL) + return; - pdev = purb->pdev; - pendp = ( PUSB_ENDPOINT )context; + pdev = purb->pdev; + pendp = (PUSB_ENDPOINT) context; - lock_dev( pdev, TRUE ); - if( dev_state( pdev ) == USB_DEV_STATE_ZOMB ) - { - goto LBL_OUT; - } + 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; + 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; - } + //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 ); + unlock_dev(pdev, TRUE); - if( purb->reference ) - ( ( PURBCOMPLETION )purb->reference )( purb, ( PVOID )( *( ( PULONG )&purb[ 1 ] ) ) ); + if (purb->reference) + ((PURBCOMPLETION) purb->reference) (purb, (PVOID) (*((PULONG) & purb[1]))); - usb_free_mem( purb ); - purb = NULL; - return; + usb_free_mem(purb); + purb = NULL; + return; } void -usb_reset_pipe_from_dispatch_completion( -PURB purb, -PVOID param -) +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; - 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; + 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 BOOL -is_header_match( -PBYTE pbuf, -ULONG type -) //used to check descriptor validity -{ - BOOL 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; -} - -BOOL -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; -} - -BOOL -usb_skip_if_desc( -PBYTE* pBUF -) +is_header_match(PBYTE pbuf, ULONG type) { BOOL 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; + 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; } BOOL -usb_skip_if_and_altif( -PUCHAR* pdesc_BUF -) +usb_skip_endp_desc(PBYTE * pbUF, LONG n) { - BOOL 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; + if (is_header_match(*pbUF, USB_DT_ENDPOINT)) + { + (*pbUF) += sizeof(USB_ENDPOINT_DESC) * n; + return TRUE; + } + return FALSE; } + BOOL -usb_skip_one_config( -PUCHAR* pconfig_desc_BUF -) +usb_skip_if_desc(PBYTE * pBUF) { - LONG if_count, i; - BOOL ret; - PUSB_CONFIGURATION_DESC pcfg_DESC = ( PUSB_CONFIGURATION_DESC )*pconfig_desc_BUF; - PUSB_INTERFACE_DESC pif_desc2 = ( PUSB_INTERFACE_DESC )&pcfg_DESC[ 1 ]; + BOOL 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; +} - ret = is_header_match( ( PUCHAR )pcfg_DESC, USB_DT_CONFIG ); - if( ret ) - *pconfig_desc_BUF = &( ( BYTE* )pcfg_DESC )[ pcfg_DESC->wTotalLength ]; - return ret; +BOOL +usb_skip_if_and_altif(PUCHAR * pdesc_BUF) +{ + BOOL 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; - ret = is_header_match( ( PUCHAR )pcfg_DESC, USB_DT_CONFIG ) - && is_header_match( ( PUCHAR ) pif_desc2, USB_DT_INTERFACE ); + while (ret && pif_desc1->bAlternateSetting != 0) + ret = usb_skip_if_desc((PUCHAR *) & pif_desc1); + } + if (ret) + *pdesc_BUF = (PUCHAR) pif_desc1; - 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; + return ret; +} + +BOOL +usb_skip_one_config(PUCHAR *pconfig_desc_BUF) +{ + LONG if_count, i; + BOOL 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 -) +usb_find_config_desc_by_idx(PUCHAR pbuf, LONG idx, LONG cfg_count) { - LONG i; - BOOL ret; - PUSB_CONFIGURATION_DESC pcfg_desc = ( PUSB_CONFIGURATION_DESC )pbuf; - if( pcfg_desc == NULL ) - return NULL; + LONG i; + BOOL 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 (cfg_count > MAX_CONFIGS_PER_DEV) + return NULL; - if( idx > cfg_count ) - return NULL; + if (idx > cfg_count) + return NULL; - if( idx == 0 ) - return pcfg_desc; + 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; + 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 -) +usb_find_config_desc_by_val(PBYTE pbuf, LONG val, LONG cfg_count) { - LONG i; - BOOL ret; - PUSB_CONFIGURATION_DESC pcfg_desc = ( PUSB_CONFIGURATION_DESC )pbuf; - if( pcfg_desc == NULL ) - return NULL; + LONG i; + BOOL 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 (cfg_count > MAX_CONFIGS_PER_DEV) + return NULL; - for( i = 0; i < cfg_count; i++ ) - { - if( pcfg_desc->bConfigurationValue == val ) - return pcfg_desc; + 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; - } + ret = usb_skip_one_config((PBYTE *) & pcfg_desc); + if (ret == FALSE) + return NULL; + } - return NULL; + return NULL; } #define if_from_handle( handle ) ( ( handle & 0xff00 ) >> 8 ) NTSTATUS -usb_submit_config_urb( -PURB purb -) +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; + 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; + USE_BASIC_NON_PENDING_IRQL; - if( purb == NULL ) - return STATUS_INVALID_PARAMETER; + if (purb == NULL) + return STATUS_INVALID_PARAMETER; - pdev = purb->pdev; - pendp = purb->pendp; + pdev = purb->pdev; + pendp = purb->pendp; - lock_dev( pdev, FALSE ); + lock_dev(pdev, FALSE); - dev_mgr = dev_mgr_from_dev( pdev ); - hcd = pdev->hcd; + 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_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; - } + 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; + 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 + && 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; - } + 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; - } + 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; + 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; + //change the dev state + pdev->flags &= ~USB_DEV_STATE_MASK; + pdev->flags |= USB_DEV_STATE_FIRST_CONFIG; - unlock_dev( pdev, FALSE ); + 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; + 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; + LBL_OUT: + unlock_dev(pdev, FALSE); + return status; } NTSTATUS -usb_submit_urb( -PUSB_DEV_MANAGER dev_mgr, -PURB purb -) +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; + 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; + PHCD hcd; + USE_BASIC_NON_PENDING_IRQL; - if( purb == NULL || dev_mgr == NULL) - return STATUS_INVALID_PARAMETER; + if (purb == NULL || dev_mgr == NULL) + return STATUS_INVALID_PARAMETER; - endp_handle = purb->endp_handle; + endp_handle = purb->endp_handle; - if( endp_handle == 0 ) - return STATUS_INVALID_PARAMETER; + 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; - } + 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 ); + 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; - } + 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; - } + 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; + 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 ]; + 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; + 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; + //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; - BOOL found; - endp_addr = psetup->wIndex; - if( ( endp_addr & 0xf ) == 0 ) - { - unlock_dev( pdev, FALSE ); - status = STATUS_INVALID_PARAMETER; - 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; + BOOL 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 ); + // 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; - } - } + goto LBL_OUT; + } + } - unlock_dev( pdev, FALSE ); - status = hcd->hcd_submit_urb( hcd, pdev, purb->pendp, purb ); + unlock_dev(pdev, FALSE); + status = hcd->hcd_submit_urb(hcd, pdev, purb->pendp, purb); - LBL_OUT: - usb_unlock_dev( pdev ); - return status; +LBL_OUT: + usb_unlock_dev(pdev); + return status; } void -usb_config_dev_completion( -PURB purb, -PVOID context -) +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; + PURB puser_urb; + PUSB_DEV pdev; + PUSB_ENDPOINT pendp; + PUSB_CTRL_SETUP_PACKET psetup; + ULONG config_val; + NTSTATUS status; - USE_BASIC_NON_PENDING_IRQL; + USE_BASIC_NON_PENDING_IRQL; - if( purb == NULL ) - { - return; - } - pdev = purb->pdev; - pendp = purb->pendp; + if (purb == NULL) + { + return; + } + pdev = purb->pdev; + pendp = purb->pendp; - if( pdev == NULL ) - return; + if (pdev == NULL) + return; - if( purb->reference != 0 ) - puser_urb = ( PURB ) purb->reference; - else - puser_urb = NULL; + if (purb->reference != 0) + puser_urb = (PURB) purb->reference; + else + puser_urb = NULL; - lock_dev( pdev, TRUE ); + lock_dev(pdev, TRUE); - if( puser_urb ) - puser_urb->status = purb->status; + 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 (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; + 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 ); + } + 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; + } - return; +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 -) +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; + PUSB_CTRL_SETUP_PACKET psetup; + LONG idx, size, count, i; + PBYTE buf; + PUSB_CONFIGURATION_DESC pcfg_desc1; - USE_BASIC_NON_PENDING_IRQL; + USE_BASIC_NON_PENDING_IRQL; - if( pdev == NULL || purb == NULL ) - return STATUS_INVALID_PARAMETER; + if (pdev == NULL || purb == NULL) + return STATUS_INVALID_PARAMETER; - if( purb->data_buffer == NULL || purb->data_length == 0 ) - { - return purb->status = 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; - } + 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 ); + if ((psetup->wValue >> 8) == USB_DT_CONFIG) + { + idx = (psetup->wValue & 0xff); - count = pdev->pusb_dev_desc->bNumConfigurations; + 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; - } + 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; + 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; + } + 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; + } - 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; + unlock_dev(pdev, FALSE); + return purb->status; } -LONG usb_count_list( PLIST_HEAD list_head ) +LONG +usb_count_list(PLIST_HEAD list_head) { - LONG count; - PLIST_ENTRY pthis, pnext; + LONG count; + PLIST_ENTRY pthis, pnext; - if( list_head == NULL ) - return 0; + if (list_head == NULL) + return 0; - count = 0; - ListFirst( list_head, pthis ); + count = 0; + ListFirst(list_head, pthis); - while( pthis ) - { - ListNext( list_head, pthis, pnext ); - pthis = pnext; - count ++; - } - return count; + while (pthis) + { + ListNext(list_head, pthis, pnext); + pthis = pnext; + count++; + } + return count; } // checks if processor supports Time Stamp Counter __inline BOOL -usb_query_clicks( -PLARGE_INTEGER clicks -) +usb_query_clicks(PLARGE_INTEGER clicks) { - BOOL ret_val; - //so we have to use intel's cpu??? - ret_val = FALSE; + BOOL ret_val; + //so we have to use intel's cpu??? + ret_val = FALSE; #ifdef _MSC_VER - __asm - { - push ebx; - push eax; - mov eax, 1; //read version - cpuid; - test edx, 0x10; //timer stamp - jz LBL_OUT; - // cpuid //serialization - rdtsc; - mov ebx, dword ptr [ clicks ]; - mov dword ptr [ ebx ], eax; - mov dword ptr [ ebx + 4 ], edx; - mov dword ptr [ ret_val ], TRUE; + __asm + { + push ebx; + push eax; + mov eax, 1; //read version + cpuid; + test edx, 0x10; //timer stamp + jz LBL_OUT; + // cpuid //serialization + rdtsc; + mov ebx, dword ptr[clicks]; + mov dword ptr[ebx], eax; + mov dword ptr[ebx + 4], edx; + mov dword ptr[ret_val], TRUE; LBL_OUT: - pop eax; - pop ebx; - } + pop eax; + pop ebx; + } #else - ret_val = FALSE; + ret_val = FALSE; #endif - return ret_val; + return ret_val; } VOID -usb_wait_ms_dpc( -ULONG ms -) +usb_wait_ms_dpc(ULONG ms) { - LARGE_INTEGER start; - LARGE_INTEGER ticker; - LARGE_INTEGER freq; - ULONG interval; - ULONG expire_count; + LARGE_INTEGER start; + LARGE_INTEGER ticker; + LARGE_INTEGER freq; + ULONG interval; + ULONG expire_count; - KeQueryPerformanceCounter( &freq ); + KeQueryPerformanceCounter(&freq); - expire_count = 2000000; - if( cpu_clock_freq ) - expire_count = ( cpu_clock_freq / 1000 ) * ms; + expire_count = 2000000; + if (cpu_clock_freq) + expire_count = (cpu_clock_freq / 1000) * ms; - if( usb_query_clicks( &start ) == FALSE ) - { - ticker.QuadPart = 0; - while( TRUE ) - { - KeQuerySystemTime( &ticker ); - interval = ticker.LowPart - start.LowPart; - if( interval >= ms * 10000 ) - break; - } - } - else - { - ticker.QuadPart = 0; - while( TRUE ) - { - usb_query_clicks( &ticker ); - interval = ticker.LowPart - start.LowPart; - if( interval >= expire_count ) - break; - } - } + if (usb_query_clicks(&start) == FALSE) + { + ticker.QuadPart = 0; + while (TRUE) + { + KeQuerySystemTime(&ticker); + interval = ticker.LowPart - start.LowPart; + if (interval >= ms * 10000) + break; + } + } + else + { + ticker.QuadPart = 0; + while (TRUE) + { + usb_query_clicks(&ticker); + interval = ticker.LowPart - start.LowPart; + if (interval >= expire_count) + break; + } + } } VOID -usb_wait_us_dpc( -ULONG us -) +usb_wait_us_dpc(ULONG us) { - LARGE_INTEGER start; - LARGE_INTEGER ticker; - LARGE_INTEGER freq; - ULONG interval; - ULONG expire_count; + LARGE_INTEGER start; + LARGE_INTEGER ticker; + LARGE_INTEGER freq; + ULONG interval; + ULONG expire_count; - KeQueryPerformanceCounter( &freq ); + KeQueryPerformanceCounter(&freq); - expire_count = 2000000; - if( cpu_clock_freq ) - expire_count = ( cpu_clock_freq / 1000000 ) * us; + expire_count = 2000000; + if (cpu_clock_freq) + expire_count = (cpu_clock_freq / 1000000) * us; - if( usb_query_clicks( &start ) == FALSE ) - { - ticker.QuadPart = 0; - while( TRUE ) - { - KeQuerySystemTime( &ticker ); - interval = ticker.LowPart - start.LowPart; - if( interval >= us * 10 ) - break; - } - } - else - { - ticker.QuadPart = 0; - while( TRUE ) - { - usb_query_clicks( &ticker ); - interval = ticker.LowPart - start.LowPart; - if( interval >= expire_count ) - break; - } - } + if (usb_query_clicks(&start) == FALSE) + { + ticker.QuadPart = 0; + while (TRUE) + { + KeQuerySystemTime(&ticker); + interval = ticker.LowPart - start.LowPart; + if (interval >= us * 10) + break; + } + } + else + { + ticker.QuadPart = 0; + while (TRUE) + { + usb_query_clicks(&ticker); + interval = ticker.LowPart - start.LowPart; + if (interval >= expire_count) + break; + } + } } VOID usb_cal_cpu_freq() { - LARGE_INTEGER tick1, tick2; - LONG i; - // interval.QuadPart = -40 * 1000 * 1000; + LARGE_INTEGER tick1, tick2; + LONG i; + // interval.QuadPart = -40 * 1000 * 1000; - if( cpu_clock_freq >= 100 * 1000 * 1000 ) // assume it is valid - return; + 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 ) ); - } + 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 -) +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; + 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; + PHCD hcd; + USE_BASIC_NON_PENDING_IRQL; - purb1 = purb; - pdev = purb->pdev; - psetup = ( PUSB_CTRL_SETUP_PACKET )purb->setup_packet; + 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; - } + 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; + 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 (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; + 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 ) ); + 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; + // 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++; - } + 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; + 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; + if (hcd == NULL) + return STATUS_INVALID_PARAMETER; - status = hcd->hcd_submit_urb( hcd, purb->pdev, purb->pendp, purb ); - return status; + 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 );\ + 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 -) +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; + 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; + USE_BASIC_NON_PENDING_IRQL; - if( purb == NULL ) - return; + 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 ) ); + 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; + 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 ); + } while (pthis); - if( palt_if != NULL ) - { - RtlCopyMemory( &temp_if, palt_if, sizeof( USB_INTERFACE ) ); + 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; - } + 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 ); - } + 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 ); + // for recursive reason, we have to store the parameter ahead + usb_complete_and_free_ctrl_urb(purb); } -VOID -usb_call_ctrl_completion( -PURB 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; + PURB parent_urb; + PCTRL_REQ_STACK pstack; + ULONG i; - if( purb == NULL ) - return; + 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; + 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; } -