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