[driver-gen-git] Add git library files.
[driver-gen.git] / rwops.c
blob1a4c5d849ada5b85ffda37e88529d7befecacb9c
1 /**
2 * @file rwops.c
4 * @brief Service register description and some register operations are here.
6 * @author Copyright (c) 2004 - 2009 CERN. Georgievskiy Yury, Alain Gagnaire
8 * @date Created on 27/02/2004
9 */
10 #include "driverGen.h"
12 /* describes all 'service' registers, provided by 'driverGen' */
13 SRVIOCTL srv_ioctl[] = {
15 .name = SRVREGPREF "DEBUG_FLAG",
16 .comment = "Flag Register. Enable/Disable various driver flags",
17 .type = "long",
18 .regSize = SZLONG,
19 .rar = AMRD | AMWR,
20 .depth = 1}
23 .name = SRVREGPREF "DEVINFO_T",
24 .comment = "Full device information (info file)",
25 .type = "long",
26 .regSize = 0, /* irrelevant, so set it to zero */
27 .rar = AMRD,
28 .depth = 1}
31 /* This register consists of the driver version string plus driver version
32 number. From the user point of view - he should pass two memory
33 locations - first that will hold version number, second one that will
34 hold version string. */
35 .name = SRVREGPREF "DRVR_VERS",
36 .comment =
37 "Driver version info (current version number and version info string)",
38 .type = "char",
39 .regSize = MAX_STR + 4, /* version string + version number */
40 .rar = AMRD,
41 .depth = 1}
44 .name = SRVREGPREF "DAL_CONSISTENT",
45 .comment =
46 "driver/DAL consistency checking (comparision between the creation dates)",
47 .type = "long",
48 .regSize = SZLONG,
49 .rar = AMRD,
50 .depth = 1}
52 /* ---------[ NOTE ON SPECIAL SERVICE REGISTERS ]-------------------
53 If you want to add a SPECIAL register, you should set reg access
54 rights (rar member) to zero. Register depth (depth member) should
55 be greater than zero. Such register will have one ioctl number */
57 /* This is a SPECIAL service register.
58 Handles repetitive register r/w access. Contains no data. */
59 .name = SRVREGPREF "REP_REG_RW",
60 .comment = "Special ioctl number for repetitive register r/w access",
61 .type = 0,
62 .regSize = 0,
63 .rar = 0, /* indicates special register type.
64 No menu entry in the test program as this register
65 contains no data */
66 .depth = 1}
69 /* SPECIAL service register.
70 Enable/Disable/Query r/w bounds checking in ioctl calls.
71 Write 1 - to enable, 0 - to disable, 2 - to query current state */
72 .name = SRVREGPREF "RW_BOUNDS",
73 .comment = "Special ioctl number to enable/disable r/w bounds"
74 " checking during ioctl call",
75 .type = 0,
76 .regSize = 0,
77 .rar = 0, /* indicates special register type.
78 No menu entry in the test program as this register
79 contains no data */
80 .depth = 1}
82 /* Add any new description before the last element!
83 !NOTE!
84 All service register names should start with 'SRVREGPREF'
85 If you add any new service register, than you should modify
86 srvRegOps.c, testMainBegin.c and ioctl/head.c template files for
87 payload implementation of the newly defined service registers.
90 .name = "LAST_SRV_REG",
91 .comment = "first user-available register ID number",
92 .type = 0,
93 .regSize = 0,
94 .rar = 0,
95 .depth = 0 /* indicates the last service reg element */
99 /**
100 * @brief Pack Ioctl number
102 * @param opNum - number to pack. (see more in detailed description)
103 * @param a_r - register access rights
104 * @param isSrv - denotes register type (service or normal)
106 * First parameter should be zero for the first invocation of this function.
107 * This number will be properly change, so that next time user should pass the
108 * previously returned number. Pay attention to the fact that if you invoke
109 * this function once, then next time as a first parameter you should pass
110 * the number that was returned by the previous call. If not follow this
111 * rule - then discrepancy between defined ioctl numbers and driver ioctl
112 * numbers will occur.
113 * Two MSB are for 'r' operation number.
114 * Two LSB are for 'w' operation number.
115 * Example: XXXX|XXXX
116 * ^ ^
117 * | |
118 * read write
119 * number number
121 * @return masked operation number.
123 int PackIoctlNum(int *opNum, ARIGHTS a_r, bool isSrv)
125 int res = -1; /* if r/w ioctl num is equal to 0xffff - then it means
126 that it's not defined for the given register */
128 switch (a_r) {
129 case AMRD: /* 'r' */
130 res = (*opNum) << 16; /* move 'r' to the 'most significant' halfword */
131 (*opNum)++;
132 break;
133 case AMWR: /* 'w' */
134 if (!isSrv) { /* because of "GET_HISTORY" is possible in this case! */
135 res = (*opNum) << 16; /* move 'r' to the 'most significant' halfword */
136 (*opNum)++;
138 res |= (*opNum);
139 (*opNum)++;
140 break;
141 case AMRD | AMWR: /* 'wr' */
142 case AMEX:
143 res = (*opNum) << 16; /* move 'r' to the 'most significant' halfword */
144 (*opNum)++;
145 res |= (*opNum);
146 (*opNum)++;
147 break;
148 default: /* access rights not defined for this register */
149 if (isSrv) { /* SPECIAL service reg. he's got one ioctl number!
150 (will be the same for read and write) */
151 res = ((*opNum) << 16) + *opNum;
152 (*opNum)++;
153 } else {
154 res = -1;
156 break;
158 return (res);
162 * @brief Build-up enumiration table header file for all module registers.
164 * @param blocks - block description
165 * @param registers - register description
166 * @param numRegisters - register amount
168 * Fill it in properly with the information from the database.
170 * @return void
172 void BuildRegIdEnum(BlockDef_t * blocks, RegisterDef_t * registers,
173 int numRegisters)
175 char *bus = TranslationGetBus(); /* 'VME' or 'DRM' */
176 FILE *fp;
177 int cntr;
179 fp = OpenFile(COMMON_FT, LOC_INCL, "RegId.h");
180 TranslationSetFreeFormat("%s", DG_INC_DIR);
181 Translate(fp, bus, "regDesc/regIdHead.h");
183 /* pass though all registers */
184 for (cntr = 0; cntr < numRegisters; cntr++) {
185 TranslationSetRegId(registers[cntr].upperName);
186 TranslationSetRegComm(registers[cntr].comment);
187 TranslationSetFancyString(registers[cntr].mode);
188 if (!cntr) {
189 /* first module register number should start
190 just after the last service register number */
191 TranslationSetDummyString(srv_ioctl[GetSrvRegNum()].
192 name);
193 Translate(fp, "common", "header/regIdEnumIndexed.h");
194 } else {
195 Translate(fp, "common", "header/regIdEnum.h");
199 Translate(fp, bus, "regDesc/regIdFoot.h");
200 fclose(fp);
204 * @brief Get number of all defined <E>Service Registers</E>
206 * @return amount of defined Service Registers.
208 int GetSrvRegNum()
210 SRVIOCTL *ptr = srv_ioctl;
211 static int cntr = -1;
213 if (cntr == -1) { /* see if already defined */
214 cntr = 0; /* reset it */
215 while (ptr->depth) { /* 0 means no more sevice registers left */
216 ptr++;
217 cntr++;
220 return (cntr);
224 * @brief Converts register access rights into register access mode.
226 * @param rar - register access rights
228 * It converts from enum representation to char representation. Note that
229 * subsequent calls modifies previously reterned string. So you should save
230 * it in a local buffer before next call to this function.
232 * @return string pointer to register access mode.
234 char *rar2mode(ARIGHTS rar)
236 static char ram[4] = { 0, 0, 0, 0 }; /* register access mode (rwe) */
238 /* read register */
239 if (rar & AMRD)
240 ram[0] = 'r';
241 else
242 ram[0] = '-';
244 /* write register */
245 if (rar & AMWR)
246 ram[1] = 'w';
247 else
248 ram[1] = '-';
250 /* extraneous register */
251 if (rar & AMEX)
252 ram[2] = 'e';
253 else
254 ram[2] = '-';
256 return (ram);
260 * @brief Converts register access mode into register access rights.
262 * @param mode - register access mode (rwec)
264 * It converts from char representation to enum representation.
266 * @return register access rights
268 ARIGHTS mode2rar(char *mode)
270 int cntr;
271 ARIGHTS rar = 0;
273 if (strlen(mode) > 4)
274 return (rar); /* wrong access mode string format */
276 for (cntr = 0; cntr < 4; cntr++) {
277 switch (mode[cntr]) {
278 case 'r':
279 rar |= AMRD;
280 break;
281 case 'w':
282 rar |= AMWR;
283 break;
284 case 'e':
285 rar |= AMEX;
286 break;
287 default:
288 rar = 0; /* oops... */
289 return (rar);
293 return (rar);