1 /* SR.H (c)Copyright Greg Smith, 2004-2009 */ 2 /* Suspend/Resume a Hercules session */ 3 4 /* 5 * The suspend/resume functions allow a hercules instance to be 6 * captured to a file and later resumed. Note that the suspend 7 * function also terminates the hercules instance. 8 * 9 * In order for an instance to be resumed, hercules must be started 10 * with a config file describing the configuration at suspend time. 11 * For example, mainsize and xpndsize must match. Also, all devices 12 * present at suspend time must be present at resume time. 13 * 14 * Disk devices must be at the same state as they were at suspend 15 * time. They can, however, be a different file type. That is, 16 * a disk could be a cckd disk at suspend time. Then a ckd disk 17 * could be created using dasdcopy and hercules resumed using the 18 * ckd disk instead. 19 * 20 * Also, hercules must be configured similarly as at suspend time. 21 * For example, if 4 emulated CPUs were active at suspend time 22 * then the session can not be resumed on a hercules with a 23 * maximum of two CPUs. Another example, you will not be able 24 * to resume a session in z900 architecture mode for a hercules 25 * that was built without z900 architecture. 26 * 27 * Device state 28 * 29 * Currently, device state is only fully saved for CKD disks. 30 * Each device class (eg TAPE, RDR, PUN, CTC) will need code 31 * to save and restore their state. Some states may not be 32 * possible to restore (eg active tcp/ip connections at the 33 * time of suspend). 34 * 35 * Further limitations 36 * 37 * Currently the vector facility state is not saved. 38 * Also, the ecpsvm state is not currently saved. 39 * 40 * File Structure 41 * 42 * The suspend/resume file (.srf) contains some number of `text 43 * units'. A text unit has an 8 byte header followed by zero or 44 * more bytes of data. 45 * 46 * The file is designed to be hercules release independent and 47 * to be host architecture independent. For example, I should be 48 * able to take an srf file created on hercules 3.02 on an intel 49 * machine and resume on a Sun machine running hercules 3.04. 50 * 51 * The header contains a 4 byte key and a 4 byte length. Both 52 * the key and the length are stored in big-endian byte order. 53 * 54 * There are 3 types of data: STRING, BUF and VALUE. 55 * 56 * A string is a null terminated sequence of bytes. The string 57 * includes the null terminator byte. The total length of a 58 * string cannot exceed SR_MAX_STRING_LENGTH (4096). The 59 * length is checked by SR_READ_STRING. 60 * 61 * A buf is a sequence of bytes whose length must be provided. 62 * The length should be checked before issuing SR_READ_BUF. 63 * 64 * A value is an arithmetic number. It's length can be 65 * 0, 1, 2, 4 or 8 bytes. Values are stored in big-endian 66 * byte order. A zero length indicates the value is 0. 67 * 68 * Text Units 69 * 70 * There are 4 categories (so far) of text units: 71 * HDR ... fields that describe the file 72 * SYS ... fields from SYSBLK 73 * CPU ... fields from REGS 74 * DEV ... fields from DEVBLK 75 * 76 * The format of a text unit key value is 77 * ace c t xxx 78 * 79 * ace -- all keys start with 0xace 80 * c -- category (0 - HDR, 1 - SYS, 2 - CPU, 3 - DEV) 81 * t -- for DEV keys, identifies the subtype for the 82 * device type (0 - general, 1 - CKD, ...) 83 * xxx -- field identifier 84 * 85 * Note that there is no array data type. When an array 86 * needs to be used, the elements should have ascending 87 * text unit key values. For example: 88 * 89 * #define SR_CPU_GR 0xace20020 90 * #define SR_CPU_GR_0 0xace20020 91 * #define SR_CPU_GR_1 0xace20021 92 * #define SR_CPU_GR_2 0xace20022 93 * #define SR_CPU_GR_3 0xace20023 94 * . . . . . . 95 * 96 * The array can be written during suspend as follows: 97 * 98 * for (i = 0; i < 16; i++) 99 * SR_WRITE_VALUE(fd, SR_CPU_GR+i, regs->gr[i], sizeof(regs->gr[0])); 100 * 101 * The array can be processed during resume as follows 102 * 103 * case SR_CPU_GR_0: 104 * case SR_CPU_GR_1: 105 * case SR_CPU_GR_2: 106 * case SR_CPU_GR_3: 107 * . . . . . . 108 * i = key - SR_CPU_GR; 109 * SR_READ_VALUE(fd, len, ®s->gr[i], sizeof(regs->gr[0])); 110 * break; 111 * 112 * The format of the .srf file is deliberately unstructured to 113 * allow for flexibility in future enhancements. However there 114 * are a few restrictions. 115 * 116 * o Key SR_SYS_ARCHNAME shoud be specified before any 117 * SR_CPU keys. The corresponding CPU is configured 118 * when the SR_CPU key is read, so sysblk.arch_mode must 119 * already be correctly set. 120 * o SR_CPU_ keys must follow the corresponding SR_CPU key. 121 * o Likewise SR_DEV_ keys must follow the corresponding SR_DEV key 122 * 123 * There may be other instances where the processing of one 124 * key requires that another key has been previously processed. 125 * 126 */ 127 128 // $Log$ 129 // Revision 1.15 2007/06/23 00:04:16 ivan 130 // Update copyright notices to include current year (2007) 131 // 132 // Revision 1.14 2006/12/08 09:43:30 jj 133 // Add CVS message log 134 // 135 136 #ifndef _HERCULES_SR_H 137 #define _HERCULES_SR_H 138 139 #include "opcode.h" 140 141 #define SR_ID "Hercules suspend/resume file" 142 #define SR_MAX_STRING_LENGTH 4096 143 144 #define SR_KEY_ID_MASK 0xfff00000 145 #define SR_KEY_ID 0xace00000 146 147 #define SR_HDR_ID 0xace00000 148 #define SR_HDR_VERSION 0xace00001 149 #define SR_HDR_DATE 0xace00002 150 151 #define SR_SYS_MASK 0xfffff000 152 #define SR_SYS_STARTED_MASK 0xace10000 153 #define SR_SYS_INTS_STATE 0xace10001 154 #define SR_SYS_ARCH_NAME 0xace10002 155 #define SR_SYS_MAINSIZE 0xace10007 156 #define SR_SYS_MAINSTOR 0xace10008 157 #define SR_SYS_SKEYSIZE 0xace10009 158 #define SR_SYS_STORKEYS 0xace1000a 159 #define SR_SYS_XPNDSIZE 0xace1000b 160 #define SR_SYS_XPNDSTOR 0xace1000c 161 #define SR_SYS_CPUID 0xace1000d 162 #define SR_SYS_IPLDEV 0xace1000e 163 #define SR_SYS_IPLCPU 0xace1000f 164 #define SR_SYS_MBO 0xace10010 165 #define SR_SYS_MBK 0xace10011 166 #define SR_SYS_MBM 0xace10012 167 #define SR_SYS_MBD 0xace10013 168 #define SR_SYS_IOINTQ 0xace10020 169 #define SR_SYS_IOPENDING 0xace10021 170 #define SR_SYS_PCIPENDING 0xace10022 171 #define SR_SYS_ATTNPENDING 0xace10023 172 #define SR_SYS_CHP_RESET 0xace10030 173 #define SR_SYS_CHP_RESET_0 0xace10030 174 #define SR_SYS_CHP_RESET_1 0xace10031 175 #define SR_SYS_CHP_RESET_2 0xace10032 176 #define SR_SYS_CHP_RESET_3 0xace10033 177 #define SR_SYS_CHP_RESET_4 0xace10034 178 #define SR_SYS_CHP_RESET_5 0xace10035 179 #define SR_SYS_CHP_RESET_6 0xace10036 180 #define SR_SYS_CHP_RESET_7 0xace10037 181 #define SR_SYS_SERVPARM 0xace10040 182 #define SR_SYS_SIGINTREQ 0xace10041 183 #define SR_SYS_VMACTIVE 0xace10042 184 #define SR_SYS_MSCHDELAY 0xace10043 185 #define SR_SYS_LOADPARM 0xace10044 186 /* 187 * Following 3 tags added for Multiple 188 * Logical Channel Subsystem support 189 */ 190 #define SR_SYS_IOPENDING_LCSS 0xace10045 191 #define SR_SYS_PCIPENDING_LCSS 0xace10046 192 #define SR_SYS_ATTNPENDING_LCSS 0xace10047 193 194 #define SR_SYS_SERVC 0xace11000 195 196 #define SR_SYS_CLOCK 0xace12000 197 198 #define SR_CPU 0xace20000 199 #define SR_CPU_ARCHMODE 0xace20001 200 #define SR_CPU_PX 0xace20002 201 #define SR_CPU_PSW 0xace20003 202 #define SR_CPU_GR 0xace20020 203 #define SR_CPU_GR_0 0xace20020 204 #define SR_CPU_GR_1 0xace20021 205 #define SR_CPU_GR_2 0xace20022 206 #define SR_CPU_GR_3 0xace20023 207 #define SR_CPU_GR_4 0xace20024 208 #define SR_CPU_GR_5 0xace20025 209 #define SR_CPU_GR_6 0xace20026 210 #define SR_CPU_GR_7 0xace20027 211 #define SR_CPU_GR_8 0xace20028 212 #define SR_CPU_GR_9 0xace20029 213 #define SR_CPU_GR_10 0xace2002a 214 #define SR_CPU_GR_11 0xace2002b 215 #define SR_CPU_GR_12 0xace2002c 216 #define SR_CPU_GR_13 0xace2002d 217 #define SR_CPU_GR_14 0xace2002e 218 #define SR_CPU_GR_15 0xace2002f 219 #define SR_CPU_CR 0xace20040 220 #define SR_CPU_CR_0 0xace20040 221 #define SR_CPU_CR_1 0xace20041 222 #define SR_CPU_CR_2 0xace20042 223 #define SR_CPU_CR_3 0xace20043 224 #define SR_CPU_CR_4 0xace20044 225 #define SR_CPU_CR_5 0xace20045 226 #define SR_CPU_CR_6 0xace20046 227 #define SR_CPU_CR_7 0xace20047 228 #define SR_CPU_CR_8 0xace20048 229 #define SR_CPU_CR_9 0xace20049 230 #define SR_CPU_CR_10 0xace2004a 231 #define SR_CPU_CR_11 0xace2004b 232 #define SR_CPU_CR_12 0xace2004c 233 #define SR_CPU_CR_13 0xace2004d 234 #define SR_CPU_CR_14 0xace2004e 235 #define SR_CPU_CR_15 0xace2004f 236 #define SR_CPU_AR 0xace20060 237 #define SR_CPU_AR_0 0xace20060 238 #define SR_CPU_AR_1 0xace20061 239 #define SR_CPU_AR_2 0xace20062 240 #define SR_CPU_AR_3 0xace20063 241 #define SR_CPU_AR_4 0xace20064 242 #define SR_CPU_AR_5 0xace20065 243 #define SR_CPU_AR_6 0xace20066 244 #define SR_CPU_AR_7 0xace20067 245 #define SR_CPU_AR_8 0xace20068 246 #define SR_CPU_AR_9 0xace20069 247 #define SR_CPU_AR_10 0xace2006a 248 #define SR_CPU_AR_11 0xace2006b 249 #define SR_CPU_AR_12 0xace2006c 250 #define SR_CPU_AR_13 0xace2006d 251 #define SR_CPU_AR_14 0xace2006e 252 #define SR_CPU_AR_15 0xace2006f 253 #define SR_CPU_FPR 0xace20080 254 #define SR_CPU_FPR_0 0xace20080 255 #define SR_CPU_FPR_1 0xace20081 256 #define SR_CPU_FPR_2 0xace20082 257 #define SR_CPU_FPR_3 0xace20083 258 #define SR_CPU_FPR_4 0xace20084 259 #define SR_CPU_FPR_5 0xace20085 260 #define SR_CPU_FPR_6 0xace20086 261 #define SR_CPU_FPR_7 0xace20087 262 #define SR_CPU_FPR_8 0xace20088 263 #define SR_CPU_FPR_9 0xace20089 264 #define SR_CPU_FPR_10 0xace2008a 265 #define SR_CPU_FPR_11 0xace2008b 266 #define SR_CPU_FPR_12 0xace2008c 267 #define SR_CPU_FPR_13 0xace2008d 268 #define SR_CPU_FPR_14 0xace2008e 269 #define SR_CPU_FPR_15 0xace2008f 270 #define SR_CPU_FPR_16 0xace20090 271 #define SR_CPU_FPR_17 0xace20091 272 #define SR_CPU_FPR_18 0xace20092 273 #define SR_CPU_FPR_19 0xace20093 274 #define SR_CPU_FPR_20 0xace20094 275 #define SR_CPU_FPR_21 0xace20095 276 #define SR_CPU_FPR_22 0xace20096 277 #define SR_CPU_FPR_23 0xace20097 278 #define SR_CPU_FPR_24 0xace20098 279 #define SR_CPU_FPR_25 0xace20099 280 #define SR_CPU_FPR_26 0xace2009a 281 #define SR_CPU_FPR_27 0xace2009b 282 #define SR_CPU_FPR_28 0xace2009c 283 #define SR_CPU_FPR_29 0xace2009d 284 #define SR_CPU_FPR_30 0xace2009e 285 #define SR_CPU_FPR_31 0xace2009f 286 #define SR_CPU_FPC 0xace20100 287 #define SR_CPU_DXC 0xace20101 288 #define SR_CPU_MC 0xace20102 289 #define SR_CPU_EA 0xace20103 290 #define SR_CPU_PTIMER 0xace20104 291 #define SR_CPU_CLKC 0xace20105 292 #define SR_CPU_CHANSET 0xace20106 293 #define SR_CPU_TODPR 0xace20107 294 #define SR_CPU_MONCLASS 0xace20108 295 #define SR_CPU_EXCARID 0xace20109 296 #define SR_CPU_INTS_STATE 0xace2010a 297 #define SR_CPU_INTS_MASK 0xace2010b 298 #define SR_CPU_EXTCCPU 0xace2010c 299 #define SR_CPU_BEAR 0xace2010d 300 #define SR_CPU_OPNDRID 0xace20110 301 #define SR_CPU_CHECKSTOP 0xace20111 302 #define SR_CPU_HOSTINT 0xace20112 303 #define SR_CPU_EXECFLAG 0xace20113 304 #define SR_CPU_INSTVALID 0xace20114 305 #define SR_CPU_PERMODE 0xace20115 306 #define SR_CPU_LOADSTATE 0xace20116 307 #define SR_CPU_INVALIDATE 0xace20117 308 #define SR_CPU_RESET_OPCTAB 0xace20118 309 #define SR_CPU_SIGPRESET 0xace20119 310 #define SR_CPU_SIGPIRESET 0xace2011a 311 #define SR_CPU_VTIMERINT 0xace2011b 312 #define SR_CPU_RTIMERINT 0xace2011c 313 #define SR_CPU_MALFCPU 0xace20120 314 #define SR_CPU_MALFCPU_0 0xace20120 315 #define SR_CPU_MALFCPU_1 0xace20121 316 #define SR_CPU_MALFCPU_2 0xace20122 317 #define SR_CPU_MALFCPU_3 0xace20123 318 #define SR_CPU_MALFCPU_4 0xace20124 319 #define SR_CPU_MALFCPU_5 0xace20125 320 #define SR_CPU_MALFCPU_6 0xace20126 321 #define SR_CPU_MALFCPU_7 0xace20127 322 #define SR_CPU_MALFCPU_8 0xace20128 323 #define SR_CPU_MALFCPU_9 0xace20129 324 #define SR_CPU_MALFCPU_10 0xace2012a 325 #define SR_CPU_MALFCPU_11 0xace2012b 326 #define SR_CPU_MALFCPU_12 0xace2012c 327 #define SR_CPU_MALFCPU_13 0xace2012d 328 #define SR_CPU_MALFCPU_14 0xace2012e 329 #define SR_CPU_MALFCPU_15 0xace2012f 330 #define SR_CPU_MALFCPU_16 0xace20130 331 #define SR_CPU_MALFCPU_17 0xace20131 332 #define SR_CPU_MALFCPU_18 0xace20132 333 #define SR_CPU_MALFCPU_19 0xace20133 334 #define SR_CPU_MALFCPU_20 0xace20134 335 #define SR_CPU_MALFCPU_21 0xace20135 336 #define SR_CPU_MALFCPU_22 0xace20136 337 #define SR_CPU_MALFCPU_23 0xace20137 338 #define SR_CPU_MALFCPU_24 0xace20138 339 #define SR_CPU_MALFCPU_25 0xace20139 340 #define SR_CPU_MALFCPU_26 0xace2013a 341 #define SR_CPU_MALFCPU_27 0xace2013b 342 #define SR_CPU_MALFCPU_28 0xace2013c 343 #define SR_CPU_MALFCPU_29 0xace2013d 344 #define SR_CPU_MALFCPU_30 0xace2013e 345 #define SR_CPU_MALFCPU_31 0xace2013f 346 #define SR_CPU_EMERCPU 0xace20140 347 #define SR_CPU_EMERCPU_0 0xace20140 348 #define SR_CPU_EMERCPU_1 0xace20141 349 #define SR_CPU_EMERCPU_2 0xace20142 350 #define SR_CPU_EMERCPU_3 0xace20143 351 #define SR_CPU_EMERCPU_4 0xace20144 352 #define SR_CPU_EMERCPU_5 0xace20145 353 #define SR_CPU_EMERCPU_6 0xace20146 354 #define SR_CPU_EMERCPU_7 0xace20147 355 #define SR_CPU_EMERCPU_8 0xace20148 356 #define SR_CPU_EMERCPU_9 0xace20149 357 #define SR_CPU_EMERCPU_10 0xace2014a 358 #define SR_CPU_EMERCPU_11 0xace2014b 359 #define SR_CPU_EMERCPU_12 0xace2014c 360 #define SR_CPU_EMERCPU_13 0xace2014d 361 #define SR_CPU_EMERCPU_14 0xace2014e 362 #define SR_CPU_EMERCPU_15 0xace2014f 363 #define SR_CPU_EMERCPU_16 0xace20150 364 #define SR_CPU_EMERCPU_17 0xace20151 365 #define SR_CPU_EMERCPU_18 0xace20152 366 #define SR_CPU_EMERCPU_19 0xace20153 367 #define SR_CPU_EMERCPU_20 0xace20154 368 #define SR_CPU_EMERCPU_21 0xace20155 369 #define SR_CPU_EMERCPU_22 0xace20156 370 #define SR_CPU_EMERCPU_23 0xace20157 371 #define SR_CPU_EMERCPU_24 0xace20158 372 #define SR_CPU_EMERCPU_25 0xace20159 373 #define SR_CPU_EMERCPU_26 0xace2015a 374 #define SR_CPU_EMERCPU_27 0xace2015b 375 #define SR_CPU_EMERCPU_28 0xace2015c 376 #define SR_CPU_EMERCPU_29 0xace2015d 377 #define SR_CPU_EMERCPU_30 0xace2015e 378 #define SR_CPU_EMERCPU_31 0xace2015f 379 380 #define SR_DEV 0xace30000 381 #define SR_DEV_DEVTYPE 0xace30001 382 #define SR_DEV_ARGC 0xace30002 383 #define SR_DEV_ARGV 0xace30003 384 #define SR_DEV_TYPNAME 0xace30004 385 /* 386 * Following tag added for multiple Logical 387 * Channel subsystem support 388 */ 389 #define SR_DEV_LCSS 0xace30005 390 #define SR_DEV_ORB 0xace30010 391 #define SR_DEV_PMCW 0xace30011 392 #define SR_DEV_SCSW 0xace30012 393 #define SR_DEV_PCISCSW 0xace30013 394 #define SR_DEV_ATTNSCSW 0xace30014 395 #define SR_DEV_CSW 0xace30015 396 #define SR_DEV_PCICSW 0xace30016 397 #define SR_DEV_ATTNCSW 0xace30017 398 #define SR_DEV_ESW 0xace30018 399 #define SR_DEV_ECW 0xace30019 400 #define SR_DEV_SENSE 0xace3001a 401 #define SR_DEV_PGSTAT 0xace3001b 402 #define SR_DEV_PGID 0xace3001c 403 /* By Adrian - SR_DEV_DRVPWD */ 404 #define SR_DEV_DRVPWD 0xace3001d 405 406 #define SR_DEV_BUSY 0xace30020 407 #define SR_DEV_RESERVED 0xace30021 408 #define SR_DEV_SUSPENDED 0xace30022 409 #define SR_DEV_PENDING 0xace30023 410 #define SR_DEV_PCIPENDING 0xace30024 411 #define SR_DEV_ATTNPENDING 0xace30025 412 #define SR_DEV_STARTPENDING 0xace30026 413 #define SR_DEV_CRWPENDING 0xace30027 414 #define SR_DEV_CCWADDR 0xace30028 415 #define SR_DEV_IDAPMASK 0xace30029 416 #define SR_DEV_IDAWFMT 0xace3002a 417 #define SR_DEV_CCWFMT 0xace3002b 418 #define SR_DEV_CCWKEY 0xace3002c 419 420 #define SR_DEV_MASK 0xfffff000 421 #define SR_DEV_CKD 0xace31000 422 #define SR_DEV_FBA 0xace32000 423 #define SR_DEV_TTY 0xace33000 424 #define SR_DEV_3270 0xace34000 425 #define SR_DEV_RDR 0xace35000 426 #define SR_DEV_PUN 0xace36000 427 #define SR_DEV_PRT 0xace37000 428 #define SR_DEV_TAPE 0xace38000 429 #define SR_DEV_COMM 0xace39000 430 #define SR_DEV_CTC 0xace3a000 431 #define SR_DEV_CTCI 0xace3b000 432 #define SR_DEV_CTCT 0xace3c000 433 #define SR_DEV_VMNET 0xace3d000 434 #define SR_DEV_LCS 0xace3e000 435 #define SR_DEV_CTCE 0xace3f000 436 437 #define SR_DELIMITER 0xaceffffe 438 #define SR_EOF 0xacefffff 439 440 #if defined (_HERCULES_SR_C) 441 #define SR_WRITE_ERROR goto sr_write_error 442 #define SR_READ_ERROR goto sr_read_error 443 #define SR_SEEK_ERROR goto sr_seek_error 444 #define SR_VALUE_ERROR goto sr_value_error 445 #define SR_STRING_ERROR goto sr_string_error 446 #else 447 #define SR_WRITE_ERROR \ 448 do { \ 449 logmsg(_("HHCSR010E write error: %s\n"), strerror(errno)); \ 450 return -1; \ 451 } while (0) 452 #define SR_READ_ERROR \ 453 do { \ 454 logmsg(_("HHCSR011E read error: %s\n"), strerror(errno)); \ 455 return -1; \ 456 } while (0) 457 #define SR_SEEK_ERROR \ 458 do { \ 459 logmsg(_("HHCSR012E seek error: %s\n"), strerror(errno)); \ 460 return -1; \ 461 } while (0) 462 #define SR_VALUE_ERROR \ 463 do { \ 464 logmsg(_("HHCSR013E value error, incorrect length\n")); \ 465 return -1; \ 466 } while (0) 467 #define SR_STRING_ERROR \ 468 do { \ 469 logmsg(_("HHCSR014E string error, incorrect length\n")); \ 470 return -1; \ 471 } while (0) 472 #endif 473 474 #ifdef HAVE_LIBZ 475 #define SR_DEFAULT_FILENAME "hercules.srf.gz" 476 #define SR_FILE gzFile 477 #define SR_OPEN(_path, _mode) \ 478 gzopen((_path), (_mode)) 479 #define SR_READ(_ptr, _size, _nmemb, _stream) \ 480 gzread((_stream), (_ptr), (unsigned int)((_size) * (_nmemb))) 481 #define SR_WRITE(_ptr, _size, _nmemb, _stream) \ 482 gzwrite((_stream), (_ptr), (unsigned int)((_size) * (_nmemb))) 483 #define SR_SEEK(_stream, _offset, _whence) \ 484 gzseek((_stream), (_offset), (_whence)) 485 #define SR_CLOSE(_stream) \ 486 gzclose((_stream)) 487 #else 488 #define SR_DEFAULT_FILENAME "hercules.srf" 489 #define SR_FILE FILE* 490 #define SR_OPEN(_path, _mode) \ 491 fopen((_path), (_mode)) 492 #define SR_READ(_ptr, _size, _nmemb, _stream) \ 493 fread((_ptr), (_size), (_nmemb), (_stream)) 494 #define SR_WRITE(_ptr, _size, _nmemb, _stream) \ 495 fwrite((_ptr), (_size), (_nmemb), (_stream)) 496 #define SR_SEEK(_stream, _offset, _whence) \ 497 fseek((_stream), (_offset), (_whence)) 498 #define SR_CLOSE(_stream) \ 499 fclose((_stream)) 500 #endif 501 502 #define SR_WRITE_HDR(_file, _key, _len) \ 503 do { \ 504 size_t _rc; \ 505 BYTE _buf[8]; \ 506 store_fw (_buf, (_key)); \ 507 store_fw (_buf+4, (_len)); \ 508 _rc = SR_WRITE(_buf, 1, 8, (_file)); \ 509 if (_rc != 8) SR_WRITE_ERROR; \ 510 } while (0) 511 512 #define SR_WRITE_STRING(_file, _key, _s) \ 513 do { \ 514 size_t _rc; \ 515 if (strlen((_s)) + 1 > SR_MAX_STRING_LENGTH) SR_STRING_ERROR; \ 516 SR_WRITE_HDR((_file), (_key), strlen((_s)) + 1); \ 517 _rc = SR_WRITE((_s), 1, strlen((_s)) + 1, (_file)); \ 518 if (_rc != strlen((_s)) + 1) SR_WRITE_ERROR; \ 519 } while (0); 520 521 #define SR_WRITE_BUF(_file, _key, _buf, _len) \ 522 do { \ 523 size_t _rc; \ 524 if ((_len)) { \ 525 SR_WRITE_HDR((_file), (_key), (_len)); \ 526 _rc = SR_WRITE((_buf), 1, (_len), (_file)); \ 527 if (_rc != (_len)) SR_WRITE_ERROR; \ 528 } else \ 529 SR_WRITE_HDR((_file), (_key), 0); \ 530 } while (0) 531 532 #define SR_WRITE_VALUE(_file, _key, _val, _len) \ 533 do { \ 534 size_t _rc; \ 535 BYTE _buf[8]; \ 536 if ((_len) != 1 && (_len) != 2 && (_len) != 4 && (_len) != 8) \ 537 SR_VALUE_ERROR; \ 538 SR_WRITE_HDR((_file), (_key), (_len)); \ 539 switch ((_len)) { \ 540 case 1: _buf[0] = (_val); break; \ 541 case 2: store_hw(_buf, (_val)); break; \ 542 case 4: store_fw(_buf, (_val)); break; \ 543 case 8: store_dw(_buf, (_val)); break; \ 544 } \ 545 _rc = SR_WRITE(_buf, 1, (_len), (_file)); \ 546 if (_rc != (_len)) SR_WRITE_ERROR; \ 547 } while (0) 548 549 #define SR_READ_HDR(_file, _key, _len) \ 550 do { \ 551 size_t _rc; \ 552 BYTE _buf[8]; \ 553 _rc = SR_READ(_buf, 1, 8, (_file)); \ 554 if (_rc != 8) SR_READ_ERROR; \ 555 (_key) = fetch_fw(_buf); \ 556 (_len) = fetch_fw(_buf+4); \ 557 } while (0) 558 559 //FIXME: Workaround for problem involving gzseek 560 // and large files. Just read the data. 561 #define SR_READ_SKIP(_file, _len) \ 562 do { \ 563 size_t _rc; \ 564 size_t _l; \ 565 BYTE _buf[256]; \ 566 _l = (_len); \ 567 while (_l) { \ 568 _rc = SR_READ(_buf, 1, _l < 256 ? _l : 256, (_file)); \ 569 if (_rc == (size_t)-1) SR_READ_ERROR; \ 570 _l -= _l < 256 ? _l : 256; \ 571 } \ 572 } while (0) 573 574 #define SR_READ_STRING(_file, _p, _len) \ 575 do { \ 576 size_t _rc; \ 577 if ((_len) > SR_MAX_STRING_LENGTH) SR_STRING_ERROR; \ 578 _rc = SR_READ((_p), 1, (_len), (_file)); \ 579 if (_rc != (_len)) SR_READ_ERROR; \ 580 } while (0) 581 582 #define SR_READ_BUF(_file, _p, _len) \ 583 do { \ 584 size_t _rc; \ 585 _rc = SR_READ((_p), 1, (_len), (_file)); \ 586 if (_rc != (_len)) SR_READ_ERROR; \ 587 } while (0) 588 589 #define SR_READ_VALUE(_file, _len1, _p, _len2) \ 590 do { \ 591 size_t _rc; \ 592 BYTE _buf[8]; \ 593 U64 _value; \ 594 if ((_len1) != 1 && (_len1) != 2 && (_len1) != 4 && (_len1) != 8) \ 595 SR_VALUE_ERROR; \ 596 _rc = SR_READ(_buf, 1, (_len1), (_file)); \ 597 if (_rc != (_len1)) SR_READ_ERROR; \ 598 switch ((_len1)) { \ 599 case 1: _value = _buf[0]; break; \ 600 case 2: _value = fetch_hw(_buf); break; \ 601 case 4: _value = fetch_fw(_buf); break; \ 602 case 8: _value = fetch_dw(_buf); break; \ 603 default: _value=0; break; /* To ward off gcc -Wall */ \ 604 } \ 605 switch ((_len2)) { \ 606 case 1: \ 607 { \ 608 BYTE *_ptr = (void *)(_p); \ 609 *_ptr = _value & 0xff; \ 610 break; \ 611 } \ 612 case 2: \ 613 { \ 614 U16 *_ptr = (void *)(_p); \ 615 *_ptr = _value & 0xffff; \ 616 break; \ 617 } \ 618 case 4: \ 619 { \ 620 U32 *_ptr = (void *)(_p); \ 621 *_ptr = _value & 0xffffffff; \ 622 break; \ 623 } \ 624 case 8: \ 625 { \ 626 U64 *_ptr = (void *)(_p); \ 627 *_ptr = _value; \ 628 break; \ 629 } \ 630 } \ 631 } while (0) 632 633 #define SR_SKIP_NULL_DEV(_dev, _file, _len) \ 634 if ((_dev) == NULL) { \ 635 SR_READ_SKIP((_file),(_len)); \ 636 break; \ 637 } 638 639 #endif /* !defined(_HERCULES_SR_H) */ 640