mirror of
https://github.com/reactos/reactos.git
synced 2025-08-02 15:16:35 +00:00
[FORMATTING]
svn path=/trunk/; revision=23616
This commit is contained in:
parent
4e7aa7365f
commit
f448f3bae0
12 changed files with 18078 additions and 20290 deletions
File diff suppressed because it is too large
Load diff
|
@ -23,96 +23,62 @@
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include "umss.h"
|
#include "umss.h"
|
||||||
|
|
||||||
VOID
|
VOID umss_cbi_send_adsc_complete(PURB purb, PVOID context);
|
||||||
umss_cbi_send_adsc_complete(
|
|
||||||
PURB purb,
|
|
||||||
PVOID context
|
|
||||||
);
|
|
||||||
|
|
||||||
VOID
|
VOID umss_cbi_transfer_data(PUMSS_DEVICE_EXTENSION pdev_ext);
|
||||||
umss_cbi_transfer_data(
|
|
||||||
PUMSS_DEVICE_EXTENSION pdev_ext
|
|
||||||
);
|
|
||||||
|
|
||||||
VOID
|
VOID umss_cbi_get_status(PUMSS_DEVICE_EXTENSION pdev_ext);
|
||||||
umss_cbi_get_status(
|
|
||||||
PUMSS_DEVICE_EXTENSION pdev_ext
|
|
||||||
);
|
|
||||||
|
|
||||||
VOID
|
VOID umss_cbi_transfer_data_complete(PURB purb, PVOID context);
|
||||||
umss_cbi_transfer_data_complete(
|
|
||||||
PURB purb,
|
|
||||||
PVOID context
|
|
||||||
);
|
|
||||||
|
|
||||||
VOID
|
VOID umss_cbi_get_status_complete(PURB purb, PVOID context);
|
||||||
umss_cbi_get_status_complete(
|
|
||||||
PURB purb,
|
|
||||||
PVOID context
|
|
||||||
);
|
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
umss_class_specific_request(
|
umss_class_specific_request(IN PUMSS_DEVICE_EXTENSION pdev_ext,
|
||||||
IN PUMSS_DEVICE_EXTENSION pdev_ext,
|
IN UCHAR request,
|
||||||
IN UCHAR request,
|
IN UCHAR dir,
|
||||||
IN UCHAR dir,
|
IN PVOID buffer,
|
||||||
IN PVOID buffer,
|
IN ULONG buffer_length,
|
||||||
IN ULONG buffer_length,
|
IN PURBCOMPLETION completion)
|
||||||
IN PURBCOMPLETION completion
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
PURB purb;
|
PURB purb;
|
||||||
NTSTATUS status;
|
NTSTATUS status;
|
||||||
|
|
||||||
purb = usb_alloc_mem( NonPagedPool, sizeof( URB ) );
|
purb = usb_alloc_mem(NonPagedPool, sizeof(URB));
|
||||||
// Build URB for the ADSC command
|
// Build URB for the ADSC command
|
||||||
UsbBuildVendorRequest(
|
UsbBuildVendorRequest(purb,
|
||||||
purb,
|
|
||||||
pdev_ext->dev_handle | 0xffff,
|
pdev_ext->dev_handle | 0xffff,
|
||||||
buffer,
|
buffer,
|
||||||
buffer_length,
|
buffer_length,
|
||||||
0x21,
|
0x21, request, 0, pdev_ext->pif_desc->bInterfaceNumber, completion, pdev_ext, 0);
|
||||||
request,
|
|
||||||
0,
|
|
||||||
pdev_ext->pif_desc->bInterfaceNumber,
|
|
||||||
completion,
|
|
||||||
pdev_ext,
|
|
||||||
0 );
|
|
||||||
|
|
||||||
status = usb_submit_urb( pdev_ext->dev_mgr, purb );
|
status = usb_submit_urb(pdev_ext->dev_mgr, purb);
|
||||||
if( status != STATUS_PENDING )
|
if (status != STATUS_PENDING)
|
||||||
{
|
{
|
||||||
usb_free_mem( purb );
|
usb_free_mem(purb);
|
||||||
purb = NULL;
|
purb = NULL;
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
dev_mgr_register_irp( pdev_ext->dev_mgr, pdev_ext->io_packet.pirp, purb );
|
dev_mgr_register_irp(pdev_ext->dev_mgr, pdev_ext->io_packet.pirp, purb);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
umss_cbi_startio(
|
umss_cbi_startio(IN PUMSS_DEVICE_EXTENSION pdev_ext, IN PIO_PACKET io_packet)
|
||||||
IN PUMSS_DEVICE_EXTENSION pdev_ext,
|
|
||||||
IN PIO_PACKET io_packet
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
NTSTATUS status;
|
NTSTATUS status;
|
||||||
|
|
||||||
status = STATUS_NOT_SUPPORTED;
|
status = STATUS_NOT_SUPPORTED;
|
||||||
return status;
|
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
|
// Send the ADSC request to the device
|
||||||
// Calls UMSS_CbiSendADSCComplete when transfer completes
|
// Calls UMSS_CbiSendADSCComplete when transfer completes
|
||||||
status = umss_class_specific_request(
|
status = umss_class_specific_request(pdev_ext,
|
||||||
pdev_ext,
|
|
||||||
ACCEPT_DEVICE_SPECIFIC_COMMAND,
|
ACCEPT_DEVICE_SPECIFIC_COMMAND,
|
||||||
USB_DIR_OUT ,
|
USB_DIR_OUT,
|
||||||
io_packet->cdb,
|
io_packet->cdb, io_packet->cdb_length, umss_cbi_send_adsc_complete);
|
||||||
io_packet->cdb_length,
|
|
||||||
umss_cbi_send_adsc_complete
|
|
||||||
);
|
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
@ -120,10 +86,7 @@ IN PIO_PACKET io_packet
|
||||||
|
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
umss_cbi_send_adsc_complete(
|
umss_cbi_send_adsc_complete(PURB purb, PVOID context)
|
||||||
PURB purb,
|
|
||||||
PVOID context
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
NTSTATUS status;
|
NTSTATUS status;
|
||||||
PIO_STACK_LOCATION irpStack;
|
PIO_STACK_LOCATION irpStack;
|
||||||
|
@ -137,73 +100,66 @@ PVOID context
|
||||||
|
|
||||||
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?
|
// BUGBUG - Should reset device here?
|
||||||
// Device failed Command Block, complete with error
|
// 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"));
|
usb_dbg_print(DBGLVL_HIGH, ("umss_cbi_send_adsc_complete(): Queuing Data Transfer DPC\n"));
|
||||||
umss_cbi_transfer_data( pdev_ext );
|
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
|
// Device supports interrupt pipe, so get status
|
||||||
umss_cbi_get_status( pdev_ext );
|
umss_cbi_get_status(pdev_ext);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Device does not report status, so complete request
|
// 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 );
|
usb_free_mem(purb);
|
||||||
purb = NULL;
|
purb = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
umss_cbi_reset_pipe(
|
umss_cbi_reset_pipe(IN PVOID reference)
|
||||||
IN PVOID reference
|
|
||||||
)
|
|
||||||
|
|
||||||
{
|
{
|
||||||
PUMSS_DEVICE_EXTENSION pdev_ext;
|
PUMSS_DEVICE_EXTENSION pdev_ext;
|
||||||
pdev_ext = (PUMSS_DEVICE_EXTENSION) reference;
|
pdev_ext = (PUMSS_DEVICE_EXTENSION) reference;
|
||||||
|
|
||||||
// Reset the appropriate pipe, based on data direction
|
// Reset the appropriate pipe, based on data direction
|
||||||
umss_reset_pipe(
|
umss_reset_pipe(pdev_ext,
|
||||||
pdev_ext,
|
(pdev_ext->io_packet.flags & USB_DIR_IN) ?
|
||||||
( 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->in_endp_idx ):
|
usb_make_handle((pdev_ext->dev_handle >> 16), pdev_ext->if_idx, pdev_ext->out_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.
|
// Device stalled endpoint, so complete I/O operation with error.
|
||||||
// BUGBUG is this correct? Check spec...
|
// 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
|
VOID
|
||||||
umss_cbi_transfer_data(
|
umss_cbi_transfer_data(PUMSS_DEVICE_EXTENSION pdev_ext)
|
||||||
PUMSS_DEVICE_EXTENSION pdev_ext
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
PVOID buffer;
|
PVOID buffer;
|
||||||
ULONG buffer_length;
|
ULONG buffer_length;
|
||||||
|
|
||||||
// Get next data buffer element, if any.
|
// 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)
|
if (NULL == buffer)
|
||||||
{
|
{
|
||||||
//Done with data phase, so move to status phase if (supported)
|
//Done with data phase, so move to status phase if (supported)
|
||||||
|
@ -222,22 +178,15 @@ PUMSS_DEVICE_EXTENSION pdev_ext
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Transfer next element of the data phase
|
// Transfer next element of the data phase
|
||||||
umss_bulk_transfer(
|
umss_bulk_transfer(pdev_ext,
|
||||||
pdev_ext,
|
(UCHAR) ((pdev_ext->io_packet.flags & USB_DIR_IN) ? USB_DIR_IN : USB_DIR_OUT),
|
||||||
(UCHAR)((pdev_ext->io_packet.flags & USB_DIR_IN ) ? USB_DIR_IN : USB_DIR_OUT ),
|
buffer, buffer_length, umss_cbi_transfer_data_complete);
|
||||||
buffer,
|
|
||||||
buffer_length,
|
|
||||||
umss_cbi_transfer_data_complete
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
umss_cbi_transfer_data_complete(
|
umss_cbi_transfer_data_complete(PURB purb, PVOID context)
|
||||||
PURB purb,
|
|
||||||
PVOID context
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
NTSTATUS status;
|
NTSTATUS status;
|
||||||
PUMSS_DEVICE_EXTENSION pdev_ext;
|
PUMSS_DEVICE_EXTENSION pdev_ext;
|
||||||
|
@ -245,78 +194,71 @@ PVOID context
|
||||||
pdev_ext = (PUMSS_DEVICE_EXTENSION) context;
|
pdev_ext = (PUMSS_DEVICE_EXTENSION) context;
|
||||||
status = purb->status;
|
status = purb->status;
|
||||||
|
|
||||||
usb_free_mem( purb );
|
usb_free_mem(purb);
|
||||||
purb = NULL;
|
purb = NULL;
|
||||||
|
|
||||||
if ( !usb_success( status ) )
|
if (!usb_success(status))
|
||||||
{
|
{
|
||||||
// Device failed Data Transfer
|
// Device failed Data Transfer
|
||||||
// Check if we need to clear stalled pipe
|
// 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
|
// Reset pipe can only be done at passive level, so we need
|
||||||
// to schedule a work item to do it.
|
// 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();
|
TRAP();
|
||||||
umss_complete_request( pdev_ext, STATUS_IO_DEVICE_ERROR );
|
umss_complete_request(pdev_ext, STATUS_IO_DEVICE_ERROR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
umss_complete_request( pdev_ext, STATUS_IO_DEVICE_ERROR );
|
umss_complete_request(pdev_ext, STATUS_IO_DEVICE_ERROR);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Transfer succeeded
|
// Transfer succeeded
|
||||||
// umss_cbi_transfer_data( pdev_ext );
|
// umss_cbi_transfer_data( pdev_ext );
|
||||||
umss_complete_request( pdev_ext, STATUS_SUCCESS );
|
umss_complete_request(pdev_ext, STATUS_SUCCESS);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
umss_cbi_get_status(
|
umss_cbi_get_status(PUMSS_DEVICE_EXTENSION pdev_ext)
|
||||||
PUMSS_DEVICE_EXTENSION pdev_ext
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
PURB purb;
|
PURB purb;
|
||||||
NTSTATUS status;
|
NTSTATUS status;
|
||||||
|
|
||||||
purb = usb_alloc_mem( NonPagedPool, sizeof( URB ) );
|
purb = usb_alloc_mem(NonPagedPool, sizeof(URB));
|
||||||
if( purb == NULL )
|
if (purb == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Build a URB for our interrupt transfer
|
// Build a URB for our interrupt transfer
|
||||||
UsbBuildInterruptOrBulkTransferRequest(
|
UsbBuildInterruptOrBulkTransferRequest(purb,
|
||||||
purb,
|
usb_make_handle((pdev_ext->dev_handle >> 16), pdev_ext->if_idx,
|
||||||
usb_make_handle( ( pdev_ext->dev_handle >> 16 ), pdev_ext->if_idx, pdev_ext->int_endp_idx ),
|
pdev_ext->int_endp_idx), (PUCHAR) & pdev_ext->idb,
|
||||||
( PUCHAR )&pdev_ext->idb,
|
sizeof(INTERRUPT_DATA_BLOCK), umss_cbi_get_status_complete,
|
||||||
sizeof( INTERRUPT_DATA_BLOCK ),
|
pdev_ext, 0);
|
||||||
umss_cbi_get_status_complete,
|
|
||||||
pdev_ext,
|
|
||||||
0
|
|
||||||
);
|
|
||||||
|
|
||||||
// Call USB driver stack
|
// Call USB driver stack
|
||||||
status = usb_submit_urb( pdev_ext->dev_mgr, purb );
|
status = usb_submit_urb(pdev_ext->dev_mgr, purb);
|
||||||
if( status != STATUS_PENDING )
|
if (status != STATUS_PENDING)
|
||||||
{
|
{
|
||||||
usb_free_mem( purb );
|
usb_free_mem(purb);
|
||||||
purb = NULL;
|
purb = NULL;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
dev_mgr_register_irp( pdev_ext->dev_mgr, pdev_ext->io_packet.pirp, purb );
|
dev_mgr_register_irp(pdev_ext->dev_mgr, pdev_ext->io_packet.pirp, purb);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
umss_cbi_get_status_complete(
|
umss_cbi_get_status_complete(PURB purb, PVOID context)
|
||||||
PURB purb,
|
|
||||||
PVOID context
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
NTSTATUS status;
|
NTSTATUS status;
|
||||||
PUMSS_DEVICE_EXTENSION pdev_ext;
|
PUMSS_DEVICE_EXTENSION pdev_ext;
|
||||||
|
@ -325,26 +267,28 @@ PVOID context
|
||||||
pdev_ext = (PUMSS_DEVICE_EXTENSION) context;
|
pdev_ext = (PUMSS_DEVICE_EXTENSION) context;
|
||||||
|
|
||||||
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);
|
||||||
|
|
||||||
usb_free_mem( purb );
|
usb_free_mem(purb);
|
||||||
purb = NULL;
|
purb = NULL;
|
||||||
|
|
||||||
if ( !usb_success( status ) )
|
if (!usb_success(status))
|
||||||
{
|
{
|
||||||
// Device failed Data Transfer
|
// Device failed Data Transfer
|
||||||
// Check if we need to clear stalled pipe
|
// 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();
|
TRAP();
|
||||||
umss_complete_request( pdev_ext, STATUS_IO_DEVICE_ERROR );
|
umss_complete_request(pdev_ext, STATUS_IO_DEVICE_ERROR);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
umss_complete_request( pdev_ext, STATUS_IO_DEVICE_ERROR );
|
umss_complete_request(pdev_ext, STATUS_IO_DEVICE_ERROR);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -352,12 +296,12 @@ PVOID context
|
||||||
idb = &(pdev_ext->idb);
|
idb = &(pdev_ext->idb);
|
||||||
|
|
||||||
// Check for an error in the status block
|
// 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
|
else
|
||||||
{
|
{
|
||||||
umss_complete_request( pdev_ext, STATUS_SUCCESS );
|
umss_complete_request(pdev_ext, STATUS_SUCCESS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,43 +28,20 @@
|
||||||
#include "hub.h"
|
#include "hub.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
|
||||||
VOID
|
VOID compdev_set_cfg_completion(PURB purb, PVOID context);
|
||||||
compdev_set_cfg_completion(
|
|
||||||
PURB purb,
|
|
||||||
PVOID context
|
|
||||||
);
|
|
||||||
|
|
||||||
VOID
|
VOID compdev_select_driver(PUSB_DEV_MANAGER dev_mgr, DEV_HANDLE dev_handle);
|
||||||
compdev_select_driver(
|
|
||||||
PUSB_DEV_MANAGER dev_mgr,
|
BOOL compdev_connect(PCONNECT_DATA param, DEV_HANDLE dev_handle);
|
||||||
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
|
BOOL
|
||||||
compdev_connect(
|
compdev_driver_init(PUSB_DEV_MANAGER dev_mgr, PUSB_DRIVER pdriver)
|
||||||
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
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
if( dev_mgr == NULL || pdriver == NULL )
|
if (dev_mgr == NULL || pdriver == NULL)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
pdriver->driver_desc.flags = USB_DRIVER_FLAG_DEV_CAPABLE;
|
pdriver->driver_desc.flags = USB_DRIVER_FLAG_DEV_CAPABLE;
|
||||||
|
@ -97,19 +74,13 @@ PUSB_DRIVER pdriver
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL
|
BOOL
|
||||||
compdev_driver_destroy(
|
compdev_driver_destroy(PUSB_DEV_MANAGER dev_mgr, PUSB_DRIVER pdriver)
|
||||||
PUSB_DEV_MANAGER dev_mgr,
|
|
||||||
PUSB_DRIVER pdriver
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL
|
BOOL
|
||||||
compdev_connect(
|
compdev_connect(PCONNECT_DATA param, DEV_HANDLE dev_handle)
|
||||||
PCONNECT_DATA param,
|
|
||||||
DEV_HANDLE dev_handle
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
PURB purb;
|
PURB purb;
|
||||||
PUSB_CTRL_SETUP_PACKET psetup;
|
PUSB_CTRL_SETUP_PACKET psetup;
|
||||||
|
@ -120,28 +91,28 @@ DEV_HANDLE dev_handle
|
||||||
PUSB_INTERFACE_DESC pif_desc;
|
PUSB_INTERFACE_DESC pif_desc;
|
||||||
PUSB_DEV_MANAGER dev_mgr;
|
PUSB_DEV_MANAGER dev_mgr;
|
||||||
|
|
||||||
if( param == NULL || dev_handle == 0 )
|
if (param == NULL || dev_handle == 0)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
dev_mgr = param->dev_mgr;
|
dev_mgr = param->dev_mgr;
|
||||||
|
|
||||||
// let's set the configuration
|
// let's set the configuration
|
||||||
purb = usb_alloc_mem( NonPagedPool, sizeof( URB ) );
|
purb = usb_alloc_mem(NonPagedPool, sizeof(URB));
|
||||||
if( purb == NULL )
|
if (purb == NULL)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
buf = usb_alloc_mem( NonPagedPool, 512 );
|
buf = usb_alloc_mem(NonPagedPool, 512);
|
||||||
if( buf == NULL )
|
if (buf == NULL)
|
||||||
{
|
{
|
||||||
usb_dbg_print( DBGLVL_MAXIMUM, ( "compdev_connect(): can not alloc buf\n" ) );
|
usb_dbg_print(DBGLVL_MAXIMUM, ("compdev_connect(): can not alloc buf\n"));
|
||||||
usb_free_mem( purb );
|
usb_free_mem(purb);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// before we set the configuration, let's search to find if there
|
// before we set the configuration, let's search to find if there
|
||||||
// exist interfaces we supported
|
// exist interfaces we supported
|
||||||
psetup = ( PUSB_CTRL_SETUP_PACKET )( purb )->setup_packet;
|
psetup = (PUSB_CTRL_SETUP_PACKET) (purb)->setup_packet;
|
||||||
urb_init( ( purb ) );
|
urb_init((purb));
|
||||||
purb->endp_handle = dev_handle | 0xffff;
|
purb->endp_handle = dev_handle | 0xffff;
|
||||||
purb->data_buffer = buf;
|
purb->data_buffer = buf;
|
||||||
purb->data_length = 512;
|
purb->data_length = 512;
|
||||||
|
@ -154,73 +125,73 @@ DEV_HANDLE dev_handle
|
||||||
psetup->wIndex = 0;
|
psetup->wIndex = 0;
|
||||||
psetup->wLength = 512;
|
psetup->wLength = 512;
|
||||||
|
|
||||||
status = usb_submit_urb( dev_mgr, purb );
|
status = usb_submit_urb(dev_mgr, purb);
|
||||||
if( status == STATUS_PENDING )
|
if (status == STATUS_PENDING)
|
||||||
{
|
{
|
||||||
TRAP();
|
TRAP();
|
||||||
usb_free_mem( buf );
|
usb_free_mem(buf);
|
||||||
usb_free_mem( purb );
|
usb_free_mem(purb);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// let's scan the interfacs for those we recognize
|
// let's scan the interfacs for those we recognize
|
||||||
pconfig_desc = ( PUSB_CONFIGURATION_DESC )buf;
|
pconfig_desc = (PUSB_CONFIGURATION_DESC) buf;
|
||||||
if( pconfig_desc->wTotalLength > 512 )
|
if (pconfig_desc->wTotalLength > 512)
|
||||||
{
|
{
|
||||||
usb_free_mem( buf );
|
usb_free_mem(buf);
|
||||||
usb_free_mem( purb );
|
usb_free_mem(purb);
|
||||||
usb_dbg_print( DBGLVL_MAXIMUM, ( "compdev_connect(): error, bad configuration desc\n" ) );
|
usb_dbg_print(DBGLVL_MAXIMUM, ("compdev_connect(): error, bad configuration desc\n"));
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
pif_desc = ( PUSB_INTERFACE_DESC )&pconfig_desc[ 1 ];
|
pif_desc = (PUSB_INTERFACE_DESC) & pconfig_desc[1];
|
||||||
for( i = 0, credit = 0; i < ( LONG )pconfig_desc->bNumInterfaces; i++ )
|
for(i = 0, credit = 0; i < (LONG) pconfig_desc->bNumInterfaces; i++)
|
||||||
{
|
{
|
||||||
for( j = 0; j < DEVMGR_MAX_DRIVERS; j++ )
|
for(j = 0; j < DEVMGR_MAX_DRIVERS; j++)
|
||||||
{
|
{
|
||||||
credit = dev_mgr_score_driver_for_if( dev_mgr, &dev_mgr->driver_list[ j ], pif_desc );
|
credit = dev_mgr_score_driver_for_if(dev_mgr, &dev_mgr->driver_list[j], pif_desc);
|
||||||
if( credit )
|
if (credit)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if( credit )
|
if (credit)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if( usb_skip_if_and_altif( ( PUCHAR* )&pif_desc ) )
|
if (usb_skip_if_and_altif((PUCHAR *) & pif_desc))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
i = pconfig_desc->bConfigurationValue;
|
i = pconfig_desc->bConfigurationValue;
|
||||||
usb_free_mem( buf );
|
usb_free_mem(buf);
|
||||||
buf = NULL;
|
buf = NULL;
|
||||||
if( credit == 0 )
|
if (credit == 0)
|
||||||
{
|
{
|
||||||
usb_free_mem( purb );
|
usb_free_mem(purb);
|
||||||
usb_dbg_print( DBGLVL_MAXIMUM, ( "compdev_connect(): oops..., no supported interface found\n" ) );
|
usb_dbg_print(DBGLVL_MAXIMUM, ("compdev_connect(): oops..., no supported interface found\n"));
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
//set the configuration
|
//set the configuration
|
||||||
urb_init( purb );
|
urb_init(purb);
|
||||||
purb->endp_handle = dev_handle | 0xffff;
|
purb->endp_handle = dev_handle | 0xffff;
|
||||||
purb->data_buffer = NULL;
|
purb->data_buffer = NULL;
|
||||||
purb->data_length = 0;
|
purb->data_length = 0;
|
||||||
purb->completion = compdev_set_cfg_completion;
|
purb->completion = compdev_set_cfg_completion;
|
||||||
purb->context = dev_mgr;
|
purb->context = dev_mgr;
|
||||||
purb->reference = ( ULONG )param->pdriver;
|
purb->reference = (ULONG) param->pdriver;
|
||||||
psetup->bmRequestType = 0;
|
psetup->bmRequestType = 0;
|
||||||
psetup->bRequest = USB_REQ_SET_CONFIGURATION;
|
psetup->bRequest = USB_REQ_SET_CONFIGURATION;
|
||||||
psetup->wValue = ( USHORT ) i;
|
psetup->wValue = (USHORT) i;
|
||||||
psetup->wIndex = 0;
|
psetup->wIndex = 0;
|
||||||
psetup->wLength = 0;
|
psetup->wLength = 0;
|
||||||
|
|
||||||
usb_dbg_print( DBGLVL_MAXIMUM, ( "compdev_connect(): start config the device, cfgval=%d\n", i ) );
|
usb_dbg_print(DBGLVL_MAXIMUM, ("compdev_connect(): start config the device, cfgval=%d\n", i));
|
||||||
status = usb_submit_urb( dev_mgr, purb );
|
status = usb_submit_urb(dev_mgr, purb);
|
||||||
|
|
||||||
if( status != STATUS_PENDING )
|
if (status != STATUS_PENDING)
|
||||||
{
|
{
|
||||||
usb_free_mem( purb );
|
usb_free_mem(purb);
|
||||||
|
|
||||||
if( status == STATUS_SUCCESS )
|
if (status == STATUS_SUCCESS)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
@ -230,34 +201,26 @@ DEV_HANDLE dev_handle
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
compdev_event_select_if_driver(
|
compdev_event_select_if_driver(PUSB_DEV pdev, ULONG event, ULONG context, ULONG param)
|
||||||
PUSB_DEV pdev,
|
|
||||||
ULONG event,
|
|
||||||
ULONG context,
|
|
||||||
ULONG param
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
PUSB_DEV_MANAGER dev_mgr;
|
PUSB_DEV_MANAGER dev_mgr;
|
||||||
DEV_HANDLE dev_handle;
|
DEV_HANDLE dev_handle;
|
||||||
PUMSS_CREATE_DATA cd;
|
PUMSS_CREATE_DATA cd;
|
||||||
|
|
||||||
if( pdev == NULL )
|
if (pdev == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
//
|
//
|
||||||
// RtlZeroMemory( &cd, sizeof( cd ) );
|
// RtlZeroMemory( &cd, sizeof( cd ) );
|
||||||
//
|
//
|
||||||
dev_mgr = dev_mgr_from_dev( pdev );
|
dev_mgr = dev_mgr_from_dev(pdev);
|
||||||
dev_handle = usb_make_handle( pdev->dev_id, 0, 0 );
|
dev_handle = usb_make_handle(pdev->dev_id, 0, 0);
|
||||||
compdev_select_driver( dev_mgr, dev_handle );
|
compdev_select_driver(dev_mgr, dev_handle);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL
|
BOOL
|
||||||
compdev_post_event_select_driver(
|
compdev_post_event_select_driver(PUSB_DEV_MANAGER dev_mgr, DEV_HANDLE dev_handle)
|
||||||
PUSB_DEV_MANAGER dev_mgr,
|
|
||||||
DEV_HANDLE dev_handle
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
PUSB_EVENT pevent;
|
PUSB_EVENT pevent;
|
||||||
BOOL bret;
|
BOOL bret;
|
||||||
|
@ -265,23 +228,23 @@ DEV_HANDLE dev_handle
|
||||||
|
|
||||||
USE_IRQL;
|
USE_IRQL;
|
||||||
|
|
||||||
if( dev_mgr == NULL || dev_handle == 0 )
|
if (dev_mgr == NULL || dev_handle == 0)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
if( usb_query_and_lock_dev( dev_mgr, dev_handle, &pdev ) != STATUS_SUCCESS )
|
if (usb_query_and_lock_dev(dev_mgr, dev_handle, &pdev) != STATUS_SUCCESS)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
KeAcquireSpinLockAtDpcLevel( &dev_mgr->event_list_lock );
|
KeAcquireSpinLockAtDpcLevel(&dev_mgr->event_list_lock);
|
||||||
lock_dev( pdev, TRUE );
|
lock_dev(pdev, TRUE);
|
||||||
|
|
||||||
if( dev_state( pdev ) == USB_DEV_STATE_ZOMB )
|
if (dev_state(pdev) == USB_DEV_STATE_ZOMB)
|
||||||
{
|
{
|
||||||
bret = FALSE;
|
bret = FALSE;
|
||||||
goto LBL_OUT;
|
goto LBL_OUT;
|
||||||
}
|
}
|
||||||
|
|
||||||
pevent = alloc_event( &dev_mgr->event_pool, 1 );
|
pevent = alloc_event(&dev_mgr->event_pool, 1);
|
||||||
if( pevent == NULL )
|
if (pevent == NULL)
|
||||||
{
|
{
|
||||||
bret = FALSE;
|
bret = FALSE;
|
||||||
goto LBL_OUT;
|
goto LBL_OUT;
|
||||||
|
@ -295,23 +258,20 @@ DEV_HANDLE dev_handle
|
||||||
pevent->process_event = compdev_event_select_if_driver;
|
pevent->process_event = compdev_event_select_if_driver;
|
||||||
pevent->process_queue = event_list_default_process_queue;
|
pevent->process_queue = event_list_default_process_queue;
|
||||||
|
|
||||||
InsertTailList( &dev_mgr->event_list, &pevent->event_link );
|
InsertTailList(&dev_mgr->event_list, &pevent->event_link);
|
||||||
KeSetEvent( &dev_mgr->wake_up_event, 0, FALSE ); // wake up the dev_mgr_thread
|
KeSetEvent(&dev_mgr->wake_up_event, 0, FALSE); // wake up the dev_mgr_thread
|
||||||
bret = TRUE;
|
bret = TRUE;
|
||||||
|
|
||||||
LBL_OUT:
|
LBL_OUT:
|
||||||
|
|
||||||
unlock_dev( pdev, TRUE );
|
unlock_dev(pdev, TRUE);
|
||||||
KeReleaseSpinLockFromDpcLevel( &dev_mgr->event_list_lock );
|
KeReleaseSpinLockFromDpcLevel(&dev_mgr->event_list_lock);
|
||||||
usb_unlock_dev( pdev );
|
usb_unlock_dev(pdev);
|
||||||
return bret;
|
return bret;
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
compdev_set_cfg_completion(
|
compdev_set_cfg_completion(PURB purb, PVOID context)
|
||||||
PURB purb,
|
|
||||||
PVOID context
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
DEV_HANDLE dev_handle;
|
DEV_HANDLE dev_handle;
|
||||||
PUSB_DEV_MANAGER dev_mgr;
|
PUSB_DEV_MANAGER dev_mgr;
|
||||||
|
@ -322,62 +282,59 @@ PVOID context
|
||||||
|
|
||||||
USE_IRQL;
|
USE_IRQL;
|
||||||
|
|
||||||
if( purb == NULL || context == NULL )
|
if (purb == NULL || context == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
dev_handle = purb->endp_handle & ~0xffff;
|
dev_handle = purb->endp_handle & ~0xffff;
|
||||||
dev_mgr = ( PUSB_DEV_MANAGER ) context;
|
dev_mgr = (PUSB_DEV_MANAGER) context;
|
||||||
pdriver = ( PUSB_DRIVER )purb->reference;
|
pdriver = (PUSB_DRIVER) purb->reference;
|
||||||
|
|
||||||
if( purb->status != STATUS_SUCCESS )
|
if (purb->status != STATUS_SUCCESS)
|
||||||
{
|
{
|
||||||
usb_free_mem( purb );
|
usb_free_mem(purb);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
usb_free_mem( purb );
|
usb_free_mem(purb);
|
||||||
purb = NULL;
|
purb = NULL;
|
||||||
|
|
||||||
// set the dev state
|
// set the dev state
|
||||||
status = usb_query_and_lock_dev( dev_mgr, dev_handle, &pdev );
|
status = usb_query_and_lock_dev(dev_mgr, dev_handle, &pdev);
|
||||||
if( status != STATUS_SUCCESS )
|
if (status != STATUS_SUCCESS)
|
||||||
{
|
{
|
||||||
usb_unlock_dev( pdev );
|
usb_unlock_dev(pdev);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// safe to release the pdev ref since we are in urb completion
|
// safe to release the pdev ref since we are in urb completion
|
||||||
usb_unlock_dev( pdev );
|
usb_unlock_dev(pdev);
|
||||||
|
|
||||||
lock_dev( pdev, TRUE );
|
lock_dev(pdev, TRUE);
|
||||||
if( dev_state( pdev ) >= USB_DEV_STATE_BEFORE_ZOMB )
|
if (dev_state(pdev) >= USB_DEV_STATE_BEFORE_ZOMB)
|
||||||
{
|
{
|
||||||
unlock_dev( pdev, TRUE );
|
unlock_dev(pdev, TRUE);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( dev_mgr_set_driver( dev_mgr, dev_handle, pdriver, pdev ) == FALSE )
|
if (dev_mgr_set_driver(dev_mgr, dev_handle, pdriver, pdev) == FALSE)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
//transit the state to configured
|
//transit the state to configured
|
||||||
pdev->flags &= ~USB_DEV_STATE_MASK;
|
pdev->flags &= ~USB_DEV_STATE_MASK;
|
||||||
pdev->flags |= USB_DEV_STATE_CONFIGURED;
|
pdev->flags |= USB_DEV_STATE_CONFIGURED;
|
||||||
unlock_dev( pdev, TRUE );
|
unlock_dev(pdev, TRUE);
|
||||||
|
|
||||||
//
|
//
|
||||||
// we change to use our thread for driver choosing. it will reduce
|
// we change to use our thread for driver choosing. it will reduce
|
||||||
// the race condition when different pnp event comes simultaneously
|
// 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" ) );
|
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 );
|
compdev_post_event_select_driver(dev_mgr, dev_handle);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
compdev_select_driver(
|
compdev_select_driver(PUSB_DEV_MANAGER dev_mgr, DEV_HANDLE dev_handle)
|
||||||
PUSB_DEV_MANAGER dev_mgr,
|
|
||||||
DEV_HANDLE dev_handle
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
URB urb;
|
URB urb;
|
||||||
LONG i, j, k, credit;
|
LONG i, j, k, credit;
|
||||||
|
@ -393,18 +350,18 @@ DEV_HANDLE dev_handle
|
||||||
|
|
||||||
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 )
|
if (buf == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// now let's get the descs, one configuration
|
// now let's get the descs, one configuration
|
||||||
urb_init( &urb );
|
urb_init(&urb);
|
||||||
psetup = ( PUSB_CTRL_SETUP_PACKET )urb.setup_packet;
|
psetup = (PUSB_CTRL_SETUP_PACKET) urb.setup_packet;
|
||||||
urb.endp_handle = dev_handle | 0xffff;
|
urb.endp_handle = dev_handle | 0xffff;
|
||||||
urb.data_buffer = buf;
|
urb.data_buffer = buf;
|
||||||
urb.data_length = 512;
|
urb.data_length = 512;
|
||||||
|
@ -417,72 +374,69 @@ DEV_HANDLE dev_handle
|
||||||
psetup->wIndex = 0;
|
psetup->wIndex = 0;
|
||||||
psetup->wLength = 512;
|
psetup->wLength = 512;
|
||||||
|
|
||||||
status = usb_submit_urb( dev_mgr, &urb );
|
status = usb_submit_urb(dev_mgr, &urb);
|
||||||
if( status == STATUS_PENDING )
|
if (status == STATUS_PENDING)
|
||||||
{
|
{
|
||||||
TRAP();
|
TRAP();
|
||||||
}
|
}
|
||||||
|
|
||||||
// let's scan the interfacs for those we recognize
|
// let's scan the interfacs for those we recognize
|
||||||
pconfig_desc = ( PUSB_CONFIGURATION_DESC )buf;
|
pconfig_desc = (PUSB_CONFIGURATION_DESC) buf;
|
||||||
if( pconfig_desc->wTotalLength > 512 )
|
if (pconfig_desc->wTotalLength > 512)
|
||||||
{
|
{
|
||||||
usb_free_mem( buf );
|
usb_free_mem(buf);
|
||||||
usb_dbg_print( DBGLVL_MAXIMUM, ( "compdev_select_driver(): error, bad configuration desc\n" ) );
|
usb_dbg_print(DBGLVL_MAXIMUM, ("compdev_select_driver(): error, bad configuration desc\n"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
pif_desc = ( PUSB_INTERFACE_DESC )&pconfig_desc[ 1 ];
|
pif_desc = (PUSB_INTERFACE_DESC) & pconfig_desc[1];
|
||||||
|
|
||||||
if( usb_query_and_lock_dev( dev_mgr, dev_handle, &pdev ) != STATUS_SUCCESS )
|
if (usb_query_and_lock_dev(dev_mgr, dev_handle, &pdev) != STATUS_SUCCESS)
|
||||||
{
|
{
|
||||||
usb_free_mem( buf );
|
usb_free_mem(buf);
|
||||||
usb_dbg_print( DBGLVL_MAXIMUM, ( "compdev_select_driver(): error, dev does not exist\n" ) );
|
usb_dbg_print(DBGLVL_MAXIMUM, ("compdev_select_driver(): error, dev does not exist\n"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for( i = 0; i < ( LONG )pconfig_desc->bNumInterfaces; i++ )
|
for(i = 0; i < (LONG) pconfig_desc->bNumInterfaces; i++)
|
||||||
{
|
{
|
||||||
for( j = 0, credit = 0, pcand = NULL; j < DEVMGR_MAX_DRIVERS; j++ )
|
for(j = 0, credit = 0, pcand = NULL; j < DEVMGR_MAX_DRIVERS; j++)
|
||||||
{
|
{
|
||||||
ptemp_drv = &dev_mgr->driver_list[ j ];
|
ptemp_drv = &dev_mgr->driver_list[j];
|
||||||
k = dev_mgr_score_driver_for_if( dev_mgr, ptemp_drv, pif_desc );
|
k = dev_mgr_score_driver_for_if(dev_mgr, ptemp_drv, pif_desc);
|
||||||
if( k > credit )
|
if (k > credit)
|
||||||
credit = k, pcand = ptemp_drv;
|
credit = k, pcand = ptemp_drv;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( credit )
|
if (credit)
|
||||||
{
|
{
|
||||||
// ok, we find one
|
// ok, we find one
|
||||||
CONNECT_DATA param;
|
CONNECT_DATA param;
|
||||||
|
|
||||||
if( pcand->disp_tbl.dev_connect )
|
if (pcand->disp_tbl.dev_connect)
|
||||||
{
|
{
|
||||||
param.dev_mgr = dev_mgr;
|
param.dev_mgr = dev_mgr;
|
||||||
param.pdriver = pcand;
|
param.pdriver = pcand;
|
||||||
param.dev_handle = 0;
|
param.dev_handle = 0;
|
||||||
pcand->disp_tbl.dev_connect( ¶m, usb_make_handle( dev_id, i, 0 ) );
|
pcand->disp_tbl.dev_connect(¶m, usb_make_handle(dev_id, i, 0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if( usb_skip_if_and_altif( ( PUCHAR* )&pif_desc ) == FALSE )
|
if (usb_skip_if_and_altif((PUCHAR *) & pif_desc) == FALSE)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
usb_unlock_dev( pdev );
|
usb_unlock_dev(pdev);
|
||||||
|
|
||||||
if( buf )
|
if (buf)
|
||||||
{
|
{
|
||||||
usb_free_mem( buf );
|
usb_free_mem(buf);
|
||||||
buf = NULL;
|
buf = NULL;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL
|
BOOL
|
||||||
compdev_stop(
|
compdev_stop(PUSB_DEV_MANAGER dev_mgr, DEV_HANDLE dev_handle)
|
||||||
PUSB_DEV_MANAGER dev_mgr,
|
|
||||||
DEV_HANDLE dev_handle
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
PUSB_DEV pdev;
|
PUSB_DEV pdev;
|
||||||
LONG i;
|
LONG i;
|
||||||
|
@ -490,37 +444,34 @@ DEV_HANDLE dev_handle
|
||||||
PUSB_DRIVER pdrv;
|
PUSB_DRIVER pdrv;
|
||||||
NTSTATUS status;
|
NTSTATUS status;
|
||||||
|
|
||||||
if( dev_mgr == NULL || dev_handle == 0 )
|
if (dev_mgr == NULL || dev_handle == 0)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
pdev = NULL;
|
pdev = NULL;
|
||||||
dev_id = dev_handle >> 16;
|
dev_id = dev_handle >> 16;
|
||||||
status = usb_query_and_lock_dev( dev_mgr, dev_handle, &pdev );
|
status = usb_query_and_lock_dev(dev_mgr, dev_handle, &pdev);
|
||||||
if( pdev )
|
if (pdev)
|
||||||
{
|
{
|
||||||
if( pdev->usb_config )
|
if (pdev->usb_config)
|
||||||
{
|
{
|
||||||
for( i = 0; i < pdev->usb_config->if_count; i++ )
|
for(i = 0; i < pdev->usb_config->if_count; i++)
|
||||||
{
|
{
|
||||||
if( pdrv = pdev->usb_config->interf[ i ].pif_drv )
|
if (pdrv = pdev->usb_config->interf[i].pif_drv)
|
||||||
{
|
{
|
||||||
pdrv->disp_tbl.dev_stop( dev_mgr, usb_make_handle( dev_id, i, 0 ) );
|
pdrv->disp_tbl.dev_stop(dev_mgr, usb_make_handle(dev_id, i, 0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if( status == STATUS_SUCCESS )
|
if (status == STATUS_SUCCESS)
|
||||||
{
|
{
|
||||||
usb_unlock_dev( pdev );
|
usb_unlock_dev(pdev);
|
||||||
}
|
}
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL
|
BOOL
|
||||||
compdev_disconnect(
|
compdev_disconnect(PUSB_DEV_MANAGER dev_mgr, DEV_HANDLE dev_handle)
|
||||||
PUSB_DEV_MANAGER dev_mgr,
|
|
||||||
DEV_HANDLE dev_handle
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
PUSB_DEV pdev;
|
PUSB_DEV pdev;
|
||||||
LONG i;
|
LONG i;
|
||||||
|
@ -528,28 +479,28 @@ DEV_HANDLE dev_handle
|
||||||
PUSB_DRIVER pdrv;
|
PUSB_DRIVER pdrv;
|
||||||
NTSTATUS status;
|
NTSTATUS status;
|
||||||
|
|
||||||
if( dev_mgr == NULL || dev_handle == 0 )
|
if (dev_mgr == NULL || dev_handle == 0)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
pdev = NULL;
|
pdev = NULL;
|
||||||
dev_id = dev_handle >> 16;
|
dev_id = dev_handle >> 16;
|
||||||
status = usb_query_and_lock_dev( dev_mgr, dev_handle, &pdev );
|
status = usb_query_and_lock_dev(dev_mgr, dev_handle, &pdev);
|
||||||
if( pdev )
|
if (pdev)
|
||||||
{
|
{
|
||||||
if( pdev->usb_config )
|
if (pdev->usb_config)
|
||||||
{
|
{
|
||||||
for( i = 0; i < pdev->usb_config->if_count; i++ )
|
for(i = 0; i < pdev->usb_config->if_count; i++)
|
||||||
{
|
{
|
||||||
if( pdrv = pdev->usb_config->interf[ i ].pif_drv )
|
if (pdrv = pdev->usb_config->interf[i].pif_drv)
|
||||||
{
|
{
|
||||||
pdrv->disp_tbl.dev_disconnect( dev_mgr, usb_make_handle( dev_id, i, 0 ) );
|
pdrv->disp_tbl.dev_disconnect(dev_mgr, usb_make_handle(dev_id, i, 0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if( status == STATUS_SUCCESS )
|
if (status == STATUS_SUCCESS)
|
||||||
{
|
{
|
||||||
usb_unlock_dev( pdev );
|
usb_unlock_dev(pdev);
|
||||||
}
|
}
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,10 +26,7 @@
|
||||||
#include "hub.h"
|
#include "hub.h"
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
disp_urb_completion(
|
disp_urb_completion(PURB purb, PVOID context)
|
||||||
PURB purb,
|
|
||||||
PVOID context
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
PUSB_CTRL_SETUP_PACKET psetup;
|
PUSB_CTRL_SETUP_PACKET psetup;
|
||||||
PUSB_DEV_MANAGER dev_mgr;
|
PUSB_DEV_MANAGER dev_mgr;
|
||||||
|
@ -37,11 +34,11 @@ PVOID context
|
||||||
NTSTATUS status;
|
NTSTATUS status;
|
||||||
PDEVEXT_HEADER dev_hdr;
|
PDEVEXT_HEADER dev_hdr;
|
||||||
|
|
||||||
if( purb == NULL )
|
if (purb == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ctrl_code = ( ULONG )purb->reference;
|
ctrl_code = (ULONG) purb->reference;
|
||||||
dev_mgr = ( PUSB_DEV_MANAGER )purb->context;
|
dev_mgr = (PUSB_DEV_MANAGER) purb->context;
|
||||||
|
|
||||||
// at this stage, the irp can not be canceled since the urb
|
// 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.
|
// won't be found in any queue and the irp is not in any queue.
|
||||||
|
@ -55,15 +52,15 @@ PVOID context
|
||||||
// running level. And the solution is to register the irp
|
// running level. And the solution is to register the irp
|
||||||
// before the urb is scheduled instead of registering it after
|
// before the urb is scheduled instead of registering it after
|
||||||
// urb is scheduled.
|
// urb is scheduled.
|
||||||
if( purb->pirp )
|
if (purb->pirp)
|
||||||
{
|
{
|
||||||
PIO_STACK_LOCATION irp_stack;
|
PIO_STACK_LOCATION irp_stack;
|
||||||
dev_mgr_remove_irp( dev_mgr, purb->pirp );
|
dev_mgr_remove_irp(dev_mgr, purb->pirp);
|
||||||
|
|
||||||
status = purb->status;
|
status = purb->status;
|
||||||
irp_stack = IoGetCurrentIrpStackLocation( purb->pirp );
|
irp_stack = IoGetCurrentIrpStackLocation(purb->pirp);
|
||||||
|
|
||||||
if( purb->status != STATUS_SUCCESS )
|
if (purb->status != STATUS_SUCCESS)
|
||||||
{
|
{
|
||||||
purb->pirp->IoStatus.Information = 0;
|
purb->pirp->IoStatus.Information = 0;
|
||||||
}
|
}
|
||||||
|
@ -72,28 +69,25 @@ PVOID context
|
||||||
// currently only IRP_MJ_DEVICE_CONTROL and IRP_MJ_INTERNAL_DEVICE_CONTROL
|
// currently only IRP_MJ_DEVICE_CONTROL and IRP_MJ_INTERNAL_DEVICE_CONTROL
|
||||||
// are allowed. And we do not need to set information
|
// are allowed. And we do not need to set information
|
||||||
// for IRP_MJ_INTERNAL_DEVICE_CONTROL
|
// for IRP_MJ_INTERNAL_DEVICE_CONTROL
|
||||||
if( irp_stack->MajorFunction == IRP_MJ_DEVICE_CONTROL )
|
if (irp_stack->MajorFunction == IRP_MJ_DEVICE_CONTROL)
|
||||||
purb->pirp->IoStatus.Information = purb->data_length;
|
purb->pirp->IoStatus.Information = purb->data_length;
|
||||||
}
|
}
|
||||||
purb->pirp->IoStatus.Status = status;
|
purb->pirp->IoStatus.Status = status;
|
||||||
if( irp_stack )
|
if (irp_stack)
|
||||||
{
|
{
|
||||||
dev_hdr = irp_stack->DeviceObject->DeviceExtension;
|
dev_hdr = irp_stack->DeviceObject->DeviceExtension;
|
||||||
if( dev_hdr->start_io )
|
if (dev_hdr->start_io)
|
||||||
{
|
{
|
||||||
IoStartNextPacket( irp_stack->DeviceObject, TRUE );
|
IoStartNextPacket(irp_stack->DeviceObject, TRUE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
IoCompleteRequest( purb->pirp, IO_NO_INCREMENT );
|
IoCompleteRequest(purb->pirp, IO_NO_INCREMENT);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
disp_noio_urb_completion(
|
disp_noio_urb_completion(PURB purb, PVOID context)
|
||||||
PURB purb,
|
|
||||||
PVOID context
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
PUSB_CTRL_SETUP_PACKET psetup;
|
PUSB_CTRL_SETUP_PACKET psetup;
|
||||||
PURB purb2;
|
PURB purb2;
|
||||||
|
@ -102,99 +96,100 @@ PVOID context
|
||||||
PIO_STACK_LOCATION irp_stack;
|
PIO_STACK_LOCATION irp_stack;
|
||||||
PDEVEXT_HEADER dev_hdr;
|
PDEVEXT_HEADER dev_hdr;
|
||||||
|
|
||||||
if( purb == NULL )
|
if (purb == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
psetup = ( PUSB_CTRL_SETUP_PACKET )purb->setup_packet;
|
psetup = (PUSB_CTRL_SETUP_PACKET) purb->setup_packet;
|
||||||
|
|
||||||
if( psetup->bmRequestType == 0x2
|
if ((psetup->bmRequestType == 0x2) &&
|
||||||
&& psetup->bRequest == USB_REQ_CLEAR_FEATURE
|
(psetup->bRequest == USB_REQ_CLEAR_FEATURE) &&
|
||||||
&& psetup->wIndex == 0 ) //reset pipe
|
(psetup->wIndex == 0)) //reset pipe
|
||||||
purb2 = ( PURB )context;
|
{
|
||||||
|
purb2 = (PURB) context;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
purb2 = purb;
|
purb2 = purb;
|
||||||
|
}
|
||||||
|
|
||||||
if( purb2->pirp == NULL )
|
if (purb2->pirp == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
dev_mgr = ( PUSB_DEV_MANAGER )purb2->context;
|
dev_mgr = (PUSB_DEV_MANAGER) purb2->context;
|
||||||
|
|
||||||
dev_mgr_remove_irp( dev_mgr, purb2->pirp );
|
dev_mgr_remove_irp(dev_mgr, purb2->pirp);
|
||||||
|
|
||||||
if( purb->status != STATUS_SUCCESS )
|
if (purb->status != STATUS_SUCCESS)
|
||||||
status = STATUS_IO_DEVICE_ERROR;
|
status = STATUS_IO_DEVICE_ERROR;
|
||||||
|
|
||||||
purb2->pirp->IoStatus.Information = 0;
|
purb2->pirp->IoStatus.Information = 0;
|
||||||
purb2->pirp->IoStatus.Status = status;
|
purb2->pirp->IoStatus.Status = status;
|
||||||
irp_stack = IoGetCurrentIrpStackLocation( purb->pirp );
|
irp_stack = IoGetCurrentIrpStackLocation(purb->pirp);
|
||||||
if( irp_stack )
|
if (irp_stack)
|
||||||
{
|
{
|
||||||
dev_hdr = irp_stack->DeviceObject->DeviceExtension;
|
dev_hdr = irp_stack->DeviceObject->DeviceExtension;
|
||||||
if( dev_hdr->start_io )
|
if (dev_hdr->start_io)
|
||||||
{
|
{
|
||||||
IoStartNextPacket( irp_stack->DeviceObject, TRUE );
|
IoStartNextPacket(irp_stack->DeviceObject, TRUE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
IoCompleteRequest( purb2->pirp, IO_NO_INCREMENT );
|
IoCompleteRequest(purb2->pirp, IO_NO_INCREMENT);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS
|
|
||||||
dev_mgr_dispatch(
|
|
||||||
IN PUSB_DEV_MANAGER dev_mgr,
|
|
||||||
IN PIRP irp
|
|
||||||
)
|
|
||||||
//this function is called by the hcd's
|
//this function is called by the hcd's
|
||||||
//dispatch when they have done their job.
|
//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;
|
PIO_STACK_LOCATION irp_stack;
|
||||||
NTSTATUS status;
|
NTSTATUS status;
|
||||||
ULONG ctrl_code;
|
ULONG ctrl_code;
|
||||||
USE_IRQL;
|
USE_IRQL;
|
||||||
|
|
||||||
if( dev_mgr == NULL || irp == NULL )
|
if (dev_mgr == NULL || irp == NULL)
|
||||||
{
|
{
|
||||||
EXIT_DISPATCH( STATUS_INVALID_PARAMETER, irp );
|
EXIT_DISPATCH(STATUS_INVALID_PARAMETER, irp);
|
||||||
}
|
}
|
||||||
|
|
||||||
status = STATUS_SUCCESS;
|
status = STATUS_SUCCESS;
|
||||||
irp_stack = IoGetCurrentIrpStackLocation (irp);
|
irp_stack = IoGetCurrentIrpStackLocation(irp);
|
||||||
ctrl_code = irp_stack->Parameters.DeviceIoControl.IoControlCode;
|
ctrl_code = irp_stack->Parameters.DeviceIoControl.IoControlCode;
|
||||||
|
|
||||||
switch ( irp_stack->MajorFunction )
|
switch (irp_stack->MajorFunction)
|
||||||
{
|
{
|
||||||
case IRP_MJ_CREATE:
|
case IRP_MJ_CREATE:
|
||||||
{
|
{
|
||||||
InterlockedIncrement( &dev_mgr->open_count );
|
InterlockedIncrement(&dev_mgr->open_count);
|
||||||
EXIT_DISPATCH( STATUS_SUCCESS, irp );
|
EXIT_DISPATCH(STATUS_SUCCESS, irp);
|
||||||
}
|
}
|
||||||
case IRP_MJ_CLOSE:
|
case IRP_MJ_CLOSE:
|
||||||
{
|
{
|
||||||
InterlockedDecrement( &dev_mgr->open_count );
|
InterlockedDecrement(&dev_mgr->open_count);
|
||||||
EXIT_DISPATCH( STATUS_SUCCESS, irp );
|
EXIT_DISPATCH(STATUS_SUCCESS, irp);
|
||||||
}
|
}
|
||||||
case IRP_MJ_INTERNAL_DEVICE_CONTROL:
|
case IRP_MJ_INTERNAL_DEVICE_CONTROL:
|
||||||
case IRP_MJ_DEVICE_CONTROL:
|
case IRP_MJ_DEVICE_CONTROL:
|
||||||
{
|
{
|
||||||
switch( ctrl_code )
|
switch (ctrl_code)
|
||||||
{
|
{
|
||||||
case IOCTL_GET_DEV_COUNT:
|
case IOCTL_GET_DEV_COUNT:
|
||||||
{
|
{
|
||||||
LONG dev_count;
|
LONG dev_count;
|
||||||
|
|
||||||
irp->IoStatus.Information = 0;
|
irp->IoStatus.Information = 0;
|
||||||
if( irp_stack->Parameters.DeviceIoControl.OutputBufferLength < sizeof( LONG ) )
|
if (irp_stack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(LONG))
|
||||||
{
|
{
|
||||||
EXIT_DISPATCH( STATUS_INVALID_PARAMETER, irp );
|
EXIT_DISPATCH(STATUS_INVALID_PARAMETER, irp);
|
||||||
}
|
}
|
||||||
|
|
||||||
KeAcquireSpinLock( &dev_mgr->dev_list_lock, &old_irql );
|
KeAcquireSpinLock(&dev_mgr->dev_list_lock, &old_irql);
|
||||||
dev_count = usb_count_list( &dev_mgr->dev_list );
|
dev_count = usb_count_list(&dev_mgr->dev_list);
|
||||||
KeReleaseSpinLock( &dev_mgr->dev_list_lock, old_irql );
|
KeReleaseSpinLock(&dev_mgr->dev_list_lock, old_irql);
|
||||||
|
|
||||||
*( ( PLONG )irp->AssociatedIrp.SystemBuffer ) = dev_count;
|
*((PLONG) irp->AssociatedIrp.SystemBuffer) = dev_count;
|
||||||
irp->IoStatus.Information = sizeof( LONG );
|
irp->IoStatus.Information = sizeof(LONG);
|
||||||
EXIT_DISPATCH( STATUS_SUCCESS, irp );
|
EXIT_DISPATCH(STATUS_SUCCESS, irp);
|
||||||
}
|
}
|
||||||
case IOCTL_ENUM_DEVICES:
|
case IOCTL_ENUM_DEVICES:
|
||||||
{
|
{
|
||||||
|
@ -204,66 +199,67 @@ IN PIRP irp
|
||||||
PENUM_DEV_ARRAY peda;
|
PENUM_DEV_ARRAY peda;
|
||||||
|
|
||||||
irp->IoStatus.Information = 0;
|
irp->IoStatus.Information = 0;
|
||||||
if( irp_stack->Parameters.DeviceIoControl.InputBufferLength < sizeof( LONG ) )
|
if (irp_stack->Parameters.DeviceIoControl.InputBufferLength < sizeof(LONG))
|
||||||
{
|
{
|
||||||
EXIT_DISPATCH( STATUS_INVALID_PARAMETER, irp );
|
EXIT_DISPATCH(STATUS_INVALID_PARAMETER, irp);
|
||||||
}
|
}
|
||||||
if( irp_stack->Parameters.DeviceIoControl.OutputBufferLength < sizeof( ENUM_DEV_ARRAY ) )
|
if (irp_stack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(ENUM_DEV_ARRAY))
|
||||||
{
|
{
|
||||||
EXIT_DISPATCH( STATUS_INVALID_PARAMETER, irp );
|
EXIT_DISPATCH(STATUS_INVALID_PARAMETER, irp);
|
||||||
}
|
}
|
||||||
array_size = *( ( PULONG )irp->AssociatedIrp.SystemBuffer );
|
array_size = *((PULONG) irp->AssociatedIrp.SystemBuffer);
|
||||||
|
|
||||||
KeAcquireSpinLock( &dev_mgr->dev_list_lock, &old_irql );
|
KeAcquireSpinLock(&dev_mgr->dev_list_lock, &old_irql);
|
||||||
dev_count = usb_count_list( &dev_mgr->dev_list );
|
dev_count = usb_count_list(&dev_mgr->dev_list);
|
||||||
dev_count = dev_count > array_size ? array_size : dev_count;
|
dev_count = dev_count > array_size ? array_size : dev_count;
|
||||||
peda = ( PENUM_DEV_ARRAY )irp->AssociatedIrp.SystemBuffer;
|
peda = (PENUM_DEV_ARRAY) irp->AssociatedIrp.SystemBuffer;
|
||||||
RtlZeroMemory( peda, sizeof( ENUM_DEV_ARRAY ) + ( dev_count - 1 ) * sizeof( ENUM_DEV_ELEMENT ) );
|
RtlZeroMemory(peda, sizeof(ENUM_DEV_ARRAY) + (dev_count - 1) * sizeof(ENUM_DEV_ELEMENT));
|
||||||
|
|
||||||
if( dev_count )
|
if (dev_count)
|
||||||
{
|
{
|
||||||
ListFirst( &dev_mgr->dev_list, pthis );
|
ListFirst(&dev_mgr->dev_list, pthis);
|
||||||
for( i = 0, j = 0; i < dev_count; i++ )
|
for(i = 0, j = 0; i < dev_count; i++)
|
||||||
{
|
{
|
||||||
pdev = struct_ptr( pthis, USB_DEV, dev_link );
|
pdev = struct_ptr(pthis, USB_DEV, dev_link);
|
||||||
ListNext( &dev_mgr->dev_list, pthis, pnext );
|
ListNext(&dev_mgr->dev_list, pthis, pnext);
|
||||||
pthis = pnext;
|
pthis = pnext;
|
||||||
|
|
||||||
lock_dev( pdev, FALSE );
|
lock_dev(pdev, FALSE);
|
||||||
if( dev_state( pdev ) == USB_DEV_STATE_ZOMB )
|
if (dev_state(pdev) == USB_DEV_STATE_ZOMB)
|
||||||
{
|
{
|
||||||
unlock_dev( pdev, FALSE );
|
unlock_dev(pdev, FALSE);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( dev_state( pdev ) < USB_DEV_STATE_ADDRESSED )
|
if (dev_state(pdev) < USB_DEV_STATE_ADDRESSED)
|
||||||
{
|
{
|
||||||
unlock_dev( pdev, FALSE );
|
unlock_dev(pdev, FALSE);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
peda->dev_arr[ i ].dev_handle = ( pdev->dev_id << 16 );
|
peda->dev_arr[i].dev_handle = (pdev->dev_id << 16);
|
||||||
//may not get the desc yet
|
//may not get the desc yet
|
||||||
if( pdev->pusb_dev_desc )
|
if (pdev->pusb_dev_desc)
|
||||||
{
|
{
|
||||||
peda->dev_arr[ i ].product_id = pdev->pusb_dev_desc->idProduct;
|
peda->dev_arr[i].product_id = pdev->pusb_dev_desc->idProduct;
|
||||||
peda->dev_arr[ i ].vendor_id = pdev->pusb_dev_desc->idVendor;
|
peda->dev_arr[i].vendor_id = pdev->pusb_dev_desc->idVendor;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
peda->dev_arr[ i ].product_id = 0xffff;
|
peda->dev_arr[i].product_id = 0xffff;
|
||||||
peda->dev_arr[ i ].vendor_id = 0xffff;
|
peda->dev_arr[i].vendor_id = 0xffff;
|
||||||
}
|
}
|
||||||
peda->dev_arr[ i ].dev_addr = pdev->dev_addr;
|
peda->dev_arr[i].dev_addr = pdev->dev_addr;
|
||||||
unlock_dev( pdev, FALSE );
|
unlock_dev(pdev, FALSE);
|
||||||
j++;
|
j++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
peda->dev_count = dev_count ? j : 0;
|
peda->dev_count = dev_count ? j : 0;
|
||||||
KeReleaseSpinLock( &dev_mgr->dev_list_lock, old_irql );
|
KeReleaseSpinLock(&dev_mgr->dev_list_lock, old_irql);
|
||||||
|
|
||||||
irp->IoStatus.Information = sizeof( ENUM_DEV_ARRAY ) + ( dev_count - 1 ) * sizeof( ENUM_DEV_ELEMENT );
|
irp->IoStatus.Information =
|
||||||
EXIT_DISPATCH( STATUS_SUCCESS, irp );
|
sizeof(ENUM_DEV_ARRAY) + (dev_count - 1) * sizeof(ENUM_DEV_ELEMENT);
|
||||||
|
EXIT_DISPATCH(STATUS_SUCCESS, irp);
|
||||||
}
|
}
|
||||||
case IOCTL_GET_DEV_DESC:
|
case IOCTL_GET_DEV_DESC:
|
||||||
{
|
{
|
||||||
|
@ -273,96 +269,93 @@ IN PIRP irp
|
||||||
PUSB_DEV pdev;
|
PUSB_DEV pdev;
|
||||||
LONG buf_size;
|
LONG buf_size;
|
||||||
|
|
||||||
if( irp_stack->Parameters.DeviceIoControl.InputBufferLength < sizeof( GET_DEV_DESC_REQ ) )
|
if (irp_stack->Parameters.DeviceIoControl.InputBufferLength < sizeof(GET_DEV_DESC_REQ))
|
||||||
{
|
{
|
||||||
EXIT_DISPATCH( STATUS_INVALID_PARAMETER, irp );
|
EXIT_DISPATCH(STATUS_INVALID_PARAMETER, irp);
|
||||||
}
|
}
|
||||||
|
|
||||||
if( irp_stack->Parameters.DeviceIoControl.OutputBufferLength < 8 )
|
if (irp_stack->Parameters.DeviceIoControl.OutputBufferLength < 8)
|
||||||
{
|
{
|
||||||
EXIT_DISPATCH( STATUS_INVALID_PARAMETER, irp );
|
EXIT_DISPATCH(STATUS_INVALID_PARAMETER, irp);
|
||||||
}
|
}
|
||||||
|
|
||||||
status = STATUS_SUCCESS;
|
status = STATUS_SUCCESS;
|
||||||
buf_size = irp_stack->Parameters.DeviceIoControl.OutputBufferLength;
|
buf_size = irp_stack->Parameters.DeviceIoControl.OutputBufferLength;
|
||||||
RtlCopyMemory( &gddr, irp->AssociatedIrp.SystemBuffer, sizeof( GET_DEV_DESC_REQ ) );
|
RtlCopyMemory(&gddr, irp->AssociatedIrp.SystemBuffer, sizeof(GET_DEV_DESC_REQ));
|
||||||
pusb_desc_header = irp->AssociatedIrp.SystemBuffer;
|
pusb_desc_header = irp->AssociatedIrp.SystemBuffer;
|
||||||
|
|
||||||
if( gddr.desc_type != USB_DT_CONFIG && gddr.desc_type != USB_DT_DEVICE )
|
if (gddr.desc_type != USB_DT_CONFIG && gddr.desc_type != USB_DT_DEVICE)
|
||||||
{
|
{
|
||||||
EXIT_DISPATCH( STATUS_INVALID_DEVICE_REQUEST, irp );
|
EXIT_DISPATCH(STATUS_INVALID_DEVICE_REQUEST, irp);
|
||||||
}
|
}
|
||||||
|
|
||||||
if( usb_query_and_lock_dev( dev_mgr, gddr.dev_handle, &pdev ) != STATUS_SUCCESS )
|
if (usb_query_and_lock_dev(dev_mgr, gddr.dev_handle, &pdev) != STATUS_SUCCESS)
|
||||||
{
|
{
|
||||||
EXIT_DISPATCH( STATUS_IO_DEVICE_ERROR, irp );
|
EXIT_DISPATCH(STATUS_IO_DEVICE_ERROR, irp);
|
||||||
}
|
}
|
||||||
|
|
||||||
lock_dev( pdev, FALSE );
|
lock_dev(pdev, FALSE);
|
||||||
if( dev_state( pdev ) == USB_DEV_STATE_ZOMB )
|
if (dev_state(pdev) == USB_DEV_STATE_ZOMB)
|
||||||
{
|
{
|
||||||
status = STATUS_INVALID_DEVICE_STATE;
|
status = STATUS_INVALID_DEVICE_STATE;
|
||||||
goto ERROR_OUT;
|
goto ERROR_OUT;
|
||||||
}
|
}
|
||||||
if( dev_state( pdev ) != USB_DEV_STATE_ADDRESSED && \
|
if (dev_state(pdev) != USB_DEV_STATE_ADDRESSED &&
|
||||||
dev_state( pdev ) != USB_DEV_STATE_CONFIGURED )
|
dev_state(pdev) != USB_DEV_STATE_CONFIGURED)
|
||||||
{
|
{
|
||||||
status = STATUS_DEVICE_NOT_READY;
|
status = STATUS_DEVICE_NOT_READY;
|
||||||
goto ERROR_OUT;
|
goto ERROR_OUT;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( pdev->pusb_dev_desc == NULL )
|
if (pdev->pusb_dev_desc == NULL)
|
||||||
{
|
{
|
||||||
status = STATUS_DEVICE_NOT_READY;
|
status = STATUS_DEVICE_NOT_READY;
|
||||||
goto ERROR_OUT;
|
goto ERROR_OUT;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( gddr.desc_type == USB_DT_DEVICE )
|
if (gddr.desc_type == USB_DT_DEVICE)
|
||||||
{
|
{
|
||||||
RtlCopyMemory(
|
RtlCopyMemory(pusb_desc_header,
|
||||||
pusb_desc_header,
|
|
||||||
pdev->pusb_dev_desc,
|
pdev->pusb_dev_desc,
|
||||||
buf_size > sizeof( USB_DEVICE_DESC )
|
buf_size > sizeof(USB_DEVICE_DESC)
|
||||||
? sizeof( USB_DEVICE_DESC ) : buf_size );
|
? sizeof(USB_DEVICE_DESC) : buf_size);
|
||||||
|
|
||||||
irp->IoStatus.Information =
|
irp->IoStatus.Information =
|
||||||
buf_size >= sizeof( USB_DEVICE_DESC )
|
buf_size >= sizeof(USB_DEVICE_DESC) ? sizeof(USB_DEVICE_DESC) : buf_size;
|
||||||
? sizeof( USB_DEVICE_DESC ): buf_size ;
|
|
||||||
}
|
}
|
||||||
else if( gddr.desc_type == USB_DT_CONFIG )
|
else if (gddr.desc_type == USB_DT_CONFIG)
|
||||||
{
|
{
|
||||||
PUSB_CONFIGURATION_DESC pusb_config_desc;
|
PUSB_CONFIGURATION_DESC pusb_config_desc;
|
||||||
if( pdev->pusb_dev_desc->bNumConfigurations <= gddr.desc_idx )
|
if (pdev->pusb_dev_desc->bNumConfigurations <= gddr.desc_idx)
|
||||||
{
|
{
|
||||||
status = STATUS_INVALID_PARAMETER;
|
status = STATUS_INVALID_PARAMETER;
|
||||||
goto ERROR_OUT;
|
goto ERROR_OUT;
|
||||||
}
|
}
|
||||||
|
|
||||||
pusb_config_desc = usb_find_config_desc_by_idx(
|
pusb_config_desc = usb_find_config_desc_by_idx((PUCHAR) & pdev->pusb_dev_desc[1],
|
||||||
( PUCHAR )&pdev->pusb_dev_desc[ 1 ],
|
|
||||||
gddr.desc_idx,
|
gddr.desc_idx,
|
||||||
pdev->pusb_dev_desc->bNumConfigurations );
|
pdev->pusb_dev_desc->
|
||||||
|
bNumConfigurations);
|
||||||
|
|
||||||
if( pusb_config_desc == NULL )
|
if (pusb_config_desc == NULL)
|
||||||
{
|
{
|
||||||
status = STATUS_DEVICE_NOT_READY;
|
status = STATUS_DEVICE_NOT_READY;
|
||||||
goto ERROR_OUT;
|
goto ERROR_OUT;
|
||||||
}
|
}
|
||||||
|
|
||||||
RtlCopyMemory(
|
RtlCopyMemory(pusb_desc_header,
|
||||||
pusb_desc_header,
|
|
||||||
pusb_config_desc,
|
pusb_config_desc,
|
||||||
buf_size >= pusb_config_desc->wTotalLength
|
buf_size >= pusb_config_desc->wTotalLength
|
||||||
? pusb_config_desc->wTotalLength : buf_size );
|
? pusb_config_desc->wTotalLength : buf_size);
|
||||||
|
|
||||||
irp->IoStatus.Information =
|
irp->IoStatus.Information =
|
||||||
buf_size >= pusb_config_desc->wTotalLength
|
buf_size >= pusb_config_desc->wTotalLength
|
||||||
? pusb_config_desc->wTotalLength : buf_size;
|
? pusb_config_desc->wTotalLength : buf_size;
|
||||||
}
|
}
|
||||||
ERROR_OUT:
|
ERROR_OUT:
|
||||||
unlock_dev( pdev, FALSE );
|
unlock_dev(pdev, FALSE);
|
||||||
usb_unlock_dev( pdev );
|
usb_unlock_dev(pdev);
|
||||||
EXIT_DISPATCH( status, irp );
|
EXIT_DISPATCH(status, irp);
|
||||||
}
|
}
|
||||||
case IOCTL_SUBMIT_URB_RD:
|
case IOCTL_SUBMIT_URB_RD:
|
||||||
case IOCTL_SUBMIT_URB_WR:
|
case IOCTL_SUBMIT_URB_WR:
|
||||||
|
@ -379,64 +372,62 @@ IN PIRP irp
|
||||||
|
|
||||||
PUSB_CTRL_SETUP_PACKET psetup;
|
PUSB_CTRL_SETUP_PACKET psetup;
|
||||||
|
|
||||||
if( irp_stack->Parameters.DeviceIoControl.InputBufferLength < sizeof( URB ) )
|
if (irp_stack->Parameters.DeviceIoControl.InputBufferLength < sizeof(URB))
|
||||||
{
|
{
|
||||||
EXIT_DISPATCH( STATUS_INVALID_PARAMETER, irp );
|
EXIT_DISPATCH(STATUS_INVALID_PARAMETER, irp);
|
||||||
}
|
}
|
||||||
|
|
||||||
purb = ( PURB )irp->AssociatedIrp.SystemBuffer;
|
purb = (PURB) irp->AssociatedIrp.SystemBuffer;
|
||||||
endp_handle = purb->endp_handle;
|
endp_handle = purb->endp_handle;
|
||||||
|
|
||||||
if( ctrl_code == IOCTL_SUBMIT_URB_RD || ctrl_code == IOCTL_SUBMIT_URB_WR )
|
if (ctrl_code == IOCTL_SUBMIT_URB_RD || ctrl_code == IOCTL_SUBMIT_URB_WR)
|
||||||
{
|
{
|
||||||
if( irp_stack->MajorFunction == IRP_MJ_DEVICE_CONTROL )
|
if (irp_stack->MajorFunction == IRP_MJ_DEVICE_CONTROL)
|
||||||
{
|
{
|
||||||
user_buffer_length = irp_stack->Parameters.DeviceIoControl.OutputBufferLength;
|
user_buffer_length = irp_stack->Parameters.DeviceIoControl.OutputBufferLength;
|
||||||
if( user_buffer_length == 0 )
|
if (user_buffer_length == 0)
|
||||||
EXIT_DISPATCH( STATUS_INVALID_PARAMETER, irp );
|
EXIT_DISPATCH(STATUS_INVALID_PARAMETER, irp);
|
||||||
user_buffer = MmGetSystemAddressForMdl( irp->MdlAddress );
|
user_buffer = MmGetSystemAddressForMdl(irp->MdlAddress);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if( purb->data_buffer == NULL || purb->data_length == 0 )
|
if (purb->data_buffer == NULL || purb->data_length == 0)
|
||||||
EXIT_DISPATCH( STATUS_INVALID_PARAMETER, irp );
|
EXIT_DISPATCH(STATUS_INVALID_PARAMETER, irp);
|
||||||
user_buffer_length = purb->data_length;
|
user_buffer_length = purb->data_length;
|
||||||
user_buffer = purb->data_buffer;
|
user_buffer = purb->data_buffer;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if( usb_query_and_lock_dev( dev_mgr, endp_handle & ~0xffff, &pdev ) != STATUS_SUCCESS )
|
if (usb_query_and_lock_dev(dev_mgr, endp_handle & ~0xffff, &pdev) != STATUS_SUCCESS)
|
||||||
{
|
{
|
||||||
EXIT_DISPATCH( STATUS_IO_DEVICE_ERROR, irp );
|
EXIT_DISPATCH(STATUS_IO_DEVICE_ERROR, irp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
lock_dev( pdev, FALSE );
|
lock_dev(pdev, FALSE);
|
||||||
if( dev_state( pdev ) == USB_DEV_STATE_ZOMB \
|
if (dev_state(pdev) == USB_DEV_STATE_ZOMB || (dev_state(pdev) < USB_DEV_STATE_ADDRESSED))
|
||||||
|| ( dev_state( pdev ) < USB_DEV_STATE_ADDRESSED ) )
|
|
||||||
|
|
||||||
{
|
{
|
||||||
status = STATUS_INVALID_DEVICE_STATE;
|
status = STATUS_INVALID_DEVICE_STATE;
|
||||||
goto ERROR_OUT1;
|
goto ERROR_OUT1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( dev_state( pdev ) == USB_DEV_STATE_ADDRESSED
|
if (dev_state(pdev) == USB_DEV_STATE_ADDRESSED && !default_endp_handle(endp_handle))
|
||||||
&& !default_endp_handle( endp_handle ) )
|
|
||||||
{
|
{
|
||||||
status = STATUS_DEVICE_NOT_READY;
|
status = STATUS_DEVICE_NOT_READY;
|
||||||
goto ERROR_OUT1;
|
goto ERROR_OUT1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if_idx = if_idx_from_handle( endp_handle );
|
if_idx = if_idx_from_handle(endp_handle);
|
||||||
endp_idx = endp_idx_from_handle( endp_handle );
|
endp_idx = endp_idx_from_handle(endp_handle);
|
||||||
|
|
||||||
//if_idx exceeds the upper limit
|
//if_idx exceeds the upper limit
|
||||||
if( pdev->usb_config )
|
if (pdev->usb_config)
|
||||||
{
|
{
|
||||||
if( if_idx >= pdev->usb_config->if_count
|
if (if_idx >= pdev->usb_config->if_count
|
||||||
|| endp_idx >= pdev->usb_config->interf[ if_idx ].endp_count )
|
|| endp_idx >= pdev->usb_config->interf[if_idx].endp_count)
|
||||||
{
|
{
|
||||||
if( !default_endp_handle( endp_handle ) )
|
if (!default_endp_handle(endp_handle))
|
||||||
{
|
{
|
||||||
status = STATUS_INVALID_DEVICE_STATE;
|
status = STATUS_INVALID_DEVICE_STATE;
|
||||||
goto ERROR_OUT1;
|
goto ERROR_OUT1;
|
||||||
|
@ -444,11 +435,11 @@ IN PIRP irp
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
endp_from_handle( pdev, endp_handle, pendp );
|
endp_from_handle(pdev, endp_handle, pendp);
|
||||||
// FIXME: don't know what evil will let loose
|
// FIXME: don't know what evil will let loose
|
||||||
if( endp_type( pendp ) != USB_ENDPOINT_XFER_CONTROL )
|
if (endp_type(pendp) != USB_ENDPOINT_XFER_CONTROL)
|
||||||
{
|
{
|
||||||
if( user_buffer_length > 0x100000 )
|
if (user_buffer_length > 0x100000)
|
||||||
{
|
{
|
||||||
status = STATUS_INVALID_PARAMETER;
|
status = STATUS_INVALID_PARAMETER;
|
||||||
goto ERROR_OUT1;
|
goto ERROR_OUT1;
|
||||||
|
@ -459,12 +450,12 @@ IN PIRP irp
|
||||||
purb->context = dev_mgr;
|
purb->context = dev_mgr;
|
||||||
purb->reference = ctrl_code;
|
purb->reference = ctrl_code;
|
||||||
|
|
||||||
if( ctrl_code == IOCTL_SUBMIT_URB_RD || ctrl_code == IOCTL_SUBMIT_URB_WR )
|
if (ctrl_code == IOCTL_SUBMIT_URB_RD || ctrl_code == IOCTL_SUBMIT_URB_WR)
|
||||||
{
|
{
|
||||||
if( ctrl_code == IOCTL_SUBMIT_URB_RD )
|
if (ctrl_code == IOCTL_SUBMIT_URB_RD)
|
||||||
KeFlushIoBuffers( irp->MdlAddress, TRUE, TRUE );
|
KeFlushIoBuffers(irp->MdlAddress, TRUE, TRUE);
|
||||||
else
|
else
|
||||||
KeFlushIoBuffers( irp->MdlAddress, FALSE, TRUE );
|
KeFlushIoBuffers(irp->MdlAddress, FALSE, TRUE);
|
||||||
|
|
||||||
purb->data_buffer = user_buffer;
|
purb->data_buffer = user_buffer;
|
||||||
purb->data_length = user_buffer_length;
|
purb->data_length = user_buffer_length;
|
||||||
|
@ -475,35 +466,35 @@ IN PIRP irp
|
||||||
purb->completion = disp_noio_urb_completion;
|
purb->completion = disp_noio_urb_completion;
|
||||||
}
|
}
|
||||||
|
|
||||||
unlock_dev( pdev, FALSE );
|
unlock_dev(pdev, FALSE);
|
||||||
|
|
||||||
// we have to mark irp before the urb is scheduled to
|
// we have to mark irp before the urb is scheduled to
|
||||||
// avoid race condition
|
// avoid race condition
|
||||||
IoMarkIrpPending( irp );
|
IoMarkIrpPending(irp);
|
||||||
ASSERT( dev_mgr_register_irp( dev_mgr, irp, purb ) );
|
ASSERT(dev_mgr_register_irp(dev_mgr, irp, purb));
|
||||||
status = usb_submit_urb( dev_mgr, purb );
|
status = usb_submit_urb(dev_mgr, purb);
|
||||||
if( status != STATUS_PENDING )
|
if (status != STATUS_PENDING)
|
||||||
{
|
{
|
||||||
IoGetCurrentIrpStackLocation( (irp) )->Control &= ~SL_PENDING_RETURNED;
|
IoGetCurrentIrpStackLocation((irp))->Control &= ~SL_PENDING_RETURNED;
|
||||||
dev_mgr_remove_irp( dev_mgr, irp );
|
dev_mgr_remove_irp(dev_mgr, irp);
|
||||||
}
|
}
|
||||||
usb_unlock_dev( pdev );
|
usb_unlock_dev(pdev);
|
||||||
if( status != STATUS_PENDING)
|
if (status != STATUS_PENDING)
|
||||||
{
|
{
|
||||||
irp->IoStatus.Status = status;
|
irp->IoStatus.Status = status;
|
||||||
IoCompleteRequest( irp, IO_NO_INCREMENT);
|
IoCompleteRequest(irp, IO_NO_INCREMENT);
|
||||||
}
|
}
|
||||||
return status;
|
return status;
|
||||||
ERROR_OUT1:
|
ERROR_OUT1:
|
||||||
unlock_dev( pdev, FALSE );
|
unlock_dev(pdev, FALSE);
|
||||||
usb_unlock_dev( pdev );
|
usb_unlock_dev(pdev);
|
||||||
irp->IoStatus.Information = 0;
|
irp->IoStatus.Information = 0;
|
||||||
EXIT_DISPATCH( status, irp );
|
EXIT_DISPATCH(status, irp);
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
irp->IoStatus.Information = 0;
|
irp->IoStatus.Information = 0;
|
||||||
EXIT_DISPATCH( STATUS_NOT_IMPLEMENTED, irp );
|
EXIT_DISPATCH(STATUS_NOT_IMPLEMENTED, irp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -513,7 +504,7 @@ IN PIRP irp
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
EXIT_DISPATCH( STATUS_INVALID_DEVICE_REQUEST, irp );
|
EXIT_DISPATCH(STATUS_INVALID_DEVICE_REQUEST, irp);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*#define IOCTL_GET_DEV_COUNT CTL_CODE( FILE_HCD_DEV_TYPE, 4093, METHOD_BUFFERED, FILE_ANY_ACCESS )
|
/*#define IOCTL_GET_DEV_COUNT CTL_CODE( FILE_HCD_DEV_TYPE, 4093, METHOD_BUFFERED, FILE_ANY_ACCESS )
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -67,72 +67,42 @@
|
||||||
max_liSTS = ( EHCI_MAX_ELEMS_POOL / ii1 ) > EHCI_MAX_LISTS_POOL ? EHCI_MAX_LISTS_POOL : ( EHCI_MAX_ELEMS_POOL / ii1 );\
|
max_liSTS = ( EHCI_MAX_ELEMS_POOL / ii1 ) > EHCI_MAX_LISTS_POOL ? EHCI_MAX_LISTS_POOL : ( EHCI_MAX_ELEMS_POOL / ii1 );\
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
VOID elem_list_destroy_elem_list(PEHCI_ELEM_LIST plist);
|
||||||
elem_list_destroy_elem_list(
|
|
||||||
PEHCI_ELEM_LIST plist
|
|
||||||
);
|
|
||||||
|
|
||||||
PLIST_ENTRY
|
PLIST_ENTRY elem_list_get_list_head(PEHCI_ELEM_LIST plist);
|
||||||
elem_list_get_list_head(
|
|
||||||
PEHCI_ELEM_LIST plist
|
|
||||||
);
|
|
||||||
|
|
||||||
LONG
|
LONG elem_list_get_total_count(PEHCI_ELEM_LIST plist);
|
||||||
elem_list_get_total_count(
|
|
||||||
PEHCI_ELEM_LIST plist
|
|
||||||
);
|
|
||||||
|
|
||||||
LONG
|
LONG elem_list_get_elem_size(PEHCI_ELEM_LIST plist);
|
||||||
elem_list_get_elem_size(
|
|
||||||
PEHCI_ELEM_LIST plist
|
|
||||||
);
|
|
||||||
|
|
||||||
LONG
|
LONG elem_list_get_link_offset(PEHCI_ELEM_LIST plist);
|
||||||
elem_list_get_link_offset(
|
|
||||||
PEHCI_ELEM_LIST plist
|
|
||||||
);
|
|
||||||
|
|
||||||
LONG
|
LONG elem_list_add_ref(PEHCI_ELEM_LIST plist);
|
||||||
elem_list_add_ref(
|
|
||||||
PEHCI_ELEM_LIST plist
|
|
||||||
);
|
|
||||||
|
|
||||||
LONG
|
LONG elem_list_release_ref(PEHCI_ELEM_LIST plist);
|
||||||
elem_list_release_ref(
|
|
||||||
PEHCI_ELEM_LIST plist
|
|
||||||
);
|
|
||||||
|
|
||||||
LONG
|
LONG elem_list_get_ref(PEHCI_ELEM_LIST plist);
|
||||||
elem_list_get_ref(
|
|
||||||
PEHCI_ELEM_LIST plist
|
|
||||||
);
|
|
||||||
|
|
||||||
BOOL
|
BOOL
|
||||||
elem_pool_lock(
|
elem_pool_lock(PEHCI_ELEM_POOL pool, BOOL at_dpc)
|
||||||
PEHCI_ELEM_POOL pool,
|
|
||||||
BOOL at_dpc
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL
|
BOOL
|
||||||
elem_pool_unlock(
|
elem_pool_unlock(PEHCI_ELEM_POOL pool, BOOL at_dpc)
|
||||||
PEHCI_ELEM_POOL pool,
|
|
||||||
BOOL at_dpc
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
LONG
|
LONG
|
||||||
get_elem_phys_part_size(
|
get_elem_phys_part_size(ULONG type)
|
||||||
ULONG type
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
// type is INIT_LIST_FLAG_XXX
|
// type is INIT_LIST_FLAG_XXX
|
||||||
LONG size;
|
LONG size;
|
||||||
|
|
||||||
size = 0;
|
size = 0;
|
||||||
switch( type )
|
switch (type)
|
||||||
{
|
{
|
||||||
case INIT_LIST_FLAG_ITD:
|
case INIT_LIST_FLAG_ITD:
|
||||||
size = 64;
|
size = 64;
|
||||||
|
@ -154,12 +124,7 @@ ULONG type
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL
|
BOOL
|
||||||
elem_list_init_elem_list(
|
elem_list_init_elem_list(PEHCI_ELEM_LIST plist, LONG init_flags, PVOID context, LONG count)
|
||||||
PEHCI_ELEM_LIST plist,
|
|
||||||
LONG init_flags,
|
|
||||||
PVOID context,
|
|
||||||
LONG count
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
LONG pages, i, j, elms_per_page;
|
LONG pages, i, j, elms_per_page;
|
||||||
PEHCI_QH pqh;
|
PEHCI_QH pqh;
|
||||||
|
@ -169,10 +134,10 @@ LONG count
|
||||||
PEHCI_FSTN pfstn;
|
PEHCI_FSTN pfstn;
|
||||||
PINIT_ELEM_LIST_CONTEXT pinit_ctx;
|
PINIT_ELEM_LIST_CONTEXT pinit_ctx;
|
||||||
|
|
||||||
if( plist == NULL || context == NULL )
|
if (plist == NULL || context == NULL)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
RtlZeroMemory( plist, sizeof( EHCI_ELEM_LIST ) );
|
RtlZeroMemory(plist, sizeof(EHCI_ELEM_LIST));
|
||||||
|
|
||||||
pinit_ctx = context;
|
pinit_ctx = context;
|
||||||
|
|
||||||
|
@ -185,34 +150,34 @@ LONG count
|
||||||
plist->release_ref = elem_list_release_ref;
|
plist->release_ref = elem_list_release_ref;
|
||||||
plist->get_ref = elem_list_get_ref;
|
plist->get_ref = elem_list_get_ref;
|
||||||
|
|
||||||
InitializeListHead( &plist->free_list );
|
InitializeListHead(&plist->free_list);
|
||||||
|
|
||||||
switch( init_flags & 0x0f )
|
switch (init_flags & 0x0f)
|
||||||
{
|
{
|
||||||
case INIT_LIST_FLAG_ITD:
|
case INIT_LIST_FLAG_ITD:
|
||||||
plist->total_count = EHCI_MAX_ITDS_LIST;
|
plist->total_count = EHCI_MAX_ITDS_LIST;
|
||||||
plist->elem_size = sizeof( EHCI_ITD );
|
plist->elem_size = sizeof(EHCI_ITD);
|
||||||
break;
|
break;
|
||||||
case INIT_LIST_FLAG_QH:
|
case INIT_LIST_FLAG_QH:
|
||||||
plist->total_count = EHCI_MAX_QHS_LIST;
|
plist->total_count = EHCI_MAX_QHS_LIST;
|
||||||
plist->elem_size = sizeof( EHCI_QH );
|
plist->elem_size = sizeof(EHCI_QH);
|
||||||
break;
|
break;
|
||||||
case INIT_LIST_FLAG_SITD:
|
case INIT_LIST_FLAG_SITD:
|
||||||
plist->total_count = EHCI_MAX_SITDS_LIST;
|
plist->total_count = EHCI_MAX_SITDS_LIST;
|
||||||
plist->elem_size = sizeof( EHCI_SITD );
|
plist->elem_size = sizeof(EHCI_SITD);
|
||||||
break;
|
break;
|
||||||
case INIT_LIST_FLAG_FSTN:
|
case INIT_LIST_FLAG_FSTN:
|
||||||
plist->total_count = EHCI_MAX_FSTNS_LIST;
|
plist->total_count = EHCI_MAX_FSTNS_LIST;
|
||||||
plist->elem_size = sizeof( EHCI_FSTN );
|
plist->elem_size = sizeof(EHCI_FSTN);
|
||||||
break;
|
break;
|
||||||
case INIT_LIST_FLAG_QTD:
|
case INIT_LIST_FLAG_QTD:
|
||||||
plist->total_count = EHCI_MAX_QTDS_LIST;
|
plist->total_count = EHCI_MAX_QTDS_LIST;
|
||||||
plist->elem_size = sizeof( EHCI_QTD );
|
plist->elem_size = sizeof(EHCI_QTD);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
goto ERROR_OUT;
|
goto ERROR_OUT;
|
||||||
}
|
}
|
||||||
if( plist->elem_size & 0x1f )
|
if (plist->elem_size & 0x1f)
|
||||||
{
|
{
|
||||||
plist->total_count = 0;
|
plist->total_count = 0;
|
||||||
goto ERROR_OUT;
|
goto ERROR_OUT;
|
||||||
|
@ -221,73 +186,66 @@ LONG count
|
||||||
plist->flags = init_flags;
|
plist->flags = init_flags;
|
||||||
plist->parent_pool = pinit_ctx->pool;
|
plist->parent_pool = pinit_ctx->pool;
|
||||||
plist->padapter = pinit_ctx->padapter;
|
plist->padapter = pinit_ctx->padapter;
|
||||||
pages = ( ( plist->elem_size * plist->total_count ) + ( PAGE_SIZE - 1 ) ) / PAGE_SIZE;
|
pages = ((plist->elem_size * plist->total_count) + (PAGE_SIZE - 1)) / PAGE_SIZE;
|
||||||
elms_per_page = PAGE_SIZE / plist->elem_size;
|
elms_per_page = PAGE_SIZE / plist->elem_size;
|
||||||
|
|
||||||
plist->phys_addrs = usb_alloc_mem( NonPagedPool,
|
plist->phys_addrs = usb_alloc_mem(NonPagedPool,
|
||||||
( sizeof( PHYSICAL_ADDRESS ) + sizeof( PBYTE ) ) * pages + \
|
(sizeof(PHYSICAL_ADDRESS) + sizeof(PBYTE)) * pages +
|
||||||
sizeof( EHCI_ELEM_LINKS ) * plist->total_count );
|
sizeof(EHCI_ELEM_LINKS) * plist->total_count);
|
||||||
|
|
||||||
if( plist->phys_addrs == NULL )
|
if (plist->phys_addrs == NULL)
|
||||||
{
|
{
|
||||||
plist->total_count = 0;
|
plist->total_count = 0;
|
||||||
goto ERROR_OUT;
|
goto ERROR_OUT;
|
||||||
}
|
}
|
||||||
|
|
||||||
plist->phys_bufs = ( PBYTE* )&plist->phys_addrs[ pages ];
|
plist->phys_bufs = (PBYTE *) & plist->phys_addrs[pages];
|
||||||
plist->elem_head_buf = ( PEHCI_ELEM_LINKS )&plist->phys_bufs[ pages ];
|
plist->elem_head_buf = (PEHCI_ELEM_LINKS) & plist->phys_bufs[pages];
|
||||||
RtlZeroMemory( plist->phys_addrs,
|
RtlZeroMemory(plist->phys_addrs,
|
||||||
( sizeof( PHYSICAL_ADDRESS ) + sizeof( PBYTE ) ) * pages + \
|
(sizeof(PHYSICAL_ADDRESS) + sizeof(PBYTE)) * pages +
|
||||||
sizeof( EHCI_ELEM_LINKS ) * plist->total_count );
|
sizeof(EHCI_ELEM_LINKS) * plist->total_count);
|
||||||
|
|
||||||
for( i = 0; i < pages; i++ )
|
for(i = 0; i < pages; i++)
|
||||||
{
|
{
|
||||||
plist->phys_bufs[ i ] = HalAllocateCommonBuffer(
|
plist->phys_bufs[i] = HalAllocateCommonBuffer(plist->padapter,
|
||||||
plist->padapter,
|
PAGE_SIZE, &plist->phys_addrs[i], FALSE);
|
||||||
PAGE_SIZE,
|
|
||||||
&plist->phys_addrs[ i ],
|
|
||||||
FALSE);
|
|
||||||
|
|
||||||
if( plist->phys_bufs[ i ] == NULL )
|
if (plist->phys_bufs[i] == NULL)
|
||||||
{
|
{
|
||||||
// failed, roll back
|
// failed, roll back
|
||||||
for( j = i - 1; j >= 0; j -- )
|
for(j = i - 1; j >= 0; j--)
|
||||||
HalFreeCommonBuffer(
|
HalFreeCommonBuffer(plist->padapter,
|
||||||
plist->padapter,
|
PAGE_SIZE, plist->phys_addrs[j], plist->phys_bufs[j], FALSE);
|
||||||
PAGE_SIZE,
|
|
||||||
plist->phys_addrs[ j ],
|
|
||||||
plist->phys_bufs[ j ],
|
|
||||||
FALSE );
|
|
||||||
goto ERROR_OUT;
|
goto ERROR_OUT;
|
||||||
}
|
}
|
||||||
RtlZeroMemory( plist->phys_bufs[ i ], PAGE_SIZE );
|
RtlZeroMemory(plist->phys_bufs[i], PAGE_SIZE);
|
||||||
for( j = 0; j < elms_per_page; j++ )
|
for(j = 0; j < elms_per_page; j++)
|
||||||
{
|
{
|
||||||
switch( init_flags & 0xf )
|
switch (init_flags & 0xf)
|
||||||
{
|
{
|
||||||
case INIT_LIST_FLAG_QH:
|
case INIT_LIST_FLAG_QH:
|
||||||
{
|
{
|
||||||
init_elem( pqh, EHCI_QH, INIT_LIST_FLAG_QH );
|
init_elem(pqh, EHCI_QH, INIT_LIST_FLAG_QH);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case INIT_LIST_FLAG_ITD:
|
case INIT_LIST_FLAG_ITD:
|
||||||
{
|
{
|
||||||
init_elem( pitd, EHCI_ITD, INIT_LIST_FLAG_ITD );
|
init_elem(pitd, EHCI_ITD, INIT_LIST_FLAG_ITD);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case INIT_LIST_FLAG_QTD:
|
case INIT_LIST_FLAG_QTD:
|
||||||
{
|
{
|
||||||
init_elem( pqtd, EHCI_QTD, INIT_LIST_FLAG_QTD );
|
init_elem(pqtd, EHCI_QTD, INIT_LIST_FLAG_QTD);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case INIT_LIST_FLAG_SITD:
|
case INIT_LIST_FLAG_SITD:
|
||||||
{
|
{
|
||||||
init_elem( psitd, EHCI_SITD, INIT_LIST_FLAG_SITD );
|
init_elem(psitd, EHCI_SITD, INIT_LIST_FLAG_SITD);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case INIT_LIST_FLAG_FSTN:
|
case INIT_LIST_FLAG_FSTN:
|
||||||
{
|
{
|
||||||
init_elem( pfstn, EHCI_FSTN, INIT_LIST_FLAG_FSTN );
|
init_elem(pfstn, EHCI_FSTN, INIT_LIST_FLAG_FSTN);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
@ -296,101 +254,80 @@ LONG count
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
ERROR_OUT:
|
ERROR_OUT:
|
||||||
|
if (plist->phys_addrs != NULL)
|
||||||
|
usb_free_mem(plist->phys_addrs);
|
||||||
|
|
||||||
if( plist->phys_addrs != NULL )
|
RtlZeroMemory(plist, sizeof(EHCI_ELEM_LIST));
|
||||||
usb_free_mem( plist->phys_addrs );
|
|
||||||
|
|
||||||
RtlZeroMemory( plist, sizeof( EHCI_ELEM_LIST ) );
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
elem_list_destroy_elem_list(
|
elem_list_destroy_elem_list(PEHCI_ELEM_LIST plist)
|
||||||
PEHCI_ELEM_LIST plist
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
LONG i, pages;
|
LONG i, pages;
|
||||||
|
|
||||||
if( plist == NULL )
|
if (plist == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
pages = ( plist->total_count * plist->elem_size + PAGE_SIZE - 1 ) / PAGE_SIZE;
|
pages = (plist->total_count * plist->elem_size + PAGE_SIZE - 1) / PAGE_SIZE;
|
||||||
for( i = 0; i < pages; i++ )
|
for(i = 0; i < pages; i++)
|
||||||
HalFreeCommonBuffer(
|
HalFreeCommonBuffer(plist->padapter, PAGE_SIZE, plist->phys_addrs[i], plist->phys_bufs[i], FALSE);
|
||||||
plist->padapter,
|
|
||||||
PAGE_SIZE,
|
|
||||||
plist->phys_addrs[ i ],
|
|
||||||
plist->phys_bufs[ i ],
|
|
||||||
FALSE );
|
|
||||||
|
|
||||||
usb_free_mem( plist->phys_addrs );
|
usb_free_mem(plist->phys_addrs);
|
||||||
RtlZeroMemory( plist, sizeof( EHCI_ELEM_LIST ) );
|
RtlZeroMemory(plist, sizeof(EHCI_ELEM_LIST));
|
||||||
}
|
}
|
||||||
|
|
||||||
PLIST_ENTRY
|
PLIST_ENTRY
|
||||||
elem_list_get_list_head(
|
elem_list_get_list_head(PEHCI_ELEM_LIST plist)
|
||||||
PEHCI_ELEM_LIST plist
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
if( plist == NULL )
|
if (plist == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
return &plist->free_list;
|
return &plist->free_list;
|
||||||
}
|
}
|
||||||
|
|
||||||
LONG
|
LONG
|
||||||
elem_list_get_total_count(
|
elem_list_get_total_count(PEHCI_ELEM_LIST plist)
|
||||||
PEHCI_ELEM_LIST plist
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
if( plist == NULL )
|
if (plist == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
return plist->total_count;;
|
return plist->total_count;;
|
||||||
}
|
}
|
||||||
|
|
||||||
LONG
|
LONG
|
||||||
elem_list_get_elem_size(
|
elem_list_get_elem_size(PEHCI_ELEM_LIST plist)
|
||||||
PEHCI_ELEM_LIST plist
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
if( plist == NULL )
|
if (plist == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
return plist->elem_size;
|
return plist->elem_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
LONG
|
LONG
|
||||||
elem_list_get_link_offset(
|
elem_list_get_link_offset(PEHCI_ELEM_LIST plist)
|
||||||
PEHCI_ELEM_LIST plist
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
if( plist == NULL )
|
if (plist == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return get_elem_phys_part_size( plist->flags & 0xf );
|
return get_elem_phys_part_size(plist->flags & 0xf);
|
||||||
}
|
}
|
||||||
|
|
||||||
LONG
|
LONG
|
||||||
elem_list_add_ref(
|
elem_list_add_ref(PEHCI_ELEM_LIST plist)
|
||||||
PEHCI_ELEM_LIST plist
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
plist->reference++;
|
plist->reference++;
|
||||||
return plist->reference;
|
return plist->reference;
|
||||||
}
|
}
|
||||||
|
|
||||||
LONG
|
LONG
|
||||||
elem_list_release_ref(
|
elem_list_release_ref(PEHCI_ELEM_LIST plist)
|
||||||
PEHCI_ELEM_LIST plist
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
plist->reference--;
|
plist->reference--;
|
||||||
return plist->reference;
|
return plist->reference;
|
||||||
}
|
}
|
||||||
|
|
||||||
LONG
|
LONG
|
||||||
elem_list_get_ref(
|
elem_list_get_ref(PEHCI_ELEM_LIST plist)
|
||||||
PEHCI_ELEM_LIST plist
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
return plist->reference;
|
return plist->reference;
|
||||||
}
|
}
|
||||||
|
@ -400,35 +337,31 @@ PEHCI_ELEM_LIST plist
|
||||||
//
|
//
|
||||||
|
|
||||||
BOOL
|
BOOL
|
||||||
elem_pool_init_pool(
|
elem_pool_init_pool(PEHCI_ELEM_POOL pool, LONG flags, PVOID context)
|
||||||
PEHCI_ELEM_POOL pool,
|
|
||||||
LONG flags,
|
|
||||||
PVOID context
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
PADAPTER_OBJECT padapter;
|
PADAPTER_OBJECT padapter;
|
||||||
INIT_ELEM_LIST_CONTEXT init_ctx;
|
INIT_ELEM_LIST_CONTEXT init_ctx;
|
||||||
|
|
||||||
if( pool == NULL || context == NULL )
|
if (pool == NULL || context == NULL)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
RtlZeroMemory( pool, sizeof( EHCI_ELEM_POOL ) );
|
RtlZeroMemory(pool, sizeof(EHCI_ELEM_POOL));
|
||||||
|
|
||||||
init_ctx.pool = pool;
|
init_ctx.pool = pool;
|
||||||
init_ctx.padapter = context;
|
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 )
|
if (pool->elem_lists[0] == NULL)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
if( elem_list_init_elem_list( pool->elem_lists[ 0 ], flags, &init_ctx, 0 ) == FALSE )
|
if (elem_list_init_elem_list(pool->elem_lists[0], flags, &init_ctx, 0) == FALSE)
|
||||||
{
|
{
|
||||||
usb_free_mem( pool->elem_lists[ 0 ] );
|
usb_free_mem(pool->elem_lists[0]);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
pool->link_offset = pool->elem_lists[ 0 ]->get_link_offset( pool->elem_lists[ 0 ] );
|
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->free_count = pool->elem_lists[0]->get_total_count(pool->elem_lists[0]);
|
||||||
pool->list_count = 1;
|
pool->list_count = 1;
|
||||||
pool->flags = flags;
|
pool->flags = flags;
|
||||||
|
|
||||||
|
@ -436,127 +369,110 @@ PVOID context
|
||||||
}
|
}
|
||||||
|
|
||||||
LONG
|
LONG
|
||||||
elem_pool_get_link_offset(
|
elem_pool_get_link_offset(PEHCI_ELEM_POOL elem_pool)
|
||||||
PEHCI_ELEM_POOL elem_pool
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
return elem_pool->link_offset;
|
return elem_pool->link_offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
LONG
|
LONG
|
||||||
elem_pool_get_total_count(
|
elem_pool_get_total_count(PEHCI_ELEM_POOL elem_pool)
|
||||||
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
|
VOID
|
||||||
elem_pool_destroy_pool(
|
elem_pool_destroy_pool(PEHCI_ELEM_POOL pool)
|
||||||
PEHCI_ELEM_POOL pool
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
LONG i;
|
LONG i;
|
||||||
if( pool == NULL )
|
if (pool == NULL)
|
||||||
return;
|
return;
|
||||||
for( i = pool->list_count - 1; i >= 0; i-- )
|
for(i = pool->list_count - 1; i >= 0; i--)
|
||||||
{
|
{
|
||||||
pool->elem_lists[ i ]->destroy_list( pool->elem_lists[ i ] );
|
pool->elem_lists[i]->destroy_list(pool->elem_lists[i]);
|
||||||
usb_free_mem( pool->elem_lists[ i ] );
|
usb_free_mem(pool->elem_lists[i]);
|
||||||
pool->elem_lists[ i ] = NULL;
|
pool->elem_lists[i] = NULL;
|
||||||
}
|
}
|
||||||
RtlZeroMemory( pool, sizeof( EHCI_ELEM_POOL ) );
|
RtlZeroMemory(pool, sizeof(EHCI_ELEM_POOL));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
PEHCI_ELEM_LINKS
|
PEHCI_ELEM_LINKS
|
||||||
elem_pool_alloc_elem(
|
elem_pool_alloc_elem(PEHCI_ELEM_POOL pool)
|
||||||
PEHCI_ELEM_POOL pool
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
LONG i;
|
LONG i;
|
||||||
PEHCI_ELEM_LIST pel;
|
PEHCI_ELEM_LIST pel;
|
||||||
PLIST_HEAD lh;
|
PLIST_HEAD lh;
|
||||||
PEHCI_ELEM_LINKS elnk;
|
PEHCI_ELEM_LINKS elnk;
|
||||||
|
|
||||||
if( pool == NULL )
|
if (pool == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
for( i = 0; i < pool->list_count; i++ )
|
for(i = 0; i < pool->list_count; i++)
|
||||||
{
|
{
|
||||||
pel = pool->elem_lists[ i ];
|
pel = pool->elem_lists[i];
|
||||||
if( pel->get_ref( pel ) == pel->get_total_count( pel ) )
|
if (pel->get_ref(pel) == pel->get_total_count(pel))
|
||||||
continue;
|
continue;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if( i == pool->list_count )
|
if (i == pool->list_count)
|
||||||
{
|
{
|
||||||
if( elem_pool_expand_pool( pool, pel->get_total_count( pel ) ) == FALSE )
|
if (elem_pool_expand_pool(pool, pel->get_total_count(pel)) == FALSE)
|
||||||
return NULL;
|
return NULL;
|
||||||
pel = pool->elem_lists[ i ];
|
pel = pool->elem_lists[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
lh = pel->get_list_head( pel );
|
lh = pel->get_list_head(pel);
|
||||||
elnk = ( PEHCI_ELEM_LINKS )RemoveHeadList( lh );
|
elnk = (PEHCI_ELEM_LINKS) RemoveHeadList(lh);
|
||||||
InitializeListHead( &elnk->elem_link );
|
InitializeListHead(&elnk->elem_link);
|
||||||
InitializeListHead( &elnk->sched_link );
|
InitializeListHead(&elnk->sched_link);
|
||||||
|
|
||||||
pel->add_ref( pel );
|
pel->add_ref(pel);
|
||||||
pool->free_count--;
|
pool->free_count--;
|
||||||
|
|
||||||
return elnk;
|
return elnk;
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
elem_pool_free_elem(
|
elem_pool_free_elem(PEHCI_ELEM_LINKS elem_link)
|
||||||
PEHCI_ELEM_LINKS elem_link
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
PLIST_HEAD lh;
|
PLIST_HEAD lh;
|
||||||
LONG ref;
|
LONG ref;
|
||||||
PEHCI_ELEM_POOL pool;
|
PEHCI_ELEM_POOL pool;
|
||||||
if( elem_link == NULL )
|
if (elem_link == NULL)
|
||||||
return;
|
return;
|
||||||
pool = elem_link->pool_link;
|
pool = elem_link->pool_link;
|
||||||
lh = elem_link->list_link->get_list_head( elem_link->list_link );
|
lh = elem_link->list_link->get_list_head(elem_link->list_link);
|
||||||
if( lh == NULL )
|
if (lh == NULL)
|
||||||
return;
|
return;
|
||||||
InsertHeadList( lh, ( PLIST_ENTRY )elem_link );
|
InsertHeadList(lh, (PLIST_ENTRY) elem_link);
|
||||||
ref = elem_link->list_link->release_ref( elem_link->list_link );
|
ref = elem_link->list_link->release_ref(elem_link->list_link);
|
||||||
pool->free_count++;
|
pool->free_count++;
|
||||||
if( ref == 0 )
|
if (ref == 0)
|
||||||
elem_pool_collect_garbage( pool );
|
elem_pool_collect_garbage(pool);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL
|
BOOL
|
||||||
elem_pool_is_empty(
|
elem_pool_is_empty(PEHCI_ELEM_POOL pool)
|
||||||
PEHCI_ELEM_POOL pool
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
PEHCI_ELEM_LIST pel;
|
PEHCI_ELEM_LIST pel;
|
||||||
|
|
||||||
if( pool == NULL )
|
if (pool == NULL)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
pel = pool->elem_lists[ 0 ];
|
pel = pool->elem_lists[0];
|
||||||
return ( pool->list_count == 1 && pool->free_count == pel->get_total_count( pel ) );
|
return (pool->list_count == 1 && pool->free_count == pel->get_total_count(pel));
|
||||||
}
|
}
|
||||||
|
|
||||||
LONG
|
LONG
|
||||||
elem_pool_get_free_count(
|
elem_pool_get_free_count(PEHCI_ELEM_POOL pool)
|
||||||
PEHCI_ELEM_POOL pool
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
if( pool == NULL )
|
if (pool == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
return pool->free_count;
|
return pool->free_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
PEHCI_ELEM_LINKS
|
PEHCI_ELEM_LINKS
|
||||||
elem_pool_alloc_elems(
|
elem_pool_alloc_elems(PEHCI_ELEM_POOL pool, LONG count)
|
||||||
PEHCI_ELEM_POOL pool,
|
|
||||||
LONG count
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
LIST_HEAD lh;
|
LIST_HEAD lh;
|
||||||
PLIST_ENTRY pthis;
|
PLIST_ENTRY pthis;
|
||||||
|
@ -565,105 +481,99 @@ LONG count
|
||||||
PEHCI_ELEM_LINKS elnk;
|
PEHCI_ELEM_LINKS elnk;
|
||||||
// calculate to see if the count is affordable
|
// calculate to see if the count is affordable
|
||||||
|
|
||||||
if( pool == NULL || count <= 0 )
|
if (pool == NULL || count <= 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
get_max_lists_count( pool, max_pool_lists );
|
get_max_lists_count(pool, max_pool_lists);
|
||||||
InitializeListHead( &lh );
|
InitializeListHead(&lh);
|
||||||
pel = pool->elem_lists[ 0 ];
|
pel = pool->elem_lists[0];
|
||||||
if( count <= pool->free_count )
|
if (count <= pool->free_count)
|
||||||
alloc_count = 0;
|
alloc_count = 0;
|
||||||
else
|
else
|
||||||
alloc_count = count - pool->free_count;
|
alloc_count = count - pool->free_count;
|
||||||
|
|
||||||
if( alloc_count > pel->get_total_count( pel ) * ( max_pool_lists - pool->list_count ) )
|
if (alloc_count > pel->get_total_count(pel) * (max_pool_lists - pool->list_count))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
for( i = 0; i < count; i++ )
|
for(i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
if( ( elnk = elem_pool_alloc_elem( pool ) ) == NULL )
|
if ((elnk = elem_pool_alloc_elem(pool)) == NULL)
|
||||||
{
|
{
|
||||||
// undo what we have done
|
// undo what we have done
|
||||||
while( IsListEmpty( &lh ) == FALSE )
|
while (IsListEmpty(&lh) == FALSE)
|
||||||
{
|
{
|
||||||
pthis = RemoveHeadList( &lh );
|
pthis = RemoveHeadList(&lh);
|
||||||
elnk = struct_ptr( pthis, EHCI_ELEM_LINKS, elem_link );
|
elnk = struct_ptr(pthis, EHCI_ELEM_LINKS, elem_link);
|
||||||
elem_pool_free_elem( elnk );
|
elem_pool_free_elem(elnk);
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
InsertTailList( &lh, &elnk->elem_link );
|
InsertTailList(&lh, &elnk->elem_link);
|
||||||
}
|
}
|
||||||
ListFirst( &lh, pthis );
|
ListFirst(&lh, pthis);
|
||||||
elnk = struct_ptr( pthis, EHCI_ELEM_LINKS, elem_link );
|
elnk = struct_ptr(pthis, EHCI_ELEM_LINKS, elem_link);
|
||||||
RemoveEntryList( &lh );
|
RemoveEntryList(&lh);
|
||||||
return elnk;
|
return elnk;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL
|
BOOL
|
||||||
elem_pool_free_elems(
|
elem_pool_free_elems(PEHCI_ELEM_LINKS elem_chains)
|
||||||
PEHCI_ELEM_LINKS elem_chains
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
// note: no list head exists.
|
// note: no list head exists.
|
||||||
LIST_HEAD lh;
|
LIST_HEAD lh;
|
||||||
PEHCI_ELEM_LINKS elnk;
|
PEHCI_ELEM_LINKS elnk;
|
||||||
|
|
||||||
InsertTailList( &elem_chains->elem_link, &lh );
|
InsertTailList(&elem_chains->elem_link, &lh);
|
||||||
while( IsListEmpty( &lh ) == FALSE )
|
while (IsListEmpty(&lh) == FALSE)
|
||||||
{
|
{
|
||||||
elnk = ( PEHCI_ELEM_LINKS )RemoveHeadList( &lh );
|
elnk = (PEHCI_ELEM_LINKS) RemoveHeadList(&lh);
|
||||||
elem_pool_free_elem( elnk );
|
elem_pool_free_elem(elnk);
|
||||||
}
|
}
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
LONG
|
LONG
|
||||||
elem_pool_get_type(
|
elem_pool_get_type(PEHCI_ELEM_POOL pool)
|
||||||
PEHCI_ELEM_POOL pool
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
if( pool == NULL )
|
if (pool == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
return ( pool->flags & 0xf );
|
return (pool->flags & 0xf);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL
|
BOOL
|
||||||
elem_pool_expand_pool(
|
elem_pool_expand_pool(PEHCI_ELEM_POOL pool, LONG elem_count)
|
||||||
PEHCI_ELEM_POOL pool,
|
|
||||||
LONG elem_count
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
LONG elem_cnt_list, list_count, i, j;
|
LONG elem_cnt_list, list_count, i, j;
|
||||||
INIT_ELEM_LIST_CONTEXT init_ctx;
|
INIT_ELEM_LIST_CONTEXT init_ctx;
|
||||||
|
|
||||||
if( pool == NULL || elem_count <= 0 || elem_count > EHCI_MAX_ELEMS_POOL )
|
if (pool == NULL || elem_count <= 0 || elem_count > EHCI_MAX_ELEMS_POOL)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
init_ctx.pool = pool;
|
init_ctx.pool = pool;
|
||||||
init_ctx.padapter = pool->elem_lists[ 0 ]->padapter;
|
init_ctx.padapter = pool->elem_lists[0]->padapter;
|
||||||
|
|
||||||
elem_cnt_list = pool->elem_lists[ 0 ]->get_total_count( pool->elem_lists[ 0 ] );
|
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;
|
list_count = (elem_count + elem_cnt_list - 1) / elem_cnt_list;
|
||||||
get_max_lists_count( pool, i );
|
get_max_lists_count(pool, i);
|
||||||
|
|
||||||
if( list_count + pool->list_count > i )
|
if (list_count + pool->list_count > i)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
for( i = pool->list_count; i < list_count + pool->list_count; i++ )
|
for(i = pool->list_count; i < list_count + pool->list_count; i++)
|
||||||
{
|
{
|
||||||
pool->elem_lists[ i ] = usb_alloc_mem( NonPagedPool, sizeof( EHCI_ELEM_LIST ) );
|
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 )
|
if (elem_list_init_elem_list(pool->elem_lists[i], pool->flags, &init_ctx, 0) == FALSE)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( i < list_count + pool->list_count )
|
if (i < list_count + pool->list_count)
|
||||||
{
|
{
|
||||||
// undo all we have done
|
// undo all we have done
|
||||||
for( j = pool->list_count; j < pool->list_count + i; j++ )
|
for(j = pool->list_count; j < pool->list_count + i; j++)
|
||||||
{
|
{
|
||||||
pool->elem_lists[ j ]->destroy_list( pool->elem_lists[ j ] );
|
pool->elem_lists[j]->destroy_list(pool->elem_lists[j]);
|
||||||
usb_free_mem( pool->elem_lists[ j ] );
|
usb_free_mem(pool->elem_lists[j]);
|
||||||
pool->elem_lists[ j ] = NULL;
|
pool->elem_lists[j] = NULL;
|
||||||
}
|
}
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
@ -675,59 +585,52 @@ LONG elem_count
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL
|
BOOL
|
||||||
elem_pool_collect_garbage(
|
elem_pool_collect_garbage(PEHCI_ELEM_POOL pool)
|
||||||
PEHCI_ELEM_POOL pool
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
LONG i, j, k, fl;
|
LONG i, j, k, fl;
|
||||||
LONG free_elem_lists[ EHCI_MAX_LISTS_POOL - 1 ];
|
LONG free_elem_lists[EHCI_MAX_LISTS_POOL - 1];
|
||||||
PEHCI_ELEM_LIST pel;
|
PEHCI_ELEM_LIST pel;
|
||||||
|
|
||||||
if( pool == NULL )
|
if (pool == NULL)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
for( i = 1, fl = 0; i < pool->list_count; i++ )
|
for(i = 1, fl = 0; i < pool->list_count; i++)
|
||||||
{
|
{
|
||||||
if( pool->elem_lists[ i ]->get_ref( pool->elem_lists[ i ] ) == 0 )
|
if (pool->elem_lists[i]->get_ref(pool->elem_lists[i]) == 0)
|
||||||
{
|
{
|
||||||
free_elem_lists[ fl++ ] = i;
|
free_elem_lists[fl++] = i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for( j = fl - 1; j >= 0; j-- )
|
for(j = fl - 1; j >= 0; j--)
|
||||||
{
|
{
|
||||||
pel = pool->elem_lists[ free_elem_lists[ j ] ];
|
pel = pool->elem_lists[free_elem_lists[j]];
|
||||||
pel->destroy_list( pel );
|
pel->destroy_list(pel);
|
||||||
usb_free_mem( pel );
|
usb_free_mem(pel);
|
||||||
|
|
||||||
for( k = free_elem_lists[ j ] + 1; k < pool->list_count; k++ )
|
for(k = free_elem_lists[j] + 1; k < pool->list_count; k++)
|
||||||
{
|
{
|
||||||
// shrink the elem_lists
|
// shrink the elem_lists
|
||||||
pool->elem_lists[ k - 1 ] = pool->elem_lists[ k ];
|
pool->elem_lists[k - 1] = pool->elem_lists[k];
|
||||||
}
|
}
|
||||||
pool->elem_lists[ k ] = NULL;
|
pool->elem_lists[k] = NULL;
|
||||||
pel = pool->elem_lists[ 0 ];
|
pel = pool->elem_lists[0];
|
||||||
pool->free_count -= pel->get_total_count( pel );
|
pool->free_count -= pel->get_total_count(pel);
|
||||||
pool->list_count --;
|
pool->list_count--;
|
||||||
}
|
}
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL
|
BOOL
|
||||||
elem_pool_can_transfer(
|
elem_pool_can_transfer(PEHCI_ELEM_POOL pool, LONG td_count)
|
||||||
PEHCI_ELEM_POOL pool,
|
|
||||||
LONG td_count
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
LONG i;
|
LONG i;
|
||||||
if( pool == NULL || td_count <= 0 )
|
if (pool == NULL || td_count <= 0)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
get_max_lists_count( pool, i );
|
get_max_lists_count(pool, i);
|
||||||
if( ( i - pool->list_count )
|
if ((i - pool->list_count)
|
||||||
* pool->elem_lists[ 0 ]->get_total_count( pool->elem_lists[ 0 ] )
|
* pool->elem_lists[0]->get_total_count(pool->elem_lists[0]) + pool->free_count < td_count)
|
||||||
+ pool->free_count < td_count )
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------
|
//----------------------------------------------------------
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -24,22 +24,13 @@
|
||||||
|
|
||||||
#define UHCI_MIN_TD_POOLS 4
|
#define UHCI_MIN_TD_POOLS 4
|
||||||
|
|
||||||
BOOL
|
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
|
|
||||||
); //add tds till pnext == NULL
|
|
||||||
|
|
||||||
|
|
||||||
PUHCI_QH
|
PUHCI_QH alloc_qh(PUHCI_QH_POOL pqh_pool); //null if failed
|
||||||
alloc_qh(
|
|
||||||
PUHCI_QH_POOL pqh_pool
|
|
||||||
); //null if failed
|
|
||||||
|
|
||||||
BOOL
|
BOOL
|
||||||
init_td_pool(
|
init_td_pool(PUHCI_TD_POOL ptd_pool)
|
||||||
PUHCI_TD_POOL ptd_pool
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
int i, pages;
|
int i, pages;
|
||||||
PTD_EXTENSION ptde;
|
PTD_EXTENSION ptde;
|
||||||
|
@ -48,92 +39,81 @@ PUHCI_TD_POOL ptd_pool
|
||||||
if (ptd_pool == NULL)
|
if (ptd_pool == NULL)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
if( ptd_pool->padapter == NULL)
|
if (ptd_pool->padapter == NULL)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
pages = sizeof( UHCI_TD ) * UHCI_MAX_POOL_TDS / PAGE_SIZE;
|
pages = sizeof(UHCI_TD) * UHCI_MAX_POOL_TDS / PAGE_SIZE;
|
||||||
RtlZeroMemory( ptd_pool->td_array, sizeof( ptd_pool->td_array ) );
|
RtlZeroMemory(ptd_pool->td_array, sizeof(ptd_pool->td_array));
|
||||||
RtlZeroMemory( ptd_pool->logic_addr, sizeof( ptd_pool->logic_addr ) );
|
RtlZeroMemory(ptd_pool->logic_addr, sizeof(ptd_pool->logic_addr));
|
||||||
|
|
||||||
for( i = 0; i < pages; i++ )
|
for(i = 0; i < pages; i++)
|
||||||
{
|
{
|
||||||
ptd_pool->td_array[ i ] =
|
ptd_pool->td_array[i] =
|
||||||
HalAllocateCommonBuffer(
|
HalAllocateCommonBuffer(ptd_pool->padapter, PAGE_SIZE, &ptd_pool->logic_addr[i], FALSE);
|
||||||
ptd_pool->padapter,
|
if (ptd_pool->td_array[i] == NULL)
|
||||||
PAGE_SIZE,
|
|
||||||
&ptd_pool->logic_addr[ i ],
|
|
||||||
FALSE);
|
|
||||||
if( ptd_pool->td_array[ i ] == NULL )
|
|
||||||
goto failed;
|
goto failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
ptd_pool->tde_array = ( PTD_EXTENSION )usb_alloc_mem(
|
ptd_pool->tde_array = (PTD_EXTENSION) usb_alloc_mem(NonPagedPool,
|
||||||
NonPagedPool,
|
sizeof(TD_EXTENSION) * UHCI_MAX_POOL_TDS);
|
||||||
sizeof( TD_EXTENSION ) * UHCI_MAX_POOL_TDS );
|
|
||||||
|
|
||||||
if (ptd_pool->tde_array == NULL)
|
if (ptd_pool->tde_array == NULL)
|
||||||
goto failed;
|
goto failed;
|
||||||
|
|
||||||
for( i = 0; i < pages; i++ )
|
for(i = 0; i < pages; i++)
|
||||||
{
|
{
|
||||||
RtlZeroMemory( ptd_pool->td_array[ i ], PAGE_SIZE );
|
RtlZeroMemory(ptd_pool->td_array[i], PAGE_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
RtlZeroMemory(
|
RtlZeroMemory(ptd_pool->tde_array, sizeof(TD_EXTENSION) * UHCI_MAX_POOL_TDS);
|
||||||
ptd_pool->tde_array,
|
|
||||||
sizeof( TD_EXTENSION ) * UHCI_MAX_POOL_TDS );
|
|
||||||
|
|
||||||
ptde = ptd_pool->tde_array;
|
ptde = ptd_pool->tde_array;
|
||||||
ptd_pool->free_count = 0;
|
ptd_pool->free_count = 0;
|
||||||
ptd_pool->total_count = UHCI_MAX_POOL_TDS;
|
ptd_pool->total_count = UHCI_MAX_POOL_TDS;
|
||||||
InitializeListHead( &ptd_pool->free_que);
|
InitializeListHead(&ptd_pool->free_que);
|
||||||
|
|
||||||
for( i = 0; i < UHCI_MAX_POOL_TDS; i++ )
|
for(i = 0; i < UHCI_MAX_POOL_TDS; i++)
|
||||||
{
|
{
|
||||||
//link tde and the td one by one, fixed since this init
|
//link tde and the td one by one, fixed since this init
|
||||||
ptd_pool->td_array[ i >> 7 ][ i & 0x7f ].ptde = &ptde[ i ];
|
ptd_pool->td_array[i >> 7][i & 0x7f].ptde = &ptde[i];
|
||||||
ptde[ i ].ptd = &ptd_pool->td_array[ i >> 7 ][ i & 0x7f ];
|
ptde[i].ptd = &ptd_pool->td_array[i >> 7][i & 0x7f];
|
||||||
ptde[ i ].flags = UHCI_ITEM_FLAG_TD;
|
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].phy_addr =
|
||||||
ptd_pool->td_array[ i >> 7 ][ i & 0x7f ].pool = ptd_pool;
|
ptd_pool->logic_addr[i >> 7].LowPart + (i & 0x7f) * sizeof(UHCI_TD);
|
||||||
ptd_pool->td_array[ i >> 7 ][ i & 0x7f ].purb = NULL;
|
ptd_pool->td_array[i >> 7][i & 0x7f].pool = ptd_pool;
|
||||||
free_td_to_pool( ptd_pool, &ptd_pool->td_array[ i >> 7 ][ i & 0x7f ]);
|
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:
|
failed:
|
||||||
for( i = 0; i < pages; i++ )
|
for(i = 0; i < pages; i++)
|
||||||
{
|
{
|
||||||
if( ptd_pool->td_array[ i ] )
|
if (ptd_pool->td_array[i])
|
||||||
{
|
{
|
||||||
HalFreeCommonBuffer( ptd_pool->padapter,
|
HalFreeCommonBuffer(ptd_pool->padapter,
|
||||||
PAGE_SIZE,
|
PAGE_SIZE, ptd_pool->logic_addr[i], ptd_pool->td_array[i], FALSE);
|
||||||
ptd_pool->logic_addr[ i ],
|
ptd_pool->td_array[i] = NULL;
|
||||||
ptd_pool->td_array[ i ],
|
ptd_pool->logic_addr[i].QuadPart = 0;
|
||||||
FALSE);
|
|
||||||
ptd_pool->td_array[ i ] = NULL;
|
|
||||||
ptd_pool->logic_addr[ i ].QuadPart = 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if( ptd_pool->tde_array )
|
if (ptd_pool->tde_array)
|
||||||
usb_free_mem( 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" ) );
|
uhci_dbg_print(DBGLVL_MAXIMUM, ("init_td_pool(): failed to init the td pool\n"));
|
||||||
TRAP();
|
TRAP();
|
||||||
|
|
||||||
ptd_pool->free_count = ptd_pool->total_count = 0;
|
ptd_pool->free_count = ptd_pool->total_count = 0;
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//add tds till pnext == NULL
|
||||||
BOOL
|
BOOL
|
||||||
free_td_to_pool(
|
free_td_to_pool(PUHCI_TD_POOL ptd_pool, PUHCI_TD ptd)
|
||||||
PUHCI_TD_POOL ptd_pool,
|
|
||||||
PUHCI_TD ptd
|
|
||||||
) //add tds till pnext == NULL
|
|
||||||
{
|
{
|
||||||
if( ptd_pool == NULL || ptd == NULL )
|
if (ptd_pool == NULL || ptd == NULL)
|
||||||
{
|
{
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
@ -142,96 +122,89 @@ PUHCI_TD ptd
|
||||||
ptd->purb = NULL;
|
ptd->purb = NULL;
|
||||||
ptd_pool->free_count++;
|
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
|
// qh routines
|
||||||
|
|
||||||
|
//null if failed
|
||||||
PUHCI_TD
|
PUHCI_TD
|
||||||
alloc_td_from_pool(
|
alloc_td_from_pool(PUHCI_TD_POOL ptd_pool)
|
||||||
PUHCI_TD_POOL ptd_pool
|
|
||||||
) //null if failed
|
|
||||||
{
|
{
|
||||||
PTD_EXTENSION ptde;
|
PTD_EXTENSION ptde;
|
||||||
PLIST_ENTRY temp;
|
PLIST_ENTRY temp;
|
||||||
|
|
||||||
if( ptd_pool == NULL )
|
if (ptd_pool == NULL)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
if( IsListEmpty( &ptd_pool->free_que ) )
|
if (IsListEmpty(&ptd_pool->free_que))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
temp = RemoveHeadList( &ptd_pool->free_que );
|
temp = RemoveHeadList(&ptd_pool->free_que);
|
||||||
|
|
||||||
if( temp == NULL )
|
if (temp == NULL)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
ptde = struct_ptr( temp, TD_EXTENSION, vert_link );
|
ptde = struct_ptr(temp, TD_EXTENSION, vert_link);
|
||||||
|
|
||||||
ptd_pool->free_count--;
|
ptd_pool->free_count--;
|
||||||
|
|
||||||
InitializeListHead( &ptde->vert_link );
|
InitializeListHead(&ptde->vert_link);
|
||||||
InitializeListHead( &ptde->hori_link );
|
InitializeListHead(&ptde->hori_link);
|
||||||
|
|
||||||
return ptde->ptd;
|
return ptde->ptd;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//test whether the pool is all free
|
||||||
BOOL
|
BOOL
|
||||||
is_pool_free(
|
is_pool_free(PUHCI_TD_POOL pool)
|
||||||
PUHCI_TD_POOL pool
|
|
||||||
) //test whether the pool is all free
|
|
||||||
{
|
{
|
||||||
if( pool == NULL )
|
if (pool == NULL)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
if( pool->free_count == pool->total_count )
|
if (pool->free_count == pool->total_count)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL
|
BOOL
|
||||||
is_pool_empty(
|
is_pool_empty(PUHCI_TD_POOL pool)
|
||||||
PUHCI_TD_POOL pool
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
if( pool == NULL )
|
if (pool == NULL)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
return ( pool->free_count == 0 );
|
return (pool->free_count == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL
|
BOOL
|
||||||
destroy_td_pool(
|
destroy_td_pool(PUHCI_TD_POOL ptd_pool)
|
||||||
PUHCI_TD_POOL ptd_pool
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
int i, pages;
|
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;
|
padapter = ptd_pool->padapter;
|
||||||
|
|
||||||
pages = sizeof( UHCI_TD ) * UHCI_MAX_POOL_TDS / PAGE_SIZE;
|
pages = sizeof(UHCI_TD) * UHCI_MAX_POOL_TDS / PAGE_SIZE;
|
||||||
if( ptd_pool && ptd_pool->padapter )
|
if (ptd_pool && ptd_pool->padapter)
|
||||||
{
|
{
|
||||||
usb_free_mem( ptd_pool->tde_array );
|
usb_free_mem(ptd_pool->tde_array);
|
||||||
ptd_pool->tde_array = NULL;
|
ptd_pool->tde_array = NULL;
|
||||||
for( i = 0; i < pages; i++ )
|
for(i = 0; i < pages; i++)
|
||||||
{
|
{
|
||||||
if( ptd_pool->td_array[ i ] )
|
if (ptd_pool->td_array[i])
|
||||||
{
|
{
|
||||||
HalFreeCommonBuffer( ptd_pool->padapter,
|
HalFreeCommonBuffer(ptd_pool->padapter,
|
||||||
PAGE_SIZE,
|
PAGE_SIZE, ptd_pool->logic_addr[i], ptd_pool->td_array[i], FALSE);
|
||||||
ptd_pool->logic_addr[ i ],
|
ptd_pool->td_array[i] = NULL;
|
||||||
ptd_pool->td_array[ i ],
|
ptd_pool->logic_addr[i].QuadPart = 0;
|
||||||
FALSE);
|
|
||||||
ptd_pool->td_array[ i ] = NULL;
|
|
||||||
ptd_pool->logic_addr[ i ].QuadPart = 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
RtlZeroMemory( ptd_pool, sizeof( UHCI_TD_POOL ) );
|
RtlZeroMemory(ptd_pool, sizeof(UHCI_TD_POOL));
|
||||||
ptd_pool->padapter = padapter;
|
ptd_pool->padapter = padapter;
|
||||||
ptd_pool->free_count = ptd_pool->total_count = 0;
|
ptd_pool->free_count = ptd_pool->total_count = 0;
|
||||||
}
|
}
|
||||||
|
@ -242,73 +215,65 @@ PUHCI_TD_POOL ptd_pool
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL
|
BOOL
|
||||||
init_td_pool_list(
|
init_td_pool_list(PUHCI_TD_POOL_LIST pool_list, PADAPTER_OBJECT padapter)
|
||||||
PUHCI_TD_POOL_LIST pool_list,
|
|
||||||
PADAPTER_OBJECT padapter
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
RtlZeroMemory( pool_list, sizeof( UHCI_TD_POOL_LIST));
|
RtlZeroMemory(pool_list, sizeof(UHCI_TD_POOL_LIST));
|
||||||
InitializeListHead( &pool_list->busy_pools );
|
InitializeListHead(&pool_list->busy_pools);
|
||||||
InitializeListHead( &pool_list->free_pools );
|
InitializeListHead(&pool_list->free_pools);
|
||||||
|
|
||||||
pool_list->free_count = UHCI_MAX_TD_POOLS;
|
pool_list->free_count = UHCI_MAX_TD_POOLS;
|
||||||
pool_list->free_tds = 0;
|
pool_list->free_tds = 0;
|
||||||
|
|
||||||
for( i = 0; i < UHCI_MAX_TD_POOLS; i++)
|
for(i = 0; i < UHCI_MAX_TD_POOLS; i++)
|
||||||
{
|
{
|
||||||
pool_list->pool_array[i].padapter = padapter;
|
pool_list->pool_array[i].padapter = padapter;
|
||||||
InsertTailList( &pool_list->free_pools, &pool_list->pool_array[i].pool_link);
|
InsertTailList(&pool_list->free_pools, &pool_list->pool_array[i].pool_link);
|
||||||
}
|
}
|
||||||
|
|
||||||
KeInitializeSpinLock( &pool_list->pool_lock );
|
KeInitializeSpinLock(&pool_list->pool_lock);
|
||||||
return expand_pool_list( pool_list, UHCI_MIN_TD_POOLS );
|
return expand_pool_list(pool_list, UHCI_MIN_TD_POOLS);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL
|
BOOL
|
||||||
destroy_td_pool_list(
|
destroy_td_pool_list(PUHCI_TD_POOL_LIST pool_list)
|
||||||
PUHCI_TD_POOL_LIST pool_list
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
PUHCI_TD_POOL pool;
|
PUHCI_TD_POOL pool;
|
||||||
while( IsListEmpty( &pool_list->busy_pools) == FALSE )
|
while (IsListEmpty(&pool_list->busy_pools) == FALSE)
|
||||||
{
|
{
|
||||||
pool = (PUHCI_TD_POOL) RemoveHeadList( &pool_list->busy_pools);
|
pool = (PUHCI_TD_POOL) RemoveHeadList(&pool_list->busy_pools);
|
||||||
destroy_td_pool( pool );
|
destroy_td_pool(pool);
|
||||||
}
|
}
|
||||||
|
|
||||||
RtlZeroMemory( pool_list, sizeof( UHCI_TD_POOL_LIST ));
|
RtlZeroMemory(pool_list, sizeof(UHCI_TD_POOL_LIST));
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL
|
BOOL
|
||||||
expand_pool_list(
|
expand_pool_list(PUHCI_TD_POOL_LIST pool_list, LONG pool_count) //private
|
||||||
PUHCI_TD_POOL_LIST pool_list,
|
|
||||||
LONG pool_count
|
|
||||||
) //private
|
|
||||||
{
|
{
|
||||||
PUHCI_TD_POOL pool;
|
PUHCI_TD_POOL pool;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if( IsListEmpty( &pool_list->free_pools) == TRUE )
|
if (IsListEmpty(&pool_list->free_pools) == TRUE)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
if( pool_list->free_count < pool_count )
|
if (pool_list->free_count < pool_count)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
for( i = 0; i < pool_count; i++ )
|
for(i = 0; i < pool_count; i++)
|
||||||
{
|
{
|
||||||
pool = (PUHCI_TD_POOL) RemoveHeadList( &pool_list->free_pools);
|
pool = (PUHCI_TD_POOL) RemoveHeadList(&pool_list->free_pools);
|
||||||
|
|
||||||
if( init_td_pool( pool ) == FALSE )
|
if (init_td_pool(pool) == FALSE)
|
||||||
{
|
{
|
||||||
//reverse the allocation
|
//reverse the allocation
|
||||||
InsertHeadList( &pool_list->free_pools, &pool->pool_link );
|
InsertHeadList(&pool_list->free_pools, &pool->pool_link);
|
||||||
// collect_garbage( pool_list );
|
// collect_garbage( pool_list );
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
InsertTailList( &pool_list->busy_pools, &pool->pool_link );
|
InsertTailList(&pool_list->busy_pools, &pool->pool_link);
|
||||||
pool_list->free_tds += UHCI_MAX_POOL_TDS;
|
pool_list->free_tds += UHCI_MAX_POOL_TDS;
|
||||||
pool_list->free_count--;
|
pool_list->free_count--;
|
||||||
}
|
}
|
||||||
|
@ -316,36 +281,34 @@ LONG pool_count
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL
|
BOOL
|
||||||
collect_garbage(
|
collect_garbage(PUHCI_TD_POOL_LIST pool_list)
|
||||||
PUHCI_TD_POOL_LIST pool_list
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
PLIST_ENTRY prev, next;
|
PLIST_ENTRY prev, next;
|
||||||
|
|
||||||
// no garbage
|
// no garbage
|
||||||
if( pool_list->free_count >= UHCI_MAX_TD_POOLS - UHCI_MIN_TD_POOLS )
|
if (pool_list->free_count >= UHCI_MAX_TD_POOLS - UHCI_MIN_TD_POOLS)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
ListFirstPrev( &pool_list->busy_pools, prev);
|
ListFirstPrev(&pool_list->busy_pools, prev);
|
||||||
ListNext( &pool_list->busy_pools, prev, next);
|
ListNext(&pool_list->busy_pools, prev, next);
|
||||||
|
|
||||||
while( next && next != &pool_list->busy_pools)
|
while (next && next != &pool_list->busy_pools)
|
||||||
{
|
{
|
||||||
if( is_pool_free( (PUHCI_TD_POOL)next ) )
|
if (is_pool_free((PUHCI_TD_POOL) next))
|
||||||
{
|
{
|
||||||
RemoveEntryList( next );
|
RemoveEntryList(next);
|
||||||
destroy_td_pool( ( PUHCI_TD_POOL )next );
|
destroy_td_pool((PUHCI_TD_POOL) next);
|
||||||
InsertTailList( &pool_list->free_pools, next);
|
InsertTailList(&pool_list->free_pools, next);
|
||||||
pool_list->free_count++;
|
pool_list->free_count++;
|
||||||
pool_list->free_tds -= UHCI_MAX_POOL_TDS;
|
pool_list->free_tds -= UHCI_MAX_POOL_TDS;
|
||||||
ListNext( &pool_list->busy_pools, prev, next);
|
ListNext(&pool_list->busy_pools, prev, next);
|
||||||
if( pool_list->free_count >= UHCI_MAX_TD_POOLS - UHCI_MIN_TD_POOLS )
|
if (pool_list->free_count >= UHCI_MAX_TD_POOLS - UHCI_MIN_TD_POOLS)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
prev = next;
|
prev = next;
|
||||||
ListNext( &pool_list->busy_pools, prev, next);
|
ListNext(&pool_list->busy_pools, prev, next);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -354,69 +317,62 @@ PUHCI_TD_POOL_LIST pool_list
|
||||||
|
|
||||||
//private
|
//private
|
||||||
LONG
|
LONG
|
||||||
get_num_free_tds(
|
get_num_free_tds(PUHCI_TD_POOL_LIST pool_list)
|
||||||
PUHCI_TD_POOL_LIST pool_list
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
return pool_list->free_tds;
|
return pool_list->free_tds;
|
||||||
}
|
}
|
||||||
|
|
||||||
//private
|
//private
|
||||||
LONG
|
LONG
|
||||||
get_max_free_tds(
|
get_max_free_tds(PUHCI_TD_POOL_LIST pool_list)
|
||||||
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
|
BOOL
|
||||||
free_td(
|
free_td(PUHCI_TD_POOL_LIST pool_list, PUHCI_TD ptd)
|
||||||
PUHCI_TD_POOL_LIST pool_list,
|
|
||||||
PUHCI_TD ptd
|
|
||||||
) //add tds till pnext == NULL
|
|
||||||
{
|
{
|
||||||
if( pool_list == NULL || ptd == NULL )
|
if (pool_list == NULL || ptd == NULL)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
if( free_td_to_pool( ptd->pool, ptd ) == FALSE )
|
if (free_td_to_pool(ptd->pool, ptd) == FALSE)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
pool_list->free_tds++;
|
pool_list->free_tds++;
|
||||||
|
|
||||||
if( is_pool_free( ptd->pool ) )
|
if (is_pool_free(ptd->pool))
|
||||||
{
|
{
|
||||||
collect_garbage( pool_list );
|
collect_garbage(pool_list);
|
||||||
}
|
}
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//null if failed
|
||||||
PUHCI_TD
|
PUHCI_TD
|
||||||
alloc_td(
|
alloc_td(PUHCI_TD_POOL_LIST pool_list)
|
||||||
PUHCI_TD_POOL_LIST pool_list
|
|
||||||
) //null if failed
|
|
||||||
{
|
{
|
||||||
PLIST_ENTRY prev, next;
|
PLIST_ENTRY prev, next;
|
||||||
PUHCI_TD new_td;
|
PUHCI_TD new_td;
|
||||||
|
|
||||||
if( pool_list == NULL )
|
if (pool_list == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if( pool_list->free_tds == 0 )
|
if (pool_list->free_tds == 0)
|
||||||
{
|
{
|
||||||
if( expand_pool_list( pool_list, 1 ) == FALSE )
|
if (expand_pool_list(pool_list, 1) == FALSE)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
ListFirst( &pool_list->busy_pools, prev );
|
ListFirst(&pool_list->busy_pools, prev);
|
||||||
|
|
||||||
while( prev && prev != &pool_list->busy_pools )
|
while (prev && prev != &pool_list->busy_pools)
|
||||||
{
|
{
|
||||||
if( is_pool_empty( (PUHCI_TD_POOL) prev ) == FALSE )
|
if (is_pool_empty((PUHCI_TD_POOL) prev) == FALSE)
|
||||||
{
|
{
|
||||||
new_td = alloc_td_from_pool( (PUHCI_TD_POOL) prev );
|
new_td = alloc_td_from_pool((PUHCI_TD_POOL) prev);
|
||||||
|
|
||||||
if( new_td == NULL )
|
if (new_td == NULL)
|
||||||
TRAP();
|
TRAP();
|
||||||
|
|
||||||
pool_list->free_tds--;
|
pool_list->free_tds--;
|
||||||
|
@ -424,7 +380,7 @@ PUHCI_TD_POOL_LIST pool_list
|
||||||
return new_td;
|
return new_td;
|
||||||
}
|
}
|
||||||
|
|
||||||
ListNext( &pool_list->busy_pools, prev, next);
|
ListNext(&pool_list->busy_pools, prev, next);
|
||||||
prev = next;
|
prev = next;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -432,86 +388,73 @@ PUHCI_TD_POOL_LIST pool_list
|
||||||
}
|
}
|
||||||
|
|
||||||
PUHCI_TD
|
PUHCI_TD
|
||||||
alloc_tds(
|
alloc_tds(PUHCI_TD_POOL_LIST pool_list, LONG count)
|
||||||
PUHCI_TD_POOL_LIST pool_list,
|
|
||||||
LONG count
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
//return value is a list of tds, vert_link chain.
|
//return value is a list of tds, vert_link chain.
|
||||||
|
|
||||||
LONG i;
|
LONG i;
|
||||||
PUHCI_TD ptd, pnext;
|
PUHCI_TD ptd, pnext;
|
||||||
|
|
||||||
if( pool_list == NULL || count <= 0 )
|
if (pool_list == NULL || count <= 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if( count >= get_max_free_tds( pool_list ) )
|
if (count >= get_max_free_tds(pool_list))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
ptd = alloc_td( pool_list );
|
ptd = alloc_td(pool_list);
|
||||||
|
|
||||||
for( i = 1; i < count; i ++ )
|
for(i = 1; i < count; i++)
|
||||||
{
|
{
|
||||||
pnext = alloc_td( pool_list );
|
pnext = alloc_td(pool_list);
|
||||||
|
|
||||||
if( pnext )
|
if (pnext)
|
||||||
{
|
{
|
||||||
InsertTailList( &ptd->ptde->vert_link, &pnext->ptde->vert_link );
|
InsertTailList(&ptd->ptde->vert_link, &pnext->ptde->vert_link);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
TRAP();
|
TRAP();
|
||||||
}
|
}
|
||||||
|
|
||||||
uhci_dbg_print( DBGLVL_MEDIUM, ("alloc_tds(): td pool-list free_tds=0x%x, free pools=0x%x\n", \
|
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_tds, pool_list->free_count));
|
||||||
pool_list->free_count ) );
|
|
||||||
|
|
||||||
return ptd;
|
return ptd;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
free_tds(
|
free_tds(PUHCI_TD_POOL_LIST pool_list, PUHCI_TD ptd)
|
||||||
PUHCI_TD_POOL_LIST pool_list,
|
|
||||||
PUHCI_TD ptd
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
PUHCI_TD ptofree;
|
PUHCI_TD ptofree;
|
||||||
PLIST_ENTRY pthis;
|
PLIST_ENTRY pthis;
|
||||||
|
|
||||||
if( pool_list == NULL || ptd == NULL )
|
if (pool_list == NULL || ptd == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
while( IsListEmpty( &ptd->ptde->vert_link ) == FALSE )
|
while (IsListEmpty(&ptd->ptde->vert_link) == FALSE)
|
||||||
{
|
{
|
||||||
pthis = RemoveHeadList( &ptd->ptde->vert_link );
|
pthis = RemoveHeadList(&ptd->ptde->vert_link);
|
||||||
ptofree = ( ( PTD_EXTENSION)pthis )->ptd;
|
ptofree = ((PTD_EXTENSION) pthis)->ptd;
|
||||||
free_td( pool_list, ptofree );
|
free_td(pool_list, ptofree);
|
||||||
}
|
}
|
||||||
|
|
||||||
free_td( pool_list, ptd );
|
free_td(pool_list, ptd);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
BOOL
|
BOOL
|
||||||
can_transfer(
|
can_transfer(PUHCI_TD_POOL_LIST pool_list, LONG td_count)
|
||||||
PUHCI_TD_POOL_LIST pool_list,
|
|
||||||
LONG td_count
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
if( td_count > get_max_free_tds( pool_list ) )
|
if (td_count > get_max_free_tds(pool_list))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
lock_td_pool(
|
lock_td_pool(PUHCI_TD_POOL_LIST pool_list, BOOL at_dpc)
|
||||||
PUHCI_TD_POOL_LIST pool_list,
|
|
||||||
BOOL at_dpc
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
//if( !at_dpc )
|
//if( !at_dpc )
|
||||||
// KeAcquireSpinLock( &pool_list->pool_lock );
|
// KeAcquireSpinLock( &pool_list->pool_lock );
|
||||||
|
@ -520,10 +463,7 @@ BOOL at_dpc
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
unlock_td_pool(
|
unlock_td_pool(PUHCI_TD_POOL_LIST pool_list, BOOL at_dpc)
|
||||||
PUHCI_TD_POOL_LIST pool_list,
|
|
||||||
BOOL at_dpc
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
//if( !at_dpc )
|
//if( !at_dpc )
|
||||||
// KeReleaseSpinLock( &pool_list->pool_lock );
|
// KeReleaseSpinLock( &pool_list->pool_lock );
|
||||||
|
@ -532,36 +472,29 @@ BOOL at_dpc
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL
|
BOOL
|
||||||
init_qh_pool(
|
init_qh_pool(PUHCI_QH_POOL pqh_pool, PADAPTER_OBJECT padapter)
|
||||||
PUHCI_QH_POOL pqh_pool,
|
|
||||||
PADAPTER_OBJECT padapter
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
PQH_EXTENSION pqhe;
|
PQH_EXTENSION pqhe;
|
||||||
LONG i;
|
LONG i;
|
||||||
|
|
||||||
if( pqh_pool == NULL || padapter == NULL )
|
if (pqh_pool == NULL || padapter == NULL)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
pqh_pool->padapter = padapter;
|
pqh_pool->padapter = padapter;
|
||||||
|
|
||||||
pqh_pool->qhe_array = (PQH_EXTENSION)usb_alloc_mem(
|
pqh_pool->qhe_array = (PQH_EXTENSION) usb_alloc_mem(NonPagedPool,
|
||||||
NonPagedPool,
|
|
||||||
sizeof(QH_EXTENSION) * UHCI_MAX_POOL_QHS);
|
sizeof(QH_EXTENSION) * UHCI_MAX_POOL_QHS);
|
||||||
|
|
||||||
if (pqh_pool->qhe_array == NULL)
|
if (pqh_pool->qhe_array == NULL)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
pqh_pool->qh_array = \
|
pqh_pool->qh_array =
|
||||||
(PUHCI_QH)HalAllocateCommonBuffer(
|
(PUHCI_QH) HalAllocateCommonBuffer(padapter,
|
||||||
padapter,
|
sizeof(UHCI_QH) * UHCI_MAX_POOL_QHS, &pqh_pool->logic_addr, FALSE);
|
||||||
sizeof(UHCI_QH) * UHCI_MAX_POOL_QHS,
|
|
||||||
&pqh_pool->logic_addr,
|
|
||||||
FALSE);
|
|
||||||
|
|
||||||
if( pqh_pool->qh_array == NULL )
|
if (pqh_pool->qh_array == NULL)
|
||||||
{
|
{
|
||||||
usb_free_mem( pqh_pool->qhe_array );
|
usb_free_mem(pqh_pool->qhe_array);
|
||||||
pqh_pool->qhe_array = NULL;
|
pqh_pool->qhe_array = NULL;
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
@ -571,8 +504,8 @@ PADAPTER_OBJECT padapter
|
||||||
pqh_pool->free_count = 0;
|
pqh_pool->free_count = 0;
|
||||||
pqh_pool->total_count = UHCI_MAX_POOL_TDS;
|
pqh_pool->total_count = UHCI_MAX_POOL_TDS;
|
||||||
|
|
||||||
KeInitializeSpinLock( &pqh_pool->pool_lock);
|
KeInitializeSpinLock(&pqh_pool->pool_lock);
|
||||||
InitializeListHead( &pqh_pool->free_que);
|
InitializeListHead(&pqh_pool->free_que);
|
||||||
|
|
||||||
|
|
||||||
for(i = 0; i < UHCI_MAX_POOL_QHS; i++)
|
for(i = 0; i < UHCI_MAX_POOL_QHS; i++)
|
||||||
|
@ -580,55 +513,52 @@ PADAPTER_OBJECT padapter
|
||||||
pqh_pool->qh_array[i].pqhe = &pqhe[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].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].reserved = 0;
|
||||||
|
|
||||||
//always breadth first
|
//always breadth first
|
||||||
pqhe[i].flags = UHCI_ITEM_FLAG_QH;
|
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
|
BOOL
|
||||||
free_qh(
|
free_qh(PUHCI_QH_POOL pqh_pool, PUHCI_QH pqh)
|
||||||
PUHCI_QH_POOL pqh_pool,
|
|
||||||
PUHCI_QH pqh
|
|
||||||
) //add qhs till pnext == NULL
|
|
||||||
{
|
{
|
||||||
if( pqh_pool == NULL || pqh == NULL)
|
if (pqh_pool == NULL || pqh == NULL)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
pqh->link = pqh->element = 0;
|
pqh->link = pqh->element = 0;
|
||||||
pqh->pqhe->purb = NULL;
|
pqh->pqhe->purb = NULL;
|
||||||
InsertTailList( &pqh_pool->free_que, &pqh->pqhe->vert_link);
|
InsertTailList(&pqh_pool->free_que, &pqh->pqhe->vert_link);
|
||||||
pqh_pool->free_count ++;
|
pqh_pool->free_count++;
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//null if failed
|
||||||
PUHCI_QH
|
PUHCI_QH
|
||||||
alloc_qh(
|
alloc_qh(PUHCI_QH_POOL pqh_pool)
|
||||||
PUHCI_QH_POOL pqh_pool
|
|
||||||
) //null if failed
|
|
||||||
{
|
{
|
||||||
PQH_EXTENSION pqhe;
|
PQH_EXTENSION pqhe;
|
||||||
|
|
||||||
if( pqh_pool == NULL )
|
if (pqh_pool == NULL)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
if( IsListEmpty( &pqh_pool->free_que))
|
if (IsListEmpty(&pqh_pool->free_que))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
pqhe = ( PQH_EXTENSION )RemoveHeadList( &pqh_pool->free_que );
|
pqhe = (PQH_EXTENSION) RemoveHeadList(&pqh_pool->free_que);
|
||||||
|
|
||||||
if( pqhe )
|
if (pqhe)
|
||||||
{
|
{
|
||||||
InitializeListHead( &pqhe->hori_link );
|
InitializeListHead(&pqhe->hori_link);
|
||||||
InitializeListHead( &pqhe->vert_link );
|
InitializeListHead(&pqhe->vert_link);
|
||||||
return pqhe->pqh;
|
return pqhe->pqh;
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -636,23 +566,19 @@ PUHCI_QH_POOL pqh_pool
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL
|
BOOL
|
||||||
destroy_qh_pool(
|
destroy_qh_pool(PUHCI_QH_POOL pqh_pool)
|
||||||
PUHCI_QH_POOL pqh_pool
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
int i;
|
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,
|
HalFreeCommonBuffer(pqh_pool->padapter,
|
||||||
sizeof(UHCI_QH) * UHCI_MAX_POOL_QHS,
|
sizeof(UHCI_QH) * UHCI_MAX_POOL_QHS,
|
||||||
pqh_pool->logic_addr,
|
pqh_pool->logic_addr, pqh_pool->qh_array, FALSE);
|
||||||
pqh_pool->qh_array,
|
|
||||||
FALSE);
|
|
||||||
|
|
||||||
RtlZeroMemory( pqh_pool, sizeof( UHCI_QH_POOL ) );
|
RtlZeroMemory(pqh_pool, sizeof(UHCI_QH_POOL));
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -662,10 +588,7 @@ PUHCI_QH_POOL pqh_pool
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
lock_qh_pool(
|
lock_qh_pool(PUHCI_QH_POOL pool, BOOL at_dpc)
|
||||||
PUHCI_QH_POOL pool,
|
|
||||||
BOOL at_dpc
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
//if( !at_dpc )
|
//if( !at_dpc )
|
||||||
// KeAcquireSpinLock( &pool->pool_lock );
|
// KeAcquireSpinLock( &pool->pool_lock );
|
||||||
|
@ -674,14 +597,10 @@ BOOL at_dpc
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
unlock_qh_pool(
|
unlock_qh_pool(PUHCI_QH_POOL pool, BOOL at_dpc)
|
||||||
PUHCI_QH_POOL pool,
|
|
||||||
BOOL at_dpc
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
//if( !at_dpc )
|
//if( !at_dpc )
|
||||||
// KeReleaseSpinLock( &pool->pool_lock );
|
// KeReleaseSpinLock( &pool->pool_lock );
|
||||||
//else
|
//else
|
||||||
// KeReleaseSpinLockFromDpcLevel( &pool->pool_lock );
|
// KeReleaseSpinLockFromDpcLevel( &pool->pool_lock );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue