[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 "debug.h"
#include "umss.h" #include "umss.h"
VOID VOID umss_cbi_send_adsc_complete(PURB purb, PVOID context);
umss_cbi_send_adsc_complete(
PURB purb,
PVOID context
);
VOID VOID umss_cbi_transfer_data(PUMSS_DEVICE_EXTENSION pdev_ext);
umss_cbi_transfer_data(
PUMSS_DEVICE_EXTENSION pdev_ext
);
VOID VOID umss_cbi_get_status(PUMSS_DEVICE_EXTENSION pdev_ext);
umss_cbi_get_status(
PUMSS_DEVICE_EXTENSION pdev_ext
);
VOID VOID umss_cbi_transfer_data_complete(PURB purb, PVOID context);
umss_cbi_transfer_data_complete(
PURB purb,
PVOID context
);
VOID VOID umss_cbi_get_status_complete(PURB purb, PVOID context);
umss_cbi_get_status_complete(
PURB purb,
PVOID context
);
NTSTATUS NTSTATUS
umss_class_specific_request( umss_class_specific_request(IN PUMSS_DEVICE_EXTENSION pdev_ext,
IN PUMSS_DEVICE_EXTENSION pdev_ext, IN UCHAR request,
IN UCHAR request, IN UCHAR dir,
IN UCHAR dir, IN PVOID buffer,
IN PVOID buffer, IN ULONG buffer_length,
IN ULONG buffer_length, IN PURBCOMPLETION completion)
IN PURBCOMPLETION completion
)
{ {
PURB purb; PURB purb;
NTSTATUS status; NTSTATUS status;
purb = usb_alloc_mem( NonPagedPool, sizeof( URB ) ); purb = usb_alloc_mem(NonPagedPool, sizeof(URB));
// Build URB for the ADSC command // Build URB for the ADSC command
UsbBuildVendorRequest( UsbBuildVendorRequest(purb,
purb,
pdev_ext->dev_handle | 0xffff, pdev_ext->dev_handle | 0xffff,
buffer, buffer,
buffer_length, buffer_length,
0x21, 0x21, request, 0, pdev_ext->pif_desc->bInterfaceNumber, completion, pdev_ext, 0);
request,
0,
pdev_ext->pif_desc->bInterfaceNumber,
completion,
pdev_ext,
0 );
status = usb_submit_urb( pdev_ext->dev_mgr, purb ); status = usb_submit_urb(pdev_ext->dev_mgr, purb);
if( status != STATUS_PENDING ) if (status != STATUS_PENDING)
{ {
usb_free_mem( purb ); usb_free_mem(purb);
purb = NULL; purb = NULL;
return status; return status;
} }
dev_mgr_register_irp( pdev_ext->dev_mgr, pdev_ext->io_packet.pirp, purb ); dev_mgr_register_irp(pdev_ext->dev_mgr, pdev_ext->io_packet.pirp, purb);
return status; return status;
} }
NTSTATUS NTSTATUS
umss_cbi_startio( umss_cbi_startio(IN PUMSS_DEVICE_EXTENSION pdev_ext, IN PIO_PACKET io_packet)
IN PUMSS_DEVICE_EXTENSION pdev_ext,
IN PIO_PACKET io_packet
)
{ {
NTSTATUS status; NTSTATUS status;
status = STATUS_NOT_SUPPORTED; status = STATUS_NOT_SUPPORTED;
return status; return status;
RtlCopyMemory( &pdev_ext->io_packet, io_packet, sizeof( pdev_ext->io_packet ) ); RtlCopyMemory(&pdev_ext->io_packet, io_packet, sizeof(pdev_ext->io_packet));
// Send the ADSC request to the device // Send the ADSC request to the device
// Calls UMSS_CbiSendADSCComplete when transfer completes // Calls UMSS_CbiSendADSCComplete when transfer completes
status = umss_class_specific_request( status = umss_class_specific_request(pdev_ext,
pdev_ext,
ACCEPT_DEVICE_SPECIFIC_COMMAND, ACCEPT_DEVICE_SPECIFIC_COMMAND,
USB_DIR_OUT , USB_DIR_OUT,
io_packet->cdb, io_packet->cdb, io_packet->cdb_length, umss_cbi_send_adsc_complete);
io_packet->cdb_length,
umss_cbi_send_adsc_complete
);
return status; return status;
} }
@ -120,10 +86,7 @@ IN PIO_PACKET io_packet
VOID VOID
umss_cbi_send_adsc_complete( umss_cbi_send_adsc_complete(PURB purb, PVOID context)
PURB purb,
PVOID context
)
{ {
NTSTATUS status; NTSTATUS status;
PIO_STACK_LOCATION irpStack; PIO_STACK_LOCATION irpStack;
@ -137,73 +100,66 @@ PVOID context
status = purb->status; status = purb->status;
dev_mgr_remove_irp( pdev_ext->dev_mgr, pdev_ext->io_packet.pirp ); dev_mgr_remove_irp(pdev_ext->dev_mgr, pdev_ext->io_packet.pirp);
if (!usb_success( status ) ) if (!usb_success(status))
{ {
usb_dbg_print( DBGLVL_MINIMUM,("umss_cbi_send_adsc_complete(): Command Block Failure!!!\n")); usb_dbg_print(DBGLVL_MINIMUM, ("umss_cbi_send_adsc_complete(): Command Block Failure!!!\n"));
// BUGBUG - Should reset device here? // BUGBUG - Should reset device here?
// Device failed Command Block, complete with error // Device failed Command Block, complete with error
umss_complete_request( pdev_ext, STATUS_IO_DEVICE_ERROR ); umss_complete_request(pdev_ext, STATUS_IO_DEVICE_ERROR);
} }
else if ( io_packet->data_length ) else if (io_packet->data_length)
{ {
usb_dbg_print( DBGLVL_HIGH,("umss_cbi_send_adsc_complete(): Queuing Data Transfer DPC\n")); usb_dbg_print(DBGLVL_HIGH, ("umss_cbi_send_adsc_complete(): Queuing Data Transfer DPC\n"));
umss_cbi_transfer_data( pdev_ext ); umss_cbi_transfer_data(pdev_ext);
} }
else if (pdev_ext->pif_desc->bInterfaceProtocol == PROTOCOL_CBI) else if (pdev_ext->pif_desc->bInterfaceProtocol == PROTOCOL_CBI)
{ {
// Device supports interrupt pipe, so get status // Device supports interrupt pipe, so get status
umss_cbi_get_status( pdev_ext ); umss_cbi_get_status(pdev_ext);
} }
else else
{ {
// Device does not report status, so complete request // Device does not report status, so complete request
umss_complete_request( pdev_ext, STATUS_SUCCESS ); umss_complete_request(pdev_ext, STATUS_SUCCESS);
} }
usb_free_mem( purb ); usb_free_mem(purb);
purb = NULL; purb = NULL;
} }
VOID VOID
umss_cbi_reset_pipe( umss_cbi_reset_pipe(IN PVOID reference)
IN PVOID reference
)
{ {
PUMSS_DEVICE_EXTENSION pdev_ext; PUMSS_DEVICE_EXTENSION pdev_ext;
pdev_ext = (PUMSS_DEVICE_EXTENSION) reference; pdev_ext = (PUMSS_DEVICE_EXTENSION) reference;
// Reset the appropriate pipe, based on data direction // Reset the appropriate pipe, based on data direction
umss_reset_pipe( umss_reset_pipe(pdev_ext,
pdev_ext, (pdev_ext->io_packet.flags & USB_DIR_IN) ?
( pdev_ext->io_packet.flags & USB_DIR_IN ) ? usb_make_handle((pdev_ext->dev_handle >> 16), pdev_ext->if_idx, pdev_ext->in_endp_idx) :
usb_make_handle( ( pdev_ext->dev_handle >> 16 ), pdev_ext->if_idx, pdev_ext->in_endp_idx ): usb_make_handle((pdev_ext->dev_handle >> 16), pdev_ext->if_idx, pdev_ext->out_endp_idx));
usb_make_handle( ( pdev_ext->dev_handle >> 16 ), pdev_ext->if_idx, pdev_ext->out_endp_idx )
);
// Device stalled endpoint, so complete I/O operation with error. // Device stalled endpoint, so complete I/O operation with error.
// BUGBUG is this correct? Check spec... // BUGBUG is this correct? Check spec...
umss_complete_request( pdev_ext, USB_STATUS_STALL_PID ); umss_complete_request(pdev_ext, USB_STATUS_STALL_PID);
} }
VOID VOID
umss_cbi_transfer_data( umss_cbi_transfer_data(PUMSS_DEVICE_EXTENSION pdev_ext)
PUMSS_DEVICE_EXTENSION pdev_ext
)
{ {
PVOID buffer; PVOID buffer;
ULONG buffer_length; ULONG buffer_length;
// Get next data buffer element, if any. // Get next data buffer element, if any.
buffer = umss_get_buffer( pdev_ext, &buffer_length ); buffer = umss_get_buffer(pdev_ext, &buffer_length);
if (NULL == buffer) if (NULL == buffer)
{ {
//Done with data phase, so move to status phase if (supported) //Done with data phase, so move to status phase if (supported)
@ -222,22 +178,15 @@ PUMSS_DEVICE_EXTENSION pdev_ext
else else
{ {
// Transfer next element of the data phase // Transfer next element of the data phase
umss_bulk_transfer( umss_bulk_transfer(pdev_ext,
pdev_ext, (UCHAR) ((pdev_ext->io_packet.flags & USB_DIR_IN) ? USB_DIR_IN : USB_DIR_OUT),
(UCHAR)((pdev_ext->io_packet.flags & USB_DIR_IN ) ? USB_DIR_IN : USB_DIR_OUT ), buffer, buffer_length, umss_cbi_transfer_data_complete);
buffer,
buffer_length,
umss_cbi_transfer_data_complete
);
} }
} }
VOID VOID
umss_cbi_transfer_data_complete( umss_cbi_transfer_data_complete(PURB purb, PVOID context)
PURB purb,
PVOID context
)
{ {
NTSTATUS status; NTSTATUS status;
PUMSS_DEVICE_EXTENSION pdev_ext; PUMSS_DEVICE_EXTENSION pdev_ext;
@ -245,78 +194,71 @@ PVOID context
pdev_ext = (PUMSS_DEVICE_EXTENSION) context; pdev_ext = (PUMSS_DEVICE_EXTENSION) context;
status = purb->status; status = purb->status;
usb_free_mem( purb ); usb_free_mem(purb);
purb = NULL; purb = NULL;
if ( !usb_success( status ) ) if (!usb_success(status))
{ {
// Device failed Data Transfer // Device failed Data Transfer
// Check if we need to clear stalled pipe // Check if we need to clear stalled pipe
if ( usb_halted( status ) ) if (usb_halted(status))
{ {
// Reset pipe can only be done at passive level, so we need // Reset pipe can only be done at passive level, so we need
// to schedule a work item to do it. // to schedule a work item to do it.
if ( !umss_schedule_workitem( ( PVOID )pdev_ext, umss_cbi_reset_pipe, pdev_ext->dev_mgr, pdev_ext->dev_handle ) ) if (!umss_schedule_workitem
((PVOID) pdev_ext, umss_cbi_reset_pipe, pdev_ext->dev_mgr, pdev_ext->dev_handle))
{ {
usb_dbg_print( DBGLVL_MINIMUM,("umss_cbi_transfer_data_complete(): Failed to allocate work-item to reset pipe!\n")); usb_dbg_print(DBGLVL_MINIMUM,
("umss_cbi_transfer_data_complete(): Failed to allocate work-item to reset pipe!\n"));
TRAP(); TRAP();
umss_complete_request( pdev_ext, STATUS_IO_DEVICE_ERROR ); umss_complete_request(pdev_ext, STATUS_IO_DEVICE_ERROR);
} }
} }
else else
{ {
umss_complete_request( pdev_ext, STATUS_IO_DEVICE_ERROR ); umss_complete_request(pdev_ext, STATUS_IO_DEVICE_ERROR);
} }
return; return;
} }
// Transfer succeeded // Transfer succeeded
// umss_cbi_transfer_data( pdev_ext ); // umss_cbi_transfer_data( pdev_ext );
umss_complete_request( pdev_ext, STATUS_SUCCESS ); umss_complete_request(pdev_ext, STATUS_SUCCESS);
return; return;
} }
VOID VOID
umss_cbi_get_status( umss_cbi_get_status(PUMSS_DEVICE_EXTENSION pdev_ext)
PUMSS_DEVICE_EXTENSION pdev_ext
)
{ {
PURB purb; PURB purb;
NTSTATUS status; NTSTATUS status;
purb = usb_alloc_mem( NonPagedPool, sizeof( URB ) ); purb = usb_alloc_mem(NonPagedPool, sizeof(URB));
if( purb == NULL ) if (purb == NULL)
return; return;
// Build a URB for our interrupt transfer // Build a URB for our interrupt transfer
UsbBuildInterruptOrBulkTransferRequest( UsbBuildInterruptOrBulkTransferRequest(purb,
purb, usb_make_handle((pdev_ext->dev_handle >> 16), pdev_ext->if_idx,
usb_make_handle( ( pdev_ext->dev_handle >> 16 ), pdev_ext->if_idx, pdev_ext->int_endp_idx ), pdev_ext->int_endp_idx), (PUCHAR) & pdev_ext->idb,
( PUCHAR )&pdev_ext->idb, sizeof(INTERRUPT_DATA_BLOCK), umss_cbi_get_status_complete,
sizeof( INTERRUPT_DATA_BLOCK ), pdev_ext, 0);
umss_cbi_get_status_complete,
pdev_ext,
0
);
// Call USB driver stack // Call USB driver stack
status = usb_submit_urb( pdev_ext->dev_mgr, purb ); status = usb_submit_urb(pdev_ext->dev_mgr, purb);
if( status != STATUS_PENDING ) if (status != STATUS_PENDING)
{ {
usb_free_mem( purb ); usb_free_mem(purb);
purb = NULL; purb = NULL;
return; return;
} }
dev_mgr_register_irp( pdev_ext->dev_mgr, pdev_ext->io_packet.pirp, purb ); dev_mgr_register_irp(pdev_ext->dev_mgr, pdev_ext->io_packet.pirp, purb);
return; return;
} }
VOID VOID
umss_cbi_get_status_complete( umss_cbi_get_status_complete(PURB purb, PVOID context)
PURB purb,
PVOID context
)
{ {
NTSTATUS status; NTSTATUS status;
PUMSS_DEVICE_EXTENSION pdev_ext; PUMSS_DEVICE_EXTENSION pdev_ext;
@ -325,26 +267,28 @@ PVOID context
pdev_ext = (PUMSS_DEVICE_EXTENSION) context; pdev_ext = (PUMSS_DEVICE_EXTENSION) context;
status = purb->status; status = purb->status;
dev_mgr_remove_irp( pdev_ext->dev_mgr, pdev_ext->io_packet.pirp ); dev_mgr_remove_irp(pdev_ext->dev_mgr, pdev_ext->io_packet.pirp);
usb_free_mem( purb ); usb_free_mem(purb);
purb = NULL; purb = NULL;
if ( !usb_success( status ) ) if (!usb_success(status))
{ {
// Device failed Data Transfer // Device failed Data Transfer
// Check if we need to clear stalled pipe // Check if we need to clear stalled pipe
if ( usb_halted( status ) ) if (usb_halted(status))
{ {
if ( !umss_schedule_workitem( (PVOID)pdev_ext, umss_cbi_reset_pipe, pdev_ext->dev_mgr, pdev_ext->dev_handle ) ) if (!umss_schedule_workitem
((PVOID) pdev_ext, umss_cbi_reset_pipe, pdev_ext->dev_mgr, pdev_ext->dev_handle))
{ {
usb_dbg_print( DBGLVL_MINIMUM,("umss_cbi_get_status_complete(): Failed to allocate work-item to reset pipe!\n")); usb_dbg_print(DBGLVL_MINIMUM,
("umss_cbi_get_status_complete(): Failed to allocate work-item to reset pipe!\n"));
TRAP(); TRAP();
umss_complete_request( pdev_ext, STATUS_IO_DEVICE_ERROR ); umss_complete_request(pdev_ext, STATUS_IO_DEVICE_ERROR);
return; return;
} }
} }
umss_complete_request( pdev_ext, STATUS_IO_DEVICE_ERROR ); umss_complete_request(pdev_ext, STATUS_IO_DEVICE_ERROR);
return; return;
} }
@ -352,12 +296,12 @@ PVOID context
idb = &(pdev_ext->idb); idb = &(pdev_ext->idb);
// Check for an error in the status block // Check for an error in the status block
if ( ( 0 != idb->bType ) || ( 0 != ( idb->bValue & 0x3 ) ) ) if ((0 != idb->bType) || (0 != (idb->bValue & 0x3)))
{ {
umss_complete_request( pdev_ext, STATUS_IO_DEVICE_ERROR ); umss_complete_request(pdev_ext, STATUS_IO_DEVICE_ERROR);
} }
else else
{ {
umss_complete_request( pdev_ext, STATUS_SUCCESS ); umss_complete_request(pdev_ext, STATUS_SUCCESS);
} }
} }

View file

@ -28,43 +28,20 @@
#include "hub.h" #include "hub.h"
#include "debug.h" #include "debug.h"
VOID VOID compdev_set_cfg_completion(PURB purb, PVOID context);
compdev_set_cfg_completion(
PURB purb,
PVOID context
);
VOID VOID compdev_select_driver(PUSB_DEV_MANAGER dev_mgr, DEV_HANDLE dev_handle);
compdev_select_driver(
PUSB_DEV_MANAGER dev_mgr, BOOL compdev_connect(PCONNECT_DATA param, DEV_HANDLE dev_handle);
DEV_HANDLE dev_handle
); BOOL compdev_stop(PUSB_DEV_MANAGER dev_mgr, DEV_HANDLE dev_handle);
BOOL compdev_disconnect(PUSB_DEV_MANAGER dev_mgr, DEV_HANDLE dev_handle);
BOOL BOOL
compdev_connect( compdev_driver_init(PUSB_DEV_MANAGER dev_mgr, PUSB_DRIVER pdriver)
PCONNECT_DATA param,
DEV_HANDLE dev_handle
);
BOOL
compdev_stop(
PUSB_DEV_MANAGER dev_mgr,
DEV_HANDLE dev_handle
);
BOOL
compdev_disconnect(
PUSB_DEV_MANAGER dev_mgr,
DEV_HANDLE dev_handle
);
BOOL
compdev_driver_init(
PUSB_DEV_MANAGER dev_mgr,
PUSB_DRIVER pdriver
)
{ {
if( dev_mgr == NULL || pdriver == NULL ) if (dev_mgr == NULL || pdriver == NULL)
return FALSE; return FALSE;
pdriver->driver_desc.flags = USB_DRIVER_FLAG_DEV_CAPABLE; pdriver->driver_desc.flags = USB_DRIVER_FLAG_DEV_CAPABLE;
@ -97,19 +74,13 @@ PUSB_DRIVER pdriver
} }
BOOL BOOL
compdev_driver_destroy( compdev_driver_destroy(PUSB_DEV_MANAGER dev_mgr, PUSB_DRIVER pdriver)
PUSB_DEV_MANAGER dev_mgr,
PUSB_DRIVER pdriver
)
{ {
return TRUE; return TRUE;
} }
BOOL BOOL
compdev_connect( compdev_connect(PCONNECT_DATA param, DEV_HANDLE dev_handle)
PCONNECT_DATA param,
DEV_HANDLE dev_handle
)
{ {
PURB purb; PURB purb;
PUSB_CTRL_SETUP_PACKET psetup; PUSB_CTRL_SETUP_PACKET psetup;
@ -120,28 +91,28 @@ DEV_HANDLE dev_handle
PUSB_INTERFACE_DESC pif_desc; PUSB_INTERFACE_DESC pif_desc;
PUSB_DEV_MANAGER dev_mgr; PUSB_DEV_MANAGER dev_mgr;
if( param == NULL || dev_handle == 0 ) if (param == NULL || dev_handle == 0)
return FALSE; return FALSE;
dev_mgr = param->dev_mgr; dev_mgr = param->dev_mgr;
// let's set the configuration // let's set the configuration
purb = usb_alloc_mem( NonPagedPool, sizeof( URB ) ); purb = usb_alloc_mem(NonPagedPool, sizeof(URB));
if( purb == NULL ) if (purb == NULL)
return FALSE; return FALSE;
buf = usb_alloc_mem( NonPagedPool, 512 ); buf = usb_alloc_mem(NonPagedPool, 512);
if( buf == NULL ) if (buf == NULL)
{ {
usb_dbg_print( DBGLVL_MAXIMUM, ( "compdev_connect(): can not alloc buf\n" ) ); usb_dbg_print(DBGLVL_MAXIMUM, ("compdev_connect(): can not alloc buf\n"));
usb_free_mem( purb ); usb_free_mem(purb);
return FALSE; return FALSE;
} }
// before we set the configuration, let's search to find if there // before we set the configuration, let's search to find if there
// exist interfaces we supported // exist interfaces we supported
psetup = ( PUSB_CTRL_SETUP_PACKET )( purb )->setup_packet; psetup = (PUSB_CTRL_SETUP_PACKET) (purb)->setup_packet;
urb_init( ( purb ) ); urb_init((purb));
purb->endp_handle = dev_handle | 0xffff; purb->endp_handle = dev_handle | 0xffff;
purb->data_buffer = buf; purb->data_buffer = buf;
purb->data_length = 512; purb->data_length = 512;
@ -154,73 +125,73 @@ DEV_HANDLE dev_handle
psetup->wIndex = 0; psetup->wIndex = 0;
psetup->wLength = 512; psetup->wLength = 512;
status = usb_submit_urb( dev_mgr, purb ); status = usb_submit_urb(dev_mgr, purb);
if( status == STATUS_PENDING ) if (status == STATUS_PENDING)
{ {
TRAP(); TRAP();
usb_free_mem( buf ); usb_free_mem(buf);
usb_free_mem( purb ); usb_free_mem(purb);
return FALSE; return FALSE;
} }
// let's scan the interfacs for those we recognize // let's scan the interfacs for those we recognize
pconfig_desc = ( PUSB_CONFIGURATION_DESC )buf; pconfig_desc = (PUSB_CONFIGURATION_DESC) buf;
if( pconfig_desc->wTotalLength > 512 ) if (pconfig_desc->wTotalLength > 512)
{ {
usb_free_mem( buf ); usb_free_mem(buf);
usb_free_mem( purb ); usb_free_mem(purb);
usb_dbg_print( DBGLVL_MAXIMUM, ( "compdev_connect(): error, bad configuration desc\n" ) ); usb_dbg_print(DBGLVL_MAXIMUM, ("compdev_connect(): error, bad configuration desc\n"));
return FALSE; return FALSE;
} }
pif_desc = ( PUSB_INTERFACE_DESC )&pconfig_desc[ 1 ]; pif_desc = (PUSB_INTERFACE_DESC) & pconfig_desc[1];
for( i = 0, credit = 0; i < ( LONG )pconfig_desc->bNumInterfaces; i++ ) for(i = 0, credit = 0; i < (LONG) pconfig_desc->bNumInterfaces; i++)
{ {
for( j = 0; j < DEVMGR_MAX_DRIVERS; j++ ) for(j = 0; j < DEVMGR_MAX_DRIVERS; j++)
{ {
credit = dev_mgr_score_driver_for_if( dev_mgr, &dev_mgr->driver_list[ j ], pif_desc ); credit = dev_mgr_score_driver_for_if(dev_mgr, &dev_mgr->driver_list[j], pif_desc);
if( credit ) if (credit)
break; break;
} }
if( credit ) if (credit)
break; break;
if( usb_skip_if_and_altif( ( PUCHAR* )&pif_desc ) ) if (usb_skip_if_and_altif((PUCHAR *) & pif_desc))
break; break;
} }
i = pconfig_desc->bConfigurationValue; i = pconfig_desc->bConfigurationValue;
usb_free_mem( buf ); usb_free_mem(buf);
buf = NULL; buf = NULL;
if( credit == 0 ) if (credit == 0)
{ {
usb_free_mem( purb ); usb_free_mem(purb);
usb_dbg_print( DBGLVL_MAXIMUM, ( "compdev_connect(): oops..., no supported interface found\n" ) ); usb_dbg_print(DBGLVL_MAXIMUM, ("compdev_connect(): oops..., no supported interface found\n"));
return FALSE; return FALSE;
} }
//set the configuration //set the configuration
urb_init( purb ); urb_init(purb);
purb->endp_handle = dev_handle | 0xffff; purb->endp_handle = dev_handle | 0xffff;
purb->data_buffer = NULL; purb->data_buffer = NULL;
purb->data_length = 0; purb->data_length = 0;
purb->completion = compdev_set_cfg_completion; purb->completion = compdev_set_cfg_completion;
purb->context = dev_mgr; purb->context = dev_mgr;
purb->reference = ( ULONG )param->pdriver; purb->reference = (ULONG) param->pdriver;
psetup->bmRequestType = 0; psetup->bmRequestType = 0;
psetup->bRequest = USB_REQ_SET_CONFIGURATION; psetup->bRequest = USB_REQ_SET_CONFIGURATION;
psetup->wValue = ( USHORT ) i; psetup->wValue = (USHORT) i;
psetup->wIndex = 0; psetup->wIndex = 0;
psetup->wLength = 0; psetup->wLength = 0;
usb_dbg_print( DBGLVL_MAXIMUM, ( "compdev_connect(): start config the device, cfgval=%d\n", i ) ); usb_dbg_print(DBGLVL_MAXIMUM, ("compdev_connect(): start config the device, cfgval=%d\n", i));
status = usb_submit_urb( dev_mgr, purb ); status = usb_submit_urb(dev_mgr, purb);
if( status != STATUS_PENDING ) if (status != STATUS_PENDING)
{ {
usb_free_mem( purb ); usb_free_mem(purb);
if( status == STATUS_SUCCESS ) if (status == STATUS_SUCCESS)
return TRUE; return TRUE;
return FALSE; return FALSE;
@ -230,34 +201,26 @@ DEV_HANDLE dev_handle
} }
VOID VOID
compdev_event_select_if_driver( compdev_event_select_if_driver(PUSB_DEV pdev, ULONG event, ULONG context, ULONG param)
PUSB_DEV pdev,
ULONG event,
ULONG context,
ULONG param
)
{ {
PUSB_DEV_MANAGER dev_mgr; PUSB_DEV_MANAGER dev_mgr;
DEV_HANDLE dev_handle; DEV_HANDLE dev_handle;
PUMSS_CREATE_DATA cd; PUMSS_CREATE_DATA cd;
if( pdev == NULL ) if (pdev == NULL)
return; return;
// //
// RtlZeroMemory( &cd, sizeof( cd ) ); // RtlZeroMemory( &cd, sizeof( cd ) );
// //
dev_mgr = dev_mgr_from_dev( pdev ); dev_mgr = dev_mgr_from_dev(pdev);
dev_handle = usb_make_handle( pdev->dev_id, 0, 0 ); dev_handle = usb_make_handle(pdev->dev_id, 0, 0);
compdev_select_driver( dev_mgr, dev_handle ); compdev_select_driver(dev_mgr, dev_handle);
return; return;
} }
BOOL BOOL
compdev_post_event_select_driver( compdev_post_event_select_driver(PUSB_DEV_MANAGER dev_mgr, DEV_HANDLE dev_handle)
PUSB_DEV_MANAGER dev_mgr,
DEV_HANDLE dev_handle
)
{ {
PUSB_EVENT pevent; PUSB_EVENT pevent;
BOOL bret; BOOL bret;
@ -265,23 +228,23 @@ DEV_HANDLE dev_handle
USE_IRQL; USE_IRQL;
if( dev_mgr == NULL || dev_handle == 0 ) if (dev_mgr == NULL || dev_handle == 0)
return FALSE; return FALSE;
if( usb_query_and_lock_dev( dev_mgr, dev_handle, &pdev ) != STATUS_SUCCESS ) if (usb_query_and_lock_dev(dev_mgr, dev_handle, &pdev) != STATUS_SUCCESS)
return FALSE; return FALSE;
KeAcquireSpinLockAtDpcLevel( &dev_mgr->event_list_lock ); KeAcquireSpinLockAtDpcLevel(&dev_mgr->event_list_lock);
lock_dev( pdev, TRUE ); lock_dev(pdev, TRUE);
if( dev_state( pdev ) == USB_DEV_STATE_ZOMB ) if (dev_state(pdev) == USB_DEV_STATE_ZOMB)
{ {
bret = FALSE; bret = FALSE;
goto LBL_OUT; goto LBL_OUT;
} }
pevent = alloc_event( &dev_mgr->event_pool, 1 ); pevent = alloc_event(&dev_mgr->event_pool, 1);
if( pevent == NULL ) if (pevent == NULL)
{ {
bret = FALSE; bret = FALSE;
goto LBL_OUT; goto LBL_OUT;
@ -295,23 +258,20 @@ DEV_HANDLE dev_handle
pevent->process_event = compdev_event_select_if_driver; pevent->process_event = compdev_event_select_if_driver;
pevent->process_queue = event_list_default_process_queue; pevent->process_queue = event_list_default_process_queue;
InsertTailList( &dev_mgr->event_list, &pevent->event_link ); InsertTailList(&dev_mgr->event_list, &pevent->event_link);
KeSetEvent( &dev_mgr->wake_up_event, 0, FALSE ); // wake up the dev_mgr_thread KeSetEvent(&dev_mgr->wake_up_event, 0, FALSE); // wake up the dev_mgr_thread
bret = TRUE; bret = TRUE;
LBL_OUT: LBL_OUT:
unlock_dev( pdev, TRUE ); unlock_dev(pdev, TRUE);
KeReleaseSpinLockFromDpcLevel( &dev_mgr->event_list_lock ); KeReleaseSpinLockFromDpcLevel(&dev_mgr->event_list_lock);
usb_unlock_dev( pdev ); usb_unlock_dev(pdev);
return bret; return bret;
} }
VOID VOID
compdev_set_cfg_completion( compdev_set_cfg_completion(PURB purb, PVOID context)
PURB purb,
PVOID context
)
{ {
DEV_HANDLE dev_handle; DEV_HANDLE dev_handle;
PUSB_DEV_MANAGER dev_mgr; PUSB_DEV_MANAGER dev_mgr;
@ -322,62 +282,59 @@ PVOID context
USE_IRQL; USE_IRQL;
if( purb == NULL || context == NULL ) if (purb == NULL || context == NULL)
return; return;
dev_handle = purb->endp_handle & ~0xffff; dev_handle = purb->endp_handle & ~0xffff;
dev_mgr = ( PUSB_DEV_MANAGER ) context; dev_mgr = (PUSB_DEV_MANAGER) context;
pdriver = ( PUSB_DRIVER )purb->reference; pdriver = (PUSB_DRIVER) purb->reference;
if( purb->status != STATUS_SUCCESS ) if (purb->status != STATUS_SUCCESS)
{ {
usb_free_mem( purb ); usb_free_mem(purb);
return; return;
} }
usb_free_mem( purb ); usb_free_mem(purb);
purb = NULL; purb = NULL;
// set the dev state // set the dev state
status = usb_query_and_lock_dev( dev_mgr, dev_handle, &pdev ); status = usb_query_and_lock_dev(dev_mgr, dev_handle, &pdev);
if( status != STATUS_SUCCESS ) if (status != STATUS_SUCCESS)
{ {
usb_unlock_dev( pdev ); usb_unlock_dev(pdev);
return; return;
} }
// safe to release the pdev ref since we are in urb completion // safe to release the pdev ref since we are in urb completion
usb_unlock_dev( pdev ); usb_unlock_dev(pdev);
lock_dev( pdev, TRUE ); lock_dev(pdev, TRUE);
if( dev_state( pdev ) >= USB_DEV_STATE_BEFORE_ZOMB ) if (dev_state(pdev) >= USB_DEV_STATE_BEFORE_ZOMB)
{ {
unlock_dev( pdev, TRUE ); unlock_dev(pdev, TRUE);
return; return;
} }
if( dev_mgr_set_driver( dev_mgr, dev_handle, pdriver, pdev ) == FALSE ) if (dev_mgr_set_driver(dev_mgr, dev_handle, pdriver, pdev) == FALSE)
return; return;
//transit the state to configured //transit the state to configured
pdev->flags &= ~USB_DEV_STATE_MASK; pdev->flags &= ~USB_DEV_STATE_MASK;
pdev->flags |= USB_DEV_STATE_CONFIGURED; pdev->flags |= USB_DEV_STATE_CONFIGURED;
unlock_dev( pdev, TRUE ); unlock_dev(pdev, TRUE);
// //
// we change to use our thread for driver choosing. it will reduce // we change to use our thread for driver choosing. it will reduce
// the race condition when different pnp event comes simultaneously // the race condition when different pnp event comes simultaneously
// //
usb_dbg_print( DBGLVL_MAXIMUM, ( "compdev_set_cfg_completion(): start select driver for the dev\n" ) ); usb_dbg_print(DBGLVL_MAXIMUM, ("compdev_set_cfg_completion(): start select driver for the dev\n"));
compdev_post_event_select_driver( dev_mgr, dev_handle ); compdev_post_event_select_driver(dev_mgr, dev_handle);
return; return;
} }
VOID VOID
compdev_select_driver( compdev_select_driver(PUSB_DEV_MANAGER dev_mgr, DEV_HANDLE dev_handle)
PUSB_DEV_MANAGER dev_mgr,
DEV_HANDLE dev_handle
)
{ {
URB urb; URB urb;
LONG i, j, k, credit; LONG i, j, k, credit;
@ -393,18 +350,18 @@ DEV_HANDLE dev_handle
USE_IRQL; USE_IRQL;
usb_dbg_print( DBGLVL_MAXIMUM, ( "compdev_select_driver(): entering...\n" ) ); usb_dbg_print(DBGLVL_MAXIMUM, ("compdev_select_driver(): entering...\n"));
dev_id = dev_handle >> 16; dev_id = dev_handle >> 16;
buf = usb_alloc_mem( NonPagedPool, 512 ); buf = usb_alloc_mem(NonPagedPool, 512);
if( buf == NULL ) if (buf == NULL)
return; return;
// now let's get the descs, one configuration // now let's get the descs, one configuration
urb_init( &urb ); urb_init(&urb);
psetup = ( PUSB_CTRL_SETUP_PACKET )urb.setup_packet; psetup = (PUSB_CTRL_SETUP_PACKET) urb.setup_packet;
urb.endp_handle = dev_handle | 0xffff; urb.endp_handle = dev_handle | 0xffff;
urb.data_buffer = buf; urb.data_buffer = buf;
urb.data_length = 512; urb.data_length = 512;
@ -417,72 +374,69 @@ DEV_HANDLE dev_handle
psetup->wIndex = 0; psetup->wIndex = 0;
psetup->wLength = 512; psetup->wLength = 512;
status = usb_submit_urb( dev_mgr, &urb ); status = usb_submit_urb(dev_mgr, &urb);
if( status == STATUS_PENDING ) if (status == STATUS_PENDING)
{ {
TRAP(); TRAP();
} }
// let's scan the interfacs for those we recognize // let's scan the interfacs for those we recognize
pconfig_desc = ( PUSB_CONFIGURATION_DESC )buf; pconfig_desc = (PUSB_CONFIGURATION_DESC) buf;
if( pconfig_desc->wTotalLength > 512 ) if (pconfig_desc->wTotalLength > 512)
{ {
usb_free_mem( buf ); usb_free_mem(buf);
usb_dbg_print( DBGLVL_MAXIMUM, ( "compdev_select_driver(): error, bad configuration desc\n" ) ); usb_dbg_print(DBGLVL_MAXIMUM, ("compdev_select_driver(): error, bad configuration desc\n"));
return; return;
} }
pif_desc = ( PUSB_INTERFACE_DESC )&pconfig_desc[ 1 ]; pif_desc = (PUSB_INTERFACE_DESC) & pconfig_desc[1];
if( usb_query_and_lock_dev( dev_mgr, dev_handle, &pdev ) != STATUS_SUCCESS ) if (usb_query_and_lock_dev(dev_mgr, dev_handle, &pdev) != STATUS_SUCCESS)
{ {
usb_free_mem( buf ); usb_free_mem(buf);
usb_dbg_print( DBGLVL_MAXIMUM, ( "compdev_select_driver(): error, dev does not exist\n" ) ); usb_dbg_print(DBGLVL_MAXIMUM, ("compdev_select_driver(): error, dev does not exist\n"));
return; return;
} }
for( i = 0; i < ( LONG )pconfig_desc->bNumInterfaces; i++ ) for(i = 0; i < (LONG) pconfig_desc->bNumInterfaces; i++)
{ {
for( j = 0, credit = 0, pcand = NULL; j < DEVMGR_MAX_DRIVERS; j++ ) for(j = 0, credit = 0, pcand = NULL; j < DEVMGR_MAX_DRIVERS; j++)
{ {
ptemp_drv = &dev_mgr->driver_list[ j ]; ptemp_drv = &dev_mgr->driver_list[j];
k = dev_mgr_score_driver_for_if( dev_mgr, ptemp_drv, pif_desc ); k = dev_mgr_score_driver_for_if(dev_mgr, ptemp_drv, pif_desc);
if( k > credit ) if (k > credit)
credit = k, pcand = ptemp_drv; credit = k, pcand = ptemp_drv;
} }
if( credit ) if (credit)
{ {
// ok, we find one // ok, we find one
CONNECT_DATA param; CONNECT_DATA param;
if( pcand->disp_tbl.dev_connect ) if (pcand->disp_tbl.dev_connect)
{ {
param.dev_mgr = dev_mgr; param.dev_mgr = dev_mgr;
param.pdriver = pcand; param.pdriver = pcand;
param.dev_handle = 0; param.dev_handle = 0;
pcand->disp_tbl.dev_connect( &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; break;
} }
} }
usb_unlock_dev( pdev ); usb_unlock_dev(pdev);
if( buf ) if (buf)
{ {
usb_free_mem( buf ); usb_free_mem(buf);
buf = NULL; buf = NULL;
} }
return; return;
} }
BOOL BOOL
compdev_stop( compdev_stop(PUSB_DEV_MANAGER dev_mgr, DEV_HANDLE dev_handle)
PUSB_DEV_MANAGER dev_mgr,
DEV_HANDLE dev_handle
)
{ {
PUSB_DEV pdev; PUSB_DEV pdev;
LONG i; LONG i;
@ -490,37 +444,34 @@ DEV_HANDLE dev_handle
PUSB_DRIVER pdrv; PUSB_DRIVER pdrv;
NTSTATUS status; NTSTATUS status;
if( dev_mgr == NULL || dev_handle == 0 ) if (dev_mgr == NULL || dev_handle == 0)
return FALSE; return FALSE;
pdev = NULL; pdev = NULL;
dev_id = dev_handle >> 16; dev_id = dev_handle >> 16;
status = usb_query_and_lock_dev( dev_mgr, dev_handle, &pdev ); status = usb_query_and_lock_dev(dev_mgr, dev_handle, &pdev);
if( pdev ) if (pdev)
{ {
if( pdev->usb_config ) if (pdev->usb_config)
{ {
for( i = 0; i < pdev->usb_config->if_count; i++ ) for(i = 0; i < pdev->usb_config->if_count; i++)
{ {
if( pdrv = pdev->usb_config->interf[ i ].pif_drv ) if (pdrv = pdev->usb_config->interf[i].pif_drv)
{ {
pdrv->disp_tbl.dev_stop( dev_mgr, usb_make_handle( dev_id, i, 0 ) ); pdrv->disp_tbl.dev_stop(dev_mgr, usb_make_handle(dev_id, i, 0));
} }
} }
} }
} }
if( status == STATUS_SUCCESS ) if (status == STATUS_SUCCESS)
{ {
usb_unlock_dev( pdev ); usb_unlock_dev(pdev);
} }
return TRUE; return TRUE;
} }
BOOL BOOL
compdev_disconnect( compdev_disconnect(PUSB_DEV_MANAGER dev_mgr, DEV_HANDLE dev_handle)
PUSB_DEV_MANAGER dev_mgr,
DEV_HANDLE dev_handle
)
{ {
PUSB_DEV pdev; PUSB_DEV pdev;
LONG i; LONG i;
@ -528,28 +479,28 @@ DEV_HANDLE dev_handle
PUSB_DRIVER pdrv; PUSB_DRIVER pdrv;
NTSTATUS status; NTSTATUS status;
if( dev_mgr == NULL || dev_handle == 0 ) if (dev_mgr == NULL || dev_handle == 0)
return FALSE; return FALSE;
pdev = NULL; pdev = NULL;
dev_id = dev_handle >> 16; dev_id = dev_handle >> 16;
status = usb_query_and_lock_dev( dev_mgr, dev_handle, &pdev ); status = usb_query_and_lock_dev(dev_mgr, dev_handle, &pdev);
if( pdev ) if (pdev)
{ {
if( pdev->usb_config ) if (pdev->usb_config)
{ {
for( i = 0; i < pdev->usb_config->if_count; i++ ) for(i = 0; i < pdev->usb_config->if_count; i++)
{ {
if( pdrv = pdev->usb_config->interf[ i ].pif_drv ) if (pdrv = pdev->usb_config->interf[i].pif_drv)
{ {
pdrv->disp_tbl.dev_disconnect( dev_mgr, usb_make_handle( dev_id, i, 0 ) ); pdrv->disp_tbl.dev_disconnect(dev_mgr, usb_make_handle(dev_id, i, 0));
} }
} }
} }
} }
if( status == STATUS_SUCCESS ) if (status == STATUS_SUCCESS)
{ {
usb_unlock_dev( pdev ); usb_unlock_dev(pdev);
} }
return TRUE; return TRUE;
} }

View file

@ -26,10 +26,7 @@
#include "hub.h" #include "hub.h"
VOID VOID
disp_urb_completion( disp_urb_completion(PURB purb, PVOID context)
PURB purb,
PVOID context
)
{ {
PUSB_CTRL_SETUP_PACKET psetup; PUSB_CTRL_SETUP_PACKET psetup;
PUSB_DEV_MANAGER dev_mgr; PUSB_DEV_MANAGER dev_mgr;
@ -37,11 +34,11 @@ PVOID context
NTSTATUS status; NTSTATUS status;
PDEVEXT_HEADER dev_hdr; PDEVEXT_HEADER dev_hdr;
if( purb == NULL ) if (purb == NULL)
return; return;
ctrl_code = ( ULONG )purb->reference; ctrl_code = (ULONG) purb->reference;
dev_mgr = ( PUSB_DEV_MANAGER )purb->context; dev_mgr = (PUSB_DEV_MANAGER) purb->context;
// at this stage, the irp can not be canceled since the urb // at this stage, the irp can not be canceled since the urb
// won't be found in any queue and the irp is not in any queue. // won't be found in any queue and the irp is not in any queue.
@ -55,15 +52,15 @@ PVOID context
// running level. And the solution is to register the irp // running level. And the solution is to register the irp
// before the urb is scheduled instead of registering it after // before the urb is scheduled instead of registering it after
// urb is scheduled. // urb is scheduled.
if( purb->pirp ) if (purb->pirp)
{ {
PIO_STACK_LOCATION irp_stack; PIO_STACK_LOCATION irp_stack;
dev_mgr_remove_irp( dev_mgr, purb->pirp ); dev_mgr_remove_irp(dev_mgr, purb->pirp);
status = purb->status; status = purb->status;
irp_stack = IoGetCurrentIrpStackLocation( purb->pirp ); irp_stack = IoGetCurrentIrpStackLocation(purb->pirp);
if( purb->status != STATUS_SUCCESS ) if (purb->status != STATUS_SUCCESS)
{ {
purb->pirp->IoStatus.Information = 0; purb->pirp->IoStatus.Information = 0;
} }
@ -72,28 +69,25 @@ PVOID context
// currently only IRP_MJ_DEVICE_CONTROL and IRP_MJ_INTERNAL_DEVICE_CONTROL // currently only IRP_MJ_DEVICE_CONTROL and IRP_MJ_INTERNAL_DEVICE_CONTROL
// are allowed. And we do not need to set information // are allowed. And we do not need to set information
// for IRP_MJ_INTERNAL_DEVICE_CONTROL // for IRP_MJ_INTERNAL_DEVICE_CONTROL
if( irp_stack->MajorFunction == IRP_MJ_DEVICE_CONTROL ) if (irp_stack->MajorFunction == IRP_MJ_DEVICE_CONTROL)
purb->pirp->IoStatus.Information = purb->data_length; purb->pirp->IoStatus.Information = purb->data_length;
} }
purb->pirp->IoStatus.Status = status; purb->pirp->IoStatus.Status = status;
if( irp_stack ) if (irp_stack)
{ {
dev_hdr = irp_stack->DeviceObject->DeviceExtension; dev_hdr = irp_stack->DeviceObject->DeviceExtension;
if( dev_hdr->start_io ) if (dev_hdr->start_io)
{ {
IoStartNextPacket( irp_stack->DeviceObject, TRUE ); IoStartNextPacket(irp_stack->DeviceObject, TRUE);
} }
} }
IoCompleteRequest( purb->pirp, IO_NO_INCREMENT ); IoCompleteRequest(purb->pirp, IO_NO_INCREMENT);
} }
return; return;
} }
VOID VOID
disp_noio_urb_completion( disp_noio_urb_completion(PURB purb, PVOID context)
PURB purb,
PVOID context
)
{ {
PUSB_CTRL_SETUP_PACKET psetup; PUSB_CTRL_SETUP_PACKET psetup;
PURB purb2; PURB purb2;
@ -102,99 +96,100 @@ PVOID context
PIO_STACK_LOCATION irp_stack; PIO_STACK_LOCATION irp_stack;
PDEVEXT_HEADER dev_hdr; PDEVEXT_HEADER dev_hdr;
if( purb == NULL ) if (purb == NULL)
return; return;
psetup = ( PUSB_CTRL_SETUP_PACKET )purb->setup_packet; psetup = (PUSB_CTRL_SETUP_PACKET) purb->setup_packet;
if( psetup->bmRequestType == 0x2 if ((psetup->bmRequestType == 0x2) &&
&& psetup->bRequest == USB_REQ_CLEAR_FEATURE (psetup->bRequest == USB_REQ_CLEAR_FEATURE) &&
&& psetup->wIndex == 0 ) //reset pipe (psetup->wIndex == 0)) //reset pipe
purb2 = ( PURB )context; {
purb2 = (PURB) context;
}
else else
{
purb2 = purb; purb2 = purb;
}
if( purb2->pirp == NULL ) if (purb2->pirp == NULL)
return; return;
dev_mgr = ( PUSB_DEV_MANAGER )purb2->context; dev_mgr = (PUSB_DEV_MANAGER) purb2->context;
dev_mgr_remove_irp( dev_mgr, purb2->pirp ); dev_mgr_remove_irp(dev_mgr, purb2->pirp);
if( purb->status != STATUS_SUCCESS ) if (purb->status != STATUS_SUCCESS)
status = STATUS_IO_DEVICE_ERROR; status = STATUS_IO_DEVICE_ERROR;
purb2->pirp->IoStatus.Information = 0; purb2->pirp->IoStatus.Information = 0;
purb2->pirp->IoStatus.Status = status; purb2->pirp->IoStatus.Status = status;
irp_stack = IoGetCurrentIrpStackLocation( purb->pirp ); irp_stack = IoGetCurrentIrpStackLocation(purb->pirp);
if( irp_stack ) if (irp_stack)
{ {
dev_hdr = irp_stack->DeviceObject->DeviceExtension; dev_hdr = irp_stack->DeviceObject->DeviceExtension;
if( dev_hdr->start_io ) if (dev_hdr->start_io)
{ {
IoStartNextPacket( irp_stack->DeviceObject, TRUE ); IoStartNextPacket(irp_stack->DeviceObject, TRUE);
} }
} }
IoCompleteRequest( purb2->pirp, IO_NO_INCREMENT ); IoCompleteRequest(purb2->pirp, IO_NO_INCREMENT);
return; return;
} }
NTSTATUS
dev_mgr_dispatch(
IN PUSB_DEV_MANAGER dev_mgr,
IN PIRP irp
)
//this function is called by the hcd's //this function is called by the hcd's
//dispatch when they have done their job. //dispatch when they have done their job.
NTSTATUS
dev_mgr_dispatch(IN PUSB_DEV_MANAGER dev_mgr, IN PIRP irp)
{ {
PIO_STACK_LOCATION irp_stack; PIO_STACK_LOCATION irp_stack;
NTSTATUS status; NTSTATUS status;
ULONG ctrl_code; ULONG ctrl_code;
USE_IRQL; USE_IRQL;
if( dev_mgr == NULL || irp == NULL ) if (dev_mgr == NULL || irp == NULL)
{ {
EXIT_DISPATCH( STATUS_INVALID_PARAMETER, irp ); EXIT_DISPATCH(STATUS_INVALID_PARAMETER, irp);
} }
status = STATUS_SUCCESS; status = STATUS_SUCCESS;
irp_stack = IoGetCurrentIrpStackLocation (irp); irp_stack = IoGetCurrentIrpStackLocation(irp);
ctrl_code = irp_stack->Parameters.DeviceIoControl.IoControlCode; ctrl_code = irp_stack->Parameters.DeviceIoControl.IoControlCode;
switch ( irp_stack->MajorFunction ) switch (irp_stack->MajorFunction)
{ {
case IRP_MJ_CREATE: case IRP_MJ_CREATE:
{ {
InterlockedIncrement( &dev_mgr->open_count ); InterlockedIncrement(&dev_mgr->open_count);
EXIT_DISPATCH( STATUS_SUCCESS, irp ); EXIT_DISPATCH(STATUS_SUCCESS, irp);
} }
case IRP_MJ_CLOSE: case IRP_MJ_CLOSE:
{ {
InterlockedDecrement( &dev_mgr->open_count ); InterlockedDecrement(&dev_mgr->open_count);
EXIT_DISPATCH( STATUS_SUCCESS, irp ); EXIT_DISPATCH(STATUS_SUCCESS, irp);
} }
case IRP_MJ_INTERNAL_DEVICE_CONTROL: case IRP_MJ_INTERNAL_DEVICE_CONTROL:
case IRP_MJ_DEVICE_CONTROL: case IRP_MJ_DEVICE_CONTROL:
{ {
switch( ctrl_code ) switch (ctrl_code)
{ {
case IOCTL_GET_DEV_COUNT: case IOCTL_GET_DEV_COUNT:
{ {
LONG dev_count; LONG dev_count;
irp->IoStatus.Information = 0; irp->IoStatus.Information = 0;
if( irp_stack->Parameters.DeviceIoControl.OutputBufferLength < sizeof( LONG ) ) if (irp_stack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(LONG))
{ {
EXIT_DISPATCH( STATUS_INVALID_PARAMETER, irp ); EXIT_DISPATCH(STATUS_INVALID_PARAMETER, irp);
} }
KeAcquireSpinLock( &dev_mgr->dev_list_lock, &old_irql ); KeAcquireSpinLock(&dev_mgr->dev_list_lock, &old_irql);
dev_count = usb_count_list( &dev_mgr->dev_list ); dev_count = usb_count_list(&dev_mgr->dev_list);
KeReleaseSpinLock( &dev_mgr->dev_list_lock, old_irql ); KeReleaseSpinLock(&dev_mgr->dev_list_lock, old_irql);
*( ( PLONG )irp->AssociatedIrp.SystemBuffer ) = dev_count; *((PLONG) irp->AssociatedIrp.SystemBuffer) = dev_count;
irp->IoStatus.Information = sizeof( LONG ); irp->IoStatus.Information = sizeof(LONG);
EXIT_DISPATCH( STATUS_SUCCESS, irp ); EXIT_DISPATCH(STATUS_SUCCESS, irp);
} }
case IOCTL_ENUM_DEVICES: case IOCTL_ENUM_DEVICES:
{ {
@ -204,66 +199,67 @@ IN PIRP irp
PENUM_DEV_ARRAY peda; PENUM_DEV_ARRAY peda;
irp->IoStatus.Information = 0; irp->IoStatus.Information = 0;
if( irp_stack->Parameters.DeviceIoControl.InputBufferLength < sizeof( LONG ) ) if (irp_stack->Parameters.DeviceIoControl.InputBufferLength < sizeof(LONG))
{ {
EXIT_DISPATCH( STATUS_INVALID_PARAMETER, irp ); EXIT_DISPATCH(STATUS_INVALID_PARAMETER, irp);
} }
if( irp_stack->Parameters.DeviceIoControl.OutputBufferLength < sizeof( ENUM_DEV_ARRAY ) ) if (irp_stack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(ENUM_DEV_ARRAY))
{ {
EXIT_DISPATCH( STATUS_INVALID_PARAMETER, irp ); EXIT_DISPATCH(STATUS_INVALID_PARAMETER, irp);
} }
array_size = *( ( PULONG )irp->AssociatedIrp.SystemBuffer ); array_size = *((PULONG) irp->AssociatedIrp.SystemBuffer);
KeAcquireSpinLock( &dev_mgr->dev_list_lock, &old_irql ); KeAcquireSpinLock(&dev_mgr->dev_list_lock, &old_irql);
dev_count = usb_count_list( &dev_mgr->dev_list ); dev_count = usb_count_list(&dev_mgr->dev_list);
dev_count = dev_count > array_size ? array_size : dev_count; dev_count = dev_count > array_size ? array_size : dev_count;
peda = ( PENUM_DEV_ARRAY )irp->AssociatedIrp.SystemBuffer; peda = (PENUM_DEV_ARRAY) irp->AssociatedIrp.SystemBuffer;
RtlZeroMemory( peda, sizeof( ENUM_DEV_ARRAY ) + ( dev_count - 1 ) * sizeof( ENUM_DEV_ELEMENT ) ); RtlZeroMemory(peda, sizeof(ENUM_DEV_ARRAY) + (dev_count - 1) * sizeof(ENUM_DEV_ELEMENT));
if( dev_count ) if (dev_count)
{ {
ListFirst( &dev_mgr->dev_list, pthis ); ListFirst(&dev_mgr->dev_list, pthis);
for( i = 0, j = 0; i < dev_count; i++ ) for(i = 0, j = 0; i < dev_count; i++)
{ {
pdev = struct_ptr( pthis, USB_DEV, dev_link ); pdev = struct_ptr(pthis, USB_DEV, dev_link);
ListNext( &dev_mgr->dev_list, pthis, pnext ); ListNext(&dev_mgr->dev_list, pthis, pnext);
pthis = pnext; pthis = pnext;
lock_dev( pdev, FALSE ); lock_dev(pdev, FALSE);
if( dev_state( pdev ) == USB_DEV_STATE_ZOMB ) if (dev_state(pdev) == USB_DEV_STATE_ZOMB)
{ {
unlock_dev( pdev, FALSE ); unlock_dev(pdev, FALSE);
continue; continue;
} }
if( dev_state( pdev ) < USB_DEV_STATE_ADDRESSED ) if (dev_state(pdev) < USB_DEV_STATE_ADDRESSED)
{ {
unlock_dev( pdev, FALSE ); unlock_dev(pdev, FALSE);
continue; continue;
} }
peda->dev_arr[ i ].dev_handle = ( pdev->dev_id << 16 ); peda->dev_arr[i].dev_handle = (pdev->dev_id << 16);
//may not get the desc yet //may not get the desc yet
if( pdev->pusb_dev_desc ) if (pdev->pusb_dev_desc)
{ {
peda->dev_arr[ i ].product_id = pdev->pusb_dev_desc->idProduct; peda->dev_arr[i].product_id = pdev->pusb_dev_desc->idProduct;
peda->dev_arr[ i ].vendor_id = pdev->pusb_dev_desc->idVendor; peda->dev_arr[i].vendor_id = pdev->pusb_dev_desc->idVendor;
} }
else else
{ {
peda->dev_arr[ i ].product_id = 0xffff; peda->dev_arr[i].product_id = 0xffff;
peda->dev_arr[ i ].vendor_id = 0xffff; peda->dev_arr[i].vendor_id = 0xffff;
} }
peda->dev_arr[ i ].dev_addr = pdev->dev_addr; peda->dev_arr[i].dev_addr = pdev->dev_addr;
unlock_dev( pdev, FALSE ); unlock_dev(pdev, FALSE);
j++; j++;
} }
} }
peda->dev_count = dev_count ? j : 0; peda->dev_count = dev_count ? j : 0;
KeReleaseSpinLock( &dev_mgr->dev_list_lock, old_irql ); KeReleaseSpinLock(&dev_mgr->dev_list_lock, old_irql);
irp->IoStatus.Information = sizeof( ENUM_DEV_ARRAY ) + ( dev_count - 1 ) * sizeof( ENUM_DEV_ELEMENT ); irp->IoStatus.Information =
EXIT_DISPATCH( STATUS_SUCCESS, irp ); sizeof(ENUM_DEV_ARRAY) + (dev_count - 1) * sizeof(ENUM_DEV_ELEMENT);
EXIT_DISPATCH(STATUS_SUCCESS, irp);
} }
case IOCTL_GET_DEV_DESC: case IOCTL_GET_DEV_DESC:
{ {
@ -273,96 +269,93 @@ IN PIRP irp
PUSB_DEV pdev; PUSB_DEV pdev;
LONG buf_size; LONG buf_size;
if( irp_stack->Parameters.DeviceIoControl.InputBufferLength < sizeof( GET_DEV_DESC_REQ ) ) if (irp_stack->Parameters.DeviceIoControl.InputBufferLength < sizeof(GET_DEV_DESC_REQ))
{ {
EXIT_DISPATCH( STATUS_INVALID_PARAMETER, irp ); EXIT_DISPATCH(STATUS_INVALID_PARAMETER, irp);
} }
if( irp_stack->Parameters.DeviceIoControl.OutputBufferLength < 8 ) if (irp_stack->Parameters.DeviceIoControl.OutputBufferLength < 8)
{ {
EXIT_DISPATCH( STATUS_INVALID_PARAMETER, irp ); EXIT_DISPATCH(STATUS_INVALID_PARAMETER, irp);
} }
status = STATUS_SUCCESS; status = STATUS_SUCCESS;
buf_size = irp_stack->Parameters.DeviceIoControl.OutputBufferLength; buf_size = irp_stack->Parameters.DeviceIoControl.OutputBufferLength;
RtlCopyMemory( &gddr, irp->AssociatedIrp.SystemBuffer, sizeof( GET_DEV_DESC_REQ ) ); RtlCopyMemory(&gddr, irp->AssociatedIrp.SystemBuffer, sizeof(GET_DEV_DESC_REQ));
pusb_desc_header = irp->AssociatedIrp.SystemBuffer; pusb_desc_header = irp->AssociatedIrp.SystemBuffer;
if( gddr.desc_type != USB_DT_CONFIG && gddr.desc_type != USB_DT_DEVICE ) if (gddr.desc_type != USB_DT_CONFIG && gddr.desc_type != USB_DT_DEVICE)
{ {
EXIT_DISPATCH( STATUS_INVALID_DEVICE_REQUEST, irp ); EXIT_DISPATCH(STATUS_INVALID_DEVICE_REQUEST, irp);
} }
if( usb_query_and_lock_dev( dev_mgr, gddr.dev_handle, &pdev ) != STATUS_SUCCESS ) if (usb_query_and_lock_dev(dev_mgr, gddr.dev_handle, &pdev) != STATUS_SUCCESS)
{ {
EXIT_DISPATCH( STATUS_IO_DEVICE_ERROR, irp ); EXIT_DISPATCH(STATUS_IO_DEVICE_ERROR, irp);
} }
lock_dev( pdev, FALSE ); lock_dev(pdev, FALSE);
if( dev_state( pdev ) == USB_DEV_STATE_ZOMB ) if (dev_state(pdev) == USB_DEV_STATE_ZOMB)
{ {
status = STATUS_INVALID_DEVICE_STATE; status = STATUS_INVALID_DEVICE_STATE;
goto ERROR_OUT; goto ERROR_OUT;
} }
if( dev_state( pdev ) != USB_DEV_STATE_ADDRESSED && \ if (dev_state(pdev) != USB_DEV_STATE_ADDRESSED &&
dev_state( pdev ) != USB_DEV_STATE_CONFIGURED ) dev_state(pdev) != USB_DEV_STATE_CONFIGURED)
{ {
status = STATUS_DEVICE_NOT_READY; status = STATUS_DEVICE_NOT_READY;
goto ERROR_OUT; goto ERROR_OUT;
} }
if( pdev->pusb_dev_desc == NULL ) if (pdev->pusb_dev_desc == NULL)
{ {
status = STATUS_DEVICE_NOT_READY; status = STATUS_DEVICE_NOT_READY;
goto ERROR_OUT; goto ERROR_OUT;
} }
if( gddr.desc_type == USB_DT_DEVICE ) if (gddr.desc_type == USB_DT_DEVICE)
{ {
RtlCopyMemory( RtlCopyMemory(pusb_desc_header,
pusb_desc_header,
pdev->pusb_dev_desc, pdev->pusb_dev_desc,
buf_size > sizeof( USB_DEVICE_DESC ) buf_size > sizeof(USB_DEVICE_DESC)
? sizeof( USB_DEVICE_DESC ) : buf_size ); ? sizeof(USB_DEVICE_DESC) : buf_size);
irp->IoStatus.Information = irp->IoStatus.Information =
buf_size >= sizeof( USB_DEVICE_DESC ) buf_size >= sizeof(USB_DEVICE_DESC) ? sizeof(USB_DEVICE_DESC) : buf_size;
? sizeof( USB_DEVICE_DESC ): buf_size ;
} }
else if( gddr.desc_type == USB_DT_CONFIG ) else if (gddr.desc_type == USB_DT_CONFIG)
{ {
PUSB_CONFIGURATION_DESC pusb_config_desc; PUSB_CONFIGURATION_DESC pusb_config_desc;
if( pdev->pusb_dev_desc->bNumConfigurations <= gddr.desc_idx ) if (pdev->pusb_dev_desc->bNumConfigurations <= gddr.desc_idx)
{ {
status = STATUS_INVALID_PARAMETER; status = STATUS_INVALID_PARAMETER;
goto ERROR_OUT; goto ERROR_OUT;
} }
pusb_config_desc = usb_find_config_desc_by_idx( pusb_config_desc = usb_find_config_desc_by_idx((PUCHAR) & pdev->pusb_dev_desc[1],
( PUCHAR )&pdev->pusb_dev_desc[ 1 ],
gddr.desc_idx, gddr.desc_idx,
pdev->pusb_dev_desc->bNumConfigurations ); pdev->pusb_dev_desc->
bNumConfigurations);
if( pusb_config_desc == NULL ) if (pusb_config_desc == NULL)
{ {
status = STATUS_DEVICE_NOT_READY; status = STATUS_DEVICE_NOT_READY;
goto ERROR_OUT; goto ERROR_OUT;
} }
RtlCopyMemory( RtlCopyMemory(pusb_desc_header,
pusb_desc_header,
pusb_config_desc, pusb_config_desc,
buf_size >= pusb_config_desc->wTotalLength buf_size >= pusb_config_desc->wTotalLength
? pusb_config_desc->wTotalLength : buf_size ); ? pusb_config_desc->wTotalLength : buf_size);
irp->IoStatus.Information = irp->IoStatus.Information =
buf_size >= pusb_config_desc->wTotalLength buf_size >= pusb_config_desc->wTotalLength
? pusb_config_desc->wTotalLength : buf_size; ? pusb_config_desc->wTotalLength : buf_size;
} }
ERROR_OUT: ERROR_OUT:
unlock_dev( pdev, FALSE ); unlock_dev(pdev, FALSE);
usb_unlock_dev( pdev ); usb_unlock_dev(pdev);
EXIT_DISPATCH( status, irp ); EXIT_DISPATCH(status, irp);
} }
case IOCTL_SUBMIT_URB_RD: case IOCTL_SUBMIT_URB_RD:
case IOCTL_SUBMIT_URB_WR: case IOCTL_SUBMIT_URB_WR:
@ -379,64 +372,62 @@ IN PIRP irp
PUSB_CTRL_SETUP_PACKET psetup; PUSB_CTRL_SETUP_PACKET psetup;
if( irp_stack->Parameters.DeviceIoControl.InputBufferLength < sizeof( URB ) ) if (irp_stack->Parameters.DeviceIoControl.InputBufferLength < sizeof(URB))
{ {
EXIT_DISPATCH( STATUS_INVALID_PARAMETER, irp ); EXIT_DISPATCH(STATUS_INVALID_PARAMETER, irp);
} }
purb = ( PURB )irp->AssociatedIrp.SystemBuffer; purb = (PURB) irp->AssociatedIrp.SystemBuffer;
endp_handle = purb->endp_handle; endp_handle = purb->endp_handle;
if( ctrl_code == IOCTL_SUBMIT_URB_RD || ctrl_code == IOCTL_SUBMIT_URB_WR ) if (ctrl_code == IOCTL_SUBMIT_URB_RD || ctrl_code == IOCTL_SUBMIT_URB_WR)
{ {
if( irp_stack->MajorFunction == IRP_MJ_DEVICE_CONTROL ) if (irp_stack->MajorFunction == IRP_MJ_DEVICE_CONTROL)
{ {
user_buffer_length = irp_stack->Parameters.DeviceIoControl.OutputBufferLength; user_buffer_length = irp_stack->Parameters.DeviceIoControl.OutputBufferLength;
if( user_buffer_length == 0 ) if (user_buffer_length == 0)
EXIT_DISPATCH( STATUS_INVALID_PARAMETER, irp ); EXIT_DISPATCH(STATUS_INVALID_PARAMETER, irp);
user_buffer = MmGetSystemAddressForMdl( irp->MdlAddress ); user_buffer = MmGetSystemAddressForMdl(irp->MdlAddress);
} }
else else
{ {
if( purb->data_buffer == NULL || purb->data_length == 0 ) if (purb->data_buffer == NULL || purb->data_length == 0)
EXIT_DISPATCH( STATUS_INVALID_PARAMETER, irp ); EXIT_DISPATCH(STATUS_INVALID_PARAMETER, irp);
user_buffer_length = purb->data_length; user_buffer_length = purb->data_length;
user_buffer = purb->data_buffer; user_buffer = purb->data_buffer;
} }
} }
if( usb_query_and_lock_dev( dev_mgr, endp_handle & ~0xffff, &pdev ) != STATUS_SUCCESS ) if (usb_query_and_lock_dev(dev_mgr, endp_handle & ~0xffff, &pdev) != STATUS_SUCCESS)
{ {
EXIT_DISPATCH( STATUS_IO_DEVICE_ERROR, irp ); EXIT_DISPATCH(STATUS_IO_DEVICE_ERROR, irp);
} }
lock_dev( pdev, FALSE ); lock_dev(pdev, FALSE);
if( dev_state( pdev ) == USB_DEV_STATE_ZOMB \ if (dev_state(pdev) == USB_DEV_STATE_ZOMB || (dev_state(pdev) < USB_DEV_STATE_ADDRESSED))
|| ( dev_state( pdev ) < USB_DEV_STATE_ADDRESSED ) )
{ {
status = STATUS_INVALID_DEVICE_STATE; status = STATUS_INVALID_DEVICE_STATE;
goto ERROR_OUT1; goto ERROR_OUT1;
} }
if( dev_state( pdev ) == USB_DEV_STATE_ADDRESSED if (dev_state(pdev) == USB_DEV_STATE_ADDRESSED && !default_endp_handle(endp_handle))
&& !default_endp_handle( endp_handle ) )
{ {
status = STATUS_DEVICE_NOT_READY; status = STATUS_DEVICE_NOT_READY;
goto ERROR_OUT1; goto ERROR_OUT1;
} }
if_idx = if_idx_from_handle( endp_handle ); if_idx = if_idx_from_handle(endp_handle);
endp_idx = endp_idx_from_handle( endp_handle ); endp_idx = endp_idx_from_handle(endp_handle);
//if_idx exceeds the upper limit //if_idx exceeds the upper limit
if( pdev->usb_config ) if (pdev->usb_config)
{ {
if( if_idx >= pdev->usb_config->if_count if (if_idx >= pdev->usb_config->if_count
|| endp_idx >= pdev->usb_config->interf[ if_idx ].endp_count ) || endp_idx >= pdev->usb_config->interf[if_idx].endp_count)
{ {
if( !default_endp_handle( endp_handle ) ) if (!default_endp_handle(endp_handle))
{ {
status = STATUS_INVALID_DEVICE_STATE; status = STATUS_INVALID_DEVICE_STATE;
goto ERROR_OUT1; goto ERROR_OUT1;
@ -444,11 +435,11 @@ IN PIRP irp
} }
} }
endp_from_handle( pdev, endp_handle, pendp ); endp_from_handle(pdev, endp_handle, pendp);
// FIXME: don't know what evil will let loose // FIXME: don't know what evil will let loose
if( endp_type( pendp ) != USB_ENDPOINT_XFER_CONTROL ) if (endp_type(pendp) != USB_ENDPOINT_XFER_CONTROL)
{ {
if( user_buffer_length > 0x100000 ) if (user_buffer_length > 0x100000)
{ {
status = STATUS_INVALID_PARAMETER; status = STATUS_INVALID_PARAMETER;
goto ERROR_OUT1; goto ERROR_OUT1;
@ -459,12 +450,12 @@ IN PIRP irp
purb->context = dev_mgr; purb->context = dev_mgr;
purb->reference = ctrl_code; purb->reference = ctrl_code;
if( ctrl_code == IOCTL_SUBMIT_URB_RD || ctrl_code == IOCTL_SUBMIT_URB_WR ) if (ctrl_code == IOCTL_SUBMIT_URB_RD || ctrl_code == IOCTL_SUBMIT_URB_WR)
{ {
if( ctrl_code == IOCTL_SUBMIT_URB_RD ) if (ctrl_code == IOCTL_SUBMIT_URB_RD)
KeFlushIoBuffers( irp->MdlAddress, TRUE, TRUE ); KeFlushIoBuffers(irp->MdlAddress, TRUE, TRUE);
else else
KeFlushIoBuffers( irp->MdlAddress, FALSE, TRUE ); KeFlushIoBuffers(irp->MdlAddress, FALSE, TRUE);
purb->data_buffer = user_buffer; purb->data_buffer = user_buffer;
purb->data_length = user_buffer_length; purb->data_length = user_buffer_length;
@ -475,35 +466,35 @@ IN PIRP irp
purb->completion = disp_noio_urb_completion; purb->completion = disp_noio_urb_completion;
} }
unlock_dev( pdev, FALSE ); unlock_dev(pdev, FALSE);
// we have to mark irp before the urb is scheduled to // we have to mark irp before the urb is scheduled to
// avoid race condition // avoid race condition
IoMarkIrpPending( irp ); IoMarkIrpPending(irp);
ASSERT( dev_mgr_register_irp( dev_mgr, irp, purb ) ); ASSERT(dev_mgr_register_irp(dev_mgr, irp, purb));
status = usb_submit_urb( dev_mgr, purb ); status = usb_submit_urb(dev_mgr, purb);
if( status != STATUS_PENDING ) if (status != STATUS_PENDING)
{ {
IoGetCurrentIrpStackLocation( (irp) )->Control &= ~SL_PENDING_RETURNED; IoGetCurrentIrpStackLocation((irp))->Control &= ~SL_PENDING_RETURNED;
dev_mgr_remove_irp( dev_mgr, irp ); dev_mgr_remove_irp(dev_mgr, irp);
} }
usb_unlock_dev( pdev ); usb_unlock_dev(pdev);
if( status != STATUS_PENDING) if (status != STATUS_PENDING)
{ {
irp->IoStatus.Status = status; irp->IoStatus.Status = status;
IoCompleteRequest( irp, IO_NO_INCREMENT); IoCompleteRequest(irp, IO_NO_INCREMENT);
} }
return status; return status;
ERROR_OUT1: ERROR_OUT1:
unlock_dev( pdev, FALSE ); unlock_dev(pdev, FALSE);
usb_unlock_dev( pdev ); usb_unlock_dev(pdev);
irp->IoStatus.Information = 0; irp->IoStatus.Information = 0;
EXIT_DISPATCH( status, irp ); EXIT_DISPATCH(status, irp);
} }
default: default:
{ {
irp->IoStatus.Information = 0; irp->IoStatus.Information = 0;
EXIT_DISPATCH( STATUS_NOT_IMPLEMENTED, irp ); EXIT_DISPATCH(STATUS_NOT_IMPLEMENTED, irp);
} }
} }
} }
@ -513,7 +504,7 @@ IN PIRP irp
break; break;
} }
} }
EXIT_DISPATCH( STATUS_INVALID_DEVICE_REQUEST, irp ); EXIT_DISPATCH(STATUS_INVALID_DEVICE_REQUEST, irp);
} }
/*#define IOCTL_GET_DEV_COUNT CTL_CODE( FILE_HCD_DEV_TYPE, 4093, METHOD_BUFFERED, FILE_ANY_ACCESS ) /*#define IOCTL_GET_DEV_COUNT CTL_CODE( FILE_HCD_DEV_TYPE, 4093, METHOD_BUFFERED, FILE_ANY_ACCESS )

File diff suppressed because it is too large Load diff

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 );\ max_liSTS = ( EHCI_MAX_ELEMS_POOL / ii1 ) > EHCI_MAX_LISTS_POOL ? EHCI_MAX_LISTS_POOL : ( EHCI_MAX_ELEMS_POOL / ii1 );\
} }
VOID VOID elem_list_destroy_elem_list(PEHCI_ELEM_LIST plist);
elem_list_destroy_elem_list(
PEHCI_ELEM_LIST plist
);
PLIST_ENTRY PLIST_ENTRY elem_list_get_list_head(PEHCI_ELEM_LIST plist);
elem_list_get_list_head(
PEHCI_ELEM_LIST plist
);
LONG LONG elem_list_get_total_count(PEHCI_ELEM_LIST plist);
elem_list_get_total_count(
PEHCI_ELEM_LIST plist
);
LONG LONG elem_list_get_elem_size(PEHCI_ELEM_LIST plist);
elem_list_get_elem_size(
PEHCI_ELEM_LIST plist
);
LONG LONG elem_list_get_link_offset(PEHCI_ELEM_LIST plist);
elem_list_get_link_offset(
PEHCI_ELEM_LIST plist
);
LONG LONG elem_list_add_ref(PEHCI_ELEM_LIST plist);
elem_list_add_ref(
PEHCI_ELEM_LIST plist
);
LONG LONG elem_list_release_ref(PEHCI_ELEM_LIST plist);
elem_list_release_ref(
PEHCI_ELEM_LIST plist
);
LONG LONG elem_list_get_ref(PEHCI_ELEM_LIST plist);
elem_list_get_ref(
PEHCI_ELEM_LIST plist
);
BOOL BOOL
elem_pool_lock( elem_pool_lock(PEHCI_ELEM_POOL pool, BOOL at_dpc)
PEHCI_ELEM_POOL pool,
BOOL at_dpc
)
{ {
return TRUE; return TRUE;
} }
BOOL BOOL
elem_pool_unlock( elem_pool_unlock(PEHCI_ELEM_POOL pool, BOOL at_dpc)
PEHCI_ELEM_POOL pool,
BOOL at_dpc
)
{ {
return TRUE; return TRUE;
} }
LONG LONG
get_elem_phys_part_size( get_elem_phys_part_size(ULONG type)
ULONG type
)
{ {
// type is INIT_LIST_FLAG_XXX // type is INIT_LIST_FLAG_XXX
LONG size; LONG size;
size = 0; size = 0;
switch( type ) switch (type)
{ {
case INIT_LIST_FLAG_ITD: case INIT_LIST_FLAG_ITD:
size = 64; size = 64;
@ -154,12 +124,7 @@ ULONG type
} }
BOOL BOOL
elem_list_init_elem_list( elem_list_init_elem_list(PEHCI_ELEM_LIST plist, LONG init_flags, PVOID context, LONG count)
PEHCI_ELEM_LIST plist,
LONG init_flags,
PVOID context,
LONG count
)
{ {
LONG pages, i, j, elms_per_page; LONG pages, i, j, elms_per_page;
PEHCI_QH pqh; PEHCI_QH pqh;
@ -169,10 +134,10 @@ LONG count
PEHCI_FSTN pfstn; PEHCI_FSTN pfstn;
PINIT_ELEM_LIST_CONTEXT pinit_ctx; PINIT_ELEM_LIST_CONTEXT pinit_ctx;
if( plist == NULL || context == NULL ) if (plist == NULL || context == NULL)
return FALSE; return FALSE;
RtlZeroMemory( plist, sizeof( EHCI_ELEM_LIST ) ); RtlZeroMemory(plist, sizeof(EHCI_ELEM_LIST));
pinit_ctx = context; pinit_ctx = context;
@ -185,34 +150,34 @@ LONG count
plist->release_ref = elem_list_release_ref; plist->release_ref = elem_list_release_ref;
plist->get_ref = elem_list_get_ref; plist->get_ref = elem_list_get_ref;
InitializeListHead( &plist->free_list ); InitializeListHead(&plist->free_list);
switch( init_flags & 0x0f ) switch (init_flags & 0x0f)
{ {
case INIT_LIST_FLAG_ITD: case INIT_LIST_FLAG_ITD:
plist->total_count = EHCI_MAX_ITDS_LIST; plist->total_count = EHCI_MAX_ITDS_LIST;
plist->elem_size = sizeof( EHCI_ITD ); plist->elem_size = sizeof(EHCI_ITD);
break; break;
case INIT_LIST_FLAG_QH: case INIT_LIST_FLAG_QH:
plist->total_count = EHCI_MAX_QHS_LIST; plist->total_count = EHCI_MAX_QHS_LIST;
plist->elem_size = sizeof( EHCI_QH ); plist->elem_size = sizeof(EHCI_QH);
break; break;
case INIT_LIST_FLAG_SITD: case INIT_LIST_FLAG_SITD:
plist->total_count = EHCI_MAX_SITDS_LIST; plist->total_count = EHCI_MAX_SITDS_LIST;
plist->elem_size = sizeof( EHCI_SITD ); plist->elem_size = sizeof(EHCI_SITD);
break; break;
case INIT_LIST_FLAG_FSTN: case INIT_LIST_FLAG_FSTN:
plist->total_count = EHCI_MAX_FSTNS_LIST; plist->total_count = EHCI_MAX_FSTNS_LIST;
plist->elem_size = sizeof( EHCI_FSTN ); plist->elem_size = sizeof(EHCI_FSTN);
break; break;
case INIT_LIST_FLAG_QTD: case INIT_LIST_FLAG_QTD:
plist->total_count = EHCI_MAX_QTDS_LIST; plist->total_count = EHCI_MAX_QTDS_LIST;
plist->elem_size = sizeof( EHCI_QTD ); plist->elem_size = sizeof(EHCI_QTD);
break; break;
default: default:
goto ERROR_OUT; goto ERROR_OUT;
} }
if( plist->elem_size & 0x1f ) if (plist->elem_size & 0x1f)
{ {
plist->total_count = 0; plist->total_count = 0;
goto ERROR_OUT; goto ERROR_OUT;
@ -221,73 +186,66 @@ LONG count
plist->flags = init_flags; plist->flags = init_flags;
plist->parent_pool = pinit_ctx->pool; plist->parent_pool = pinit_ctx->pool;
plist->padapter = pinit_ctx->padapter; plist->padapter = pinit_ctx->padapter;
pages = ( ( plist->elem_size * plist->total_count ) + ( PAGE_SIZE - 1 ) ) / PAGE_SIZE; pages = ((plist->elem_size * plist->total_count) + (PAGE_SIZE - 1)) / PAGE_SIZE;
elms_per_page = PAGE_SIZE / plist->elem_size; elms_per_page = PAGE_SIZE / plist->elem_size;
plist->phys_addrs = usb_alloc_mem( NonPagedPool, plist->phys_addrs = usb_alloc_mem(NonPagedPool,
( sizeof( PHYSICAL_ADDRESS ) + sizeof( PBYTE ) ) * pages + \ (sizeof(PHYSICAL_ADDRESS) + sizeof(PBYTE)) * pages +
sizeof( EHCI_ELEM_LINKS ) * plist->total_count ); sizeof(EHCI_ELEM_LINKS) * plist->total_count);
if( plist->phys_addrs == NULL ) if (plist->phys_addrs == NULL)
{ {
plist->total_count = 0; plist->total_count = 0;
goto ERROR_OUT; goto ERROR_OUT;
} }
plist->phys_bufs = ( PBYTE* )&plist->phys_addrs[ pages ]; plist->phys_bufs = (PBYTE *) & plist->phys_addrs[pages];
plist->elem_head_buf = ( PEHCI_ELEM_LINKS )&plist->phys_bufs[ pages ]; plist->elem_head_buf = (PEHCI_ELEM_LINKS) & plist->phys_bufs[pages];
RtlZeroMemory( plist->phys_addrs, RtlZeroMemory(plist->phys_addrs,
( sizeof( PHYSICAL_ADDRESS ) + sizeof( PBYTE ) ) * pages + \ (sizeof(PHYSICAL_ADDRESS) + sizeof(PBYTE)) * pages +
sizeof( EHCI_ELEM_LINKS ) * plist->total_count ); sizeof(EHCI_ELEM_LINKS) * plist->total_count);
for( i = 0; i < pages; i++ ) for(i = 0; i < pages; i++)
{ {
plist->phys_bufs[ i ] = HalAllocateCommonBuffer( plist->phys_bufs[i] = HalAllocateCommonBuffer(plist->padapter,
plist->padapter, PAGE_SIZE, &plist->phys_addrs[i], FALSE);
PAGE_SIZE,
&plist->phys_addrs[ i ],
FALSE);
if( plist->phys_bufs[ i ] == NULL ) if (plist->phys_bufs[i] == NULL)
{ {
// failed, roll back // failed, roll back
for( j = i - 1; j >= 0; j -- ) for(j = i - 1; j >= 0; j--)
HalFreeCommonBuffer( HalFreeCommonBuffer(plist->padapter,
plist->padapter, PAGE_SIZE, plist->phys_addrs[j], plist->phys_bufs[j], FALSE);
PAGE_SIZE,
plist->phys_addrs[ j ],
plist->phys_bufs[ j ],
FALSE );
goto ERROR_OUT; goto ERROR_OUT;
} }
RtlZeroMemory( plist->phys_bufs[ i ], PAGE_SIZE ); RtlZeroMemory(plist->phys_bufs[i], PAGE_SIZE);
for( j = 0; j < elms_per_page; j++ ) for(j = 0; j < elms_per_page; j++)
{ {
switch( init_flags & 0xf ) switch (init_flags & 0xf)
{ {
case INIT_LIST_FLAG_QH: case INIT_LIST_FLAG_QH:
{ {
init_elem( pqh, EHCI_QH, INIT_LIST_FLAG_QH ); init_elem(pqh, EHCI_QH, INIT_LIST_FLAG_QH);
break; break;
} }
case INIT_LIST_FLAG_ITD: case INIT_LIST_FLAG_ITD:
{ {
init_elem( pitd, EHCI_ITD, INIT_LIST_FLAG_ITD ); init_elem(pitd, EHCI_ITD, INIT_LIST_FLAG_ITD);
break; break;
} }
case INIT_LIST_FLAG_QTD: case INIT_LIST_FLAG_QTD:
{ {
init_elem( pqtd, EHCI_QTD, INIT_LIST_FLAG_QTD ); init_elem(pqtd, EHCI_QTD, INIT_LIST_FLAG_QTD);
break; break;
} }
case INIT_LIST_FLAG_SITD: case INIT_LIST_FLAG_SITD:
{ {
init_elem( psitd, EHCI_SITD, INIT_LIST_FLAG_SITD ); init_elem(psitd, EHCI_SITD, INIT_LIST_FLAG_SITD);
break; break;
} }
case INIT_LIST_FLAG_FSTN: case INIT_LIST_FLAG_FSTN:
{ {
init_elem( pfstn, EHCI_FSTN, INIT_LIST_FLAG_FSTN ); init_elem(pfstn, EHCI_FSTN, INIT_LIST_FLAG_FSTN);
break; break;
} }
default: default:
@ -296,101 +254,80 @@ LONG count
} }
} }
return TRUE; return TRUE;
ERROR_OUT: ERROR_OUT:
if (plist->phys_addrs != NULL)
usb_free_mem(plist->phys_addrs);
if( plist->phys_addrs != NULL ) RtlZeroMemory(plist, sizeof(EHCI_ELEM_LIST));
usb_free_mem( plist->phys_addrs );
RtlZeroMemory( plist, sizeof( EHCI_ELEM_LIST ) );
return FALSE; return FALSE;
} }
VOID VOID
elem_list_destroy_elem_list( elem_list_destroy_elem_list(PEHCI_ELEM_LIST plist)
PEHCI_ELEM_LIST plist
)
{ {
LONG i, pages; LONG i, pages;
if( plist == NULL ) if (plist == NULL)
return; return;
pages = ( plist->total_count * plist->elem_size + PAGE_SIZE - 1 ) / PAGE_SIZE; pages = (plist->total_count * plist->elem_size + PAGE_SIZE - 1) / PAGE_SIZE;
for( i = 0; i < pages; i++ ) for(i = 0; i < pages; i++)
HalFreeCommonBuffer( HalFreeCommonBuffer(plist->padapter, PAGE_SIZE, plist->phys_addrs[i], plist->phys_bufs[i], FALSE);
plist->padapter,
PAGE_SIZE,
plist->phys_addrs[ i ],
plist->phys_bufs[ i ],
FALSE );
usb_free_mem( plist->phys_addrs ); usb_free_mem(plist->phys_addrs);
RtlZeroMemory( plist, sizeof( EHCI_ELEM_LIST ) ); RtlZeroMemory(plist, sizeof(EHCI_ELEM_LIST));
} }
PLIST_ENTRY PLIST_ENTRY
elem_list_get_list_head( elem_list_get_list_head(PEHCI_ELEM_LIST plist)
PEHCI_ELEM_LIST plist
)
{ {
if( plist == NULL ) if (plist == NULL)
return NULL; return NULL;
return &plist->free_list; return &plist->free_list;
} }
LONG LONG
elem_list_get_total_count( elem_list_get_total_count(PEHCI_ELEM_LIST plist)
PEHCI_ELEM_LIST plist
)
{ {
if( plist == NULL ) if (plist == NULL)
return 0; return 0;
return plist->total_count;; return plist->total_count;;
} }
LONG LONG
elem_list_get_elem_size( elem_list_get_elem_size(PEHCI_ELEM_LIST plist)
PEHCI_ELEM_LIST plist
)
{ {
if( plist == NULL ) if (plist == NULL)
return 0; return 0;
return plist->elem_size; return plist->elem_size;
} }
LONG LONG
elem_list_get_link_offset( elem_list_get_link_offset(PEHCI_ELEM_LIST plist)
PEHCI_ELEM_LIST plist
)
{ {
if( plist == NULL ) if (plist == NULL)
return 0; return 0;
return get_elem_phys_part_size( plist->flags & 0xf ); return get_elem_phys_part_size(plist->flags & 0xf);
} }
LONG LONG
elem_list_add_ref( elem_list_add_ref(PEHCI_ELEM_LIST plist)
PEHCI_ELEM_LIST plist
)
{ {
plist->reference++; plist->reference++;
return plist->reference; return plist->reference;
} }
LONG LONG
elem_list_release_ref( elem_list_release_ref(PEHCI_ELEM_LIST plist)
PEHCI_ELEM_LIST plist
)
{ {
plist->reference--; plist->reference--;
return plist->reference; return plist->reference;
} }
LONG LONG
elem_list_get_ref( elem_list_get_ref(PEHCI_ELEM_LIST plist)
PEHCI_ELEM_LIST plist
)
{ {
return plist->reference; return plist->reference;
} }
@ -400,35 +337,31 @@ PEHCI_ELEM_LIST plist
// //
BOOL BOOL
elem_pool_init_pool( elem_pool_init_pool(PEHCI_ELEM_POOL pool, LONG flags, PVOID context)
PEHCI_ELEM_POOL pool,
LONG flags,
PVOID context
)
{ {
PADAPTER_OBJECT padapter; PADAPTER_OBJECT padapter;
INIT_ELEM_LIST_CONTEXT init_ctx; INIT_ELEM_LIST_CONTEXT init_ctx;
if( pool == NULL || context == NULL ) if (pool == NULL || context == NULL)
return FALSE; return FALSE;
RtlZeroMemory( pool, sizeof( EHCI_ELEM_POOL ) ); RtlZeroMemory(pool, sizeof(EHCI_ELEM_POOL));
init_ctx.pool = pool; init_ctx.pool = pool;
init_ctx.padapter = context; init_ctx.padapter = context;
pool->elem_lists[ 0 ] = usb_alloc_mem( NonPagedPool, sizeof( EHCI_ELEM_LIST ) ); pool->elem_lists[0] = usb_alloc_mem(NonPagedPool, sizeof(EHCI_ELEM_LIST));
if( pool->elem_lists[ 0 ] == NULL ) if (pool->elem_lists[0] == NULL)
return FALSE; return FALSE;
if( elem_list_init_elem_list( pool->elem_lists[ 0 ], flags, &init_ctx, 0 ) == FALSE ) if (elem_list_init_elem_list(pool->elem_lists[0], flags, &init_ctx, 0) == FALSE)
{ {
usb_free_mem( pool->elem_lists[ 0 ] ); usb_free_mem(pool->elem_lists[0]);
return FALSE; return FALSE;
} }
pool->link_offset = pool->elem_lists[ 0 ]->get_link_offset( pool->elem_lists[ 0 ] ); pool->link_offset = pool->elem_lists[0]->get_link_offset(pool->elem_lists[0]);
pool->free_count = pool->elem_lists[ 0 ]->get_total_count( pool->elem_lists[ 0 ] ); pool->free_count = pool->elem_lists[0]->get_total_count(pool->elem_lists[0]);
pool->list_count = 1; pool->list_count = 1;
pool->flags = flags; pool->flags = flags;
@ -436,127 +369,110 @@ PVOID context
} }
LONG LONG
elem_pool_get_link_offset( elem_pool_get_link_offset(PEHCI_ELEM_POOL elem_pool)
PEHCI_ELEM_POOL elem_pool
)
{ {
return elem_pool->link_offset; return elem_pool->link_offset;
} }
LONG LONG
elem_pool_get_total_count( elem_pool_get_total_count(PEHCI_ELEM_POOL elem_pool)
PEHCI_ELEM_POOL elem_pool
)
{ {
return elem_pool->elem_lists[ 0 ]->get_total_count( elem_pool->elem_lists[ 0 ] ) * elem_pool->list_count; return elem_pool->elem_lists[0]->get_total_count(elem_pool->elem_lists[0]) * elem_pool->list_count;
} }
VOID VOID
elem_pool_destroy_pool( elem_pool_destroy_pool(PEHCI_ELEM_POOL pool)
PEHCI_ELEM_POOL pool
)
{ {
LONG i; LONG i;
if( pool == NULL ) if (pool == NULL)
return; return;
for( i = pool->list_count - 1; i >= 0; i-- ) for(i = pool->list_count - 1; i >= 0; i--)
{ {
pool->elem_lists[ i ]->destroy_list( pool->elem_lists[ i ] ); pool->elem_lists[i]->destroy_list(pool->elem_lists[i]);
usb_free_mem( pool->elem_lists[ i ] ); usb_free_mem(pool->elem_lists[i]);
pool->elem_lists[ i ] = NULL; pool->elem_lists[i] = NULL;
} }
RtlZeroMemory( pool, sizeof( EHCI_ELEM_POOL ) ); RtlZeroMemory(pool, sizeof(EHCI_ELEM_POOL));
return; return;
} }
PEHCI_ELEM_LINKS PEHCI_ELEM_LINKS
elem_pool_alloc_elem( elem_pool_alloc_elem(PEHCI_ELEM_POOL pool)
PEHCI_ELEM_POOL pool
)
{ {
LONG i; LONG i;
PEHCI_ELEM_LIST pel; PEHCI_ELEM_LIST pel;
PLIST_HEAD lh; PLIST_HEAD lh;
PEHCI_ELEM_LINKS elnk; PEHCI_ELEM_LINKS elnk;
if( pool == NULL ) if (pool == NULL)
return NULL; return NULL;
for( i = 0; i < pool->list_count; i++ ) for(i = 0; i < pool->list_count; i++)
{ {
pel = pool->elem_lists[ i ]; pel = pool->elem_lists[i];
if( pel->get_ref( pel ) == pel->get_total_count( pel ) ) if (pel->get_ref(pel) == pel->get_total_count(pel))
continue; continue;
break; break;
} }
if( i == pool->list_count ) if (i == pool->list_count)
{ {
if( elem_pool_expand_pool( pool, pel->get_total_count( pel ) ) == FALSE ) if (elem_pool_expand_pool(pool, pel->get_total_count(pel)) == FALSE)
return NULL; return NULL;
pel = pool->elem_lists[ i ]; pel = pool->elem_lists[i];
} }
lh = pel->get_list_head( pel ); lh = pel->get_list_head(pel);
elnk = ( PEHCI_ELEM_LINKS )RemoveHeadList( lh ); elnk = (PEHCI_ELEM_LINKS) RemoveHeadList(lh);
InitializeListHead( &elnk->elem_link ); InitializeListHead(&elnk->elem_link);
InitializeListHead( &elnk->sched_link ); InitializeListHead(&elnk->sched_link);
pel->add_ref( pel ); pel->add_ref(pel);
pool->free_count--; pool->free_count--;
return elnk; return elnk;
} }
VOID VOID
elem_pool_free_elem( elem_pool_free_elem(PEHCI_ELEM_LINKS elem_link)
PEHCI_ELEM_LINKS elem_link
)
{ {
PLIST_HEAD lh; PLIST_HEAD lh;
LONG ref; LONG ref;
PEHCI_ELEM_POOL pool; PEHCI_ELEM_POOL pool;
if( elem_link == NULL ) if (elem_link == NULL)
return; return;
pool = elem_link->pool_link; pool = elem_link->pool_link;
lh = elem_link->list_link->get_list_head( elem_link->list_link ); lh = elem_link->list_link->get_list_head(elem_link->list_link);
if( lh == NULL ) if (lh == NULL)
return; return;
InsertHeadList( lh, ( PLIST_ENTRY )elem_link ); InsertHeadList(lh, (PLIST_ENTRY) elem_link);
ref = elem_link->list_link->release_ref( elem_link->list_link ); ref = elem_link->list_link->release_ref(elem_link->list_link);
pool->free_count++; pool->free_count++;
if( ref == 0 ) if (ref == 0)
elem_pool_collect_garbage( pool ); elem_pool_collect_garbage(pool);
return; return;
} }
BOOL BOOL
elem_pool_is_empty( elem_pool_is_empty(PEHCI_ELEM_POOL pool)
PEHCI_ELEM_POOL pool
)
{ {
PEHCI_ELEM_LIST pel; PEHCI_ELEM_LIST pel;
if( pool == NULL ) if (pool == NULL)
return TRUE; return TRUE;
pel = pool->elem_lists[ 0 ]; pel = pool->elem_lists[0];
return ( pool->list_count == 1 && pool->free_count == pel->get_total_count( pel ) ); return (pool->list_count == 1 && pool->free_count == pel->get_total_count(pel));
} }
LONG LONG
elem_pool_get_free_count( elem_pool_get_free_count(PEHCI_ELEM_POOL pool)
PEHCI_ELEM_POOL pool
)
{ {
if( pool == NULL ) if (pool == NULL)
return 0; return 0;
return pool->free_count; return pool->free_count;
} }
PEHCI_ELEM_LINKS PEHCI_ELEM_LINKS
elem_pool_alloc_elems( elem_pool_alloc_elems(PEHCI_ELEM_POOL pool, LONG count)
PEHCI_ELEM_POOL pool,
LONG count
)
{ {
LIST_HEAD lh; LIST_HEAD lh;
PLIST_ENTRY pthis; PLIST_ENTRY pthis;
@ -565,105 +481,99 @@ LONG count
PEHCI_ELEM_LINKS elnk; PEHCI_ELEM_LINKS elnk;
// calculate to see if the count is affordable // calculate to see if the count is affordable
if( pool == NULL || count <= 0 ) if (pool == NULL || count <= 0)
return NULL; return NULL;
get_max_lists_count( pool, max_pool_lists ); get_max_lists_count(pool, max_pool_lists);
InitializeListHead( &lh ); InitializeListHead(&lh);
pel = pool->elem_lists[ 0 ]; pel = pool->elem_lists[0];
if( count <= pool->free_count ) if (count <= pool->free_count)
alloc_count = 0; alloc_count = 0;
else else
alloc_count = count - pool->free_count; alloc_count = count - pool->free_count;
if( alloc_count > pel->get_total_count( pel ) * ( max_pool_lists - pool->list_count ) ) if (alloc_count > pel->get_total_count(pel) * (max_pool_lists - pool->list_count))
return NULL; return NULL;
for( i = 0; i < count; i++ ) for(i = 0; i < count; i++)
{ {
if( ( elnk = elem_pool_alloc_elem( pool ) ) == NULL ) if ((elnk = elem_pool_alloc_elem(pool)) == NULL)
{ {
// undo what we have done // undo what we have done
while( IsListEmpty( &lh ) == FALSE ) while (IsListEmpty(&lh) == FALSE)
{ {
pthis = RemoveHeadList( &lh ); pthis = RemoveHeadList(&lh);
elnk = struct_ptr( pthis, EHCI_ELEM_LINKS, elem_link ); elnk = struct_ptr(pthis, EHCI_ELEM_LINKS, elem_link);
elem_pool_free_elem( elnk ); elem_pool_free_elem(elnk);
} }
return NULL; return NULL;
} }
InsertTailList( &lh, &elnk->elem_link ); InsertTailList(&lh, &elnk->elem_link);
} }
ListFirst( &lh, pthis ); ListFirst(&lh, pthis);
elnk = struct_ptr( pthis, EHCI_ELEM_LINKS, elem_link ); elnk = struct_ptr(pthis, EHCI_ELEM_LINKS, elem_link);
RemoveEntryList( &lh ); RemoveEntryList(&lh);
return elnk; return elnk;
} }
BOOL BOOL
elem_pool_free_elems( elem_pool_free_elems(PEHCI_ELEM_LINKS elem_chains)
PEHCI_ELEM_LINKS elem_chains
)
{ {
// note: no list head exists. // note: no list head exists.
LIST_HEAD lh; LIST_HEAD lh;
PEHCI_ELEM_LINKS elnk; PEHCI_ELEM_LINKS elnk;
InsertTailList( &elem_chains->elem_link, &lh ); InsertTailList(&elem_chains->elem_link, &lh);
while( IsListEmpty( &lh ) == FALSE ) while (IsListEmpty(&lh) == FALSE)
{ {
elnk = ( PEHCI_ELEM_LINKS )RemoveHeadList( &lh ); elnk = (PEHCI_ELEM_LINKS) RemoveHeadList(&lh);
elem_pool_free_elem( elnk ); elem_pool_free_elem(elnk);
} }
return TRUE; return TRUE;
} }
LONG LONG
elem_pool_get_type( elem_pool_get_type(PEHCI_ELEM_POOL pool)
PEHCI_ELEM_POOL pool
)
{ {
if( pool == NULL ) if (pool == NULL)
return -1; return -1;
return ( pool->flags & 0xf ); return (pool->flags & 0xf);
} }
BOOL BOOL
elem_pool_expand_pool( elem_pool_expand_pool(PEHCI_ELEM_POOL pool, LONG elem_count)
PEHCI_ELEM_POOL pool,
LONG elem_count
)
{ {
LONG elem_cnt_list, list_count, i, j; LONG elem_cnt_list, list_count, i, j;
INIT_ELEM_LIST_CONTEXT init_ctx; INIT_ELEM_LIST_CONTEXT init_ctx;
if( pool == NULL || elem_count <= 0 || elem_count > EHCI_MAX_ELEMS_POOL ) if (pool == NULL || elem_count <= 0 || elem_count > EHCI_MAX_ELEMS_POOL)
return FALSE; return FALSE;
init_ctx.pool = pool; init_ctx.pool = pool;
init_ctx.padapter = pool->elem_lists[ 0 ]->padapter; init_ctx.padapter = pool->elem_lists[0]->padapter;
elem_cnt_list = pool->elem_lists[ 0 ]->get_total_count( pool->elem_lists[ 0 ] ); elem_cnt_list = pool->elem_lists[0]->get_total_count(pool->elem_lists[0]);
list_count = ( elem_count + elem_cnt_list - 1 ) / elem_cnt_list; list_count = (elem_count + elem_cnt_list - 1) / elem_cnt_list;
get_max_lists_count( pool, i ); get_max_lists_count(pool, i);
if( list_count + pool->list_count > i ) if (list_count + pool->list_count > i)
return FALSE; return FALSE;
for( i = pool->list_count; i < list_count + pool->list_count; i++ ) for(i = pool->list_count; i < list_count + pool->list_count; i++)
{ {
pool->elem_lists[ i ] = usb_alloc_mem( NonPagedPool, sizeof( EHCI_ELEM_LIST ) ); pool->elem_lists[i] = usb_alloc_mem(NonPagedPool, sizeof(EHCI_ELEM_LIST));
if( elem_list_init_elem_list( pool->elem_lists[ i ], pool->flags, &init_ctx, 0 ) == FALSE ) if (elem_list_init_elem_list(pool->elem_lists[i], pool->flags, &init_ctx, 0) == FALSE)
break; break;
} }
if( i < list_count + pool->list_count ) if (i < list_count + pool->list_count)
{ {
// undo all we have done // undo all we have done
for( j = pool->list_count; j < pool->list_count + i; j++ ) for(j = pool->list_count; j < pool->list_count + i; j++)
{ {
pool->elem_lists[ j ]->destroy_list( pool->elem_lists[ j ] ); pool->elem_lists[j]->destroy_list(pool->elem_lists[j]);
usb_free_mem( pool->elem_lists[ j ] ); usb_free_mem(pool->elem_lists[j]);
pool->elem_lists[ j ] = NULL; pool->elem_lists[j] = NULL;
} }
return FALSE; return FALSE;
} }
@ -675,59 +585,52 @@ LONG elem_count
} }
BOOL BOOL
elem_pool_collect_garbage( elem_pool_collect_garbage(PEHCI_ELEM_POOL pool)
PEHCI_ELEM_POOL pool
)
{ {
LONG i, j, k, fl; LONG i, j, k, fl;
LONG free_elem_lists[ EHCI_MAX_LISTS_POOL - 1 ]; LONG free_elem_lists[EHCI_MAX_LISTS_POOL - 1];
PEHCI_ELEM_LIST pel; PEHCI_ELEM_LIST pel;
if( pool == NULL ) if (pool == NULL)
return FALSE; return FALSE;
for( i = 1, fl = 0; i < pool->list_count; i++ ) for(i = 1, fl = 0; i < pool->list_count; i++)
{ {
if( pool->elem_lists[ i ]->get_ref( pool->elem_lists[ i ] ) == 0 ) if (pool->elem_lists[i]->get_ref(pool->elem_lists[i]) == 0)
{ {
free_elem_lists[ fl++ ] = i; free_elem_lists[fl++] = i;
} }
} }
for( j = fl - 1; j >= 0; j-- ) for(j = fl - 1; j >= 0; j--)
{ {
pel = pool->elem_lists[ free_elem_lists[ j ] ]; pel = pool->elem_lists[free_elem_lists[j]];
pel->destroy_list( pel ); pel->destroy_list(pel);
usb_free_mem( pel ); usb_free_mem(pel);
for( k = free_elem_lists[ j ] + 1; k < pool->list_count; k++ ) for(k = free_elem_lists[j] + 1; k < pool->list_count; k++)
{ {
// shrink the elem_lists // shrink the elem_lists
pool->elem_lists[ k - 1 ] = pool->elem_lists[ k ]; pool->elem_lists[k - 1] = pool->elem_lists[k];
} }
pool->elem_lists[ k ] = NULL; pool->elem_lists[k] = NULL;
pel = pool->elem_lists[ 0 ]; pel = pool->elem_lists[0];
pool->free_count -= pel->get_total_count( pel ); pool->free_count -= pel->get_total_count(pel);
pool->list_count --; pool->list_count--;
} }
return TRUE; return TRUE;
} }
BOOL BOOL
elem_pool_can_transfer( elem_pool_can_transfer(PEHCI_ELEM_POOL pool, LONG td_count)
PEHCI_ELEM_POOL pool,
LONG td_count
)
{ {
LONG i; LONG i;
if( pool == NULL || td_count <= 0 ) if (pool == NULL || td_count <= 0)
return FALSE; return FALSE;
get_max_lists_count( pool, i ); get_max_lists_count(pool, i);
if( ( i - pool->list_count ) if ((i - pool->list_count)
* pool->elem_lists[ 0 ]->get_total_count( pool->elem_lists[ 0 ] ) * pool->elem_lists[0]->get_total_count(pool->elem_lists[0]) + pool->free_count < td_count)
+ pool->free_count < td_count )
return FALSE; return FALSE;
return TRUE; return TRUE;
} }
//---------------------------------------------------------- //----------------------------------------------------------

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -24,22 +24,13 @@
#define UHCI_MIN_TD_POOLS 4 #define UHCI_MIN_TD_POOLS 4
BOOL BOOL free_td_to_pool(PUHCI_TD_POOL ptd_pool, PUHCI_TD ptd); //add tds till pnext == NULL
free_td_to_pool(
PUHCI_TD_POOL ptd_pool,
PUHCI_TD ptd
); //add tds till pnext == NULL
PUHCI_QH PUHCI_QH alloc_qh(PUHCI_QH_POOL pqh_pool); //null if failed
alloc_qh(
PUHCI_QH_POOL pqh_pool
); //null if failed
BOOL BOOL
init_td_pool( init_td_pool(PUHCI_TD_POOL ptd_pool)
PUHCI_TD_POOL ptd_pool
)
{ {
int i, pages; int i, pages;
PTD_EXTENSION ptde; PTD_EXTENSION ptde;
@ -48,92 +39,81 @@ PUHCI_TD_POOL ptd_pool
if (ptd_pool == NULL) if (ptd_pool == NULL)
return FALSE; return FALSE;
if( ptd_pool->padapter == NULL) if (ptd_pool->padapter == NULL)
return FALSE; return FALSE;
pages = sizeof( UHCI_TD ) * UHCI_MAX_POOL_TDS / PAGE_SIZE; pages = sizeof(UHCI_TD) * UHCI_MAX_POOL_TDS / PAGE_SIZE;
RtlZeroMemory( ptd_pool->td_array, sizeof( ptd_pool->td_array ) ); RtlZeroMemory(ptd_pool->td_array, sizeof(ptd_pool->td_array));
RtlZeroMemory( ptd_pool->logic_addr, sizeof( ptd_pool->logic_addr ) ); RtlZeroMemory(ptd_pool->logic_addr, sizeof(ptd_pool->logic_addr));
for( i = 0; i < pages; i++ ) for(i = 0; i < pages; i++)
{ {
ptd_pool->td_array[ i ] = ptd_pool->td_array[i] =
HalAllocateCommonBuffer( HalAllocateCommonBuffer(ptd_pool->padapter, PAGE_SIZE, &ptd_pool->logic_addr[i], FALSE);
ptd_pool->padapter, if (ptd_pool->td_array[i] == NULL)
PAGE_SIZE,
&ptd_pool->logic_addr[ i ],
FALSE);
if( ptd_pool->td_array[ i ] == NULL )
goto failed; goto failed;
} }
ptd_pool->tde_array = ( PTD_EXTENSION )usb_alloc_mem( ptd_pool->tde_array = (PTD_EXTENSION) usb_alloc_mem(NonPagedPool,
NonPagedPool, sizeof(TD_EXTENSION) * UHCI_MAX_POOL_TDS);
sizeof( TD_EXTENSION ) * UHCI_MAX_POOL_TDS );
if (ptd_pool->tde_array == NULL) if (ptd_pool->tde_array == NULL)
goto failed; goto failed;
for( i = 0; i < pages; i++ ) for(i = 0; i < pages; i++)
{ {
RtlZeroMemory( ptd_pool->td_array[ i ], PAGE_SIZE ); RtlZeroMemory(ptd_pool->td_array[i], PAGE_SIZE);
} }
RtlZeroMemory( RtlZeroMemory(ptd_pool->tde_array, sizeof(TD_EXTENSION) * UHCI_MAX_POOL_TDS);
ptd_pool->tde_array,
sizeof( TD_EXTENSION ) * UHCI_MAX_POOL_TDS );
ptde = ptd_pool->tde_array; ptde = ptd_pool->tde_array;
ptd_pool->free_count = 0; ptd_pool->free_count = 0;
ptd_pool->total_count = UHCI_MAX_POOL_TDS; ptd_pool->total_count = UHCI_MAX_POOL_TDS;
InitializeListHead( &ptd_pool->free_que); InitializeListHead(&ptd_pool->free_que);
for( i = 0; i < UHCI_MAX_POOL_TDS; i++ ) for(i = 0; i < UHCI_MAX_POOL_TDS; i++)
{ {
//link tde and the td one by one, fixed since this init //link tde and the td one by one, fixed since this init
ptd_pool->td_array[ i >> 7 ][ i & 0x7f ].ptde = &ptde[ i ]; ptd_pool->td_array[i >> 7][i & 0x7f].ptde = &ptde[i];
ptde[ i ].ptd = &ptd_pool->td_array[ i >> 7 ][ i & 0x7f ]; ptde[i].ptd = &ptd_pool->td_array[i >> 7][i & 0x7f];
ptde[ i ].flags = UHCI_ITEM_FLAG_TD; ptde[i].flags = UHCI_ITEM_FLAG_TD;
ptd_pool->td_array[ i >> 7 ][ i & 0x7f ].phy_addr = ptd_pool->logic_addr[ i >> 7 ].LowPart + ( i & 0x7f ) * sizeof( UHCI_TD ); ptd_pool->td_array[i >> 7][i & 0x7f].phy_addr =
ptd_pool->td_array[ i >> 7 ][ i & 0x7f ].pool = ptd_pool; ptd_pool->logic_addr[i >> 7].LowPart + (i & 0x7f) * sizeof(UHCI_TD);
ptd_pool->td_array[ i >> 7 ][ i & 0x7f ].purb = NULL; ptd_pool->td_array[i >> 7][i & 0x7f].pool = ptd_pool;
free_td_to_pool( ptd_pool, &ptd_pool->td_array[ i >> 7 ][ i & 0x7f ]); ptd_pool->td_array[i >> 7][i & 0x7f].purb = NULL;
free_td_to_pool(ptd_pool, &ptd_pool->td_array[i >> 7][i & 0x7f]);
} }
return TRUE; return TRUE;
failed: failed:
for( i = 0; i < pages; i++ ) for(i = 0; i < pages; i++)
{ {
if( ptd_pool->td_array[ i ] ) if (ptd_pool->td_array[i])
{ {
HalFreeCommonBuffer( ptd_pool->padapter, HalFreeCommonBuffer(ptd_pool->padapter,
PAGE_SIZE, PAGE_SIZE, ptd_pool->logic_addr[i], ptd_pool->td_array[i], FALSE);
ptd_pool->logic_addr[ i ], ptd_pool->td_array[i] = NULL;
ptd_pool->td_array[ i ], ptd_pool->logic_addr[i].QuadPart = 0;
FALSE);
ptd_pool->td_array[ i ] = NULL;
ptd_pool->logic_addr[ i ].QuadPart = 0;
} }
} }
if( ptd_pool->tde_array ) if (ptd_pool->tde_array)
usb_free_mem( ptd_pool->tde_array); usb_free_mem(ptd_pool->tde_array);
uhci_dbg_print( DBGLVL_MAXIMUM, ( "init_td_pool(): failed to init the td pool\n" ) ); uhci_dbg_print(DBGLVL_MAXIMUM, ("init_td_pool(): failed to init the td pool\n"));
TRAP(); TRAP();
ptd_pool->free_count = ptd_pool->total_count = 0; ptd_pool->free_count = ptd_pool->total_count = 0;
return FALSE; return FALSE;
} }
//add tds till pnext == NULL
BOOL BOOL
free_td_to_pool( free_td_to_pool(PUHCI_TD_POOL ptd_pool, PUHCI_TD ptd)
PUHCI_TD_POOL ptd_pool,
PUHCI_TD ptd
) //add tds till pnext == NULL
{ {
if( ptd_pool == NULL || ptd == NULL ) if (ptd_pool == NULL || ptd == NULL)
{ {
return FALSE; return FALSE;
} }
@ -142,96 +122,89 @@ PUHCI_TD ptd
ptd->purb = NULL; ptd->purb = NULL;
ptd_pool->free_count++; ptd_pool->free_count++;
InsertTailList( &ptd_pool->free_que, &ptd->ptde->vert_link); InsertTailList(&ptd_pool->free_que, &ptd->ptde->vert_link);
return TRUE; return TRUE;
} }
// qh routines // qh routines
//null if failed
PUHCI_TD PUHCI_TD
alloc_td_from_pool( alloc_td_from_pool(PUHCI_TD_POOL ptd_pool)
PUHCI_TD_POOL ptd_pool
) //null if failed
{ {
PTD_EXTENSION ptde; PTD_EXTENSION ptde;
PLIST_ENTRY temp; PLIST_ENTRY temp;
if( ptd_pool == NULL ) if (ptd_pool == NULL)
return FALSE; return FALSE;
if( IsListEmpty( &ptd_pool->free_que ) ) if (IsListEmpty(&ptd_pool->free_que))
return FALSE; return FALSE;
temp = RemoveHeadList( &ptd_pool->free_que ); temp = RemoveHeadList(&ptd_pool->free_que);
if( temp == NULL ) if (temp == NULL)
return FALSE; return FALSE;
ptde = struct_ptr( temp, TD_EXTENSION, vert_link ); ptde = struct_ptr(temp, TD_EXTENSION, vert_link);
ptd_pool->free_count--; ptd_pool->free_count--;
InitializeListHead( &ptde->vert_link ); InitializeListHead(&ptde->vert_link);
InitializeListHead( &ptde->hori_link ); InitializeListHead(&ptde->hori_link);
return ptde->ptd; return ptde->ptd;
} }
//test whether the pool is all free
BOOL BOOL
is_pool_free( is_pool_free(PUHCI_TD_POOL pool)
PUHCI_TD_POOL pool
) //test whether the pool is all free
{ {
if( pool == NULL ) if (pool == NULL)
return FALSE; return FALSE;
if( pool->free_count == pool->total_count ) if (pool->free_count == pool->total_count)
return TRUE; return TRUE;
return FALSE; return FALSE;
} }
BOOL BOOL
is_pool_empty( is_pool_empty(PUHCI_TD_POOL pool)
PUHCI_TD_POOL pool
)
{ {
if( pool == NULL ) if (pool == NULL)
return FALSE; return FALSE;
return ( pool->free_count == 0 ); return (pool->free_count == 0);
} }
BOOL BOOL
destroy_td_pool( destroy_td_pool(PUHCI_TD_POOL ptd_pool)
PUHCI_TD_POOL ptd_pool
)
{ {
int i, pages; int i, pages;
PADAPTER_OBJECT padapter; //we need this garbage for allocation PADAPTER_OBJECT padapter; //we need this garbage for allocation
padapter = ptd_pool->padapter; padapter = ptd_pool->padapter;
pages = sizeof( UHCI_TD ) * UHCI_MAX_POOL_TDS / PAGE_SIZE; pages = sizeof(UHCI_TD) * UHCI_MAX_POOL_TDS / PAGE_SIZE;
if( ptd_pool && ptd_pool->padapter ) if (ptd_pool && ptd_pool->padapter)
{ {
usb_free_mem( ptd_pool->tde_array ); usb_free_mem(ptd_pool->tde_array);
ptd_pool->tde_array = NULL; ptd_pool->tde_array = NULL;
for( i = 0; i < pages; i++ ) for(i = 0; i < pages; i++)
{ {
if( ptd_pool->td_array[ i ] ) if (ptd_pool->td_array[i])
{ {
HalFreeCommonBuffer( ptd_pool->padapter, HalFreeCommonBuffer(ptd_pool->padapter,
PAGE_SIZE, PAGE_SIZE, ptd_pool->logic_addr[i], ptd_pool->td_array[i], FALSE);
ptd_pool->logic_addr[ i ], ptd_pool->td_array[i] = NULL;
ptd_pool->td_array[ i ], ptd_pool->logic_addr[i].QuadPart = 0;
FALSE);
ptd_pool->td_array[ i ] = NULL;
ptd_pool->logic_addr[ i ].QuadPart = 0;
} }
} }
RtlZeroMemory( ptd_pool, sizeof( UHCI_TD_POOL ) ); RtlZeroMemory(ptd_pool, sizeof(UHCI_TD_POOL));
ptd_pool->padapter = padapter; ptd_pool->padapter = padapter;
ptd_pool->free_count = ptd_pool->total_count = 0; ptd_pool->free_count = ptd_pool->total_count = 0;
} }
@ -242,73 +215,65 @@ PUHCI_TD_POOL ptd_pool
} }
BOOL BOOL
init_td_pool_list( init_td_pool_list(PUHCI_TD_POOL_LIST pool_list, PADAPTER_OBJECT padapter)
PUHCI_TD_POOL_LIST pool_list,
PADAPTER_OBJECT padapter
)
{ {
int i; int i;
RtlZeroMemory( pool_list, sizeof( UHCI_TD_POOL_LIST)); RtlZeroMemory(pool_list, sizeof(UHCI_TD_POOL_LIST));
InitializeListHead( &pool_list->busy_pools ); InitializeListHead(&pool_list->busy_pools);
InitializeListHead( &pool_list->free_pools ); InitializeListHead(&pool_list->free_pools);
pool_list->free_count = UHCI_MAX_TD_POOLS; pool_list->free_count = UHCI_MAX_TD_POOLS;
pool_list->free_tds = 0; pool_list->free_tds = 0;
for( i = 0; i < UHCI_MAX_TD_POOLS; i++) for(i = 0; i < UHCI_MAX_TD_POOLS; i++)
{ {
pool_list->pool_array[i].padapter = padapter; pool_list->pool_array[i].padapter = padapter;
InsertTailList( &pool_list->free_pools, &pool_list->pool_array[i].pool_link); InsertTailList(&pool_list->free_pools, &pool_list->pool_array[i].pool_link);
} }
KeInitializeSpinLock( &pool_list->pool_lock ); KeInitializeSpinLock(&pool_list->pool_lock);
return expand_pool_list( pool_list, UHCI_MIN_TD_POOLS ); return expand_pool_list(pool_list, UHCI_MIN_TD_POOLS);
} }
BOOL BOOL
destroy_td_pool_list( destroy_td_pool_list(PUHCI_TD_POOL_LIST pool_list)
PUHCI_TD_POOL_LIST pool_list
)
{ {
PUHCI_TD_POOL pool; PUHCI_TD_POOL pool;
while( IsListEmpty( &pool_list->busy_pools) == FALSE ) while (IsListEmpty(&pool_list->busy_pools) == FALSE)
{ {
pool = (PUHCI_TD_POOL) RemoveHeadList( &pool_list->busy_pools); pool = (PUHCI_TD_POOL) RemoveHeadList(&pool_list->busy_pools);
destroy_td_pool( pool ); destroy_td_pool(pool);
} }
RtlZeroMemory( pool_list, sizeof( UHCI_TD_POOL_LIST )); RtlZeroMemory(pool_list, sizeof(UHCI_TD_POOL_LIST));
return TRUE; return TRUE;
} }
BOOL BOOL
expand_pool_list( expand_pool_list(PUHCI_TD_POOL_LIST pool_list, LONG pool_count) //private
PUHCI_TD_POOL_LIST pool_list,
LONG pool_count
) //private
{ {
PUHCI_TD_POOL pool; PUHCI_TD_POOL pool;
int i; int i;
if( IsListEmpty( &pool_list->free_pools) == TRUE ) if (IsListEmpty(&pool_list->free_pools) == TRUE)
return FALSE; return FALSE;
if( pool_list->free_count < pool_count ) if (pool_list->free_count < pool_count)
return FALSE; return FALSE;
for( i = 0; i < pool_count; i++ ) for(i = 0; i < pool_count; i++)
{ {
pool = (PUHCI_TD_POOL) RemoveHeadList( &pool_list->free_pools); pool = (PUHCI_TD_POOL) RemoveHeadList(&pool_list->free_pools);
if( init_td_pool( pool ) == FALSE ) if (init_td_pool(pool) == FALSE)
{ {
//reverse the allocation //reverse the allocation
InsertHeadList( &pool_list->free_pools, &pool->pool_link ); InsertHeadList(&pool_list->free_pools, &pool->pool_link);
// collect_garbage( pool_list ); // collect_garbage( pool_list );
return FALSE; return FALSE;
} }
InsertTailList( &pool_list->busy_pools, &pool->pool_link ); InsertTailList(&pool_list->busy_pools, &pool->pool_link);
pool_list->free_tds += UHCI_MAX_POOL_TDS; pool_list->free_tds += UHCI_MAX_POOL_TDS;
pool_list->free_count--; pool_list->free_count--;
} }
@ -316,36 +281,34 @@ LONG pool_count
} }
BOOL BOOL
collect_garbage( collect_garbage(PUHCI_TD_POOL_LIST pool_list)
PUHCI_TD_POOL_LIST pool_list
)
{ {
PLIST_ENTRY prev, next; PLIST_ENTRY prev, next;
// no garbage // no garbage
if( pool_list->free_count >= UHCI_MAX_TD_POOLS - UHCI_MIN_TD_POOLS ) if (pool_list->free_count >= UHCI_MAX_TD_POOLS - UHCI_MIN_TD_POOLS)
return TRUE; return TRUE;
ListFirstPrev( &pool_list->busy_pools, prev); ListFirstPrev(&pool_list->busy_pools, prev);
ListNext( &pool_list->busy_pools, prev, next); ListNext(&pool_list->busy_pools, prev, next);
while( next && next != &pool_list->busy_pools) while (next && next != &pool_list->busy_pools)
{ {
if( is_pool_free( (PUHCI_TD_POOL)next ) ) if (is_pool_free((PUHCI_TD_POOL) next))
{ {
RemoveEntryList( next ); RemoveEntryList(next);
destroy_td_pool( ( PUHCI_TD_POOL )next ); destroy_td_pool((PUHCI_TD_POOL) next);
InsertTailList( &pool_list->free_pools, next); InsertTailList(&pool_list->free_pools, next);
pool_list->free_count++; pool_list->free_count++;
pool_list->free_tds -= UHCI_MAX_POOL_TDS; pool_list->free_tds -= UHCI_MAX_POOL_TDS;
ListNext( &pool_list->busy_pools, prev, next); ListNext(&pool_list->busy_pools, prev, next);
if( pool_list->free_count >= UHCI_MAX_TD_POOLS - UHCI_MIN_TD_POOLS ) if (pool_list->free_count >= UHCI_MAX_TD_POOLS - UHCI_MIN_TD_POOLS)
break; break;
} }
else else
{ {
prev = next; prev = next;
ListNext( &pool_list->busy_pools, prev, next); ListNext(&pool_list->busy_pools, prev, next);
} }
} }
return TRUE; return TRUE;
@ -354,69 +317,62 @@ PUHCI_TD_POOL_LIST pool_list
//private //private
LONG LONG
get_num_free_tds( get_num_free_tds(PUHCI_TD_POOL_LIST pool_list)
PUHCI_TD_POOL_LIST pool_list
)
{ {
return pool_list->free_tds; return pool_list->free_tds;
} }
//private //private
LONG LONG
get_max_free_tds( get_max_free_tds(PUHCI_TD_POOL_LIST pool_list)
PUHCI_TD_POOL_LIST pool_list
)
{ {
return pool_list->free_tds + pool_list->free_count * UHCI_MAX_POOL_TDS; return pool_list->free_tds + pool_list->free_count * UHCI_MAX_POOL_TDS;
} }
//add tds till pnext == NULL
BOOL BOOL
free_td( free_td(PUHCI_TD_POOL_LIST pool_list, PUHCI_TD ptd)
PUHCI_TD_POOL_LIST pool_list,
PUHCI_TD ptd
) //add tds till pnext == NULL
{ {
if( pool_list == NULL || ptd == NULL ) if (pool_list == NULL || ptd == NULL)
return FALSE; return FALSE;
if( free_td_to_pool( ptd->pool, ptd ) == FALSE ) if (free_td_to_pool(ptd->pool, ptd) == FALSE)
return FALSE; return FALSE;
pool_list->free_tds++; pool_list->free_tds++;
if( is_pool_free( ptd->pool ) ) if (is_pool_free(ptd->pool))
{ {
collect_garbage( pool_list ); collect_garbage(pool_list);
} }
return TRUE; return TRUE;
} }
//null if failed
PUHCI_TD PUHCI_TD
alloc_td( alloc_td(PUHCI_TD_POOL_LIST pool_list)
PUHCI_TD_POOL_LIST pool_list
) //null if failed
{ {
PLIST_ENTRY prev, next; PLIST_ENTRY prev, next;
PUHCI_TD new_td; PUHCI_TD new_td;
if( pool_list == NULL ) if (pool_list == NULL)
return NULL; return NULL;
if( pool_list->free_tds == 0 ) if (pool_list->free_tds == 0)
{ {
if( expand_pool_list( pool_list, 1 ) == FALSE ) if (expand_pool_list(pool_list, 1) == FALSE)
return NULL; return NULL;
} }
ListFirst( &pool_list->busy_pools, prev ); ListFirst(&pool_list->busy_pools, prev);
while( prev && prev != &pool_list->busy_pools ) while (prev && prev != &pool_list->busy_pools)
{ {
if( is_pool_empty( (PUHCI_TD_POOL) prev ) == FALSE ) if (is_pool_empty((PUHCI_TD_POOL) prev) == FALSE)
{ {
new_td = alloc_td_from_pool( (PUHCI_TD_POOL) prev ); new_td = alloc_td_from_pool((PUHCI_TD_POOL) prev);
if( new_td == NULL ) if (new_td == NULL)
TRAP(); TRAP();
pool_list->free_tds--; pool_list->free_tds--;
@ -424,7 +380,7 @@ PUHCI_TD_POOL_LIST pool_list
return new_td; return new_td;
} }
ListNext( &pool_list->busy_pools, prev, next); ListNext(&pool_list->busy_pools, prev, next);
prev = next; prev = next;
} }
@ -432,86 +388,73 @@ PUHCI_TD_POOL_LIST pool_list
} }
PUHCI_TD PUHCI_TD
alloc_tds( alloc_tds(PUHCI_TD_POOL_LIST pool_list, LONG count)
PUHCI_TD_POOL_LIST pool_list,
LONG count
)
{ {
//return value is a list of tds, vert_link chain. //return value is a list of tds, vert_link chain.
LONG i; LONG i;
PUHCI_TD ptd, pnext; PUHCI_TD ptd, pnext;
if( pool_list == NULL || count <= 0 ) if (pool_list == NULL || count <= 0)
return NULL; return NULL;
if( count >= get_max_free_tds( pool_list ) ) if (count >= get_max_free_tds(pool_list))
return NULL; return NULL;
ptd = alloc_td( pool_list ); ptd = alloc_td(pool_list);
for( i = 1; i < count; i ++ ) for(i = 1; i < count; i++)
{ {
pnext = alloc_td( pool_list ); pnext = alloc_td(pool_list);
if( pnext ) if (pnext)
{ {
InsertTailList( &ptd->ptde->vert_link, &pnext->ptde->vert_link ); InsertTailList(&ptd->ptde->vert_link, &pnext->ptde->vert_link);
} }
else else
TRAP(); TRAP();
} }
uhci_dbg_print( DBGLVL_MEDIUM, ("alloc_tds(): td pool-list free_tds=0x%x, free pools=0x%x\n", \ uhci_dbg_print(DBGLVL_MEDIUM, ("alloc_tds(): td pool-list free_tds=0x%x, free pools=0x%x\n",
pool_list->free_tds, pool_list->free_tds, pool_list->free_count));
pool_list->free_count ) );
return ptd; return ptd;
} }
VOID VOID
free_tds( free_tds(PUHCI_TD_POOL_LIST pool_list, PUHCI_TD ptd)
PUHCI_TD_POOL_LIST pool_list,
PUHCI_TD ptd
)
{ {
PUHCI_TD ptofree; PUHCI_TD ptofree;
PLIST_ENTRY pthis; PLIST_ENTRY pthis;
if( pool_list == NULL || ptd == NULL ) if (pool_list == NULL || ptd == NULL)
return; return;
while( IsListEmpty( &ptd->ptde->vert_link ) == FALSE ) while (IsListEmpty(&ptd->ptde->vert_link) == FALSE)
{ {
pthis = RemoveHeadList( &ptd->ptde->vert_link ); pthis = RemoveHeadList(&ptd->ptde->vert_link);
ptofree = ( ( PTD_EXTENSION)pthis )->ptd; ptofree = ((PTD_EXTENSION) pthis)->ptd;
free_td( pool_list, ptofree ); free_td(pool_list, ptofree);
} }
free_td( pool_list, ptd ); free_td(pool_list, ptd);
return; return;
} }
BOOL BOOL
can_transfer( can_transfer(PUHCI_TD_POOL_LIST pool_list, LONG td_count)
PUHCI_TD_POOL_LIST pool_list,
LONG td_count
)
{ {
if( td_count > get_max_free_tds( pool_list ) ) if (td_count > get_max_free_tds(pool_list))
return FALSE; return FALSE;
return TRUE; return TRUE;
} }
VOID VOID
lock_td_pool( lock_td_pool(PUHCI_TD_POOL_LIST pool_list, BOOL at_dpc)
PUHCI_TD_POOL_LIST pool_list,
BOOL at_dpc
)
{ {
//if( !at_dpc ) //if( !at_dpc )
// KeAcquireSpinLock( &pool_list->pool_lock ); // KeAcquireSpinLock( &pool_list->pool_lock );
@ -520,10 +463,7 @@ BOOL at_dpc
} }
VOID VOID
unlock_td_pool( unlock_td_pool(PUHCI_TD_POOL_LIST pool_list, BOOL at_dpc)
PUHCI_TD_POOL_LIST pool_list,
BOOL at_dpc
)
{ {
//if( !at_dpc ) //if( !at_dpc )
// KeReleaseSpinLock( &pool_list->pool_lock ); // KeReleaseSpinLock( &pool_list->pool_lock );
@ -532,36 +472,29 @@ BOOL at_dpc
} }
BOOL BOOL
init_qh_pool( init_qh_pool(PUHCI_QH_POOL pqh_pool, PADAPTER_OBJECT padapter)
PUHCI_QH_POOL pqh_pool,
PADAPTER_OBJECT padapter
)
{ {
PQH_EXTENSION pqhe; PQH_EXTENSION pqhe;
LONG i; LONG i;
if( pqh_pool == NULL || padapter == NULL ) if (pqh_pool == NULL || padapter == NULL)
return FALSE; return FALSE;
pqh_pool->padapter = padapter; pqh_pool->padapter = padapter;
pqh_pool->qhe_array = (PQH_EXTENSION)usb_alloc_mem( pqh_pool->qhe_array = (PQH_EXTENSION) usb_alloc_mem(NonPagedPool,
NonPagedPool,
sizeof(QH_EXTENSION) * UHCI_MAX_POOL_QHS); sizeof(QH_EXTENSION) * UHCI_MAX_POOL_QHS);
if (pqh_pool->qhe_array == NULL) if (pqh_pool->qhe_array == NULL)
return FALSE; return FALSE;
pqh_pool->qh_array = \ pqh_pool->qh_array =
(PUHCI_QH)HalAllocateCommonBuffer( (PUHCI_QH) HalAllocateCommonBuffer(padapter,
padapter, sizeof(UHCI_QH) * UHCI_MAX_POOL_QHS, &pqh_pool->logic_addr, FALSE);
sizeof(UHCI_QH) * UHCI_MAX_POOL_QHS,
&pqh_pool->logic_addr,
FALSE);
if( pqh_pool->qh_array == NULL ) if (pqh_pool->qh_array == NULL)
{ {
usb_free_mem( pqh_pool->qhe_array ); usb_free_mem(pqh_pool->qhe_array);
pqh_pool->qhe_array = NULL; pqh_pool->qhe_array = NULL;
return FALSE; return FALSE;
} }
@ -571,8 +504,8 @@ PADAPTER_OBJECT padapter
pqh_pool->free_count = 0; pqh_pool->free_count = 0;
pqh_pool->total_count = UHCI_MAX_POOL_TDS; pqh_pool->total_count = UHCI_MAX_POOL_TDS;
KeInitializeSpinLock( &pqh_pool->pool_lock); KeInitializeSpinLock(&pqh_pool->pool_lock);
InitializeListHead( &pqh_pool->free_que); InitializeListHead(&pqh_pool->free_que);
for(i = 0; i < UHCI_MAX_POOL_QHS; i++) for(i = 0; i < UHCI_MAX_POOL_QHS; i++)
@ -580,55 +513,52 @@ PADAPTER_OBJECT padapter
pqh_pool->qh_array[i].pqhe = &pqhe[i]; pqh_pool->qh_array[i].pqhe = &pqhe[i];
pqhe[i].pqh = &pqh_pool->qh_array[i]; pqhe[i].pqh = &pqh_pool->qh_array[i];
pqh_pool->qh_array[i].phy_addr = ( pqh_pool->logic_addr.LowPart + ( sizeof( UHCI_QH) * i ) ) | UHCI_PTR_QH; pqh_pool->qh_array[i].phy_addr = (pqh_pool->logic_addr.LowPart + (sizeof(UHCI_QH) * i)) | UHCI_PTR_QH;
//pqh_pool->qh_array[i].reserved = 0; //pqh_pool->qh_array[i].reserved = 0;
//always breadth first //always breadth first
pqhe[i].flags = UHCI_ITEM_FLAG_QH; pqhe[i].flags = UHCI_ITEM_FLAG_QH;
free_qh( pqh_pool, &pqh_pool->qh_array[i] ); free_qh(pqh_pool, &pqh_pool->qh_array[i]);
} }
return TRUE; return TRUE;
} }
//add qhs till pnext == NULL
BOOL BOOL
free_qh( free_qh(PUHCI_QH_POOL pqh_pool, PUHCI_QH pqh)
PUHCI_QH_POOL pqh_pool,
PUHCI_QH pqh
) //add qhs till pnext == NULL
{ {
if( pqh_pool == NULL || pqh == NULL) if (pqh_pool == NULL || pqh == NULL)
return FALSE; return FALSE;
pqh->link = pqh->element = 0; pqh->link = pqh->element = 0;
pqh->pqhe->purb = NULL; pqh->pqhe->purb = NULL;
InsertTailList( &pqh_pool->free_que, &pqh->pqhe->vert_link); InsertTailList(&pqh_pool->free_que, &pqh->pqhe->vert_link);
pqh_pool->free_count ++; pqh_pool->free_count++;
return TRUE; return TRUE;
} }
//null if failed
PUHCI_QH PUHCI_QH
alloc_qh( alloc_qh(PUHCI_QH_POOL pqh_pool)
PUHCI_QH_POOL pqh_pool
) //null if failed
{ {
PQH_EXTENSION pqhe; PQH_EXTENSION pqhe;
if( pqh_pool == NULL ) if (pqh_pool == NULL)
return FALSE; return FALSE;
if( IsListEmpty( &pqh_pool->free_que)) if (IsListEmpty(&pqh_pool->free_que))
return FALSE; return FALSE;
pqhe = ( PQH_EXTENSION )RemoveHeadList( &pqh_pool->free_que ); pqhe = (PQH_EXTENSION) RemoveHeadList(&pqh_pool->free_que);
if( pqhe ) if (pqhe)
{ {
InitializeListHead( &pqhe->hori_link ); InitializeListHead(&pqhe->hori_link);
InitializeListHead( &pqhe->vert_link ); InitializeListHead(&pqhe->vert_link);
return pqhe->pqh; return pqhe->pqh;
} }
return NULL; return NULL;
@ -636,23 +566,19 @@ PUHCI_QH_POOL pqh_pool
} }
BOOL BOOL
destroy_qh_pool( destroy_qh_pool(PUHCI_QH_POOL pqh_pool)
PUHCI_QH_POOL pqh_pool
)
{ {
int i; int i;
if(pqh_pool) if (pqh_pool)
{ {
usb_free_mem(pqh_pool->qhe_array); usb_free_mem(pqh_pool->qhe_array);
HalFreeCommonBuffer( pqh_pool->padapter, HalFreeCommonBuffer(pqh_pool->padapter,
sizeof(UHCI_QH) * UHCI_MAX_POOL_QHS, sizeof(UHCI_QH) * UHCI_MAX_POOL_QHS,
pqh_pool->logic_addr, pqh_pool->logic_addr, pqh_pool->qh_array, FALSE);
pqh_pool->qh_array,
FALSE);
RtlZeroMemory( pqh_pool, sizeof( UHCI_QH_POOL ) ); RtlZeroMemory(pqh_pool, sizeof(UHCI_QH_POOL));
} }
else else
@ -662,10 +588,7 @@ PUHCI_QH_POOL pqh_pool
} }
VOID VOID
lock_qh_pool( lock_qh_pool(PUHCI_QH_POOL pool, BOOL at_dpc)
PUHCI_QH_POOL pool,
BOOL at_dpc
)
{ {
//if( !at_dpc ) //if( !at_dpc )
// KeAcquireSpinLock( &pool->pool_lock ); // KeAcquireSpinLock( &pool->pool_lock );
@ -674,14 +597,10 @@ BOOL at_dpc
} }
VOID VOID
unlock_qh_pool( unlock_qh_pool(PUHCI_QH_POOL pool, BOOL at_dpc)
PUHCI_QH_POOL pool,
BOOL at_dpc
)
{ {
//if( !at_dpc ) //if( !at_dpc )
// KeReleaseSpinLock( &pool->pool_lock ); // KeReleaseSpinLock( &pool->pool_lock );
//else //else
// KeReleaseSpinLockFromDpcLevel( &pool->pool_lock ); // KeReleaseSpinLockFromDpcLevel( &pool->pool_lock );
} }

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff