?? datapkt.c
字號:
}
IsochDescriptorReserved->Flags |= STATE_DETACHING_BUFFERS;
KeReleaseSpinLock(&pDevExt->IsochDescriptorLock, oldIrql);
IsochDescriptor = (PISOCH_DESCRIPTOR) (((PUCHAR) IsochDescriptorReserved) - FIELDOFFSET(ISOCH_DESCRIPTOR, DeviceReserved[0]));
pIrp = (PIRP) IsochDescriptor->DeviceReserved[5];
ASSERT(pIrp);
pIrb = (PIRB) IsochDescriptor->DeviceReserved[6];
ASSERT(pIrb);
DbgMsg1(("DCamReSubmitPacket: detaching IsochDescriptor %x IsochDescriptorReserved %x, pSrb %x\n",
IsochDescriptor, IsochDescriptorReserved, IsochDescriptorReserved->Srb));
#if DBG
// Should not have been detached
ASSERT((IsochDescriptor->DeviceReserved[7] == 0x87654321));
IsochDescriptor->DeviceReserved[7]++;
#endif
pIrb->FunctionNumber = REQUEST_ISOCH_DETACH_BUFFERS;
pIrb->Flags = 0;
pIrb->u.IsochDetachBuffers.hResource = hStaleResource;
pIrb->u.IsochDetachBuffers.nNumberOfDescriptors = 1;
pIrb->u.IsochDetachBuffers.pIsochDescriptor = IsochDescriptor;
NextIrpStack = IoGetNextIrpStackLocation(pIrp);
NextIrpStack->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL;
NextIrpStack->Parameters.DeviceIoControl.IoControlCode = IOCTL_1394_CLASS;
NextIrpStack->Parameters.Others.Argument1 = pIrb;
IoSetCompletionRoutine(
pIrp,
DCamReSubmitPacketCR,
IsochDescriptor,
TRUE,
TRUE,
TRUE
);
Status =
IoCallDriver(
pDevExt->BusDeviceObject,
pIrp
);
ASSERT(Status == STATUS_SUCCESS || Status == STATUS_PENDING);
} else {
ERROR_LOG(("PendingCount %d, but list is empty!!\n", cntPendingRead));
ASSERT(cntPendingRead == 0);
}
} // for()
return Status;
}
VOID
DCamReadStreamWorker(
IN PHW_STREAM_REQUEST_BLOCK pSrb,
IN PISOCH_DESCRIPTOR IsochDescriptor
)
/*++
Routine Description:
Does most of the work for handling reads via Attach buffers
Arguments:
Srb - Pointer to Stream request block
IsochDescriptor - Pointer to IsochDescriptor to be used
Return Value:
Nothing
--*/
{
PIRB pIrb;
PIRP pIrp;
PIO_STACK_LOCATION NextIrpStack;
PDCAM_EXTENSION pDevExt;
PISOCH_DESCRIPTOR_RESERVED IsochDescriptorReserved;
NTSTATUS Status;
pDevExt = (PDCAM_EXTENSION) pSrb->HwDeviceExtension;
pIrp = (PIRP) IsochDescriptor->DeviceReserved[5];
ASSERT(pIrp);
pIrb = (PIRB) IsochDescriptor->DeviceReserved[6];
ASSERT(pIrb);
#if DBG
// track number time the same IsochDescriptor are attaching; should only be one.
IsochDescriptor->DeviceReserved[4]++;
#endif
//
// It is pending and will be completed in isoch callback or cancelled.
//
pSrb->Status = STATUS_PENDING;
IsochDescriptorReserved = (PISOCH_DESCRIPTOR_RESERVED) &IsochDescriptor->DeviceReserved[0];
DbgMsg3(("\'DCamReadStreamWorker: enter with pSrb = %x, pDevExt=0x%x\n", pSrb, pDevExt));
//
// Attach descriptor onto our pending descriptor list
//
ExInterlockedInsertTailList(
&pDevExt->IsochDescriptorList,
&IsochDescriptorReserved->DescriptorList,
&pDevExt->IsochDescriptorLock
);
pIrb->FunctionNumber = REQUEST_ISOCH_ATTACH_BUFFERS;
pIrb->Flags = 0;
pIrb->u.IsochAttachBuffers.hResource = pDevExt->hResource;
pIrb->u.IsochAttachBuffers.nNumberOfDescriptors = 1;
pIrb->u.IsochAttachBuffers.pIsochDescriptor = IsochDescriptor;
NextIrpStack = IoGetNextIrpStackLocation(pIrp);
NextIrpStack->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL;
NextIrpStack->Parameters.DeviceIoControl.IoControlCode = IOCTL_1394_CLASS;
NextIrpStack->Parameters.Others.Argument1 = pIrb;
IoSetCompletionRoutine(
pIrp,
DCamAttachBufferCR,
IsochDescriptor,
TRUE,
TRUE,
TRUE
);
Status =
IoCallDriver(
pDevExt->BusDeviceObject,
pIrp
);
ASSERT(Status == STATUS_SUCCESS || Status == STATUS_PENDING);
return; // Complete Asynchronously in IoCompletionRoutine*
}
VOID
DCamReadStream(
IN PHW_STREAM_REQUEST_BLOCK Srb
)
/*++
Routine Description:
Called when an Read Data Srb request is received
Arguments:
Srb - Pointer to Stream request block
Return Value:
Nothing
--*/
{
PIRB pIrb;
PIRP pIrp;
KIRQL oldIrql;
PDCAM_EXTENSION pDevExt;
PSTREAMEX pStrmEx;
PISOCH_DESCRIPTOR IsochDescriptor;
PISOCH_DESCRIPTOR_RESERVED IsochDescriptorReserved;
NTSTATUS StatusWait;
pIrb = (PIRB) Srb->SRBExtension;
pDevExt = (PDCAM_EXTENSION) Srb->HwDeviceExtension;
ASSERT(pDevExt != NULL);
pStrmEx = (PSTREAMEX) pDevExt->pStrmEx;
ASSERT(pStrmEx);
if(pDevExt->bDevRemoved ||
pStrmEx == NULL) {
Srb->Status = pDevExt->bDevRemoved ? STATUS_DEVICE_REMOVED : STATUS_UNSUCCESSFUL;
Srb->ActualBytesTransferred = 0;
Srb->CommandData.DataBufferArray->DataUsed = 0;
ERROR_LOG(("DCamReadStream: Failed with Status %x or pStrmEx %x\n", Srb->Status, pStrmEx));
StreamClassStreamNotification(StreamRequestComplete, Srb->StreamObject, Srb);
return;
}
//
// Mutext for either StreamIo (SRB_READ) ControlIo (SRB_SET_STREAM_STATE)
//
// Non-alertable; wait infinite
StatusWait = KeWaitForSingleObject( &pStrmEx->hMutex, Executive, KernelMode, FALSE, 0 );
ASSERT(StatusWait == STATUS_SUCCESS);
DbgMsg3(("\'%d:%s) DCamReadStream: enter with Srb %x, DevExt %x\n",
pDevExt->idxDev, pDevExt->pchVendorName, Srb, pDevExt));
// Rule:
// Only accept read requests when in either the Pause or Run
// States. If Stopped, immediately return the SRB.
if (pStrmEx->KSState == KSSTATE_STOP ||
pStrmEx->KSState == KSSTATE_ACQUIRE) {
DbgMsg2(("\'%d:%s)DCamReadStream: Current KSState(%d) < (%d)=KSSTATE_PAUSE; Srb=0x%x; DevExt=0x%x",
pDevExt->idxDev, pDevExt->pchVendorName, pStrmEx->KSState, KSSTATE_PAUSE, Srb, pDevExt));
DbgMsg2(("\'DCamReadStream: PendingRead=%d, IsochDescriptorList(%s)\n",
pDevExt->PendingReadCount, IsListEmpty(&pDevExt->IsochDescriptorList)?"Empty":"!Empty"));
Srb->Status = STATUS_UNSUCCESSFUL;
Srb->CommandData.DataBufferArray->DataUsed = 0;
StreamClassStreamNotification(StreamRequestComplete, Srb->StreamObject, Srb);
KeReleaseMutex(&pStrmEx->hMutex, FALSE);
return;
}
// Buffer need to be big enough
if (IsochInfoTable[pStrmEx->idxIsochTable].CompletePictureSize > Srb->CommandData.DataBufferArray->FrameExtent) {
ASSERT(IsochInfoTable[pStrmEx->idxIsochTable].CompletePictureSize <= Srb->CommandData.DataBufferArray->FrameExtent);
Srb->Status = STATUS_INVALID_PARAMETER;
StreamClassStreamNotification(StreamRequestComplete, Srb->StreamObject, Srb);
KeReleaseMutex(&pStrmEx->hMutex, FALSE);
return;
}
//
// Use our own IRP
//
pIrp = IoAllocateIrp(pDevExt->BusDeviceObject->StackSize, FALSE);
if(!pIrp) {
ASSERT(pIrp);
Srb->Status = STATUS_INSUFFICIENT_RESOURCES;
return;
}
//
// This structure (IsochDescriptor) has (ULONG) DeviceReserved[8];
// Its first 4 ULONGs are used by IsochDescriptorReserved,
// The 6th (index[5]), is used to keep pIrp
// 7th (index[6]), is used to keep pIrb
//
IsochDescriptor = ExAllocatePoolWithTag(NonPagedPool, sizeof(ISOCH_DESCRIPTOR), 'macd');
if (!IsochDescriptor) {
ASSERT(FALSE);
Srb->Status = STATUS_INSUFFICIENT_RESOURCES;
StreamClassStreamNotification(StreamRequestComplete, Srb->StreamObject, Srb);
KeReleaseMutex(&pStrmEx->hMutex, FALSE);
return;
}
DbgMsg3(("\'DCamReadStream: IsochDescriptor = %x\n", IsochDescriptor));
IsochDescriptor->fulFlags = SYNCH_ON_SY;
DbgMsg3(("\'DCamReadStream: Incoming Mdl = %x\n", Srb->Irp->MdlAddress));
IsochDescriptor->Mdl = Srb->Irp->MdlAddress;
// Use size match what we originally requested in AllocateIsoch
IsochDescriptor->ulLength = IsochInfoTable[pStrmEx->idxIsochTable].CompletePictureSize;
IsochDescriptor->nMaxBytesPerFrame = IsochInfoTable[pStrmEx->idxIsochTable].QuadletPayloadPerPacket << 2;
IsochDescriptor->ulSynch = START_OF_PICTURE;
IsochDescriptor->ulTag = 0;
IsochDescriptor->Callback = DCamIsochCallback;
IsochDescriptor->Context1 = pDevExt;
IsochDescriptor->Context2 = IsochDescriptor;
//
// IsochDescriptorReserved is pointed to the DeviceReserved[0];
// The entire, except the links, are kept in the DeviceReserved[]
//
IsochDescriptorReserved = (PISOCH_DESCRIPTOR_RESERVED) &IsochDescriptor->DeviceReserved[0];
IsochDescriptorReserved->Srb = Srb;
IsochDescriptorReserved->Flags = 0;
IsochDescriptor->DeviceReserved[5] = (ULONG_PTR) pIrp;
IsochDescriptor->DeviceReserved[6] = (ULONG_PTR) pIrb;
#if DBG
//
// Put signatures and use these count to track if the IsochDescriptor
// has been attached or detached unexpectely.
//
// When attach, [4]++ (DCamReadStreamWorker(), DCamReSumbitPacketCR())
// detach, [7]++ (DCamIsochcallback(), DCamCancelPacketCR(), DCamResubmitPacket())
//
IsochDescriptor->DeviceReserved[4] = 0x12345678;
IsochDescriptor->DeviceReserved[7] = 0x87654321;
#endif
//
// Checking here to see if we have enuff resources to put this read
// down right away. Since we only allocated N amount of resources
// from the 1394 stack beneath us, we'll have to stay within that
// limit and do some of the throttling ourself.
//
KeAcquireSpinLock(&pDevExt->IsochWaitingLock, &oldIrql);
if (InterlockedIncrement(&pDevExt->PendingReadCount) > MAX_BUFFERS_SUPPLIED) {
//
// don't have enuff resources to do an attach buffers right now.
// we'll queue this request and pull it off later when another
// read completes.
//
DbgMsg2(("\'DCamReadStream: Queueing request - Read Count = %x\n", pDevExt->PendingReadCount));
InsertTailList(
&pDevExt->IsochWaitingList,
&IsochDescriptorReserved->DescriptorList
);
KeReleaseSpinLock(&pDevExt->IsochWaitingLock, oldIrql);
KeReleaseMutex(&pStrmEx->hMutex, FALSE);
return;
}
if(pStrmEx->KSState == KSSTATE_PAUSE) {
DbgMsg2(("\'DCamReadStream: Doing Pre-read in _PAUSE state; Srb %x, pDevExt %x, PendingCount %d\n",
Srb, pDevExt, pDevExt->PendingReadCount));
}
//
// Do actual read work here via our Read worker function
//
KeReleaseSpinLock(&pDevExt->IsochWaitingLock, oldIrql);
DCamReadStreamWorker(Srb, IsochDescriptor);
KeReleaseMutex(&pStrmEx->hMutex, FALSE);
}
VOID
DCamReceiveDataPacket(
IN PHW_STREAM_REQUEST_BLOCK Srb
)
/*++
Routine Description:
Called with video data packet commands
Arguments:
Srb - Pointer to Stream request block
Return Value:
Nothing
--*/
{
PAGED_CODE();
//
// determine the type of packet.
//
switch (Srb->Command) {
case SRB_READ_DATA:
DbgMsg3(("\'DCamReceiveDataPacket: SRB_READ_DATA\n"));
DCamReadStream(Srb);
// This request will be completed asynchronously...
break;
case SRB_WRITE_DATA:
DbgMsg3(("\'DCamReceiveDataPacket: SRB_WRITE_DATA, not used for digital camera.\n"));
ASSERT(FALSE);
default:
//
// invalid / unsupported command. Fail it as such
//
Srb->Status = STATUS_NOT_IMPLEMENTED;
StreamClassStreamNotification(StreamRequestComplete, Srb->StreamObject, Srb);
}
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -