forked from Hercules-Aethra/aethra
-
Notifications
You must be signed in to change notification settings - Fork 0
/
cckd64.h
228 lines (188 loc) · 12 KB
/
cckd64.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
/* CCKD64.H (C) Copyright "Fish" (David B. Trout), 2018-2022 */
/* CCKD64 dasd struct and type definitions */
/* */
/* Released under "The Q Public License Version 1" */
/* (http://www.hercules-390.org/herclic.html) as modifications to */
/* Hercules. */
#ifndef _CCKD64_H_
#define _CCKD64_H_
#include "cckd.h" // (need CCKD_MAX_SF, etc)
/*-------------------------------------------------------------------*/
/* IMPORTANT PROGRAMMING NOTE: for whatever reason, base dasd */
/* image files use a L2_trkoff value of zero in their L1tab entry */
/* for non-existent tracks, whereas shadow files use a value of -1. */
/* To ensure we remain 100% compatible with all non-CCKD64 versions */
/* of Hercules, we MUST enforce this same inconsistent use design. */
/*-------------------------------------------------------------------*/
#define CCKD64_NOSIZE ((U64)0)
#define CCKD64_MAXSIZE ((U64)MAX_OFFSET_T)
#define CCKD64_BASE_NO_OFFSET CCKD64_NOSIZE
#define CCKD64_SHADOW_NO_OFFSET CCKD64_MAXSIZE
/*-------------------------------------------------------------------*/
/* struct typedefs */
/*-------------------------------------------------------------------*/
typedef struct CCKD64_DEVHDR CCKD64_DEVHDR; // Compress device header
typedef struct CCKD64_L2ENT CCKD64_L2ENT; // Level 2 table entry
typedef struct CCKD64_FREEBLK CCKD64_FREEBLK; // Free block
typedef struct CCKD64_IFREEBLK CCKD64_IFREEBLK;// Free block (internal)
typedef struct CCKD64_EXT CCKD64_EXT; // CCKD Extension block
typedef struct SPCTAB64 SPCTAB64; // Space table
/*-------------------------------------------------------------------*/
/* Record layouts and sizes */
/*-------------------------------------------------------------------*/
#define CKD_R0 CKD_RECHDR /* Record-0 count field */
#define CKD_EOFREC CKD_RECHDR /* An END-OF-FILE record is \
a count field with klen \
of zero and dlen of zero, \
i.e. a zero length record */
static
const CKD_RECHDR CKD_ENDTRK = /* END-OF-TRACK marker is a \
count field (i.e. record \
header) consisting of... */ \
{{0xff,0xff},{0xff,0xff},0xff,0xff,{0xff,0xff}}; /* ...all 0xffs */
#define CKD_R0_SIZE ((S64)sizeof(CKD_R0))
#define CKD_R0_DLEN (8)
#define CKD_EOF_SIZE ((S64)sizeof(CKD_EOFREC))
#define CKD_ENDTRK_SIZE ((S64)sizeof(CKD_ENDTRK))
#define CKD_MIN_TRKSIZE (CKD_TRKHDR_SIZE + CKD_ENDTRK_SIZE)
#define CKD_NULL_FMT2_DLEN (4096)
/*-------------------------------------------------------------------*/
/* Structure definitions for Compressed CCKD64/CFBA64 devices */
/*-------------------------------------------------------------------*/
/* NOTE: The num_L1tab, num_L2tab, cyls, cdh_size, cdh_used, */
/* free_off, free_total, free_largest, free_num, free_imbed, */
/* and cmp_parm fields are kept in LITTLE endian format. */
/*-------------------------------------------------------------------*/
struct CCKD64_DEVHDR /* Compress device header */
{
/* 0 */BYTE cdh_vrm[3]; /* Version Release Modifier */
/* 3 */BYTE cdh_opts; /* Options byte */
/* 4 */S32 num_L1tab; /* Number of L1tab entries */
/* 8 */S32 num_L2tab; /* Number of L2tab entries */
/* 12 */FWORD cdh_cyls; /* CCKD: Cylinders on device
CFBA: Sectors on device */
/* 16 */U64 cdh_size; /* File size */
/* 24 */U64 cdh_used; /* File used */
/* 32 */U64 free_off; /* Offset to free space */
/* 40 */U64 free_total; /* Total free space */
/* 48 */U64 free_largest; /* Largest free space */
/* 56 */S64 free_num; /* Number free spaces */
/* 64 */U64 free_imbed; /* Imbedded free space */
/* 72 */BYTE cdh_nullfmt; /* Null track format */
/* 73 */BYTE cmp_algo; /* Compression algorithm */
/* 74 */S16 cmp_parm; /* Compression parameter */
/* 76 */BYTE resv2[436]; /* Reserved */
};
struct CCKD64_L2ENT { /* Level 2 table entry */
/* NOTE: all fields are numeric and always in LITTLE endian format. */
U64 L2_trkoff; /* Offset to track image */
U16 L2_len; /* Track length */
U16 L2_size; /* Track size (size >= len) */
U32 L2_pad; /* (padding/reserved) */
};
struct CCKD64_FREEBLK { /* Free block (file) */
/* NOTE: all fields are numeric and always in LITTLE endian format. */
U64 fb_offnxt; /* Offset to NEXT free blk */
U64 fb_len; /* Length of THIS free blk */
};
struct CCKD64_IFREEBLK { /* Free block (internal) */
/* NOTE: because this control block is an INTERNAL control block */
/* which does not actually exist in the emulated dasd image file */
/* (i.e. it is only used internally), all of its fields are always */
/* in *HOST* endian format (little endian on little endian hosts */
/* and big endian on big endian hosts). */
U64 ifb_offnxt; /* Offset to NEXT free blk */
U64 ifb_len; /* Length of THIS free blk */
int ifb_idxprv; /* Index to prev free blk */
int ifb_idxnxt; /* Index to next free blk */
int ifb_pending; /* 1=Free pending (don't use)*/
int ifb_pad; /* (padding/reserved) */
};
/*-------------------------------------------------------------------*/
/* struct sizes, etc. */
/*-------------------------------------------------------------------*/
typedef U64 CCKD64_L1ENT; /* Level 1 table entry */
typedef CCKD64_L1ENT CCKD64_L1TAB[]; /* Level 1 table */
typedef CCKD64_L2ENT CCKD64_L2TAB[256];/* Level 2 table */
#define CCKD_TRACE_SIZE ((S64)sizeof(CCKD_ITRACE))
#define CCKD64_DEVHDR_SIZE ((S64)sizeof(CCKD64_DEVHDR))
#define CCKD64_L1ENT_SIZE ((S64)sizeof(CCKD64_L1ENT))
#define CCKD64_L2ENT_SIZE ((S64)sizeof(CCKD64_L2ENT))
#define CCKD64_L2TAB_SIZE ((S64)sizeof(CCKD64_L2TAB))
#define CCKD64_FREEBLK_SIZE ((S64)sizeof(CCKD64_FREEBLK))
#define CCKD64_IFREEBLK_SIZE ((S64)sizeof(CCKD64_IFREEBLK))
#define CCKD64_DEVHDR_POS (CKD_DEVHDR_SIZE)
#define CCKD64_L1TAB_POS ((CCKD64_DEVHDR_POS)+(CCKD64_DEVHDR_SIZE))
#define FBA_SECTOR_SIZE 512
#define CFBA_BLKS_PER_GRP 120
#define CFBA_BLKGRP_SIZE (FBA_SECTOR_SIZE * CFBA_BLKS_PER_GRP)
/*-------------------------------------------------------------------*/
/* CCKD Extension Block */
/*-------------------------------------------------------------------*/
struct CCKD64_EXT { /* Ext for compressed ckd */
DEVBLK *devnext; /* cckd device queue */
unsigned int ckddasd:1, /* 1=CKD dasd */
fbadasd:1, /* 1=FBA dasd */
cckdioact:1, /* 1=Channel program active */
bufused:1, /* 1=newbuf was used */
updated:1, /* 1=Update occurred */
merging:1, /* 1=File merge in progress */
stopping:1, /* 1=Device is closing */
notnull:1, /* 1=Device has track images */
L2ok:1, /* 1=All l2s below bounds */
sfmerge:1, /* 1=sf-xxxx merge */
sfforce:1; /* 1=sf-xxxx force */
int sflevel; /* sfk xxxx level */
LOCK filelock; /* File lock */
LOCK cckdiolock; /* I/O lock */
COND cckdiocond; /* I/O condition */
U64 cckd_maxsize; /* Maximum file size */
int cckdwaiters; /* Number I/O waiters */
int wrpending; /* Number writes pending */
int ras; /* Number readaheads active */
int sfn; /* Number active shadow files*/
int sfx; /* Active level 2 file index */
int L1idx; /* Active level 2 table index*/
CCKD64_L2ENT *L2tab; /* Active level 2 table */
int L2_active; /* Active level 2 cache entry*/
U64 L2_bounds; /* L2 tables boundary */
int active; /* Active cache entry */
BYTE *newbuf; /* Uncompressed buffer */
CCKD64_IFREEBLK *ifb; /* Internal free space chain */
int free_count; /* Number of entries in chain*/
int free_idx1st; /* Index of 1st entry */
int free_idxlast; /* Index of last entry */
int free_idxavail; /* Index of available entry */
unsigned int free_minsize; /* Minimum free space size */
int lastsync; /* Time of last sync */
int ralkup[CCKD_MAX_RA_SIZE];/* Lookup table */
int ratrk; /* Track to readahead */
unsigned int totreads; /* Total nbr trk reads */
unsigned int totwrites; /* Total nbr trk writes */
unsigned int totl2reads; /* Total nbr l2 reads */
unsigned int cachehits; /* Cache hits */
unsigned int readaheads; /* Number trks read ahead */
unsigned int switches; /* Number trk switches */
unsigned int misses; /* Number readahead misses */
int fd[CCKD_MAX_SF+1]; /* File descriptors */
BYTE swapend[CCKD_MAX_SF+1]; /* Swap endian flag */
BYTE open[CCKD_MAX_SF+1]; /* Open flag */
int reads[CCKD_MAX_SF+1]; /* Nbr track reads */
int L2_reads[CCKD_MAX_SF+1];/* Nbr l2 reads */
int writes[CCKD_MAX_SF+1]; /* Nbr track writes */
CCKD64_L1ENT *L1tab[CCKD_MAX_SF+1]; /* Level 1 tables */
CCKD64_DEVHDR cdevhdr[CCKD_MAX_SF+1]; /* cckd device hdr */
};
/*-------------------------------------------------------------------*/
/* Space table */
/*-------------------------------------------------------------------*/
struct SPCTAB64
{
BYTE spc_typ; /* Type of space */
int spc_val; /* Value for space */
int spc_val2; /* Another value for space */
U64 spc_off; /* Space offset */
U64 spc_len; /* Space length */
U64 spc_siz; /* Space size */
};
#endif // _CCKD64_H_