⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ez_usb_device_driver_design.c

📁 EZ_usb 设备通用驱动设计 for windows
💻 C
📖 第 1 页 / 共 5 页
字号:
   } // if ntStatus is PENDING

   goto Ezusb_Dispatch_Done;
            
Ezusb_Dispatch_Done:

   Ezusb_KdPrint (("Exit Ezusb_DispatchPower %x\n", ntStatus));
   return ntStatus;

}//Ezusb_DispatchPower


VOID
Ezusb_Unload(
    IN PDRIVER_OBJECT DriverObject
    )
/*++
Routine Description:
    Free all the allocated resources, etc.
    TODO: This is a placeholder for driver writer to add code on unload

Arguments:
    DriverObject - pointer to a driver object

Return Value:
    None
--*/
{
    Ezusb_KdPrint (("enter Ezusb_Unload\n"));
    /*
    // TODO: Free any global resources allocated in DriverEntry
    */
    Ezusb_KdPrint (("exit Ezusb_Unload\n"));
}

NTSTATUS
Ezusb_HandleRemoveDevice(
   IN PDEVICE_OBJECT fdo,
   IN PIRP Irp
   )
{
   NTSTATUS ntStatus;
   PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;
   ULONG i;

   // set the removing flag to prevent any new I/O's
   pdx->removing = TRUE;

   // brute force - send an abort pipe message to all pipes to cancel any
   // pending transfers.  this should solve the problem of the driver blocking
   // on a REMOVE message because there is a pending transfer.
   for (i = 0; i < pdx->Interface->NumberOfPipes; i++)
   {
      Ezusb_AbortPipe(fdo,(USBD_PIPE_HANDLE) pdx->Interface->Pipes[i].PipeHandle);
   }

   UnlockDevice(fdo);			// once for LockDevice at start of dispatch
   UnlockDevice(fdo);			// once for initialization during AddDevice
   KeWaitForSingleObject(&pdx->evRemove, Executive, KernelMode, FALSE, NULL);

	Ezusb_RemoveDevice(fdo);

   ntStatus = Ezusb_DefaultPnpHandler(fdo, Irp);

   return ntStatus;				// lower-level completed IoStatus already

}


NTSTATUS
Ezusb_HandleStartDevice(
   IN PDEVICE_OBJECT fdo,
   IN PIRP Irp
   )
{
   NTSTATUS ntStatus;

   //
   // First let all lower-level drivers handle this request.
   //
   ntStatus = ForwardAndWait(fdo, Irp);
	if (!NT_SUCCESS(ntStatus))
		return CompleteRequest(Irp, ntStatus, Irp->IoStatus.Information);

   //
   // now do whatever we need to do to start the device
   //
   ntStatus = Ezusb_StartDevice(fdo);

	return CompleteRequest(Irp, ntStatus, 0);
}

NTSTATUS
Ezusb_StartDevice(
    IN  PDEVICE_OBJECT fdo
    )
