isostrm.c
上传用户:leituo004
上传日期:2014-11-03
资源大小:159k
文件大小:20k
源码类别:

驱动编程

开发平台:

Visual C++

  1. /*++
  2. Copyright (c) 2000  Microsoft Corporation
  3. Module Name:
  4.     isostrm.c
  5. Abstract:
  6.     This file has routines for stream transfers.
  7.     Stream transfers are initiated and stopped using
  8.     the IOCTLs exposed by this driver.
  9.     The stream transfer information is contained in 
  10.     ISOUSB_STREAM_OBJECT structure which is securely
  11.     placed in the FileObject. The ISOUSB_STREAM_OBJECT 
  12.     structure has links to ISOUSB_TRANSFER_OBJECT 
  13.     (each TRANSFER_OBJECT corresponds to the number of 
  14.     irp/urb pair circulating).
  15.     So if the user-mode app simply crashes or aborts or 
  16.     does not terminate, we can cleanly abort the stream
  17.     transfers.
  18. Environment:
  19.     Kernel mode
  20. Notes:
  21.     Copyright (c) 2000 Microsoft Corporation.  
  22.     All Rights Reserved.
  23. --*/
  24. #include "isousb.h"
  25. #include "isopnp.h"
  26. #include "isopwr.h"
  27. #include "isodev.h"
  28. #include "isousr.h"
  29. #include "isowmi.h"
  30. #include "isorwr.h"
  31. #include "isostrm.h"
  32. NTSTATUS
  33. IsoUsb_StartIsoStream(
  34.     IN PDEVICE_OBJECT DeviceObject,
  35.     IN PIRP           Irp
  36.     )
  37. /*++
  38.  
  39. Routine Description:
  40.     This routine create a single stream object and
  41.     invokes StartTransfer for ISOUSB_MAX_IRP number of 
  42.     times.
  43. Arguments:
  44.     DeviceObject - pointer to device object
  45.     Irp - I/O request packet
  46. Return Value:
  47.     NT status value
  48. --*/
  49. {
  50.     ULONG                  i;
  51.     ULONG                  info;
  52.     ULONG                  inputBufferLength;
  53.     ULONG                  outputBufferLength;
  54.     NTSTATUS               ntStatus;
  55.     PFILE_OBJECT           fileObject;
  56.     PDEVICE_EXTENSION      deviceExtension;
  57.     PIO_STACK_LOCATION     irpStack;
  58.     PISOUSB_STREAM_OBJECT  streamObject;
  59.     PUSBD_PIPE_INFORMATION pipeInformation;
  60.     info = 0;
  61.     irpStack = IoGetCurrentIrpStackLocation(Irp);
  62.     fileObject = irpStack->FileObject;
  63.     streamObject = NULL;
  64.     pipeInformation = NULL;
  65.     deviceExtension = DeviceObject->DeviceExtension;
  66.     inputBufferLength = irpStack->Parameters.DeviceIoControl.InputBufferLength;
  67.     outputBufferLength = irpStack->Parameters.DeviceIoControl.OutputBufferLength;
  68.     IsoUsb_DbgPrint(3, ("IsoUsb_StartIsoStream - beginsn"));
  69.     streamObject = ExAllocatePool(NonPagedPool, 
  70.                                   sizeof(struct _ISOUSB_STREAM_OBJECT));
  71.     if(streamObject == NULL) {
  72.         IsoUsb_DbgPrint(1, ("failed to alloc mem for streamObjectn"));
  73.         ntStatus = STATUS_INSUFFICIENT_RESOURCES;
  74.         goto IsoUsb_StartIsoStream_Exit;
  75.     }
  76.     RtlZeroMemory(streamObject, sizeof(ISOUSB_STREAM_OBJECT));
  77.     //
  78.     // The Isoch IN pipe for the board is the 5th pipe
  79.     //
  80.     pipeInformation = &(deviceExtension->UsbInterface->Pipes[ISOCH_IN_PIPE_INDEX]);
  81.     // reset the pipe
  82.     //
  83.     IsoUsb_ResetPipe(DeviceObject, pipeInformation);
  84.     
  85.     streamObject->DeviceObject = DeviceObject;
  86.     streamObject->PipeInformation = pipeInformation;
  87.     KeInitializeEvent(&streamObject->NoPendingIrpEvent,
  88.                       NotificationEvent,
  89.                       FALSE);
  90.     for(i = 0; i < ISOUSB_MAX_IRP; i++) {
  91.         ntStatus = IsoUsb_StartTransfer(DeviceObject,
  92.                                         streamObject,
  93.                                         i);
  94.         if(!NT_SUCCESS(ntStatus)) {
  95.          
  96.             //
  97.             // we continue sending transfer object irps..
  98.             //
  99.             
  100.             IsoUsb_DbgPrint(1, ("IsoUsb_StartTransfer [%d] - failedn", i));
  101.             if(ntStatus == STATUS_INSUFFICIENT_RESOURCES) {
  102.                 
  103.                 ASSERT(streamObject->TransferObjectList[i] == NULL);
  104.             }
  105.         }
  106.     }
  107.     if(fileObject && fileObject->FsContext) {
  108.         
  109.         if(streamObject->PendingIrps) {
  110.             ((PFILE_OBJECT_CONTENT)fileObject->FsContext)->StreamInformation 
  111.                                                                 = streamObject;
  112.         }
  113.         else {
  114.             IsoUsb_DbgPrint(1, ("no transfer object irp sent..abort..n"));
  115.             ExFreePool(streamObject);
  116.             ((PFILE_OBJECT_CONTENT)fileObject->FsContext)->StreamInformation = NULL;
  117.         }
  118.     }
  119. IsoUsb_StartIsoStream_Exit:
  120.     Irp->IoStatus.Information = info;
  121.     Irp->IoStatus.Status = ntStatus;
  122.     IoCompleteRequest(Irp, IO_NO_INCREMENT);
  123.     IsoUsb_DbgPrint(3, ("IsoUsb_StartIsoStream::"));
  124.     IsoUsb_IoDecrement(deviceExtension);
  125.     IsoUsb_DbgPrint(3, ("IsoUsb_StartIsoStream - endsn"));
  126.     return ntStatus;
  127. }
  128. NTSTATUS
  129. IsoUsb_StartTransfer(
  130.     IN PDEVICE_OBJECT        DeviceObject,
  131.     IN PISOUSB_STREAM_OBJECT StreamObject,
  132.     IN ULONG                 Index
  133.     )
  134. /*++
  135.  
  136. Routine Description:
  137.     This routine creates a transfer object for each irp/urb pair.
  138.     After initializing the pair, it sends the irp down the stack.
  139. Arguments:
  140.     DeviceObject - pointer to device object.
  141.     StreamObject - pointer to stream object
  142.     Index - index into the transfer object table in stream object
  143. Return Value:
  144.     NT status value
  145. --*/
  146. {
  147.     PIRP                    irp;
  148.     CCHAR                   stackSize;
  149.     ULONG                   packetSize;
  150.     ULONG                   maxXferSize;
  151.     ULONG                   numPackets;
  152.     NTSTATUS                ntStatus;
  153.     PDEVICE_EXTENSION       deviceExtension;
  154.     PIO_STACK_LOCATION      nextStack;
  155.     PISOUSB_TRANSFER_OBJECT transferObject;
  156.     deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
  157.     maxXferSize = StreamObject->PipeInformation->MaximumTransferSize;
  158.     packetSize = StreamObject->PipeInformation->MaximumPacketSize;
  159.     numPackets = maxXferSize / packetSize;
  160.     IsoUsb_DbgPrint(3, ("IsoUsb_StartTransfer - beginsn"));
  161.     transferObject = ExAllocatePool(NonPagedPool,
  162.                                     sizeof(struct _ISOUSB_TRANSFER_OBJECT));
  163.     if(transferObject == NULL) {
  164.         IsoUsb_DbgPrint(1, ("failed to alloc mem for transferObjectn"));
  165.         return STATUS_INSUFFICIENT_RESOURCES;
  166.     }
  167.     RtlZeroMemory(transferObject,
  168.                   sizeof(struct _ISOUSB_TRANSFER_OBJECT));
  169.     transferObject->StreamObject = StreamObject;
  170.     
  171.     stackSize = (CCHAR) (deviceExtension->TopOfStackDeviceObject->StackSize + 1);
  172.     irp = IoAllocateIrp(stackSize, FALSE);
  173.     if(irp == NULL) {
  174.         IsoUsb_DbgPrint(1, ("failed to alloc mem for irpn"));
  175.         ExFreePool(transferObject);
  176.         return STATUS_INSUFFICIENT_RESOURCES;
  177.     }
  178.     transferObject->Irp = irp;
  179.     transferObject->DataBuffer = ExAllocatePool(NonPagedPool,
  180.                                                 maxXferSize);
  181.     if(transferObject->DataBuffer == NULL) {
  182.         IsoUsb_DbgPrint(1, ("failed to alloc mem for DataBuffern"));
  183.         ExFreePool(transferObject);
  184.         IoFreeIrp(irp);
  185.         return STATUS_INSUFFICIENT_RESOURCES;
  186.     }
  187.     transferObject->Urb = ExAllocatePool(NonPagedPool,
  188.                                          GET_ISO_URB_SIZE(numPackets));
  189.     if(transferObject->Urb == NULL) {
  190.         IsoUsb_DbgPrint(1, ("failed to alloc mem for Urbn"));
  191.         ExFreePool(transferObject->DataBuffer);
  192.         IoFreeIrp(irp);
  193.         ExFreePool(transferObject);
  194.         return STATUS_INSUFFICIENT_RESOURCES;
  195.     }
  196.     IsoUsb_InitializeStreamUrb(DeviceObject, transferObject);
  197.     StreamObject->TransferObjectList[Index] = transferObject;
  198.     InterlockedIncrement(&StreamObject->PendingIrps);
  199.     nextStack = IoGetNextIrpStackLocation(irp);
  200.     nextStack->Parameters.Others.Argument1 = transferObject->Urb;
  201.     nextStack->Parameters.DeviceIoControl.IoControlCode = 
  202.                                    IOCTL_INTERNAL_USB_SUBMIT_URB;
  203.     nextStack->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL;
  204.     IoSetCompletionRoutine(irp, 
  205.                            IsoUsb_IsoIrp_Complete,
  206.                            transferObject,
  207.                            TRUE,
  208.                            TRUE,
  209.                            TRUE);
  210.     IsoUsb_DbgPrint(3, ("IsoUsb_StartTransfer::"));
  211.     IsoUsb_IoIncrement(deviceExtension);
  212.     ntStatus = IoCallDriver(deviceExtension->TopOfStackDeviceObject,
  213.                             irp);
  214.     if(NT_SUCCESS(ntStatus)) {
  215.         ntStatus = STATUS_SUCCESS;
  216.     }
  217.     IsoUsb_DbgPrint(3, ("IsoUsb_StartTransfer - endsn"));
  218.     return ntStatus;
  219. }
  220. NTSTATUS
  221. IsoUsb_InitializeStreamUrb(
  222.     IN PDEVICE_OBJECT          DeviceObject,
  223.     IN PISOUSB_TRANSFER_OBJECT TransferObject
  224.     )
  225. /*++
  226.  
  227. Routine Description:
  228.     This routine initializes the irp/urb pair in the transfer object.
  229. Arguments:
  230.     DeviceObject - pointer to device object
  231.     TransferObject - pointer to transfer object
  232. Return Value:
  233.     NT status value
  234. --*/
  235. {
  236.     PURB                  urb;
  237.     ULONG                 i;
  238.     ULONG                 siz;
  239.     ULONG                 packetSize;
  240.     ULONG                 numPackets;
  241.     ULONG                 maxXferSize;
  242.     PISOUSB_STREAM_OBJECT streamObject;
  243.     urb = TransferObject->Urb;
  244.     streamObject = TransferObject->StreamObject;
  245.     maxXferSize = streamObject->PipeInformation->MaximumTransferSize;
  246.     packetSize = streamObject->PipeInformation->MaximumPacketSize;
  247.     numPackets = maxXferSize / packetSize;
  248.     IsoUsb_DbgPrint(3, ("IsoUsb_InitializeStreamUrb - beginsn"));
  249.     if(numPackets > 255) {
  250.         numPackets = 255;
  251.         maxXferSize = packetSize * numPackets;
  252.     }
  253.     siz = GET_ISO_URB_SIZE(numPackets);
  254.     RtlZeroMemory(urb, siz);
  255.     urb->UrbIsochronousTransfer.Hdr.Length = (USHORT) siz;
  256.     urb->UrbIsochronousTransfer.Hdr.Function = URB_FUNCTION_ISOCH_TRANSFER;
  257.     urb->UrbIsochronousTransfer.PipeHandle =
  258.                                 streamObject->PipeInformation->PipeHandle;
  259.     urb->UrbIsochronousTransfer.TransferFlags = USBD_TRANSFER_DIRECTION_IN;
  260.     urb->UrbIsochronousTransfer.TransferBufferMDL = NULL;
  261.     urb->UrbIsochronousTransfer.TransferBuffer = TransferObject->DataBuffer;
  262.     urb->UrbIsochronousTransfer.TransferBufferLength = numPackets * packetSize;
  263.     urb->UrbIsochronousTransfer.TransferFlags |= USBD_START_ISO_TRANSFER_ASAP;
  264.     urb->UrbIsochronousTransfer.NumberOfPackets = numPackets;
  265.     urb->UrbIsochronousTransfer.UrbLink = NULL;
  266.     for(i=0; i<urb->UrbIsochronousTransfer.NumberOfPackets; i++) {
  267.         urb->UrbIsochronousTransfer.IsoPacket[i].Offset = i * packetSize;
  268.         //
  269.         // For input operation, length is set to whatever the device supplies.
  270.         //
  271.         urb->UrbIsochronousTransfer.IsoPacket[i].Length = 0;
  272.     }
  273.     IsoUsb_DbgPrint(3, ("IsoUsb_InitializeStreamUrb - endsn"));
  274.     return STATUS_SUCCESS;
  275. }
  276. NTSTATUS
  277. IsoUsb_IsoIrp_Complete(
  278.     IN PDEVICE_OBJECT DeviceObject,
  279.     IN PIRP           Irp,
  280.     IN PVOID          Context
  281.     )
  282. /*++
  283.  
  284. Routine Description:
  285.     This is the completion routine of the irp in the irp/urb pair
  286.     passed down the stack for stream transfers.
  287.     If the transfer was cancelled or the device yanked out, then we
  288.     release resources, dump the statistics and return 
  289.     STATUS_MORE_PROCESSING_REQUIRED, so that the cleanup module can
  290.     free the irp.
  291.     otherwise, we reinitialize the transfers and continue recirculaiton 
  292.     of the irps.
  293. Arguments:
  294.     DeviceObject - pointer to device object below us.
  295.     Irp - I/O completion routine.
  296.     Context - context passed to the completion routine
  297. Return Value:
  298. --*/
  299. {
  300.     NTSTATUS                ntStatus;
  301.     PDEVICE_OBJECT          deviceObject;
  302.     PDEVICE_EXTENSION       deviceExtension;
  303.     PIO_STACK_LOCATION      nextStack;
  304.     PISOUSB_STREAM_OBJECT   streamObject;
  305.     PISOUSB_TRANSFER_OBJECT transferObject;
  306.     transferObject = (PISOUSB_TRANSFER_OBJECT) Context;
  307.     streamObject = transferObject->StreamObject;
  308.     deviceObject = streamObject->DeviceObject;
  309.     deviceExtension = (PDEVICE_EXTENSION) deviceObject->DeviceExtension;
  310.     IsoUsb_DbgPrint(3, ("IsoUsb_IsoIrp_Complete - beginsn"));
  311.     ntStatus = IsoUsb_ProcessTransfer(transferObject);
  312.     if((ntStatus == STATUS_CANCELLED) ||
  313.        (ntStatus == STATUS_DEVICE_NOT_CONNECTED)) {
  314.     
  315.         IsoUsb_DbgPrint(3, ("Isoch irp cancelled/device removedn"));
  316.         //
  317.         // this is the last irp to complete with this erroneous value
  318.         // signal an event and return STATUS_MORE_PROCESSING_REQUIRED
  319.         //
  320.         if(InterlockedDecrement(&streamObject->PendingIrps) == 0) {
  321.             KeSetEvent(&streamObject->NoPendingIrpEvent,
  322.                        1,
  323.                        FALSE);
  324.             IsoUsb_DbgPrint(3, ("-----------------------------n"));
  325.         }
  326.         IsoUsb_DbgPrint(3, ("IsoUsb_IsoIrp_Complete::"));
  327.         IsoUsb_IoDecrement(deviceExtension);
  328.         transferObject->Irp = NULL;
  329.         IoFreeIrp(Irp);
  330.         return STATUS_MORE_PROCESSING_REQUIRED;
  331.     }
  332.     //
  333.     // otherwise circulate the irps.
  334.     //
  335.     IsoUsb_InitializeStreamUrb(deviceObject, transferObject);
  336.     nextStack = IoGetNextIrpStackLocation(Irp);
  337.     nextStack->Parameters.Others.Argument1 = transferObject->Urb;
  338.     nextStack->Parameters.DeviceIoControl.IoControlCode = 
  339.                                                 IOCTL_INTERNAL_USB_SUBMIT_URB;
  340.     nextStack->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL;
  341.     IoSetCompletionRoutine(Irp,
  342.                            IsoUsb_IsoIrp_Complete,
  343.                            transferObject,
  344.                            TRUE,
  345.                            TRUE,
  346.                            TRUE);
  347.     transferObject->TimesRecycled++;
  348.     ntStatus = IoCallDriver(deviceExtension->TopOfStackDeviceObject,
  349.                             Irp);
  350.     IsoUsb_DbgPrint(3, ("IsoUsb_IsoIrp_Complete - endsn"));
  351.     IsoUsb_DbgPrint(3, ("-----------------------------n"));
  352.     return STATUS_MORE_PROCESSING_REQUIRED;
  353. }
  354. NTSTATUS
  355. IsoUsb_ProcessTransfer(
  356.     IN PISOUSB_TRANSFER_OBJECT TransferObject
  357.     )
  358. /*++
  359.  
  360. Routine Description:
  361.     This routine is invoked from the completion routine to check the status
  362.     of the irp, urb and the isochronous packets.
  363.     updates statistics
  364. Arguments:
  365.     TranferObject - pointer to transfer object for the irp/urb pair which completed.
  366. Return Value:
  367.     NT status value
  368. --*/
  369. {
  370.     PIRP        irp;
  371.     PURB        urb;
  372.     ULONG       i;
  373.     NTSTATUS    ntStatus;
  374.     USBD_STATUS usbdStatus;
  375.     irp = TransferObject->Irp;
  376.     urb = TransferObject->Urb;
  377.     ntStatus = irp->IoStatus.Status;
  378.     IsoUsb_DbgPrint(3, ("IsoUsb_ProcessTransfer - beginsn"));
  379.     if(!NT_SUCCESS(ntStatus)) {
  380.         IsoUsb_DbgPrint(3, ("Isoch irp failed with status = %Xn", ntStatus));
  381.     }
  382.     usbdStatus = urb->UrbHeader.Status;
  383.     if(!USBD_SUCCESS(usbdStatus)) {
  384.         IsoUsb_DbgPrint(3, ("urb failed with status = %Xn", usbdStatus));
  385.     }
  386.     //
  387.     // check each of the urb packets
  388.     //
  389.     for(i = 0; i < urb->UrbIsochronousTransfer.NumberOfPackets; i++) {
  390.         TransferObject->TotalPacketsProcessed++;
  391.         usbdStatus = urb->UrbIsochronousTransfer.IsoPacket[i].Status;
  392.         if(!USBD_SUCCESS(usbdStatus)) {
  393. //            IsoUsb_DbgPrint(3, ("Iso packet %d failed with status = %Xn", i, usbdStatus));
  394.             
  395.             TransferObject->ErrorPacketCount++;
  396.         }
  397.         else {
  398.             
  399.             TransferObject->TotalBytesProcessed += urb->UrbIsochronousTransfer.IsoPacket[i].Length;
  400.         }
  401.     }
  402.     IsoUsb_DbgPrint(3, ("IsoUsb_ProcessTransfer - endsn"));
  403.     return ntStatus;
  404. }
  405. NTSTATUS
  406. IsoUsb_StopIsoStream(
  407.     IN PDEVICE_OBJECT        DeviceObject,
  408.     IN PISOUSB_STREAM_OBJECT StreamObject,
  409.     IN PIRP                  Irp
  410.     )
  411. /*++
  412.  
  413. Routine Description:
  414.     This routine is invoked from the IOCTL to stop the stream transfers.
  415. Arguments:
  416.     DeviceObject - pointer to device object
  417.     StreamObject - pointer to stream object
  418.     Irp - pointer to Irp
  419. Return Value:
  420.     NT status value
  421. --*/
  422. {
  423.     ULONG              i;
  424.     KIRQL              oldIrql;
  425.     PDEVICE_EXTENSION  deviceExtension;
  426.     PIO_STACK_LOCATION irpStack;
  427.     //
  428.     // initialize vars
  429.     //
  430.     irpStack = IoGetCurrentIrpStackLocation(Irp);
  431.     deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
  432.     IsoUsb_DbgPrint(3, ("IsoUsb_StopIsoStream - beginsn"));
  433.     if((StreamObject == NULL) ||
  434.        (StreamObject->DeviceObject != DeviceObject)) {
  435.         IsoUsb_DbgPrint(1, ("invalid streamObjectn"));
  436.         return STATUS_INVALID_PARAMETER;
  437.     }
  438.     IsoUsb_StreamObjectCleanup(StreamObject, deviceExtension);
  439.     IsoUsb_DbgPrint(3, ("IsoUsb_StopIsoStream - endsn"));
  440.     return STATUS_SUCCESS;
  441. }
  442. NTSTATUS
  443. IsoUsb_StreamObjectCleanup(
  444.     IN PISOUSB_STREAM_OBJECT StreamObject,
  445.     IN PDEVICE_EXTENSION     DeviceExtension
  446.     )
  447. /*++
  448.  
  449. Routine Description:
  450.     This routine is invoked either when the user-mode app passes an IOCTL to
  451.     abort stream transfers or when the the cleanup dispatch routine is run.
  452.     It is guaranteed to run only once for every stream transfer.
  453. Arguments:
  454.     StreamObject - StreamObject corresponding to stream transfer which
  455.     needs to be aborted.
  456.     DeviceExtension - pointer to device extension
  457. Return Value:
  458.     NT status value
  459. --*/
  460. {
  461.     ULONG                   i;
  462.     ULONG                   timesRecycled;
  463.     ULONG                   totalPacketsProcessed;
  464.     ULONG                   totalBytesProcessed;
  465.     ULONG                   errorPacketCount;
  466.     PISOUSB_TRANSFER_OBJECT xferObject;
  467.     //
  468.     // initialize the variables
  469.     //
  470.     timesRecycled = 0;
  471.     totalPacketsProcessed = 0;
  472.     totalBytesProcessed = 0;
  473.     errorPacketCount = 0;
  474.     //
  475.     // cancel transferobject irps/urb pair
  476.     // safe to touch these irps because the 
  477.     // completion routine always returns 
  478.     // STATUS_MORE_PRCESSING_REQUIRED
  479.     // 
  480.     //
  481.     for(i = 0; i < ISOUSB_MAX_IRP; i++) {
  482.         if(StreamObject->TransferObjectList[i] &&
  483.            StreamObject->TransferObjectList[i]->Irp) {
  484.         
  485.             IoCancelIrp(StreamObject->TransferObjectList[i]->Irp);
  486.         }
  487.     }
  488.     //
  489.     // wait for the transfer objects irps to complete.
  490.     //
  491.     KeWaitForSingleObject(&StreamObject->NoPendingIrpEvent,
  492.                           Executive,
  493.                           KernelMode,
  494.                           FALSE,
  495.                           NULL);
  496.     //
  497.     // dump the statistics
  498.     //
  499.     for(i = 0; i < ISOUSB_MAX_IRP; i++) {
  500.         xferObject = StreamObject->TransferObjectList[i];
  501.         if(xferObject) {
  502.             timesRecycled += xferObject->TimesRecycled;
  503.             totalPacketsProcessed += xferObject->TotalPacketsProcessed;
  504.             totalBytesProcessed += xferObject->TotalBytesProcessed;
  505.             errorPacketCount += xferObject->ErrorPacketCount;
  506.         }
  507.     }
  508.     IsoUsb_DbgPrint(3, ("TimesRecycled = %dn", timesRecycled));
  509.     IsoUsb_DbgPrint(3, ("TotalPacketsProcessed = %dn", totalPacketsProcessed));
  510.     IsoUsb_DbgPrint(3, ("TotalBytesProcessed = %dn", totalBytesProcessed));
  511.     IsoUsb_DbgPrint(3, ("ErrorPacketCount = %dn", errorPacketCount));
  512.     //
  513.     // free all the buffers, urbs and transfer objects 
  514.     // associated with stream object
  515.     //
  516.     for(i = 0; i < ISOUSB_MAX_IRP; i++) {
  517.         
  518.         xferObject = StreamObject->TransferObjectList[i];
  519.         if(xferObject) { 
  520.             
  521.             if(xferObject->Urb) {
  522.                 ExFreePool(xferObject->Urb);
  523.                 xferObject->Urb = NULL;
  524.             }
  525.             if(xferObject->DataBuffer) {
  526.     
  527.                 ExFreePool(xferObject->DataBuffer);
  528.                 xferObject->DataBuffer = NULL;
  529.             }
  530.             ExFreePool(xferObject);
  531.             StreamObject->TransferObjectList[i] = NULL;
  532.         }
  533.     }
  534.     ExFreePool(StreamObject);
  535. //    IsoUsb_ResetParentPort(DeviceObject);
  536.     return STATUS_SUCCESS;
  537. }