[FORMATTING]

svn path=/trunk/; revision=23616
This commit is contained in:
Aleksey Bragin 2006-08-20 14:01:17 +00:00
parent 4e7aa7365f
commit f448f3bae0
12 changed files with 18078 additions and 20290 deletions

File diff suppressed because it is too large Load diff

View file

@ -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);
}
}

View file

@ -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( &param, usb_make_handle( dev_id, i, 0 ) );
pcand->disp_tbl.dev_connect(&param, 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;
}

View file

@ -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

View file

@ -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

View file

@ -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