Title: Proving that software doesnt hang
1 Proving that software doesnt hang
Byron Cook bycook_at_microsoft.com
Microsoft Research, Cambridge Joint work with
Josh Berdine, Dino Distefano, Alexey Gotsman,
Peter OHearn, Andreas Podelski, Andrey
Rybalchenko, and others
2Introduction
- Reactive systems
- Operating systems
- Medical systems
- Web servers clients
- Email servers clients
- etc...
3Introduction
- Reactive systems
- Operating systems
- Medical systems
- Web servers clients
- Email servers clients
- etc...
4Experimental results
Lines of code (x1000)
Cut-point set size
5Experimental results
Lines of code (x1000)
Cut-point set size
6Experimental results
Lines of code (x1000)
Cut-point set size
7Experimental results
Lines of code (x1000)
Cut-point set size
8Outline
- Introduction
- Proof rule for termination
- TERMINATOR
- MUTANT/TERMINATOR
- Conclusion Discussion
9Proof rule
Theorem A program is terminating if there exists
a finite set of well-founded relations T T1,
, Tm such that the transition relation of each
cyclic path segment ?n ?nm in the program is
included in one of the relations.
10Proof rule
Theorem A program is terminating if there exists
a finite set of well-founded relations T T1,
, Tm such that the transition relation of each
cyclic path segment ?n ?nm in the program is
included in one of the relations.
11Proof rule
BOOLEAN WriteCommandRegister( IN
PHW_DEVICE_EXTENSION DeviceExtension, IN
UCHAR AdapterCommand, IN BOOLEAN WaitForIdle
) / Routine Description Write
operation code to command register. Arguments
DeviceExtension - Pointer to adapter
extension AdapterCommand - Value to be
written to register WaitForIdle - Indicates
if the idle bit needs to be checked Return
Value TRUE if command sent. FALSE if
timed out waiting for adapter. --/
PBASE_REGISTER baseIoAddress DeviceExtension-gtBa
seIoAddress ULONG i UCHAR status
// // Wait up to 500 milliseconds for adapter
to be ready. // for (i0 ilt5000 i)
status ScsiPortReadPortUchar(baseIoA
ddress-gtStatusRegister) if ((status
IOP_COMMAND_DATA_OUT_FULL) (
WaitForIdle !(status IOP_SCSI_HBA_IDLE)))
// // Stall 100
microseconds before // trying again.
// ScsiPortStallExecution(
100) else //
// Adapter ready. Break out of loop.
// break if
(i5000) ScsiPortLogError(
DeviceExtension, NULL,
0, DeviceExtension-gtHostTargetId,
0, SP_INTERNAL_ADAPTER_ERROR,
(4 ltlt 8) status )
DebugPrint((1, "Aha154xWriteCommandRegister
Write command timed out\n")) return
FALSE ScsiPortWritePortUchar(baseIoAd
dress-gtCommandRegister, AdapterCommand)
return TRUE // end WriteCommandRegister()
UCHAR MapError( IN PVOID HwDeviceExtension,
IN PSCSI_REQUEST_BLOCK Srb, IN PCCB Ccb
) PHW_DEVICE_EXTENSION deviceExtension
HwDeviceExtension UCHAR status ULONG
logError ULONG residualBytes switch
(Ccb-gtHostStatus) case
CCB_SELECTION_TIMEOUT return
SRB_STATUS_SELECTION_TIMEOUT case
CCB_COMPLETE if (Ccb-gtTargetStatus
SCSISTAT_CHECK_CONDITION)
// // Update SRB with number of
bytes transferred. //
THREE_TO_FOUR((PFOUR_BYTE)residualBytes,
Ccb-gtDataLength)
if (Srb-gtDataTransferLen
gth lt residualBytes)
DebugPrint((0, residualBytes))
// // Seems to be a FW bug
in some revs. where //
residual comes back as a negative number, yet
the // request is
successful. //
Srb-gtDataTransferLength 0
Srb-gtSrbStatus SRB_STATUS_PHASE_SEQUENCE_FA
ILURE //
// Log the event and then the residual byte
count. //
ScsiPortLogError(HwDeviceExtension,
NULL,
0,
deviceExtension-gtHostTargetId,
0,
SP_PROTOCOL_ERROR,
0xc ltlt 8)
return(SRB_STATUS_PHASE_SEQUENCE_FAILURE)
else
Srb-gtDataTransferLength - residualBytes
return
SRB_STATUS_ERROR case
CCB_DATA_OVER_UNDER_RUN //
// Check for data underrun if using
scatter/gather // command with
residual bytes. // if
(deviceExtension-gtCcbScatterGatherCommand
SCATTER_GATHER_COMMAND)
THREE_TO_FOUR((PFOUR_BYTE)residualBytes,
Ccb-gtDataLength)
if (residualBytes)
Theorem A program is terminating if there exists
a finite set of well-founded relations T T1,
, Tm such that the transition relation of each
cyclic path segment ?n ?nm in the program is
included in one of the relations
ULONG AhaParseArgumentString( IN PCHAR
String, IN PCHAR KeyWord ) PCHAR
cptr PCHAR kptr ULONG value ULONG
stringLength 0 ULONG keyWordLength 0
ULONG index // // Calculate the string
length and lower case all characters. //
cptr String while (cptr)
cptr stringLength //
// Calculate the keyword length and lower case
all characters. // cptr KeyWord
while (cptr) cptr
keyWordLength if (keyWordLength gt
stringLength) // // Can't
possibly have a match. // return
0 // // Now setup and start the
compare. // cptr String ContinueSearch
// // The input string may start with
white space. Skip it. // while (cptr
' ' cptr '\t') cptr
if (cptr '\0') // // end
of string. // return 0
kptr KeyWord while (AhaToLower(cptr)
AhaToLower(kptr)) cptr
kptr if ((cptr - 1) '\0')
// // end of string
// return 0
cptr kptr if ((kptr - 1)
'\0') // // May have a match
backup and check for blank or equals.
// cptr-- while (cptr ' '
cptr '\t') cptr
// // Found a match. Make
sure there is an equals. // if
(cptr ! '') // //
Not a match so move to the next semicolon.
// while (cptr)
if (cptr '') goto
ContinueSearch
return 0 //
// Skip the equals sign. //
cptr // // Skip white space.
// while ((cptr ' ') (cptr
'\t')) cptr
if (cptr '\0') //
// Early end of string, return not found
// return 0 if
(cptr '') // //
This isn't it either. //
cptr goto ContinueSearch
value 0 if ((cptr '0')
(AhaToLower((cptr 1)) 'x'))
// // Value is in Hex. Skip the
"0x" // cptr 2
for (index 0 (cptr index) index)
if ((cptr index) ' '
(cptr index) '\t'
(cptr index) '')
break
if (((cptr index) gt '0') ((cptr
index) lt '9')) value (16
value) ((cptr index) - '0')
else if
((AhaToLower((cptr index)) gt 'a')
(AhaToLower((cptr index)) lt 'f'))
value (16 value)
AhaToLower(((cptr index)) - 'a' 10)
else //
// Syntax error, return
not found. //
return 0
else
// // Value is in Decimal.
// for (index 0 (cptr
index) index) if ((cptr
index) ' ' (cptr
index) '\t' (cptr
index) '') break
if (((cptr index)
gt '0') ((cptr index) lt '9'))
value (10 value) ((cptr index)
- '0') else
// // Syntax error return
not found. //
return 0
return value else
// // Not a match check for '' to
continue search. // while (cptr)
if (cptr '')
goto ContinueSearch
return 0
12Proof rule
BOOLEAN WriteCommandRegister( IN
PHW_DEVICE_EXTENSION DeviceExtension, IN
UCHAR AdapterCommand, IN BOOLEAN WaitForIdle
) / Routine Description Write
operation code to command register. Arguments
DeviceExtension - Pointer to adapter
extension AdapterCommand - Value to be
written to register WaitForIdle - Indicates
if the idle bit needs to be checked Return
Value TRUE if command sent. FALSE if
timed out waiting for adapter. --/
PBASE_REGISTER baseIoAddress DeviceExtension-gtBa
seIoAddress ULONG i UCHAR status
// // Wait up to 500 milliseconds for adapter
to be ready. // for (i0 ilt5000 i)
status ScsiPortReadPortUchar(baseIoA
ddress-gtStatusRegister) if ((status
IOP_COMMAND_DATA_OUT_FULL) (
WaitForIdle !(status IOP_SCSI_HBA_IDLE)))
// // Stall 100
microseconds before // trying again.
// ScsiPortStallExecution(
100) else //
// Adapter ready. Break out of loop.
// break if
(i5000) ScsiPortLogError(
DeviceExtension, NULL,
0, DeviceExtension-gtHostTargetId,
0, SP_INTERNAL_ADAPTER_ERROR,
(4 ltlt 8) status )
DebugPrint((1, "Aha154xWriteCommandRegister
Write command timed out\n")) return
FALSE ScsiPortWritePortUchar(baseIoAd
dress-gtCommandRegister, AdapterCommand)
return TRUE // end WriteCommandRegister()
UCHAR MapError( IN PVOID HwDeviceExtension,
IN PSCSI_REQUEST_BLOCK Srb, IN PCCB Ccb
) PHW_DEVICE_EXTENSION deviceExtension
HwDeviceExtension UCHAR status ULONG
logError ULONG residualBytes switch
(Ccb-gtHostStatus) case
CCB_SELECTION_TIMEOUT return
SRB_STATUS_SELECTION_TIMEOUT case
CCB_COMPLETE if (Ccb-gtTargetStatus
SCSISTAT_CHECK_CONDITION)
// // Update SRB with number of
bytes transferred. //
THREE_TO_FOUR((PFOUR_BYTE)residualBytes,
Ccb-gtDataLength)
if (Srb-gtDataTransferLen
gth lt residualBytes)
DebugPrint((0, residualBytes))
// // Seems to be a FW bug
in some revs. where //
residual comes back as a negative number, yet
the // request is
successful. //
Srb-gtDataTransferLength 0
Srb-gtSrbStatus SRB_STATUS_PHASE_SEQUENCE_FA
ILURE //
// Log the event and then the residual byte
count. //
ScsiPortLogError(HwDeviceExtension,
NULL,
0,
deviceExtension-gtHostTargetId,
0,
SP_PROTOCOL_ERROR,
0xc ltlt 8)
return(SRB_STATUS_PHASE_SEQUENCE_FAILURE)
else
Srb-gtDataTransferLength - residualBytes
return
SRB_STATUS_ERROR case
CCB_DATA_OVER_UNDER_RUN //
// Check for data underrun if using
scatter/gather // command with
residual bytes. // if
(deviceExtension-gtCcbScatterGatherCommand
SCATTER_GATHER_COMMAND)
THREE_TO_FOUR((PFOUR_BYTE)residualBytes,
Ccb-gtDataLength)
if (residualBytes)
Theorem A program is terminating if there exists
a finite set of well-founded relations T T1,
, Tm such that the transition relation of each
cyclic path segment??n ?nm in the program is
included in one of the relations
ULONG AhaParseArgumentString( IN PCHAR
String, IN PCHAR KeyWord ) PCHAR
cptr PCHAR kptr ULONG value ULONG
stringLength 0 ULONG keyWordLength 0
ULONG index // // Calculate the string
length and lower case all characters. //
cptr String while (cptr)
cptr stringLength //
// Calculate the keyword length and lower case
all characters. // cptr KeyWord
while (cptr) cptr
keyWordLength if (keyWordLength gt
stringLength) // // Can't
possibly have a match. // return
0 // // Now setup and start the
compare. // cptr String ContinueSearch
// // The input string may start with
white space. Skip it. // while (cptr
' ' cptr '\t') cptr
if (cptr '\0') // // end
of string. // return 0
kptr KeyWord while (AhaToLower(cptr)
AhaToLower(kptr)) cptr
kptr if ((cptr - 1) '\0')
// // end of string
// return 0
cptr kptr if ((kptr - 1)
'\0') // // May have a match
backup and check for blank or equals.
// cptr-- while (cptr ' '
cptr '\t') cptr
// // Found a match. Make
sure there is an equals. // if
(cptr ! '') // //
Not a match so move to the next semicolon.
// while (cptr)
if (cptr '') goto
ContinueSearch
return 0 //
// Skip the equals sign. //
cptr // // Skip white space.
// while ((cptr ' ') (cptr
'\t')) cptr
if (cptr '\0') //
// Early end of string, return not found
// return 0 if
(cptr '') // //
This isn't it either. //
cptr goto ContinueSearch
value 0 if ((cptr '0')
(AhaToLower((cptr 1)) 'x'))
// // Value is in Hex. Skip the
"0x" // cptr 2
for (index 0 (cptr index) index)
if ((cptr index) ' '
(cptr index) '\t'
(cptr index) '')
break
if (((cptr index) gt '0') ((cptr
index) lt '9')) value (16
value) ((cptr index) - '0')
else if
((AhaToLower((cptr index)) gt 'a')
(AhaToLower((cptr index)) lt 'f'))
value (16 value)
AhaToLower(((cptr index)) - 'a' 10)
else //
// Syntax error, return
not found. //
return 0
else
// // Value is in Decimal.
// for (index 0 (cptr
index) index) if ((cptr
index) ' ' (cptr
index) '\t' (cptr
index) '') break
if (((cptr index)
gt '0') ((cptr index) lt '9'))
value (10 value) ((cptr index)
- '0') else
// // Syntax error return
not found. //
return 0
return value else
// // Not a match check for '' to
continue search. // while (cptr)
if (cptr '')
goto ContinueSearch
return 0
13Proof rule
BOOLEAN WriteCommandRegister( IN
PHW_DEVICE_EXTENSION DeviceExtension, IN
UCHAR AdapterCommand, IN BOOLEAN WaitForIdle
) / Routine Description Write
operation code to command register. Arguments
DeviceExtension - Pointer to adapter
extension AdapterCommand - Value to be
written to register WaitForIdle - Indicates
if the idle bit needs to be checked Return
Value TRUE if command sent. FALSE if
timed out waiting for adapter. --/
PBASE_REGISTER baseIoAddress DeviceExtension-gtBa
seIoAddress ULONG i UCHAR status
// // Wait up to 500 milliseconds for adapter
to be ready. // for (i0 ilt5000 i)
status ScsiPortReadPortUchar(baseIoA
ddress-gtStatusRegister) if ((status
IOP_COMMAND_DATA_OUT_FULL) (
WaitForIdle !(status IOP_SCSI_HBA_IDLE)))
// // Stall 100
microseconds before // trying again.
// ScsiPortStallExecution(
100) else //
// Adapter ready. Break out of loop.
// break if
(i5000) ScsiPortLogError(
DeviceExtension, NULL,
0, DeviceExtension-gtHostTargetId,
0, SP_INTERNAL_ADAPTER_ERROR,
(4 ltlt 8) status )
DebugPrint((1, "Aha154xWriteCommandRegister
Write command timed out\n")) return
FALSE ScsiPortWritePortUchar(baseIoAd
dress-gtCommandRegister, AdapterCommand)
return TRUE // end WriteCommandRegister()
UCHAR MapError( IN PVOID HwDeviceExtension,
IN PSCSI_REQUEST_BLOCK Srb, IN PCCB Ccb
) PHW_DEVICE_EXTENSION deviceExtension
HwDeviceExtension UCHAR status ULONG
logError ULONG residualBytes switch
(Ccb-gtHostStatus) case
CCB_SELECTION_TIMEOUT return
SRB_STATUS_SELECTION_TIMEOUT case
CCB_COMPLETE if (Ccb-gtTargetStatus
SCSISTAT_CHECK_CONDITION)
// // Update SRB with number of
bytes transferred. //
THREE_TO_FOUR((PFOUR_BYTE)residualBytes,
Ccb-gtDataLength)
if (Srb-gtDataTransferLen
gth lt residualBytes)
DebugPrint((0, residualBytes))
// // Seems to be a FW bug
in some revs. where //
residual comes back as a negative number, yet
the // request is
successful. //
Srb-gtDataTransferLength 0
Srb-gtSrbStatus SRB_STATUS_PHASE_SEQUENCE_FA
ILURE //
// Log the event and then the residual byte
count. //
ScsiPortLogError(HwDeviceExtension,
NULL,
0,
deviceExtension-gtHostTargetId,
0,
SP_PROTOCOL_ERROR,
0xc ltlt 8)
return(SRB_STATUS_PHASE_SEQUENCE_FAILURE)
else
Srb-gtDataTransferLength - residualBytes
return
SRB_STATUS_ERROR case
CCB_DATA_OVER_UNDER_RUN //
// Check for data underrun if using
scatter/gather // command with
residual bytes. // if
(deviceExtension-gtCcbScatterGatherCommand
SCATTER_GATHER_COMMAND)
THREE_TO_FOUR((PFOUR_BYTE)residualBytes,
Ccb-gtDataLength)
if (residualBytes)
Theorem A program is terminating if there exists
a finite set of well-founded relations T T1,
, Tm such that the transition relation of each
cyclic path segment??n ?nm in the program is
included in one of the relations
ULONG AhaParseArgumentString( IN PCHAR
String, IN PCHAR KeyWord ) PCHAR
cptr PCHAR kptr ULONG value ULONG
stringLength 0 ULONG keyWordLength 0
ULONG index // // Calculate the string
length and lower case all characters. //
cptr String while (cptr)
cptr stringLength //
// Calculate the keyword length and lower case
all characters. // cptr KeyWord
while (cptr) cptr
keyWordLength if (keyWordLength gt
stringLength) // // Can't
possibly have a match. // return
0 // // Now setup and start the
compare. // cptr String ContinueSearch
// // The input string may start with
white space. Skip it. // while (cptr
' ' cptr '\t') cptr
if (cptr '\0') // // end
of string. // return 0
kptr KeyWord while (AhaToLower(cptr)
AhaToLower(kptr)) cptr
kptr if ((cptr - 1) '\0')
// // end of string
// return 0
cptr kptr if ((kptr - 1)
'\0') // // May have a match
backup and check for blank or equals.
// cptr-- while (cptr ' '
cptr '\t') cptr
// // Found a match. Make
sure there is an equals. // if
(cptr ! '') // //
Not a match so move to the next semicolon.
// while (cptr)
if (cptr '') goto
ContinueSearch
return 0 //
// Skip the equals sign. //
cptr // // Skip white space.
// while ((cptr ' ') (cptr
'\t')) cptr
if (cptr '\0') //
// Early end of string, return not found
// return 0 if
(cptr '') // //
This isn't it either. //
cptr goto ContinueSearch
value 0 if ((cptr '0')
(AhaToLower((cptr 1)) 'x'))
// // Value is in Hex. Skip the
"0x" // cptr 2
for (index 0 (cptr index) index)
if ((cptr index) ' '
(cptr index) '\t'
(cptr index) '')
break
if (((cptr index) gt '0') ((cptr
index) lt '9')) value (16
value) ((cptr index) - '0')
else if
((AhaToLower((cptr index)) gt 'a')
(AhaToLower((cptr index)) lt 'f'))
value (16 value)
AhaToLower(((cptr index)) - 'a' 10)
else //
// Syntax error, return
not found. //
return 0
else
// // Value is in Decimal.
// for (index 0 (cptr
index) index) if ((cptr
index) ' ' (cptr
index) '\t' (cptr
index) '') break
if (((cptr index)
gt '0') ((cptr index) lt '9'))
value (10 value) ((cptr index)
- '0') else
// // Syntax error return
not found. //
return 0
return value else
// // Not a match check for '' to
continue search. // while (cptr)
if (cptr '')
goto ContinueSearch
return 0
14Proof rule
BOOLEAN WriteCommandRegister( IN
PHW_DEVICE_EXTENSION DeviceExtension, IN
UCHAR AdapterCommand, IN BOOLEAN WaitForIdle
) / Routine Description Write
operation code to command register. Arguments
DeviceExtension - Pointer to adapter
extension AdapterCommand - Value to be
written to register WaitForIdle - Indicates
if the idle bit needs to be checked Return
Value TRUE if command sent. FALSE if
timed out waiting for adapter. --/
PBASE_REGISTER baseIoAddress DeviceExtension-gtBa
seIoAddress ULONG i UCHAR status
// // Wait up to 500 milliseconds for adapter
to be ready. // for (i0 ilt5000 i)
status ScsiPortReadPortUchar(baseIoA
ddress-gtStatusRegister) if ((status
IOP_COMMAND_DATA_OUT_FULL) (
WaitForIdle !(status IOP_SCSI_HBA_IDLE)))
// // Stall 100
microseconds before // trying again.
// ScsiPortStallExecution(
100) else //
// Adapter ready. Break out of loop.
// break if
(i5000) ScsiPortLogError(
DeviceExtension, NULL,
0, DeviceExtension-gtHostTargetId,
0, SP_INTERNAL_ADAPTER_ERROR,
(4 ltlt 8) status )
DebugPrint((1, "Aha154xWriteCommandRegister
Write command timed out\n")) return
FALSE ScsiPortWritePortUchar(baseIoAd
dress-gtCommandRegister, AdapterCommand)
return TRUE // end WriteCommandRegister()
UCHAR MapError( IN PVOID HwDeviceExtension,
IN PSCSI_REQUEST_BLOCK Srb, IN PCCB Ccb
) PHW_DEVICE_EXTENSION deviceExtension
HwDeviceExtension UCHAR status ULONG
logError ULONG residualBytes switch
(Ccb-gtHostStatus) case
CCB_SELECTION_TIMEOUT return
SRB_STATUS_SELECTION_TIMEOUT case
CCB_COMPLETE if (Ccb-gtTargetStatus
SCSISTAT_CHECK_CONDITION)
// // Update SRB with number of
bytes transferred. //
THREE_TO_FOUR((PFOUR_BYTE)residualBytes,
Ccb-gtDataLength)
if (Srb-gtDataTransferLen
gth lt residualBytes)
DebugPrint((0, residualBytes))
// // Seems to be a FW bug
in some revs. where //
residual comes back as a negative number, yet
the // request is
successful. //
Srb-gtDataTransferLength 0
Srb-gtSrbStatus SRB_STATUS_PHASE_SEQUENCE_FA
ILURE //
// Log the event and then the residual byte
count. //
ScsiPortLogError(HwDeviceExtension,
NULL,
0,
deviceExtension-gtHostTargetId,
0,
SP_PROTOCOL_ERROR,
0xc ltlt 8)
return(SRB_STATUS_PHASE_SEQUENCE_FAILURE)
else
Srb-gtDataTransferLength - residualBytes
return
SRB_STATUS_ERROR case
CCB_DATA_OVER_UNDER_RUN //
// Check for data underrun if using
scatter/gather // command with
residual bytes. // if
(deviceExtension-gtCcbScatterGatherCommand
SCATTER_GATHER_COMMAND)
THREE_TO_FOUR((PFOUR_BYTE)residualBytes,
Ccb-gtDataLength)
if (residualBytes)
Theorem A program is terminating if there exists
a finite set of well-founded relations T T1,
, Tm such that the transition relation of each
cyclic path segment??n ?nm in the program is
included in one of the relations
ULONG AhaParseArgumentString( IN PCHAR
String, IN PCHAR KeyWord ) PCHAR
cptr PCHAR kptr ULONG value ULONG
stringLength 0 ULONG keyWordLength 0
ULONG index // // Calculate the string
length and lower case all characters. //
cptr String while (cptr)
cptr stringLength //
// Calculate the keyword length and lower case
all characters. // cptr KeyWord
while (cptr) cptr
keyWordLength if (keyWordLength gt
stringLength) // // Can't
possibly have a match. // return
0 // // Now setup and start the
compare. // cptr String ContinueSearch
// // The input string may start with
white space. Skip it. // while (cptr
' ' cptr '\t') cptr
if (cptr '\0') // // end
of string. // return 0
kptr KeyWord while (AhaToLower(cptr)
AhaToLower(kptr)) cptr
kptr if ((cptr - 1) '\0')
// // end of string
// return 0
cptr kptr if ((kptr - 1)
'\0') // // May have a match
backup and check for blank or equals.
// cptr-- while (cptr ' '
cptr '\t') cptr
// // Found a match. Make
sure there is an equals. // if
(cptr ! '') // //
Not a match so move to the next semicolon.
// while (cptr)
if (cptr '') goto
ContinueSearch
return 0 //
// Skip the equals sign. //
cptr // // Skip white space.
// while ((cptr ' ') (cptr
'\t')) cptr
if (cptr '\0') //
// Early end of string, return not found
// return 0 if
(cptr '') // //
This isn't it either. //
cptr goto ContinueSearch
value 0 if ((cptr '0')
(AhaToLower((cptr 1)) 'x'))
// // Value is in Hex. Skip the
"0x" // cptr 2
for (index 0 (cptr index) index)
if ((cptr index) ' '
(cptr index) '\t'
(cptr index) '')
break
if (((cptr index) gt '0') ((cptr
index) lt '9')) value (16
value) ((cptr index) - '0')
else if
((AhaToLower((cptr index)) gt 'a')
(AhaToLower((cptr index)) lt 'f'))
value (16 value)
AhaToLower(((cptr index)) - 'a' 10)
else //
// Syntax error, return
not found. //
return 0
else
// // Value is in Decimal.
// for (index 0 (cptr
index) index) if ((cptr
index) ' ' (cptr
index) '\t' (cptr
index) '') break
if (((cptr index)
gt '0') ((cptr index) lt '9'))
value (10 value) ((cptr index)
- '0') else
// // Syntax error return
not found. //
return 0
return value else
// // Not a match check for '' to
continue search. // while (cptr)
if (cptr '')
goto ContinueSearch
return 0
15Proof rule
BOOLEAN WriteCommandRegister( IN
PHW_DEVICE_EXTENSION DeviceExtension, IN
UCHAR AdapterCommand, IN BOOLEAN WaitForIdle
) / Routine Description Write
operation code to command register. Arguments
DeviceExtension - Pointer to adapter
extension AdapterCommand - Value to be
written to register WaitForIdle - Indicates
if the idle bit needs to be checked Return
Value TRUE if command sent. FALSE if
timed out waiting for adapter. --/
PBASE_REGISTER baseIoAddress DeviceExtension-gtBa
seIoAddress ULONG i UCHAR status
// // Wait up to 500 milliseconds for adapter
to be ready. // for (i0 ilt5000 i)
status ScsiPortReadPortUchar(baseIoA
ddress-gtStatusRegister) if ((status
IOP_COMMAND_DATA_OUT_FULL) (
WaitForIdle !(status IOP_SCSI_HBA_IDLE)))
// // Stall 100
microseconds before // trying again.
// ScsiPortStallExecution(
100) else //
// Adapter ready. Break out of loop.
// break if
(i5000) ScsiPortLogError(
DeviceExtension, NULL,
0, DeviceExtension-gtHostTargetId,
0, SP_INTERNAL_ADAPTER_ERROR,
(4 ltlt 8) status )
DebugPrint((1, "Aha154xWriteCommandRegister
Write command timed out\n")) return
FALSE ScsiPortWritePortUchar(baseIoAd
dress-gtCommandRegister, AdapterCommand)
return TRUE // end WriteCommandRegister()
UCHAR MapError( IN PVOID HwDeviceExtension,
IN PSCSI_REQUEST_BLOCK Srb, IN PCCB Ccb
) PHW_DEVICE_EXTENSION deviceExtension
HwDeviceExtension UCHAR status ULONG
logError ULONG residualBytes switch
(Ccb-gtHostStatus) case
CCB_SELECTION_TIMEOUT return
SRB_STATUS_SELECTION_TIMEOUT case
CCB_COMPLETE if (Ccb-gtTargetStatus
SCSISTAT_CHECK_CONDITION)
// // Update SRB with number of
bytes transferred. //
THREE_TO_FOUR((PFOUR_BYTE)residualBytes,
Ccb-gtDataLength)
if (Srb-gtDataTransferLen
gth lt residualBytes)
DebugPrint((0, residualBytes))
// // Seems to be a FW bug
in some revs. where //
residual comes back as a negative number, yet
the // request is
successful. //
Srb-gtDataTransferLength 0
Srb-gtSrbStatus SRB_STATUS_PHASE_SEQUENCE_FA
ILURE //
// Log the event and then the residual byte
count. //
ScsiPortLogError(HwDeviceExtension,
NULL,
0,
deviceExtension-gtHostTargetId,
0,
SP_PROTOCOL_ERROR,
0xc ltlt 8)
return(SRB_STATUS_PHASE_SEQUENCE_FAILURE)
else
Srb-gtDataTransferLength - residualBytes
return
SRB_STATUS_ERROR case
CCB_DATA_OVER_UNDER_RUN //
// Check for data underrun if using
scatter/gather // command with
residual bytes. // if
(deviceExtension-gtCcbScatterGatherCommand
SCATTER_GATHER_COMMAND)
THREE_TO_FOUR((PFOUR_BYTE)residualBytes,
Ccb-gtDataLength)
if (residualBytes)
Theorem A program is terminating if there exists
a finite set of well-founded relations T T1,
, Tm such that the transition relation of each
cyclic path segment??n ?nm in the program is
included in one of the relations
ULONG AhaParseArgumentString( IN PCHAR
String, IN PCHAR KeyWord ) PCHAR
cptr PCHAR kptr ULONG value ULONG
stringLength 0 ULONG keyWordLength 0
ULONG index // // Calculate the string
length and lower case all characters. //
cptr String while (cptr)
cptr stringLength //
// Calculate the keyword length and lower case
all characters. // cptr KeyWord
while (cptr) cptr
keyWordLength if (keyWordLength gt
stringLength) // // Can't
possibly have a match. // return
0 // // Now setup and start the
compare. // cptr String ContinueSearch
// // The input string may start with
white space. Skip it. // while (cptr
' ' cptr '\t') cptr
if (cptr '\0') // // end
of string. // return 0
kptr KeyWord while (AhaToLower(cptr)
AhaToLower(kptr)) cptr
kptr if ((cptr - 1) '\0')
// // end of string
// return 0
cptr kptr if ((kptr - 1)
'\0') // // May have a match
backup and check for blank or equals.
// cptr-- while (cptr ' '
cptr '\t') cptr
// // Found a match. Make
sure there is an equals. // if
(cptr ! '') // //
Not a match so move to the next semicolon.
// while (cptr)
if (cptr '') goto
ContinueSearch
return 0 //
// Skip the equals sign. //
cptr // // Skip white space.
// while ((cptr ' ') (cptr
'\t')) cptr
if (cptr '\0') //
// Early end of string, return not found
// return 0 if
(cptr '') // //
This isn't it either. //
cptr goto ContinueSearch
value 0 if ((cptr '0')
(AhaToLower((cptr 1)) 'x'))
// // Value is in Hex. Skip the
"0x" // cptr 2
for (index 0 (cptr index) index)
if ((cptr index) ' '
(cptr index) '\t'
(cptr index) '')
break
if (((cptr index) gt '0') ((cptr
index) lt '9')) value (16
value) ((cptr index) - '0')
else if
((AhaToLower((cptr index)) gt 'a')
(AhaToLower((cptr index)) lt 'f'))
value (16 value)
AhaToLower(((cptr index)) - 'a' 10)
else //
// Syntax error, return
not found. //
return 0
else
// // Value is in Decimal.
// for (index 0 (cptr
index) index) if ((cptr
index) ' ' (cptr
index) '\t' (cptr
index) '') break
if (((cptr index)
gt '0') ((cptr index) lt '9'))
value (10 value) ((cptr index)
- '0') else
// // Syntax error return
not found. //
return 0
return value else
// // Not a match check for '' to
continue search. // while (cptr)
if (cptr '')
goto ContinueSearch
return 0
16Proof rule
BOOLEAN WriteCommandRegister( IN
PHW_DEVICE_EXTENSION DeviceExtension, IN
UCHAR AdapterCommand, IN BOOLEAN WaitForIdle
) / Routine Description Write
operation code to command register. Arguments
DeviceExtension - Pointer to adapter
extension AdapterCommand - Value to be
written to register WaitForIdle - Indicates
if the idle bit needs to be checked Return
Value TRUE if command sent. FALSE if
timed out waiting for adapter. --/
PBASE_REGISTER baseIoAddress DeviceExtension-gtBa
seIoAddress ULONG i UCHAR status
// // Wait up to 500 milliseconds for adapter
to be ready. // for (i0 ilt5000 i)
status ScsiPortReadPortUchar(baseIoA
ddress-gtStatusRegister) if ((status
IOP_COMMAND_DATA_OUT_FULL) (
WaitForIdle !(status IOP_SCSI_HBA_IDLE)))
// // Stall 100
microseconds before // trying again.
// ScsiPortStallExecution(
100) else //
// Adapter ready. Break out of loop.
// break if
(i5000) ScsiPortLogError(
DeviceExtension, NULL,
0, DeviceExtension-gtHostTargetId,
0, SP_INTERNAL_ADAPTER_ERROR,
(4 ltlt 8) status )
DebugPrint((1, "Aha154xWriteCommandRegister
Write command timed out\n")) return
FALSE ScsiPortWritePortUchar(baseIoAd
dress-gtCommandRegister, AdapterCommand)
return TRUE // end WriteCommandRegister()
UCHAR MapError( IN PVOID HwDeviceExtension,
IN PSCSI_REQUEST_BLOCK Srb, IN PCCB Ccb
) PHW_DEVICE_EXTENSION deviceExtension
HwDeviceExtension UCHAR status ULONG
logError ULONG residualBytes switch
(Ccb-gtHostStatus) case
CCB_SELECTION_TIMEOUT return
SRB_STATUS_SELECTION_TIMEOUT case
CCB_COMPLETE if (Ccb-gtTargetStatus
SCSISTAT_CHECK_CONDITION)
// // Update SRB with number of
bytes transferred. //
THREE_TO_FOUR((PFOUR_BYTE)residualBytes,
Ccb-gtDataLength)
if (Srb-gtDataTransferLen
gth lt residualBytes)
DebugPrint((0, residualBytes))
// // Seems to be a FW bug
in some revs. where //
residual comes back as a negative number, yet
the // request is
successful. //
Srb-gtDataTransferLength 0
Srb-gtSrbStatus SRB_STATUS_PHASE_SEQUENCE_FA
ILURE //
// Log the event and then the residual byte
count. //
ScsiPortLogError(HwDeviceExtension,
NULL,
0,
deviceExtension-gtHostTargetId,
0,
SP_PROTOCOL_ERROR,
0xc ltlt 8)
return(SRB_STATUS_PHASE_SEQUENCE_FAILURE)
else
Srb-gtDataTransferLength - residualBytes
return
SRB_STATUS_ERROR case
CCB_DATA_OVER_UNDER_RUN //
// Check for data underrun if using
scatter/gather // command with
residual bytes. // if
(deviceExtension-gtCcbScatterGatherCommand
SCATTER_GATHER_COMMAND)
THREE_TO_FOUR((PFOUR_BYTE)residualBytes,
Ccb-gtDataLength)
if (residualBytes)
Theorem A program is terminating if there exists
a finite set of well-founded relations T T1,
, Tm such that the transition relation of each
cyclic path segment??n ?nm in the program is
included in one of the relations
ULONG AhaParseArgumentString( IN PCHAR
String, IN PCHAR KeyWord ) PCHAR
cptr PCHAR kptr ULONG value ULONG
stringLength 0 ULONG keyWordLength 0
ULONG index // // Calculate the string
length and lower case all characters. //
cptr String while (cptr)
cptr stringLength //
// Calculate the keyword length and lower case
all characters. // cptr KeyWord
while (cptr) cptr
keyWordLength if (keyWordLength gt
stringLength) // // Can't
possibly have a match. // return
0 // // Now setup and start the
compare. // cptr String ContinueSearch
// // The input string may start with
white space. Skip it. // while (cptr
' ' cptr '\t') cptr
if (cptr '\0') // // end
of string. // return 0
kptr KeyWord while (AhaToLower(cptr)
AhaToLower(kptr)) cptr
kptr if ((cptr - 1) '\0')
// // end of string
// return 0
cptr kptr if ((kptr - 1)
'\0') // // May have a match
backup and check for blank or equals.
// cptr-- while (cptr ' '
cptr '\t') cptr
// // Found a match. Make
sure there is an equals. // if
(cptr ! '') // //
Not a match so move to the next semicolon.
// while (cptr)
if (cptr '') goto
ContinueSearch
return 0 //
// Skip the equals sign. //
cptr // // Skip white space.
// while ((cptr ' ') (cptr
'\t')) cptr
if (cptr '\0') //
// Early end of string, return not found
// return 0 if
(cptr '') // //
This isn't it either. //
cptr goto ContinueSearch
value 0 if ((cptr '0')
(AhaToLower((cptr 1)) 'x'))
// // Value is in Hex. Skip the
"0x" // cptr 2
for (index 0 (cptr index) index)
if ((cptr index) ' '
(cptr index) '\t'
(cptr index) '')
break
if (((cptr index) gt '0') ((cptr
index) lt '9')) value (16
value) ((cptr index) - '0')
else if
((AhaToLower((cptr index)) gt 'a')
(AhaToLower((cptr index)) lt 'f'))
value (16 value)
AhaToLower(((cptr index)) - 'a' 10)
else //
// Syntax error, return
not found. //
return 0
else
// // Value is in Decimal.
// for (index 0 (cptr
index) index) if ((cptr
index) ' ' (cptr
index) '\t' (cptr
index) '') break
if (((cptr index)
gt '0') ((cptr index) lt '9'))
value (10 value) ((cptr index)
- '0') else
// // Syntax error return
not found. //
return 0
return value else
// // Not a match check for '' to
continue search. // while (cptr)
if (cptr '')
goto ContinueSearch
return 0
17Proof rule
BOOLEAN WriteCommandRegister( IN
PHW_DEVICE_EXTENSION DeviceExtension, IN
UCHAR AdapterCommand, IN BOOLEAN WaitForIdle
) / Routine Description Write
operation code to command register. Arguments
DeviceExtension - Pointer to adapter
extension AdapterCommand - Value to be
written to register WaitForIdle - Indicates
if the idle bit needs to be checked Return
Value TRUE if command sent. FALSE if
timed out waiting for adapter. --/
PBASE_REGISTER baseIoAddress DeviceExtension-gtBa
seIoAddress ULONG i UCHAR status
// // Wait up to 500 milliseconds for adapter
to be ready. // for (i0 ilt5000 i)
status ScsiPortReadPortUchar(baseIoA
ddress-gtStatusRegister) if ((status
IOP_COMMAND_DATA_OUT_FULL) (
WaitForIdle !(status IOP_SCSI_HBA_IDLE)))
// // Stall 100
microseconds before // trying again.
// ScsiPortStallExecution(
100) else //
// Adapter ready. Break out of loop.
// break if
(i5000) ScsiPortLogError(
DeviceExtension, NULL,
0, DeviceExtension-gtHostTargetId,
0, SP_INTERNAL_ADAPTER_ERROR,
(4 ltlt 8) status )
DebugPrint((1, "Aha154xWriteCommandRegister
Write command timed out\n")) return
FALSE ScsiPortWritePortUchar(baseIoAd
dress-gtCommandRegister, AdapterCommand)
return TRUE // end WriteCommandRegister()
UCHAR MapError( IN PVOID HwDeviceExtension,
IN PSCSI_REQUEST_BLOCK Srb, IN PCCB Ccb
) PHW_DEVICE_EXTENSION deviceExtension
HwDeviceExtension UCHAR status ULONG
logError ULONG residualBytes switch
(Ccb-gtHostStatus) case
CCB_SELECTION_TIMEOUT return
SRB_STATUS_SELECTION_TIMEOUT case
CCB_COMPLETE if (Ccb-gtTargetStatus
SCSISTAT_CHECK_CONDITION)
// // Update SRB with number of
bytes transferred. //
THREE_TO_FOUR((PFOUR_BYTE)residualBytes,
Ccb-gtDataLength)
if (Srb-gtDataTransferLen
gth lt residualBytes)
DebugPrint((0, residualBytes))
// // Seems to be a FW bug
in some revs. where //
residual comes back as a negative number, yet
the // request is
successful. //
Srb-gtDataTransferLength 0
Srb-gtSrbStatus SRB_STATUS_PHASE_SEQUENCE_FA
ILURE //
// Log the event and then the residual byte
count. //
ScsiPortLogError(HwDeviceExtension,
NULL,
0,
deviceExtension-gtHostTargetId,
0,
SP_PROTOCOL_ERROR,
0xc ltlt 8)
return(SRB_STATUS_PHASE_SEQUENCE_FAILURE)
else
Srb-gtDataTransferLength - residualBytes
return
SRB_STATUS_ERROR case
CCB_DATA_OVER_UNDER_RUN //
// Check for data underrun if using
scatter/gather // command with
residual bytes. // if
(deviceExtension-gtCcbScatterGatherCommand
SCATTER_GATHER_COMMAND)
THREE_TO_FOUR((PFOUR_BYTE)residualBytes,
Ccb-gtDataLength)
if (residualBytes)
Theorem A program is terminating if there exists
a finite set of well-founded relations T T1,
, Tm such that the transition relation of each
cyclic path segment??n ?nm in the program is
included in one of the relations
ULONG AhaParseArgumentString( IN PCHAR
String, IN PCHAR KeyWord ) PCHAR
cptr PCHAR kptr ULONG value ULONG
stringLength 0 ULONG keyWordLength 0
ULONG index // // Calculate the string
length and lower case all characters. //
cptr String while (cptr)
cptr stringLength //
// Calculate the keyword length and lower case
all characters. // cptr KeyWord
while (cptr) cptr
keyWordLength if (keyWordLength gt
stringLength) // // Can't
possibly have a match. // return
0 // // Now setup and start the
compare. // cptr String ContinueSearch
// // The input string may start with
white space. Skip it. // while (cptr
' ' cptr '\t') cptr
if (cptr '\0') // // end
of string. // return 0
kptr KeyWord while (AhaToLower(cptr)
AhaToLower(kptr)) cptr
kptr if ((cptr - 1) '\0')
// // end of string
// return 0
cptr kptr if ((kptr - 1)
'\0') // // May have a match
backup and check for blank or equals.
// cptr-- while (cptr ' '
cptr '\t') cptr
// // Found a match. Make
sure there is an equals. // if
(cptr ! '') // //
Not a match so move to the next semicolon.
// while (cptr)
if (cptr '') goto
ContinueSearch
return 0 //
// Skip the equals sign. //
cptr // // Skip white space.
// while ((cptr ' ') (cptr
'\t')) cptr
if (cptr '\0') //
// Early end of string, return not found
// return 0 if
(cptr '') // //
This isn't it either. //
cptr goto ContinueSearch
value 0 if ((cptr '0')
(AhaToLower((cptr 1)) 'x'))
// // Value is in Hex. Skip the
"0x" // cptr 2
for (index 0 (cptr index) index)
if ((cptr index) ' '
(cptr index) '\t'
(cptr index) '')
break
if (((cptr index) gt '0') ((cptr
index) lt '9')) value (16
value) ((cptr index) - '0')
else if
((AhaToLower((cptr index)) gt 'a')
(Ah