/*++

Routine Description:
   Initializes a given instance of the Ezusb Device on the USB.

   Arguments:
      fdo - pointer to the device object for this instance of a
                      Ezusb Device

Return Value:
   NT status code
--*/
{
    PDEVICE_EXTENSION pdx;
    NTSTATUS ntStatus;
    PUSB_DEVICE_DESCRIPTOR deviceDescriptor = NULL;
    PURB urb;
    ULONG siz;

    Ezusb_KdPrint (("enter Ezusb_StartDevice\n"));

    pdx = fdo->DeviceExtension;
    pdx->NeedCleanup = TRUE;

    /*
    // Get some memory from then non paged pool (fixed, locked system memory)
    // for use by the USB Request Block (urb) for the specific USB Request we
    // will be performing below (a USB device request).
    */
    urb = ExAllocatePool( NonPagedPool,
                          sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST));

    if (urb) {

        siz = sizeof(USB_DEVICE_DESCRIPTOR);

        // Get some non paged memory for the device descriptor contents
        deviceDescriptor = ExAllocatePool(NonPagedPool,
                                          siz);

        if (deviceDescriptor) {

            // Use a macro in the standard USB header files to build the URB
            UsbBuildGetDescriptorRequest(urb,
                                         (USHORT) sizeof (struct _URB_CONTROL_DESCRIPTOR_REQUEST),
                                         USB_DEVICE_DESCRIPTOR_TYPE,
                                         0,
                                         0,
                                         deviceDescriptor,
                                         NULL,
                                         siz,
                                         NULL);

            // Get the device descriptor
            ntStatus = Ezusb_CallUSBD(fdo, urb);

            // Dump out the descriptor info to the debugger
            if (NT_SUCCESS(ntStatus)) {
                Ezusb_KdPrint (("Device Descriptor = %x, len %x\n",
                                deviceDescriptor,
                                urb->UrbControlDescriptorRequest.TransferBufferLength));

                Ezusb_KdPrint (("Ezusb Device Descriptor:\n"));
                Ezusb_KdPrint (("-------------------------\n"));
                Ezusb_KdPrint (("bLength %d\n", deviceDescriptor->bLength));
                Ezusb_KdPrint (("bDescriptorType 0x%x\n", deviceDescriptor->bDescriptorType));
                Ezusb_KdPrint (("bcdUSB 0x%x\n", deviceDescriptor->bcdUSB));
                Ezusb_KdPrint (("bDeviceClass 0x%x\n", deviceDescriptor->bDeviceClass));
                Ezusb_KdPrint (("bDeviceSubClass 0x%x\n", deviceDescriptor->bDeviceSubClass));
                Ezusb_KdPrint (("bDeviceProtocol 0x%x\n", deviceDescriptor->bDeviceProtocol));
                Ezusb_KdPrint (("bMaxPacketSize0 0x%x\n", deviceDescriptor->bMaxPacketSize0));
                Ezusb_KdPrint (("idVendor 0x%x\n", deviceDescriptor->idVendor));
                Ezusb_KdPrint (("idProduct 0x%x\n", deviceDescriptor->idProduct));
                Ezusb_KdPrint (("bcdDevice 0x%x\n", deviceDescriptor->bcdDevice));
                Ezusb_KdPrint (("iManufacturer 0x%x\n", deviceDescriptor->iManufacturer));
                Ezusb_KdPrint (("iProduct 0x%x\n", deviceDescriptor->iProduct));
                Ezusb_KdPrint (("iSerialNumber 0x%x\n", deviceDescriptor->iSerialNumber));
                Ezusb_KdPrint (("bNumConfigurations 0x%x\n", deviceDescriptor->bNumConfigurations));
            }
        } else {
            ntStatus = STATUS_NO_MEMORY;
        }

        if (NT_SUCCESS(ntStatus)) {
            /*
            // Put a ptr to the device descriptor in the device extension for easy
            // access (like a "cached" copy).  We will free this memory when the
            // device is removed.  See the "Ezusb_RemoveDevice" code.
            */
            pdx->DeviceDescriptor = deviceDescriptor;
            pdx->Stopped = FALSE;
        } else if (deviceDescriptor) {
            /*
            // If the bus transaction failed, then free up the memory created to hold
            // the device descriptor, since the device is probably non-functional
            */
            ExFreePool(deviceDescriptor);
            pdx->DeviceDescriptor = NULL;
        }

        ExFreePool(urb);

    } else {
        // Failed getting memory for the Urb 
        ntStatus = STATUS_NO_MEMORY;
    }

    // If the Get_Descriptor call was successful, then configure the device.
    if (NT_SUCCESS(ntStatus)) {
        ntStatus = Ezusb_ConfigureDevice(fdo);
    }

#ifdef DOWNLOAD_KEIL_MONITOR
   //
   // download the Keil monitor
   //

   //
   // First download loader firmware.  The loader firmware implements a vendor
   // specific command that will allow us to anchor load to external ram
   //
   Ezusb_8051Reset(fdo,1);
   Ezusb_DownloadIntelHex(fdo,loader);
   Ezusb_8051Reset(fdo,0);

   //
   // Now download the Keil Monitor
   //
   if (IsFx2(fdo))
   {
      Ezusb_KdPrint (("**** Downloading FX2 monitor\n"));
      Ezusb_DownloadIntelHex(fdo,mon_ext_sio1_fx2);
   }
   else
   {
      Ezusb_KdPrint (("**** Downloading EZ-USB monitor\n"));
      Ezusb_DownloadIntelHex(fdo,mon_ext_sio1_ezusb);
   }

   Ezusb_8051Reset(fdo,1);
   Ezusb_8051Reset(fdo,0);

