USB-драйвер,чтение.
От: Rusas  
Дата: 02.04.06 20:39
Оценка:
Здравствуйте, проблема заключается в следующем:
При попытке чтения данных с устройства драйвер уходит в бесконечное ожидание события в функции DoCallUSBD.
При просмотре URB-пакетов через USB Monitor видно, что URB-пакет на чтение не посылается.

NTSTATUS DoCallUSBD(IN PDEVICE_OBJECT fdo, IN PURB Urb)
{
NTSTATUS ntStatus,status=STATUS_SUCCESS;
PDEVICE_EXTENSION pdx;
PIRP irp;
KEVENT event;
IO_STATUS_BLOCK ioStatus;
PIO_STACK_LOCATION nextStack;

pdx=fdo->DeviceExtension;
KeInitializeEvent(&event,NotificationEvent,0);

irp=IoBuildDeviceIoControlRequest(IOCTL_INTERNAL_USB_SUBMIT_URB,
pdx->StackDeviceObject,NULL,0,NULL,0,1,&event,&ioStatus);

nextStack=IoGetNextIrpStackLocation(irp);
nextStack->Parameters.Others.Argument1=Urb;

ntStatus=IoCallDriver(pdx->StackDeviceObject,irp);
if (ntStatus==STATUS_PENDING)
{
DbgPrint(" STATUS_PENDING");
status=KeWaitForSingleObject(&event,Suspended,KernelMode,0,NULL);
}else
{
ioStatus.Status=ntStatus;
}



if (NT_SUCCESS(ntStatus))
{
if (!(USBD_SUCCESS(Urb->UrbHeader.Status)))
ntStatus=STATUS_UNSUCCESSFUL;
}

return ntStatus;
}

NTSTATUS OnDeviceRead(IN PDEVICE_OBJECT fdo, IN PIRP Irp)
{
NTSTATUS ntStatus,status=STATUS_SUCCESS;
PDEVICE_EXTENSION pdx;
PIO_STACK_LOCATION pNextStack;
PURB urb;
ULONG urbSize=0;
ULONG transferFlags=0;

pdx=fdo->DeviceExtension;

pNextStack=IoGetNextIrpStackLocation(Irp);

urbSize=sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER);
urb=ExAllocatePool(NonPagedPool,urbSize);

transferFlags=USBD_SHORT_TRANSFER_OK|USBD_TRANSFER_DIRECTION_IN;

UsbBuildInterruptOrBulkTransferRequest(urb,(USHORT)urbSize,pdx->ReadFromDevicePipeHandle,
NULL,Irp->MdlAddress,MmGetMdlByteCount(Irp->MdlAddress),transferFlags,NULL);

ntStatus=DoCallUSBD(fdo,urb);

if (NT_SUCCESS(ntStatus))
{
Irp->IoStatus.Information=urb->UrbBulkOrInterruptTransfer.TransferBufferLength;
}

ExFreePool(urb);

return ntStatus;
}

В чем может быть проблема?
Re: USB-драйвер,чтение.
От: Аноним  
Дата: 04.04.06 16:12
Оценка:
Похоже, устройство не выставляет данные на передачу?
Нужно, чтобы перед обращением, устройство забило в fifo своего встроенного контроллера функции usb данные и выставило некий флаг готовности.
Re[2]: USB-драйвер,чтение.
От: Rusas  
Дата: 04.04.06 17:21
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Похоже, устройство не выставляет данные на передачу?

А>Нужно, чтобы перед обращением, устройство забило в fifo своего встроенного контроллера функции usb данные и выставило некий флаг готовности.

Устройство выставляет данные на передачу, т.к. другой драйвер, написанный с использованием Driver Studio работает с данным устройством и успешно принимает данные.
Мне кажется я не правильно формирую URB-пакет.Если у кого-нибудь есть пример драйвера или код считывания информации с конечной точки устройства, поделитесь пожалуйста, буду очеь признателен.
Re[3]: USB-драйвер,чтение.
От: Аноним  
Дата: 04.04.06 19:26
Оценка:
Вот так отправлял пакетик, и это, в своё время, работало:

NTSTATUS SendAwaitUrb(PDEVICE_OBJECT fdo, PURB urb)
{
PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;

KEVENT event;
KeInitializeEvent(&event, NotificationEvent, FALSE);

IO_STATUS_BLOCK iostatus;
PIRP Irp = IoBuildDeviceIoControlRequest(IOCTL_INTERNAL_USB_SUBMIT_URB,pdx->LowerDeviceObject, NULL, 0, NULL, 0, TRUE, &event, &iostatus);

if (!Irp)
{
    KdPrint(("Unable to allocate IRP"));
    return STATUS_INSUFFICIENT_RESOURCES;
};

PIO_STACK_LOCATION stack = IoGetNextIrpStackLocation(Irp);
stack->Parameters.Others.Argument1 = (PVOID)urb;
NTSTATUS status = IoCallDriver(pdx->LowerDeviceObject, Irp);
if (status == STATUS_PENDING)
{
LARGE_INTEGER interval;
interval.LowPart  = (ULONG)(-9000000); // 900 ms
interval.HighPart = -1;
BOOLEAN cancelled = FALSE;
while (STATUS_TIMEOUT == KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, &interval))
{
KdPrint(("SendAwaitUrb() wait too long..."));
if (!cancelled)
{
KdPrint(("...cancel irp"));
IoCancelIrp(Irp);
cancelled = TRUE;
};
};
status = iostatus.Status;
};
return status;
};



И кусок с подготовкой urb на чтение осьмибайтного пакетика:

URB urb;
UCHAR data[8]; 
// .......
RtlZeroMemory(data,sizeof(data));
UsbBuildInterruptOrBulkTransferRequest(&urb,
(USHORT)sizeof(_URB_BULK_OR_INTERRUPT_TRANSFER),
pdx->PIPE1, // IN pipe
data,NULL,sizeof(data),USBD_TRANSFER_DIRECTION_IN,NULL);

status = SendAwaitUrb(pdx->Pdo,&urb);
if (!NT_SUCCESS(status))
{ // Неудачное чтение
  KdPrint(("PIPE1 read error"));
  ResetPipe(pdx->Pdo,pdx->PIPE1);
// ............
Re[4]: USB-драйвер,чтение.
От: Rusas  
Дата: 04.04.06 23:09
Оценка:
Попробовал прочитать данные вышеуказанным способом, теперь выпал в BSOD из драйвера hhdusbh.sys.
Возник еще один вопрос: надо-ли конечные точки устройства каким-нибудь особенным образом инициализировать или можно сохранить PipeHandle и сразу обращаться к точке с запросом на чтение?
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.