driver-gen/xml-lib: Search for version header files in the correct dir
[driver-gen.git] / rwops.c
blobdd3b9650d48951c67d37b489b0e8bfa07c2e354b
1 /**
2 * @file rwops.c
4 * @brief Service register description and some register operations are here.
6 * @author Copyright (C) 2002 CERN. Stuart Baird
7 * @author Copyright (C) 2003 CERN. Alain Gagnaire
8 * @author Copyright (C) 2003 - 2010 CERN. Georgievskiy Yury <ygeorgie@cern.ch>
10 * @date Created on 27/02/2004
12 * @section license_sec License
13 * Released under the GPL
15 #include "driverGen.h"
17 /* describes all 'service' registers, provided by 'driverGen' */
18 SRVIOCTL srv_ioctl[] = {
20 .name = SRVREGPREF "DEBUG_FLAG",
21 .comment = "Flag Register. Enable/Disable various driver flags",
22 .type = "long",
23 .regSize = SZLONG,
24 .rar = AMRD | AMWR,
25 .depth = 1}
28 .name = SRVREGPREF "DEVINFO_T",
29 .comment = "Full device information (info file)",
30 .type = "long",
31 .regSize = 0, /* irrelevant, so set it to zero */
32 .rar = AMRD,
33 .depth = 1}
36 /* This register consists of the driver version string plus driver version
37 number. From the user point of view - he should pass two memory
38 locations - first that will hold version number, second one that will
39 hold version string. */
40 .name = SRVREGPREF "DRVR_VERS",
41 .comment =
42 "Driver version info (current version number and version info string)",
43 .type = "char",
44 .regSize = MAX_STR + 4, /* version string + version number */
45 .rar = AMRD,
46 .depth = 1}
49 .name = SRVREGPREF "DAL_CONSISTENT",
50 .comment =
51 "driver/DAL consistency checking (comparision between the creation dates)",
52 .type = "long",
53 .regSize = SZLONG,
54 .rar = AMRD,
55 .depth = 1}
57 /* ---------[ NOTE ON SPECIAL SERVICE REGISTERS ]-------------------
58 If you want to add a SPECIAL register, you should set reg access
59 rights (rar member) to zero. Register depth (depth member) should
60 be greater than zero. Such register will have one ioctl number */
62 /* This is a SPECIAL service register.
63 Handles repetitive register r/w access. Contains no data. */
64 .name = SRVREGPREF "REP_REG_RW",
65 .comment = "Special ioctl number for repetitive register r/w access",
66 .type = 0,
67 .regSize = 0,
68 .rar = 0, /* indicates special register type.
69 No menu entry in the test program as this register
70 contains no data */
71 .depth = 1}
74 /* SPECIAL service register.
75 Enable/Disable/Query r/w bounds checking in ioctl calls.
76 Write 1 - to enable, 0 - to disable, 2 - to query current state */
77 .name = SRVREGPREF "RW_BOUNDS",
78 .comment = "Special ioctl number to enable/disable r/w bounds"
79 " checking during ioctl call",
80 .type = 0,
81 .regSize = 0,
82 .rar = 0, /* indicates special register type.
83 No menu entry in the test program as this register
84 contains no data */
85 .depth = 1}
87 /* Add any new description before the last element!
88 !NOTE!
89 All service register names should start with 'SRVREGPREF'
90 If you add any new service register, than you should modify
91 srvRegOps.c, testMainBegin.c and ioctl/head.c template files for
92 payload implementation of the newly defined service registers.
95 .name = "LAST_SRV_REG",
96 .comment = "first user-available register ID number",
97 .type = 0,
98 .regSize = 0,
99 .rar = 0,
100 .depth = 0 /* indicates the last service reg element */
105 * @brief Pack Ioctl number
107 * @param opNum - number to pack. (see more in detailed description)
108 * @param a_r - register access rights
109 * @param isSrv - denotes register type (service or normal)
111 * First parameter should be zero for the first invocation of this function.
112 * This number will be properly change, so that next time user should pass the
113 * previously returned number. Pay attention to the fact that if you invoke
114 * this function once, then next time as a first parameter you should pass
115 * the number that was returned by the previous call. If not follow this
116 * rule - then discrepancy between defined ioctl numbers and driver ioctl
117 * numbers will occur.
118 * Two MSB are for 'r' operation number.
119 * Two LSB are for 'w' operation number.
120 * Example: XXXX|XXXX
121 * ^ ^
122 * | |
123 * read write
124 * number number
126 * @return masked operation number.
128 int PackIoctlNum(int *opNum, ARIGHTS a_r, bool isSrv)
130 int res = -1; /* if r/w ioctl num is equal to 0xffff - then it means
131 that it's not defined for the given register */
133 switch (a_r) {
134 case AMRD: /* 'r' */
135 res = (*opNum) << 16; /* move 'r' to the 'most significant' halfword */
136 (*opNum)++;
137 break;
138 case AMWR: /* 'w' */
139 if (!isSrv) { /* because of "GET_HISTORY" is possible in this case! */
140 res = (*opNum) << 16; /* move 'r' to the 'most significant' halfword */
141 (*opNum)++;
143 res |= (*opNum);
144 (*opNum)++;
145 break;
146 case AMRD | AMWR: /* 'wr' */
147 case AMEX:
148 res = (*opNum) << 16; /* move 'r' to the 'most significant' halfword */
149 (*opNum)++;
150 res |= (*opNum);
151 (*opNum)++;
152 break;
153 default: /* access rights not defined for this register */
154 if (isSrv) { /* SPECIAL service reg. he's got one ioctl number!
155 (will be the same for read and write) */
156 res = ((*opNum) << 16) + *opNum;
157 (*opNum)++;
158 } else {
159 res = -1;
161 break;
163 return (res);
167 * @brief Build-up enumiration table header file for all module registers.
169 * @param blocks - block description
170 * @param registers - register description
171 * @param numRegisters - register amount
173 * Fill it in properly with the information from the database.
175 * @return void
177 void BuildRegIdEnum(BlockDef_t * blocks, RegisterDef_t * registers,
178 int numRegisters)
180 char *bus = TranslationGetBus(); /* 'VME' or 'DRM' */
181 FILE *fp;
182 int cntr;
184 fp = OpenFile(COMMON_FT, LOC_INCL, "RegId.h");
185 TranslationSetFreeFormat("%s", DG_INC_DIR);
186 Translate(fp, bus, "regDesc/regIdHead.h");
188 /* pass though all registers */
189 for (cntr = 0; cntr < numRegisters; cntr++) {
190 TranslationSetRegId(registers[cntr].upperName);
191 TranslationSetRegComm(registers[cntr].comment);
192 TranslationSetFancyString(registers[cntr].mode);
193 if (!cntr) {
194 /* first module register number should start
195 just after the last service register number */
196 TranslationSetDummyString(srv_ioctl[GetSrvRegNum()].
197 name);
198 Translate(fp, "common", "header/regIdEnumIndexed.h");
199 } else {
200 Translate(fp, "common", "header/regIdEnum.h");
204 Translate(fp, bus, "regDesc/regIdFoot.h");
205 fclose(fp);
209 * @brief Get number of all defined <E>Service Registers</E>
211 * @return amount of defined Service Registers.
213 int GetSrvRegNum()
215 SRVIOCTL *ptr = srv_ioctl;
216 static int cntr = -1;
218 if (cntr == -1) { /* see if already defined */
219 cntr = 0; /* reset it */
220 while (ptr->depth) { /* 0 means no more sevice registers left */
221 ptr++;
222 cntr++;
225 return (cntr);
229 * @brief Converts register access rights into register access mode.
231 * @param rar - register access rights
233 * It converts from enum representation to char representation. Note that
234 * subsequent calls modifies previously reterned string. So you should save
235 * it in a local buffer before next call to this function.
237 * @return string pointer to register access mode.
239 char *rar2mode(ARIGHTS rar)
241 static char ram[4] = { 0, 0, 0, 0 }; /* register access mode (rwe) */
243 /* read register */
244 if (rar & AMRD)
245 ram[0] = 'r';
246 else
247 ram[0] = '-';
249 /* write register */
250 if (rar & AMWR)
251 ram[1] = 'w';
252 else
253 ram[1] = '-';
255 /* extraneous register */
256 if (rar & AMEX)
257 ram[2] = 'e';
258 else
259 ram[2] = '-';
261 return (ram);
265 * @brief Converts register access mode into register access rights.
267 * @param mode - register access mode (rwec)
269 * It converts from char representation to enum representation.
271 * @return register access rights
273 ARIGHTS mode2rar(char *mode)
275 int cntr;
276 ARIGHTS rar = 0;
278 if (strlen(mode) > 4)
279 return (rar); /* wrong access mode string format */
281 for (cntr = 0; cntr < 4; cntr++) {
282 switch (mode[cntr]) {
283 case 'r':
284 rar |= AMRD;
285 break;
286 case 'w':
287 rar |= AMWR;
288 break;
289 case 'e':
290 rar |= AMEX;
291 break;
292 default:
293 rar = 0; /* oops... */
294 return (rar);
298 return (rar);