/* Source: WDK/src_5239/kmdf/1394/isochapi.c, line 1178. */
void
t1394_IsochTimeout(
    PDEVICE_EXTENSION   DeviceExtension, /* added for SLAyer */
/*     IN PKDPC                Dpc, */
    /* IN */ PISOCH_DETACH_DATA   IsochDetachData/* , */
/*     IN PVOID                SystemArgument1, */
/*     IN PVOID                SystemArgument2 */
    )
{
/*     PDEVICE_EXTENSION   DeviceExtension; */

/*     UNREFERENCED_PARAMETER(Dpc); */
/*     UNREFERENCED_PARAMETER(SystemArgument1); */
/*     UNREFERENCED_PARAMETER(SystemArgument2); */

/*     ENTER("t1394_IsochTimeout"); */
/*     TRACE(TL_WARNING, ("Isoch Timeout!\n")); */

    //
    // ISSUE: the device extension we are referencing comes from the IsochDetachData
    // but it is possible this memory has been freed before we enter this function.
    // The only way to check is to validate against our DeviceExtension->IsochDetachList
    // but if the IsochDetachData has been freed then that won't be accessible
    //
/*     DeviceExtension = IsochDetachData->DeviceExtension; */
    if (DeviceExtension)
    {
        // make sure nobody else has already handled this request yet

		WdfSpinLockAcquire(DeviceExtension->IsochSpinLock);
        if (t1394_IsOnList(&IsochDetachData->IsochDetachList, &DeviceExtension->IsochDetachData))
        {
            RemoveEntryList(&IsochDetachData->IsochDetachList);

			WdfSpinLockRelease(DeviceExtension->IsochSpinLock);


/*             if(KeCancelTimer(&IsochDetachData->Timer)) */
            {

/*                 TRACE(TL_TRACE, ("IsochTimeout: IsochDetachData = 0x%x\n", IsochDetachData)); */
/*                 TRACE(TL_TRACE, ("IsochTimeout: IsochDetachData->Irp = 0x%x\n", IsochDetachData->Request)); */
/*                 TRACE(TL_TRACE, ("IsochTimeout: IsochDetachData->newIrp = 0x%x\n", IsochDetachData->newIrp)); */

                // need to save the status of the attach
                // we'll clean up in the same spot for success's and timeout's
/*                 IsochDetachData->AttachStatus = STATUS_TIMEOUT; */
                t1394_IsochCleanup(IsochDetachData);
            }
        }
        else
        {

			WdfSpinLockRelease(DeviceExtension->IsochSpinLock);

        }
    }

/*     EXIT("t1394_IsochTimeout", 0); */
} // t1394_IsochTimeout
int body() {
  __rho_1_ = nondet();
   if (__rho_1_>0) {

       // haven't stopped yet, lets do so
       ntStatus = t1394Diag_PnpStopDevice(DeviceObject, Irp);
   }

   ntStatus = IoSetDeviceInterfaceState();


   // lets free up any crom data structs we've allocated...
   keA = 1; keA = 0; KeAcquireSpinLock(lock3, Irql);

   __rho_2_ = nondet();
   k1 = __rho_2_;
   while (1) { 
     if (!(k1>0)) break;

     __rho_3_ = nondet();
       CromData = __rho_3_;

       // get struct off list
       k1--;

       // need to free up everything associated with this allocate...
       if (CromData>0)
       {
	   __rho_4_ = nondet();
           if (__rho_4_>0)
               ExFreePool0();

	   __rho_5_ = nondet();
           if (__rho_5_>0)
               IoFreeMdl();

           // we already checked CromData
           ExFreePool1(CromData);
       }
   }

   keR = 1; keR = 0; KeReleaseSpinLock(lock3, Irql);

   keA = 1; keA = 0; KeAcquireSpinLock(lock1, Irql);

   __rho_6_ = nondet();
   k2 = __rho_6_;
   while (1) {
     if (!(k2>0)) break;

     AsyncAddressData = nondet();

       // get struct off list
       AsyncAddressData = nondet();
       k2--;

       // need to free up everything associated with this allocate...

       __rho_7_ = nondet();
       if (__rho_7_>0)
           IoFreeMdl();

       __rho_8_ = nondet();
       if (__rho_8_>0)
           ExFreePool0();

       __rho_9_ = nondet();
       if (__rho_9_>0)
           ExFreePool0();

       if (AsyncAddressData>0)
           ExFreePool0();
   }

   keR = 1; keR = 0; KeReleaseSpinLock(lock1, Irql);

   // free up any attached isoch buffers
   while (TRUE) {

       keA = 1; keA = 0; KeAcquireSpinLock(lock4, Irql);

       __rho_10_ = nondet();
       k3 = __rho_10_;
       if (k3>0) {

	 IsochDetachData = nondet();
	 i = nondet();

           IsochDetachData = nondet();
           k3--;


           KeCancelTimer();
           keR = 1; keR = 0; KeReleaseSpinLock(lock4, Irql);


           t1394_IsochCleanup(IsochDetachData);
       }
       else {

           keR = 1; keR = 0; KeReleaseSpinLock(lock4, Irql);
           break;
       }
   }

   // remove any isoch resource data

   __rho_11_ = nondet();
   k4 = __rho_11_;
   while (TRUE) {

       keA = 1; keA = 0; KeAcquireSpinLock(lock5, Irql);
       if (k4>0) {

	 __rho_12_ = nondet();
           IsochResourceData = __rho_12_;
           k4--;

           keR = 1; keR = 0; KeReleaseSpinLock(lock5, Irql);


           if (IsochResourceData>0) {

	       pIrb = nondet();
               ResourceIrp = nondet();
               StackSize = nondet();
               ResourceIrp = IoAllocateIrp(StackSize, FALSE);

               if (ResourceIrp == 0) {

               }
               else {

                   pIrb = ExAllocatePool(NonPagedPool, 0);

                   if (pIrb<=0) {

                       IoFreeIrp(ResourceIrp);
                   }
                   else {

                       RtlZeroMemory (pIrb, 0);

                       ntStatus = t1394_SubmitIrpSynch(ResourceIrp, pIrb);


                       ExFreePool1(pIrb);
                       IoFreeIrp(ResourceIrp);
                   }
               }
           }
       }
       else {

           keR = 1; keR = 0; KeReleaseSpinLock(lock5, Irql);
           break;
       }
   }

   // get rid of any pending bus reset notify requests
   keA = 1; keA = 0; KeAcquireSpinLock(lock6, Irql);

   __rho_13_ = nondet();
   k5 = __rho_13_;
   while (1) {
     if (!(k5>0)) break;

       prevCancel = NULL;

       // get the irp off of the list
       BusResetIrp = nondet();
       k5--;


       // make this irp non-cancelable...
       prevCancel = IoSetCancelRoutine(NULL);


       // and complete it...
       IoCompleteRequest(IO_NO_INCREMENT);

       ExFreePool1(BusResetIrp);
   }

   keR = 1; keR = 0; KeReleaseSpinLock(lock6, Irql);

   // free up the symbolic link

  while(1) { dummy=dummy; } L_return: return 0;
} // t1394Diag_PnpRemoveDevice
int main() {
    if (__VERIFIER_nondet_int()) {

        // haven't stopped yet, lets do so
        ntStatus = t1394Diag_PnpStopDevice(DeviceObject, Irp);
    }

    ntStatus = IoSetDeviceInterfaceState();


    // lets free up any crom data structs we've allocated...
    KeAcquireSpinLock(&lock3, &Irql);

    k1 = __VERIFIER_nondet_int();
    while (k1>0) {

        CromData = __VERIFIER_nondet_int();

        // get struct off list
        k1--;

        // need to free up everything associated with this allocate...
        if (CromData)
        {
            if (__VERIFIER_nondet_int())
                ExFreePool0();

            if (__VERIFIER_nondet_int())
                IoFreeMdl();

            // we already checked CromData
            ExFreePool1(CromData);
        }
    }

    KeReleaseSpinLock(&lock3, Irql);

    KeAcquireSpinLock(&lock1, &Irql);

    k2 = __VERIFIER_nondet_int();
    while (k2>0) {

        AsyncAddressData = __VERIFIER_nondet_int();

        // get struct off list
        AsyncAddressData = __VERIFIER_nondet_int();
        k2--;

        // need to free up everything associated with this allocate...
        if (__VERIFIER_nondet_int())
            IoFreeMdl();

        if (__VERIFIER_nondet_int())
            ExFreePool0();

        if (__VERIFIER_nondet_int())
            ExFreePool0();

        if (AsyncAddressData)
            ExFreePool0();
    }

    KeReleaseSpinLock(&lock1, Irql);

    // free up any attached isoch buffers
    while (TRUE) {

        KeAcquireSpinLock(&lock4, &Irql);

        k3 = __VERIFIER_nondet_int();
        if (k3>0) {

            IsochDetachData = __VERIFIER_nondet_int();
            i = __VERIFIER_nondet_int();

            IsochDetachData = __VERIFIER_nondet_int();
            k3--;


            KeCancelTimer();
            KeReleaseSpinLock(&lock4, Irql);


            t1394_IsochCleanup(IsochDetachData);
        }
        else {

            KeReleaseSpinLock(&lock4, Irql);
            break;
        }
    }

    // remove any isoch resource data

    k4 = __VERIFIER_nondet_int();
    while (TRUE) {

        KeAcquireSpinLock(&lock5, &Irql);
        if (k4>0) {

            IsochResourceData = __VERIFIER_nondet_int();
            k4--;

            KeReleaseSpinLock(&lock5, Irql);


            if (IsochResourceData) {

                pIrb = __VERIFIER_nondet_int();
                ResourceIrp = __VERIFIER_nondet_int();
                StackSize = __VERIFIER_nondet_int();
                ResourceIrp = IoAllocateIrp(StackSize, FALSE);

                if (ResourceIrp == NULL) {

                }
                else {

                    pIrb = ExAllocatePool(NonPagedPool, sizeof(IRB));

                    if (!pIrb) {

                        IoFreeIrp(ResourceIrp);
                    }
                    else {

                        RtlZeroMemory (pIrb, sizeof (IRB));

                        ntStatus = t1394_SubmitIrpSynch(ResourceIrp, pIrb);


                        ExFreePool1(pIrb);
                        IoFreeIrp(ResourceIrp);
                    }
                }
            }
        }
        else {

            KeReleaseSpinLock(&lock5, Irql);
            break;
        }
    }

    // get rid of any pending bus reset notify requests
    KeAcquireSpinLock(&lock6, &Irql);

    k5 = __VERIFIER_nondet_int();
    while (k5>0) {

        prevCancel = NULL;

        // get the irp off of the list
        BusResetIrp = __VERIFIER_nondet_int();
        k5--;


        // make this irp non-cancelable...
        prevCancel = IoSetCancelRoutine(NULL);


        // and complete it...
        IoCompleteRequest(IO_NO_INCREMENT);

        ExFreePool1(BusResetIrp);
    }

    KeReleaseSpinLock(&lock6, Irql);

    // free up the symbolic link
    if(ntStatus != STATUS_SUCCESS) {
        phi_nSUC_ret = 1;
    }
    while(1) {}
}