void cdc_ncm_intr_complete(struct urb *urb) { struct if_usb_devdata *pipe_data = urb->context; struct usb_link_device *usb_ld = pipe_data->usb_ld; int ret; mif_debug("status = %d\n", urb->status); switch (urb->status) { /* success */ case -ENOENT: /* urb killed by L2 suspend */ case 0: usb_ld->rx_cnt++; if (urb->actual_length) { mif_info("ep=%d\n", usb_pipeendpoint(urb->pipe)); pr_urb(__func__, urb); } cdc_ncm_status(pipe_data, urb); break; case -ESHUTDOWN: /* hardware gone */ mif_err("intr shutdown, code %d\n", urb->status); return; /* NOTE: not throttling like RX/TX, since this endpoint * already polls infrequently */ default: mif_err("intr status %d\n", urb->status); break; } if (!urb->status) { /*skip -ENOENT L2 enter status */ memset(urb->transfer_buffer, 0, urb->transfer_buffer_length); ret = usb_submit_urb(urb, GFP_ATOMIC); mif_debug("status: usb_submit_urb ret=%d\n", ret); if (ret != 0) mif_err("intr resubmit --> %d\n", ret); } }
NTSTATUS InterruptPipeCompletion( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context ) /*++ Routine Description: Completion routine for the read request. This routine indicates the received packet from the WDM driver to NDIS. This routine also handles the case where another thread has canceled the read request. Arguments: DeviceObject - not used. Should be NULL Irp - Pointer to our read IRP Context - pointer to our adapter context structure Return Value: STATUS_MORE_PROCESSING_REQUIRED - because this is an asynchronouse IRP and we want to reuse it. --*/ { PNOTICB pNotiCB = (PNOTICB)Context; PMP_ADAPTER Adapter = pNotiCB->Adapter; ULONG bytesRead = 0; UNREFERENCED_PARAMETER(DeviceObject); DEBUGP(MP_TRACE, ("--> InterruptPipeCompletion\n")); if(!NT_SUCCESS(Irp->IoStatus.Status)) { Adapter->nReadsCompletedWithError++; DEBUGP (MP_LOUD, ("Read request failed %x\n", Irp->IoStatus.Status)); // // Clear the flag to prevent any more reads from being // posted to the target device. // MP_CLEAR_FLAG(Adapter, fMP_POST_INTERRUPT); } else { bytesRead = (ULONG)pNotiCB->Urb->UrbBulkOrInterruptTransfer.TransferBufferLength; DEBUGP (MP_VERY_LOUD, ("Read %d bytes\n", bytesRead)); pNotiCB->ulSize=bytesRead; } if (InterlockedExchange((PVOID)&pNotiCB->IrpLock, IRPLOCK_COMPLETED) == IRPLOCK_CANCEL_STARTED) { // // NICFreeBusyRecvPackets has got the control of the IRP. It will // now take the responsibility of freeing the IRP. // Therefore... return STATUS_MORE_PROCESSING_REQUIRED; } if (NT_SUCCESS(Irp->IoStatus.Status)) { cdc_ncm_status(Adapter,pNotiCB->pData,pNotiCB->ulSize); } if(NdisInterlockedDecrement(&pNotiCB->Ref) == 0) { NICFreeNotify(pNotiCB); } DEBUGP(MP_TRACE, ("<-- InterruptPipeCompletion\n")); return STATUS_MORE_PROCESSING_REQUIRED; }