/*++

    Copyright (c) Microsoft Corporation.  All rights reserved.

Rule Name:

    StorPortSpinLock

Domain:

    storport

Rule ID:

    Not Applicable

Description:

    This rule verifies that locks acquired via StorPortAcquireSpinLock
    are promptly released via StorPortReleaseSpinLock. The miniport driver fails the rule
    if it attempts to acquire a lock that it had already acquired,
    or if it attempts to release a lock that it had not acquired.
    In addition, at the end of the dispatch or cancel routine, 
    the driver should not hold any spin locks.    

Help Link:

    https://go.microsoft.com/fwlink/?LinkId=507241

--*/



#include "ntddk_slic.h"

state{
   enum {unlocked,locked} s = unlocked;
}

watch StorPortAcquireSpinLock.exit.$4;

StorPortAcquireSpinLock.exit[guard $4]
{  
        if (s == locked) {
            abort "The driver is calling $fname after already acquiring the spinlock.";
        } else {
            s = locked;
        }
}

StorPortReleaseSpinLock.entry[guard $2]
{
	if (s != locked) {
		abort "The driver is calling $fname without first acquiring the spinlock.";
	} else {
		s = unlocked;
	}
}

sdv_main.exit
{
	if (s == locked) {
		abort "The Storport callback routine has returned without releasing a spinlock.";
	}
}
