VOID STREAMAPI CompleteDeviceSRB ( IN PHW_STREAM_REQUEST_BLOCK pSrb ) { DbgLogTrace(("TestCap: Completing Adapter SRB %8x\n", pSrb)); StreamClassDeviceNotification( DeviceRequestComplete, pSrb->HwDeviceExtension, pSrb); }
VOID DCamSurpriseRemoval( IN PHW_STREAM_REQUEST_BLOCK pSrb ) /*++ Routine Description: Response to SRB_SURPRISE_REMOVAL. Arguments: pSrb - Pointer to the stream request block Return Value: None. --*/ { PIRP pIrp; PIRB pIrb; PDCAM_EXTENSION pDevExt; PSTREAMEX pStrmEx; NTSTATUS Status; PAGED_CODE(); pIrb = (PIRB) pSrb->SRBExtension; ASSERT(pIrb); pDevExt = (PDCAM_EXTENSION) pSrb->HwDeviceExtension; ASSERT(pDevExt); // // Set this to stop accepting incoming read. // pDevExt->bDevRemoved = TRUE; // // Wait until all pending work items are completed! // KeWaitForSingleObject( &pDevExt->PendingWorkItemEvent, Executive, KernelMode, FALSE, NULL ); // // Wait for currect read to be attached so we cancel them all. // pStrmEx = pDevExt->pStrmEx; if(pStrmEx) { // Make sure that this structure is still valid. if(pStrmEx->pVideoInfoHeader) { KeWaitForSingleObject( &pStrmEx->hMutex, Executive, KernelMode, FALSE, 0 ); KeReleaseMutex(&pStrmEx->hMutex, FALSE); } } pIrp = IoAllocateIrp(pDevExt->BusDeviceObject->StackSize, FALSE); if(!pIrp) { ERROR_LOG(("DCamSurpriseRemovalPacket: faile to get resource; pIrb=%p, pDevExt=%p, pIrp\n", pIrb, pDevExt)); pSrb->Status = STATUS_INSUFFICIENT_RESOURCES; StreamClassDeviceNotification(DeviceRequestComplete, pSrb->HwDeviceExtension, pSrb); return; } // // un-register a bus reset callback notification // pIrb->FunctionNumber = REQUEST_BUS_RESET_NOTIFICATION; pIrb->Flags = 0; pIrb->u.BusResetNotification.fulFlags = DEREGISTER_NOTIFICATION_ROUTINE; pIrb->u.BusResetNotification.ResetRoutine = (PBUS_BUS_RESET_NOTIFICATION) DCamBusResetNotification; pIrb->u.BusResetNotification.ResetContext = 0; Status = DCamSubmitIrpSynch(pDevExt, pIrp, pIrb); if(Status) { ERROR_LOG(("DCamSurpriseRemoval: Status %x while trying to deregister bus reset notification.\n", Status)); } if(pStrmEx && pStrmEx->pVideoInfoHeader) { // // Stop isoch transmission so we can detach buffers and cancel pending SRBs // pIrb->FunctionNumber = REQUEST_ISOCH_STOP; pIrb->Flags = 0; pIrb->u.IsochStop.hResource = pDevExt->hResource; pIrb->u.IsochStop.fulFlags = 0; Status = DCamSubmitIrpSynch(pDevExt, pIrp, pIrb); if(Status) { ERROR_LOG(("DCamSurpriseRemoval: Status %x while trying to ISOCH_STOP.\n", Status)); } IoFreeIrp(pIrp); if( InterlockedExchange((PLONG)&pStrmEx->CancelToken, 1 ) == 0 ) { DCamCancelAllPackets( pDevExt, &pDevExt->PendingReadCount ); } COMPLETE_SRB( pSrb ); } else { IoFreeIrp(pIrp); StreamClassDeviceNotification(DeviceRequestComplete, pSrb->HwDeviceExtension, pSrb); } }