This section describes the data structures used by PDIAGEX.
The pdiagex_dds_t structure defines the device driver structure (dds) for PDIAGEX. The pdiagex_dds_t structure must be initialized with attributes for the resource before calling pdiag_open(). The pdiagex_dds_t structure is defined in /usr/include/sys/pdiagex_dds.h and contains the following fields:
/*----------------------------------------------------------------------*/
/* PDIAGEX_DDS_T
/* This structure MUST be filled in by the Calling Application (TU)
/* This structure is passed to pdiagex in the pdiag_open() routine
/*----------------------------------------------------------------------*/
typedef struct {
uint32 slot_num; /* slot number of adapter
/* BUS DATA */
uint32 bus_id; /* Identifies the I/O bus that the DMA
/* channel is to be allocated on.
uint32 bus_type; /* BUS_MICRO_CHANNEL, BUS_60X or BUS_BID
uint32 bus_io_addr; /* Base address of Bus I/O area
uint32 bus_io_length; /* Length (width) of Bus I/O area
uint32 bus_mem_addr; /* Base address of Shared Bus Memory area
uint32 bus_mem_length; /* Length (width) of Shared Bus Memory area
/* DMA /
/* Next three are for BUS_MICRO_CHANNEL devices only */
uint32 dma_bus_mem; /* Base address of Bus Memory DMA area
uint32 dma_bus_length; /* Length (multiple of PAGESIZE) of BUS
/* Memory DMA area in bytes.
uint32 dma_lvl; /* Bus arbitration level
uint32 maxmaster; /* maximum number of concurrent
/* dma_master calls
uint32 dma_flags; /* DMA flags as defined in sys/dma.h.
/* These flags describe what actions to
/* take ( master/slave, initialize the
/* channel, etc. Not used by 60X type devices)
/* dma_bus_flags is for BUS_BID devices only */
uint32 dma_bus_flags; /* Bus flags specific for DMA operation
uint32 dma_chan_id; /* For BUS_MICRO_CHANNEL
/* Dma channel ID is returned as a result
/* of the DMA initialization.
/* For BUS_BID
/* Dma channel ID is the assigned DMA
/* channel for the device.
/* For BUS_60X
/* Dma channel ID is not used
/* Interrupt Handler */
pdiag_addr_t data_ptr; /* Pointer for passing data to interrupt
uint32 d_count; /* Count of bytes of data for interrupt
uint32 bus_intr_lvl; /* Interrupt level
uint32 intr_priority; /* Interrupt priority
uint32 intr_flags; /* Interrupt flags as defined in intr.h
/* Attribute Expansion Area */
pdiag_addr_t attributes; /* Pointer to specific attributes
}pdiagex_dds_t;
The pdiagex_opflags_t structure defines the device operations to be used. The pdiagex_opflags_t structure is defined in /usr/include/sys/pdiagex_dds.h and consists of the following:
/*----------------------------------------------------------------------*/
/* PDIAGEX_OPFLAGS_T
/* This structure MUST be filled in by the Calling Application (TU)
/* This structure is used for Read and Write Operations
/*----------------------------------------------------------------------*/
typedef struct {
uint32 memio; /* Type of Memory Operation
/*PDIAG_MEM_OP,PDIAG_IO_OP,PDIAG_POS_OP
uint32 count; /* Number of accesses to perform
uint32 addr_incr_flag; /* Flag that determines whether the data
/* buffer address and/or the offset
/* address gets incremented on each of
/* count accesses.
/* PDIAG_SING_LOC_ACC or
/* PDIAG_SING_LOC_HW or
/* PDIAG_SING_LOC_BUF or
/* PDIAG_MULT_LOC_ACC
uint32 intr_level; /* Indicates which environment the
/* calling application is in.
/* PROCLEV or INTRKMEM or INTRPMEM
struct timestruc_t *times; /* Address of times structure, NULL if
/* not used.
} pdiagex_opflags_t;
The dma_struct structure defines the DMA structure used by PDIAGEX. The dma_struct structure is defined in /usr/include/sys/pdiagex_sys.h and contains the following fields:
typedef struct dmast {
struct dmast *next;
int firsttcw; /* first TCW used (micro channel only) */
int last_tcw; /* last TCW used (micro channel only) */
int dma_flags; /* see /usr/include/sys/dma.h */
uchar *baddr; /* address of the host buffer to DMA to/from */
uchar *daddr; /*Phys addr in DMAbus_mem, from
diag_dma_master()*/
uint count; /* size of the DMA data in bytes */
struct xmem dp; /* Cross Memory descriptor of baddr */
char pinned; /* NonZero if DMA buffer was pinned */
char xmattached; /* NonZero if DMA buffer was CrossMemAttached */
char in_use; /* TRUE if this linked list member is valid */
} dma_info_t;
| Parameter | Description |
|---|---|
| next | Pointer to the next dma_info_t structure in an 'in_use' list. |
| firsttcw | (Micro Channel devices Only) first page of pdiagex_dds_t.dma_bus_mem used by an active DMA master/slave operation. |
| last_tcw | (Micro Channel devices Only) last page of pdiagex_dds_t.dma_bus_mem used by an active DMA master/slave operation. |
| dma_flags | DMA flags as defined in <sys/dma.h>. These flags describe what actions to take (such as, master/slave transfer, initialize the DMA channel, and so on). |
| *baddr | Address of memory buffer for transfer. |
| *daddr | Address used to program the DMA master. |
| count | Size (in bytes) of the DMA transfer. |
| dp | Address of cross-memory descriptor. |
| pinned | Nonzero if DMA buffer was pinned. |
| xmattached | Nonzero if DMA buffer was cross-memory attached. |
| in_use | Flag for determining if DMA buffer is valid for transfer. |
The AIOO_STRUCT_T structure defines the allocations, initializations, and outstanding operations for each handle. This provides a mechanism for error-recovery cleanup, cleanup of outstanding operations during a close, and general protection from the application. Common code may also be used for cleanup operations.
/* Allocation/Initialization/OutstandingOperations Binary Flags Structure */
typedef struct {
uint AllocIntrptDataMem : 1;
uint AllocDmaAreaMem : 1;
uint CopyDDS : 1;
uint CopyIntrptEnt : 1;
uint PinIntrptFunct : 1;
uint PinUIntrptData : 1;
uint PinDiagExt : 1;
uint InitIntrptChan : 1;
uint InitDmaChan : 1;
uint XmatUIntrptData : 1;
} aioo_struct_t;
| Parameter | Description |
|---|---|
| AllocIntrptDataMem | Nonzero if Interrupt data area allocated. |
| AllocDmaAreaMem | Nonzero if DMA data area allocated. |
| CopyDDS | Nonzero if DDS data was copied to handle. |
| CopyIntrptEnt | Nonzero if Intrpt function was in Kernel. |
| PinIntrptFunct | Nonzero if Intrpt function was pinned. |
| PinUIntrptData | Nonzero if Intrpt data area was pinned. |
| PinDiagExt | Nonzero if Pinned PDIAGEX Extension. |
| InitIntrptChan | Nonzero if Intrpt channel was initialized. |
| InitDmaChan | Nonzero if DMA channel was initialized. |
| XmatUIntrptData | Nonzero if Intrpt data area was XMattached. |
The diag_struc_t structure defines the complete data structure returned in the handle for the pdiag_open() call. This structure holds all the needed information for all the other PDIAGEX function calls.
typedef struct handl {
struct intr intr;
struct handl *next;
int (*intr_func)();
uchar *intr_data;>
struct xmem udata_dp;
diagex_dds_t dds;
struct timestruc_t itime;
struct timestruc_t ntime;
dma_info_t *dma_info;
aioo_struct_t aioo;
char *scratch_pad;
uint sleep_flag;
uint sleep_word;
uint flag_word;
struct watchdog wdt;
struct d_handle * dhandle;
dma_dio * dio_st;
uint timeout;
} diag_struc_t;
| Parameter | Description |
|---|---|
| intr | Interrupt handler structure as defined in <sys/intr.h>. Needs to be first parameter in diag_struc_t. |
| (*intr_func)() | Pointer to user's interrupt handler. |
| *intr_data | Pointer to interrupt data. |
| udata_dp | Address of cross-memory descriptor for interrupt data. |
| dds | Structure that contains the device driver structure (dds) information for PDIAGEX. See the diagex_dds structure defined above. |
| itime | Time elapsed for interrupts. Updated at interrupts. |
| ntime | Time elapsed for read or write operations. Updated at reads or writes. |
| *dma_info | Pointer to dma_info_t structure which allows multiple DMA operations. See the dma_info_t structure defined above. |
| aioo | Set of flags for Allocations, Initializations, and Outstanding Operations. |
| scratch_pad | PIO scratch pad for large transfers. |
| sleep_flag | pdiag_dd_watch_for_interrupt() sets this flag to TRUE if it is sleeping and waiting for the
application's interrupt handler to call pdiag_dd_interrupt_notify(). This flag is initialized
to FALSE and will be set to FALSE after pdiag_dd_watch_for_interrupt() wakes up.
>The application's interrupt handler should use this word to determine whether to 'wakeup' pdiag_dd_watch_for_interrupt(). This flag should not be modified by the application's interrupt handler. |
| sleep_word | pdiag_dd_watch_for_interrupt() sleeps on this
word until the application's interrupt handler calls pdiag_dd_interrupt_notify() using this word.
This word should not be modified by the application's interrupt handler. |
| flag_word | This flag is defined by the application and should be set by the application's interrupt handler to specify certain interrupt conditions. The application may call pdiag_dd_watch_for_interrupt(), specifying a flag_mask which will be bitwise ANDed with this flag_word. When this AND operation produces a nonzero result and pdiag_dd_watch_for_interrupt() is awake, pdiag_dd_watch_for_interrupt() will return. |
| wdt | This is the watchdog timer used by the timeout function. |
| dhandle | Structure returned by D_MAP_INIT macro which is called in the pdiag_open() function. This handle is used to issue DMA operations to rspc type systems. |
| dio_st | Pointer to a DIO structure used in DMA operations. |
| timeout | True if watchdog timer expired. |