#endif // if DOWNLOAD_KEIL_MONITOR

    Ezusb_KdPrint (("exit Ezusb_StartDevice (%x)\n", ntStatus));

    return ntStatus;
}


NTSTATUS
Ezusb_RemoveDevice(
    IN  PDEVICE_OBJECT fdo
    )
/*++

Routine Description:
    Removes a given instance of a Ezusb Device device on the USB.

Arguments:
    fdo - pointer to the device object for this instance of a Ezusb Device

Return Value:
    NT status code

--*/
{
   PDEVICE_EXTENSION pdx;
   NTSTATUS ntStatus = STATUS_SUCCESS;

   Ezusb_KdPrint (("enter Ezusb_RemoveDevice\n"));

   pdx = fdo->DeviceExtension;

   if (pdx->DeviceDescriptor)
   {
      ExFreePool(pdx->DeviceDescriptor);
   }

   //
   // Free up any interface structures in our device extension
   //
   if (pdx->Interface != NULL)
   {
      ExFreePool(pdx->Interface);
   }

   //
   // remove the device object's symbolic link
   //
   if (pdx->NeedCleanup)
   {
      UNICODE_STRING deviceLinkUnicodeString;

      pdx->NeedCleanup = FALSE;

      RtlInitUnicodeString (&deviceLinkUnicodeString,
                           pdx->DeviceLinkNameBuffer);

      IoDeleteSymbolicLink(&deviceLinkUnicodeString);
    }

   IoDetachDevice(pdx->StackDeviceObject);

   IoDeleteDevice (fdo);

   Ezusb_KdPrint (("exit Ezusb_RemoveDevice (%x)\n", ntStatus));

   return ntStatus;
}


NTSTATUS
Ezusb_StopDevice(
   IN  PDEVICE_OBJECT fdo
   )
/*++
Routine Description:
   Stops a given instance of a Ezusb Device device on USB.

Arguments:
   fdo - pointer to the device object for this instance of a Ezusb Device

Return Value:
   NT status code

  --*/
{
   PDEVICE_EXTENSION pdx;
   NTSTATUS ntStatus = STATUS_SUCCESS;
   PURB urb;
   ULONG siz;

   Ezusb_KdPrint (("enter Ezusb_StopDevice\n"));

   pdx = fdo->DeviceExtension;

   //
   // Send the select configuration urb with a NULL pointer for the configuration
   // handle, this closes the configuration and puts the device in the 'unconfigured'
   // state.
   //

   siz = sizeof(struct _URB_SELECT_CONFIGURATION);

   urb = ExAllocatePool(NonPagedPool,
                      siz);

   if (urb)
   {
      NTSTATUS status;

      UsbBuildSelectConfigurationRequest(urb,
                                       (USHORT) siz,
                                       NULL);

      status = Ezusb_CallUSBD(fdo, urb);

      Ezusb_KdPrint (("Device Configuration Closed status = %x usb status = %x.\n",
                     status, urb->UrbHeader.Status));

      ExFreePool(urb);
   }
   else
   {
      ntStatus = STATUS_NO_MEMORY;
   }

   Ezusb_KdPrint (("exit Ezusb_StopDevice (%x)\n", ntStatus));

   return ntStatus;
}

NTSTATUS
Ezusb_PnPAddDevice(
    IN PDRIVER_OBJECT DriverObject,
    IN PDEVICE_OBJECT PhysicalDeviceObject
    )
/*++
Routine Description:
    This routine is called to create a new instance of the device

Arguments:
    DriverObject - pointer to the driver object for this instance of Ezusb
    PhysicalDeviceObject - pointer to a device object created by the bus

Return Value:
    STATUS_SUCCESS if successful,
    STATUS_UNSUCCESSFUL otherwise

--*/
{
   NTSTATUS                ntStatus = STATUS_SUCCESS;
   PDEVICE_OBJECT          deviceObject = NULL;
   PDEVICE_EXTENSION       pdx;
   int instance;

   Ezusb_KdPrint(("enter Ezusb_PnPAddDevice\n"));

#define MAX_EZUSB_DEVICES 8

   //
   // create our functional device object (FDO).  This driver supports multiple ezusb devices.
   // This loop will look for an available instance number.  Keep incrementing the instance
   // until a call to Ezusb_CreateDeviceObject succeeds.
   //
   instance = 0;
   do

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -