skip book previous and next navigation links
go up to top of book: HP OpenVMS Alpha Version 7.3-2 New Features and... HP OpenVMS Alpha Version 7.3-2 New Features and...
go to beginning of part: OpenVMS Alpha Version 7.3-2 New Features OpenVMS Alpha Version 7.3-2 New Features
go to beginning of chapter: Programming Features Programming Features
go to previous page: C Run-Time Library Enhancements C Run-Time Library Enhancements
go to next page: HP DECdtm Version 2.1HP DECdtm Version 2.1
end of book navigation links

DDT Intercept Establisher Routines and Device Configuration Notification Routines 



OpenVMS Alpha Version 7.3-2 introduces new routines for use in OpenVMS applications that are developed by third-party application providers. These new routines are designed for establishing driver dispatch table (DDT) intercepts of OpenVMS device drivers and for providing notification of device configuration by way of a callback. These routines can be used by any privileged kernel-mode application that alters the DDT. The routines provide a new method for intercepting calls into the driver by way of DDT entry points so that multiple intercepts work correctly. Note that the routines for providing notification of device configuration (and for revoking notification) are not limited to use with the DDT intercept establisher routines.

These routines, when used in third-party kernel-mode applications such as disk caching products and SCSI disk-shadowing applications, enable these applications to run in an OpenVMS SCSI or Fibre Channel multipath configuration. Any third-party applications that rely on altering the DDT of the OpenVMS Alpha SCSI disk-class driver (SYS$DKDRIVER.EXE), the SCSI tape-class driver (SYS$MKDRIVER), or the SCSI generic-class driver (SYS$GKDRIVER) will require source changes to use these new routines.

If you are using a third-party disk-caching product or disk-shadowing application, avoid using it in an OpenVMS SCSI or Fibre Channel multipath configuration until you confirm that the application has been revised to use these new routines.

These new routines provide a solution to a problem that developed after the introduction of SCSI and Fibre Channel multipath support in OpenVMS Alpha Version 7.2-1. Customer were advised to avoid using these third-party SCSI disk-caching and disk-shadowing applications when their SCSI devices were configured for multipath failover. The new routines enable providers of third-party application providers to modify their applications so that they function correctly.

DDT Intercept Establisher Routines 

New routines establish the DDT intercepts. Third-party applications that modified the DDT directly can be modified to use the appropriate establisher routines, so that they function properly in an OpenVMS SCSI or Fibre Channel configuration. These routines establish intercepts on a per-UCB basis.

At a given entry point, there can be multiple declarations of DDT intercepts. The following figure illustrates multiple DDT declarations.

 

Figure 1  DDT Intercepts  
DDT Intercepts

The new DDT intercept establisher routines are:

If there are multiple declarations of DDT intercepts, they are called in descending order, from the highest level DDT (DDT$K_ITCLVL_TOP) to the lowest-level DDT (DDT$K_ITCLVL_DRVR).

Although the standard driver cancel, altstart, start, and mntver routines do not return a status, the intermediate routines must return either SS$_SUPERSEDE or SS$_CHAINW status. Any other return value results in a bugcheck. As the return value suggests, the SS$_SUPERSEDE return value from the intermediate routine supersedes the lower-level call to the DDT intercept routines. The SS$_CHAINW return value from the intermediate routine causes the next lower-level DDT intercept routines to be called.

The intercept DDTs are placed in the DDT chain according to their level. The top-level DDT is always the dispatcher DDT, and the bottom-level DDT is always the driver-level DDT. Other DDTs are placed in descending order between the top-level DDT and the driver-level DDT.

Intercept Levels 

The following intercept levels are currently defined and reserved for use by HP:

DDT$K_ITCLVL_TOP 32767

DDT$K_ITCLVL_HSM 24576

DDT$K_ITCLVL_MPDEV 4096

DDT$K_ITCLVL_DRVR 0

The valid intercept levels are from 4097 to 32766, except for 24576, which is reserved for the HSM interval. You can define as many intercepts as needed in that range.

Restrictions 

The following restrictions exist:

Manufacturers of third-party products that rely on altering the DDT of either the OpenVMS Alpha SCSI disk-class driver (SYS$DKDRIVER.EXE), the SCSI tape-class driver (SYS$MKDRIVER), or the SCSI generic-class driver (SYS$GKDRIVER) can contact HP at vms_drivers@zko.dec.com for more information.

Routines 

The following pages provide the functional description of each routine.

IOC_STD$ESTABLISH_DDT_START

Establishes DDT$PS_START_2 intercept.

Functional Description

This routine establishes the intercept of the DDT$PS_START_2 routine.

Calling Convention

int ioc_std$establish_ddt_start (UCB *ucb, int (*start_itc_routine)(IRP *irp,
UCB *ucb), int level,int flag)

Input

ucb
Pointer to a UCB whose DDT$PS_START_2 is to be intercepted.
start_itc_routine
The intercepting start routine. This routine is called before the driver's start routine. The calling convention of the start routine is the same as the standard DDT$PS_START_2 routine, except that this routine must return one of the following status values:
SS$_CHAINW - The next start routine should be called.

SS$_SUPERSEDE - No more start routines should be called.


Any other return value results in a bugcheck.
level
Level of DDT to be intercepted. Currently, multipath does not support an intercept level below MPDEV intercept.
flag
Placeholder for future development; must be zero.

Return Value

SS$NORMAL DDT intercept added successfully.
This routine may also return various other error status values,
including any status returned on a failure to allocate pool.

Synchronization Environment

Caller must be in kernel mode, IPL at or below UCB fork IPL.

Almost all use of the DDT within OpenVMS requires holding the UCB fork lock. This is why this routine acquires and conditionally releases the UCB fork lock to change the DDT.

IOC_STD$ESTABLISH_DDT_ALTSTART

Establishes DDT$PS_ALTSTART_2 intercept.

Functional Description

This routine establishes the intercept of the DDT$PS_ALTSTART_2 routine.

Calling Convention

int ioc_std$establish_ddt_altstart (UCB *ucb, int (*altstart_itc_routine)(IRP *irp,
UCB *ucb), int level,int flag)

Input

ucb
Pointer to a UCB whose DDT$PS_ALTSTART_2 is to be intercepted.
altstart_itc_routine
The intercepting altstart routine. This routine is called before the driver's altstart routine. The calling convention of the altstart routine is the same as the standard DDT$PS_ALTSTART_2 routine, except that this routine must return one of the following status values:
SS$_CHAINW - The next altstart routine should be called.

SS$_SUPERSEDE - No more altstart routines should be called.


Any other return value results in a bugcheck.
level
Level of DDT to be intercepted. Currently, multipath does not support an intercept level below MPDEV intercept.
flag
Placeholder for future development; must be zero.

Return Value

SS$NORMAL DDT intercept added successfully.
This routine may also return various other error status values,
including any status returned on a failure to allocate nonpaged pool.

Synchronization Environment

Caller must be in kernel mode, IPL at or below UCB fork IPL.

Almost all use of the DDT within OpenVMS requires holding the UCB fork lock. This is why this routine acquires and conditionally releases the UCB fork lock to change the DDT.

IOC_STD$ESTABLISH_DDT_CANCEL

Establishes DDT$PS_CANCEL_2 intercept.

Functional Description

This routine establishes the intercept of the DDT$PS_CANCEL_2 routine.

Calling Convention

int ioc_std$establish_ddt_cancel (UCB *ucb, int (*cancel_itc_routine)(int chan,
IRP *irp,PCB *pcb,UCB *ucb, int reason), int level,int flag)

Input

ucb
Pointer to a UCB whose DDT$PS_CANCEL_2 is to be intercepted.
cancel_itc_routine
The intercepting cancel routine. This routine is called before the driver's cancel routine. The calling convention of the cancel routine is the same as the standard DDT$PS_CANCEL_2 routine, except that this routine must return one of the following status values:
SS$_CHAINW - The next cancel routine should be called.

SS$_SUPERSEDE - No more cancel routines should be called.


Any other return value results in a bugcheck.
level
Level of DDT to be intercepted. Currently, multipath does not support an intercept level below MPDEV intercept.
flag
Placeholder for future development; must be zero.

Return Value

SS$NORMAL DDT intercept added successfully.
This routine may also return various other error status values,
including any status returned on a failure to allocate nonpaged pool.

Synchronization Environment

Caller must be in kernel mode, IPL at or below UCB fork IPL.

Almost all use of the DDT within OpenVMS requires holding the UCB fork lock. This is why this routine acquires and conditionally releases the UCB fork lock to change the DDT.

IOC_STD$ESTABLISH_DDT_MNTVER

Establishes DDT$PS_MNTVER_2 intercept.

Functional Description

This routine establishes the intercept of the DDT$PS_MNTVER_2 routine.

Calling Convention

int ioc_std$establish_ddt_mntver (UCB *ucb, int(*mntver_itc_routine)(IRP *irp,
UCB *ucb), int level,int flag)

Input

ucb
Pointer to a UCB whose DDT$PS_MNTVER_2 is to be intercepted.
mntver_itc_routine
The intercepting mntver routine. This routine is called before the driver's mntver routine. The calling convention of the mntver routine is the same as the standard DDT$PS_MNTVER_2 routine, except that this routine must return one of the following status values:
SS$_CHAINW - The next mntver routine should be called.

SS$_SUPERSEDE - No more mntver routines should be called.


Any other return value results in a bugcheck.
level
Level of DDT to be intercepted. Currently, multipath does not support an intercept level below MPDEV intercept.
flag
Placeholder for future development; must be zero.

Return Value

SS$NORMAL DDT intercept added successfully.
This routine may also return various other error status values,
including any status returned on a failure to allocate pool.

Synchronization Environment

Caller must be in kernel mode, IPL at or below UCB fork IPL.

Almost all use of the DDT within OpenVMS requires holding the UCB fork lock. This is why this routine acquires and conditionally releases the UCB fork lock to change the DDT.

Device Registration Callback Routines 

OpenVMS Alpha Version 7.3-2 also introduces a kernel-mode API for notification of device configuration by way of a callback. This API was designed to enhance the functionality provided by the new IOC_STD$ESTABLISH_DDT_xxx routines, which provide a mechanism to intercept calls through a driver dispatch table (DDT).

This API provides a kernel mode "registration" routine, IOC_STD$DEVCONFIG_REGISTER, that privileged code can call, and a complementary routine, IOC_STD$DEVCONFIG_DEREGISTER, to revoke the registration. The registration routine specifies a device class and a callback routine address. Subsequently, when any new device of that class is configured, the specified callback routine is called before the device becomes visible to other threads of execution.

The callback routine can call any of the IOC_STD$ESTABLISH_DDT_xxx routines for that device and thus guarantees that the driver intercept is in place before any I/O could possibly be issued to the driver.

IOC_STD$DEVCONFIG_REGISTER

Delivers a notification via a callback when a new device of a specified device class is configured on this system.

Functional Description

IOC_STD$DEVCONFIG_REGISTER is the registration routine that delivers a notification via a callback when a new device of a specified device class is configured on this system. The callback notification occurs when a device is first configured on a system. Notification is not provided when an additional path or a new MSCP server is added for an existing device.The notification mechanism remains in effect until it is revoked by a call to the IOC_STD$DEVCONFIG_DEREGISTER routine.

Calling Convention

int ioc_std$devconfig_register( int flags, int devclass, void (*devconfigured)(UCB *ucb, int64 user_param), int64 user_param, int64 *ret_handle );

Input

flags
Reserved for future enhancements. Must be zero. All other values result in a SS$BADPARAM error.
devclass
The device class value, DC$_xxx from devdef.h in STARLET, for which notification is desired. Any value greater than 0 and less than 256 is supported. All other values result in a SS$BADPARAM error.
devconfigured
Address of the caller's desired callback routine, which must be in S0/S1 space. When a new device is configured, this routine is called after the device UCB has been linked into the I/O database and sufficiently initialized so that the I/O database mutex is about to be released. This is after the appropriate driver's structure initialization routine has been called but before the driver's unit initialization is called. The IPL is at the UCB fork IPL, and the UCB fork lock is held.
user_param
Arbitrary 64-bit integer parameter that is passed to the callback routine. Can be used by the callback routine as a context parameter. The same combination of devclass value, devconfigured value, and user_param value cannot be registered twice.

Output

ret_handle
64-bit "handle" that can be used with the ioc_std$devconfig_deregister routine to revoke this notification request. The caller should treat the ret_handle value as an "opaque" quantity. A ret_handle value of zero is returned if the routine fails.

Return Values

SS$_NORMAL Notification was successfully delivered.
SS$_BADPARAM The flags or devclass parameter values are invalid.
SS$_IVADDR The callback routine address is not in S0/S1 space.

SS$_CBKEXISTS Callback already exists for this combination of devclass, devconfigured, and
user_param values. Multiple registration request for exactly the same notification
routine, device class, and parameter are not allowed.Other return values: Other error return values are possible, including any error return from an attempt to
allocate nonpaged pool.

Synchronization Environment

This routine must be called from kernel mode, process context, IPL 2 or lower. It returns at the entry IPL. This routine declares an SPLIPLHIGH fatal bugcheck if the entry IPL is greater than 2.

Access to the list of registered device configuration callbacks is protected by the I/O database mutex. Therefore, this routine acquires the I/O database mutex for write access and may put the calling process into a resource wait state. This routine releases the I/O database mutex and restore the entry IPL before returning to the caller.

IOC_STD$DEVCONFIG_DEREGISTER

Functional Description

IOC_STD$DEVCONFIG_DEREGISTER revokes a device configuration notification callback that was previously enabled by a call to IOC_STD$DEVCONFIG_REGISTER.

Calling Convention

int ioc_std$devconfig_deregister( int64 ret_handle );

Input

ret_handle
64-bit "handle" that was returned by a prior call to ioc_std$devconfig_deregister.

Return Values

SS$_NORMAL Successfully revoked notification.
SS$NOSUCHCBK Did not find a registered device configuration callback with the specified handle,
or the handle value is invalid.

Synchronization Environment

This routine must be called from kernel mode, process context, IPL 2 or lower. It returns at the entry IPL. This routine will declare a SPLIPLHIGH fatal bugcheck if the entry IPL is greater than 2.Access to the list of registered device configuration callbacks is protected by the I/O database mutex. Therefore, this routine acquires the I/O database mutex for write access and may put the calling process into a resource wait state. This routine releases the I/O database mutex before returning to the caller.

Device Configuration Callback Routine 

Functional Description

The device configuration callback routine is a caller-specified routine. It is established as a device configuration callback routine by a call to the IOC_STD_$DEVCONFIG_REGISTER register routine.

The device configuration callback routine is called after a new device UCB has been linked into the I/O database and sufficiently initialized such that the I/O database mutex is about to be released. This is after the appropriate driver's structure initialization routine has been called but before the driver's unit init routine is called.

The device configuration routine must be accessible in system context. Therefore, the address of the device configuration routine must be in S0/S1 space. This is enforced by the IOC_STD$DEVCONFIG_REGISTER routine.

The callback is not invoked when an additional path or a new MSCP server is added for an existing device, even though an additional UCB could be created for the new path.

Calling Convention

void (*devconfigured)(UCB *ucb, int64 user_param );

Input

ucb
Address of the UCB that was just linked into the I/O database.
user_param
64-bit value that was specified on the call to ioc_std$devconfig_register that established this callback routine.

Return Values

None.

Synchronization Environment

The device configuration callback routine is called in kernel mode at UCB fork IPL, with the UCB fork lock held. The I/O database mutex is held for write access.

Note that the environment of the device configuration routine is not appropriate for calls to IOC_STD$DEVCONFIG_REGISTER and IOC_STD$DECVCONFIG_DEREGISTER


go to previous page: C Run-Time Library Enhancements C Run-Time Library Enhancements
go to next page: HP DECdtm Version 2.1HP DECdtm Version 2.1