vmod/vmodttl: fixed bug related to luns not ordered and/or not starting from zero.
[ht-drivers.git] / utils / extest / cmd_skel.c
blob2d2ebcdc7fd997d1287089abdc24a0e7ab3d2249
1 /**
2 * @file cmd_skel.c
4 * @brief extest's command handlers for skel-based drivers
6 * @author Copyright (C) 2009 CERN CO/HT Emilio G. Cota
7 * <emilio.garcia.cota@cern.ch>
8 * @author Copyright (C) 2008 CERN CO/HT Yury Georgievskiy
9 * <yury.georgievskiy@cern.ch>
11 * @section license_sec License
12 * Released under the GPL v2. (and only v2, not any later version)
14 #include <sys/ioctl.h>
15 #include <time.h>
16 #include <unistd.h>
18 /* local includes */
19 #include <err.h>
20 #include <general_usr.h> /* for handy definitions (mperr etc..) */
22 #include <extest.h>
24 extern int get_free_user_handle(int);
25 extern void print_modules();
27 /**
28 * hndl_swdeb - handler for software debugging
30 * @param cmdd - command description
31 * @param atoms - command atoms list
33 * @return >= 0 - on success
34 * @return tst_prg_err_t - on failure
36 int hndl_swdeb(struct cmd_desc* cmdd, struct atom *atoms)
38 SkelDrvrDebug db;
39 unsigned int flag;
41 if (atoms == (struct atom*)VERBOSE_HELP) {
42 printf("%s - print current software debugging state\n"
43 "%s flag [pid] - set software debugging\n"
44 "flag:\n"
45 "\t0x00: disable debugging\n"
46 "\t0x01: assertion violations\n"
47 "\t0x02: trace all IOCTLS\n"
48 "\t0x04: warning messages\n"
49 "\t0x08: module specific debug warnings\n"
50 "\t0x10: verbose debugging information\n"
51 "\t0x100: driver emulation on NO hardware\n"
52 "pid is optional (current pid is the default)\n",
53 cmdd->name, cmdd->name);
54 goto out;
57 if (is_last_atom(atoms)) { /* no arguments --> GET debug */
58 if (ioctl(_DNFD, SkelDrvrIoctlGET_DEBUG, &db) < 0) {
59 mperr("%s ioctl failed\n", "GET_DEBUG");
60 return -TST_ERR_IOCTL;
62 flag = db.DebugFlag;
63 printf("Software debug mask: 0x%x\n", flag);
64 if (flag & SkelDrvrDebugFlagASSERTION)
65 printf("Flag set: assertion violations\n");
66 if (flag & SkelDrvrDebugFlagTRACE)
67 printf("Flag set: trace all IOCTL calls\n");
68 if (flag & SkelDrvrDebugFlagWARNING)
69 printf("Flag set: warning messages\n");
70 if (flag & SkelDrvrDebugFlagMODULE)
71 printf("Flag set: module specific debug warnings\n");
72 if (flag & SkelDrvrDebugFlagINFORMATION)
73 printf("Flag set: all debug information\n");
74 if (flag & SkelDrvrDebugFlagEMULATION)
75 printf("Flag set: emulation on NO hardware\n");
76 goto out;
78 /* SET debug */
79 atoms++;
80 if (atoms->type != Numeric) {
81 printf("invalid argument\n");
82 return -TST_ERR_WRONG_ARG;
84 db.DebugFlag = atoms->val;
85 printf("flag: %x\n", db.DebugFlag);
86 atoms++;
87 if (is_last_atom(atoms) || !atoms->val)
88 db.ClientPid = getpid();
89 else {
90 if (atoms->type == Numeric)
91 db.ClientPid = atoms->val;
92 else
93 return -TST_ERR_WRONG_ARG;
95 if (ioctl(_DNFD, SkelDrvrIoctlSET_DEBUG, &db) < 0) {
96 mperr("%s ioctl failed\n", "SET_DEBUG");
97 return -TST_ERR_IOCTL;
99 printf("%s ioctl: successfully set flag 0x%x for pid %d\n",
100 "SET_DEBUG", db.DebugFlag, db.ClientPid);
101 out:
102 return 1;
106 * hndl_getversion - handler for get driver/module version
108 * @param cmdd - command description
109 * @param atoms - command atoms list
111 * @return >= 0 - on success
112 * @return tst_prg_err_t - on failure
114 int hndl_getversion(struct cmd_desc* cmdd, struct atom *atoms)
116 SkelDrvrVersion vers;
118 if (atoms == (struct atom*)VERBOSE_HELP) {
119 printf("No further help available\n");
120 goto out;
122 if (ioctl(_DNFD, SkelDrvrIoctlGET_VERSION, &vers) < 0) {
123 mperr("GET_VERSION ioctl failed\n");
124 return -TST_ERR_IOCTL;
126 printf("Version:\n"
127 "\tDriver compile date (human): %s"
128 "\tDriver compile date (EPOCH): %d\n"
129 "\tModule version: %s\n",
130 ctime((time_t *)&vers.DriverVersion), vers.DriverVersion,
131 vers.ModuleVersion);
132 out:
133 return 1;
137 * select_module - select a particular module
139 * @param modnr module number to select
141 * @return 0 - on success
142 * @return (negative) error code - on failure
144 int select_module(int modnr)
146 if (modnr == tst_glob_d.mod)
147 return 0;
148 if (ioctl(_DNFD, SkelDrvrIoctlSET_MODULE, &modnr) < 0) {
149 mperr("%s ioctl fails\n", "SET_MODULE");
150 return -TST_ERR_IOCTL;
152 tst_glob_d.mod = modnr;
153 printf("Controlling module #%d\n", tst_glob_d.mod);
154 return 0;
158 * hndl_module - handle for 'module' -- used to manage devices
160 * @param cmdd - command description
161 * @param atoms - command atoms list
163 * @return >= 0 - on success
164 * @return tst_prg_err_t - on failure
166 int hndl_module(struct cmd_desc *cmdd, struct atom *atoms)
168 int sel; /* keep ret. code from select_module */
170 if (atoms == (struct atom *)VERBOSE_HELP) {
171 printf("select or show modules\n"
172 "%s - shows currently selected module\n"
173 "%s ? - prints all managed modules by the driver\n"
174 "%s x - select module x (where x ranges from 1 to n)\n"
175 "%s ++ - select next module\n"
176 "%s -- - select next module\n",
177 cmdd->name, cmdd->name, cmdd->name, cmdd->name,
178 cmdd->name);
179 goto out;
181 if (ioctl(_DNFD, SkelDrvrIoctlGET_MODULE_COUNT, &tst_glob_d.ma) < 0) {
182 mperr("Can't get module count. %s ioctl fails\n",
183 "GET_MODULE_COUNT");
184 goto out;
186 if (!tst_glob_d.ma) {
187 printf("The driver does not control any modules\n");
188 goto out;
190 ++atoms;
192 if (atoms->type != Numeric) {
193 if (atoms->type == Operator)
194 switch (atoms->oid) {
195 case OprNOOP:
196 print_modules();
197 break;
198 case OprINC:
199 sel = select_module(tst_glob_d.mod + 1);
200 if (sel < 0)
201 return sel;
202 goto out;
203 case OprDECR:
204 sel = select_module(tst_glob_d.mod - 1);
205 if (sel < 0)
206 return sel;
207 goto out;
208 default:
209 break;
211 if (tst_glob_d.mod)
212 printf("Controlling module #%d (out of %d)\n",
213 tst_glob_d.mod, tst_glob_d.ma);
214 else
215 printf("The driver manages %d device%s\n",
216 tst_glob_d.ma, tst_glob_d.ma > 1 ? "s" : "");
217 goto out;
219 sel = select_module(atoms->val);
220 if (sel < 0)
221 return sel;
222 out:
223 return 1;
227 * hndl_nextmodule - select next module handler
229 * @param cmdd - command description
230 * @param atoms - command atoms list
232 * @return >= 0 - on success
233 * @return tst_prg_err_t - on failure
235 int hndl_nextmodule(struct cmd_desc *cmdd, struct atom *atoms)
237 int sel; /* keep ret. code from select_module */
239 if (atoms == (struct atom *)VERBOSE_HELP) {
240 printf("%s - select next module\n"
241 "This command takes no arguments.\n", cmdd->name);
242 goto out;
244 sel = select_module(tst_glob_d.mod + 1);
245 if (sel < 0)
246 return sel;
247 out:
248 return 1;
252 * print_rawio - print the 'RawIO' beginning of line
254 * @param rio - RawIo block
255 * @param radix - hex (16) or decimal
257 void print_rawio(SkelDrvrRawIoBlock *rio, int radix)
259 printf("\n%08x@space#%02x: ", rio->Offset, rio->SpaceNumber);
260 if (radix == 16)
261 printf("0x%-*x ", rio->DataWidth >> 2, rio->Data);
262 else
263 printf("%5d ", rio->Data);
268 * rawio_input - manage 'RawIO' command input
270 * @param ch - initial input character
271 * @param rio - RawIo block
272 * @param radix - hex (16) or decimal
274 * @return 0 - on success
275 * @return tst_prg_err_t - on failure
277 int rawio_input(char ch, SkelDrvrRawIoBlock *rio, int *radix)
279 char str[128];
280 char *endptr;
281 int input;
282 int i = 0;
283 char c = ch;
285 bzero((void *)str, 128);
286 switch (c) {
287 case '/':
288 while (c != '\n' && i < 128) {
289 c = getchar();
290 str[i++] = c;
292 input = strtoul(str, &endptr, *radix);
293 if (endptr != str) { /* caught something */
294 rio->Offset = input;
295 printf("\n");
297 break;
298 case 'x':
299 *radix = 16;
300 break;
301 case 'd':
302 *radix = 10;
303 break;
304 case '\n':
305 rio->Offset += rio->DataWidth / 8;
306 break;
307 case '.':
308 c = getchar();
309 printf("\n");
310 break;
311 default: /* write */
312 str[i++] = c;
313 while (c != '\n' && i < 128) {
314 c = getchar();
315 str[i++] = c;
317 input = strtoul(str, &endptr, *radix);
318 if (endptr == str)
319 break; /* nothing caught */
320 rio->Data = input;
321 if (ioctl(_DNFD, SkelDrvrIoctlRAW_WRITE, rio) < 0) {
322 mperr("RAW_WRITE ioctl fails");
323 return -TST_ERR_IOCTL;
325 break;
327 return 0;
331 * hndl_rawio - 'RawIO' handler
333 * @param cmdd - command description
334 * @param atoms - command atoms list
336 * @return >= 0 - on success
337 * @return tst_prg_err_t - on failure
339 int hndl_rawio(struct cmd_desc* cmdd, struct atom *atoms)
341 SkelDrvrRawIoBlock rio;
342 int radix = 16;
343 int err;
344 char c = '\n';
346 if (atoms == (struct atom *)VERBOSE_HELP) {
347 printf("raw I/O\n"
348 "%s spacenumber datawidth offset\n"
349 "\tspacenumber: VME->AddressModifier, PCI->BAR\n"
350 "\tdatawidth: 8, 16, 32.\n"
351 "\toffset: offset within the address space\n",
352 cmdd->name);
353 goto out;
355 if (!compulsory_ok(cmdd)) {
356 printf("Wrong parameter amount\n");
357 return -TST_ERR_ARG_O_S;
359 if (((atoms + 1)->type | (atoms + 2)->type | (atoms + 3)->type)
360 != Numeric) {
361 printf("Invalid argument (parameters have to be numeric.)\n");
362 return -TST_ERR_WRONG_ARG;
364 rio.SpaceNumber = (++atoms)->val;
365 rio.DataWidth = (++atoms)->val;
366 rio.DataWidth &= (1 << 3) | (1 << 4) | (1 << 5);
367 if (!rio.DataWidth) {
368 printf("Invalid argument (DataWidth must be 8, 16 or 32.)\n");
369 return -TST_ERR_WRONG_ARG;
371 rio.Offset = (++atoms)->val;
373 printf("RawIO: [/]: Open; [CR]: Next; [.]: Exit; [x]: Hex; [d]: Dec\n");
374 do {
375 if (ioctl(_DNFD, SkelDrvrIoctlRAW_READ, &rio) < 0) {
376 mperr("%s ioctl fails:\n"
377 "space #: %d; data width:%d, offset: %d\n",
378 "RAW_READ", rio.SpaceNumber, rio.DataWidth,
379 rio.Offset);
380 return -TST_ERR_IOCTL;
382 print_rawio(&rio, radix);
383 c = getchar();
384 if ((err = rawio_input(c, &rio, &radix)))
385 return err;
386 } while (c != '.');
387 out:
388 return 1;
392 * hndl_maps - handler for showing the address mappings of the current device
394 * @param cmdd - command description
395 * @param atoms - command atoms list
397 * @return >= 0 - on success
398 * @return tst_prg_err_t - on failure
400 int hndl_maps(struct cmd_desc *cmdd, struct atom *atoms)
402 int i;
403 SkelDrvrMaps maps;
405 if (atoms == (struct atom *)VERBOSE_HELP) {
406 printf("%s takes no parameters\n"
407 "\tjust select a module before issuing %s\n",
408 cmdd->name, cmdd->name);
409 goto out;
411 if (ioctl(_DNFD, SkelDrvrIoctlGET_MODULE_MAPS, &maps) < 0) {
412 mperr("%s ioctl fails\n", "GET_MODULE_MAPS");
413 return -TST_ERR_IOCTL;
415 if (!maps.Mappings) {
416 printf("No mappings for module #%d\n", tst_glob_d.mod);
417 goto out;
419 printf("Space#\t\tMapped\n"
420 "------\t\t------\n");
422 for (i = 0; i < maps.Mappings; i++) {
423 printf("0x%x\t\t0x%lx\n", maps.Maps[i].SpaceNumber,
424 maps.Maps[i].Mapped);
426 out:
427 return 1;
431 * hndl_timeout - 'timeout' handler
433 * @param cmdd - command description
434 * @param atoms - command atoms list
436 * @return >= 0 - on success
437 * @return tst_prg_err_t - on failure
439 int hndl_timeout(struct cmd_desc *cmdd, struct atom *atoms)
441 int timeout;
443 if (atoms == (struct atom *)VERBOSE_HELP) {
444 printf("get/set timeout\n"
445 "%s - shows current timeout [in 10ms chunks]\n"
446 "%s x - set timeout x [in 10ms chunks]\n",
447 cmdd->name, cmdd->name);
448 goto out;
450 if (is_last_atom(atoms)) {
451 if (ioctl(_DNFD, SkelDrvrIoctlGET_TIMEOUT, &timeout) < 0) {
452 mperr("%s ioctl fails\n", "GET_TIMEOUT");
453 return -TST_ERR_IOCTL;
455 printf("timeout: %d [10*ms]\n", timeout);
456 goto out;
458 atoms++;
459 if (atoms->type != Numeric) {
460 printf("Invalid argument (must be numeric.)\n");
461 return -TST_ERR_WRONG_ARG;
463 timeout = atoms->val;
464 if (ioctl(_DNFD, SkelDrvrIoctlSET_TIMEOUT, &timeout) < 0) {
465 mperr("%s ioctl fails\n", "SET_TIMEOUT");
466 return -TST_ERR_IOCTL;
468 printf("timeout set to %d [10*ms] == %d ms\n", timeout, timeout * 10);
469 out:
470 return 1;
475 * print_queue - display current device's queue information
477 int print_queue()
479 unsigned int qflag, qsize, qover;
481 if (ioctl(_DNFD, SkelDrvrIoctlGET_QUEUE_FLAG, &qflag) < 0) {
482 mperr("%s ioctl fails\n", "GET_QUEUE_FLAG");
483 return -TST_ERR_IOCTL;
485 if (ioctl(_DNFD, SkelDrvrIoctlGET_QUEUE_SIZE, &qsize) < 0) {
486 mperr("%s ioctl fails\n", "GET_QUEUE_SIZE");
487 return -TST_ERR_IOCTL;
489 if (ioctl(_DNFD, SkelDrvrIoctlGET_QUEUE_OVERFLOW, &qover) < 0) {
490 mperr("%s ioctl fails\n", "GET_QUEUE_OVERFLOW");
491 return -TST_ERR_IOCTL;
493 if (qflag)
494 printf("Queueing is OFF\n");
495 else {
496 printf("Queueing is ON\n"
497 "\tQueue size: %d\n"
498 "\tQueue overflow: %d\n", qsize, qover);
500 return 0;
504 * hndl_queue - 'queue' handler
506 * @param cmdd - command description
507 * @param atoms - command atoms list
509 * @return >= 0 - on success
510 * @return tst_prg_err_t - on failure
512 int hndl_queue(struct cmd_desc *cmdd, struct atom *atoms)
514 int qflag;
515 int ret;
517 if (atoms == (struct atom *)VERBOSE_HELP) {
518 printf("get/set queue flag\n"
519 "%s - shows current state of the queue\n"
520 "%s 1 - Turn queueing OFF\n"
521 "%s 0 - Turn queueing ON\n",
522 cmdd->name, cmdd->name, cmdd->name);
523 goto out;
525 if ((++atoms)->type == Numeric) {
526 qflag = atoms->val;
527 if (ioctl(_DNFD, SkelDrvrIoctlSET_QUEUE_FLAG, &qflag) < 0) {
528 mperr("%s ioctl fails\n", "SET_QUEUE_FLAG");
529 return -TST_ERR_IOCTL;
531 printf("Queue switched %s successfully\n",
532 !!qflag ? "OFF" : "ON");
533 goto out;
535 ret = print_queue();
536 if (ret < 0)
537 return ret;
538 out:
539 return 1;
544 * print_client_connections - show a client's list of connections
546 * @param pid - pid of the client
548 * @return number of connections of the client
550 int print_client_connections(int pid)
552 int i;
553 int mypid = getpid();
554 SkelDrvrConnection *conn;
555 SkelDrvrClientConnections conns;
557 bzero((void *)&conns, sizeof(SkelDrvrClientConnections));
558 conns.Pid = pid;
559 if (ioctl(_DNFD, SkelDrvrIoctlGET_CLIENT_CONNECTIONS, &conns) < 0) {
560 mperr("%s ioctl fails\n", "GET_CLIENT_CONNECTIONS");
561 return -TST_ERR_IOCTL;
563 printf("Pid: %d%s\n", pid, pid == mypid ? " (test program)" : "");
564 if (!conns.Size)
565 return 0;
566 for (i = 0; i < conns.Size; i++) {
567 conn = &conns.Connections[i];
568 printf("\tModule: %d, Mask: 0x%08x\n", conn->Module,
569 conn->ConMask);
571 return conns.Size;
575 * hndl_clients - 'list of clients' handler
577 * @param cmdd - command description
578 * @param atoms - command atoms list
580 * @return >= 0 - on success
581 * @return tst_prg_err_t - on failure
583 int hndl_clients(struct cmd_desc *cmdd, struct atom *atoms)
585 int i;
586 int ccret;
587 SkelDrvrClientList clist;
589 if (atoms == (struct atom *)VERBOSE_HELP) {
590 printf("%s - shows connected clients\n", cmdd->name);
591 goto out;
593 if (ioctl(_DNFD, SkelDrvrIoctlGET_CLIENT_LIST, &clist) < 0) {
594 mperr("%s ioctl fails\n", "GET_CLIENT_LIST");
595 return -TST_ERR_IOCTL;
597 for (i = 0; i < clist.Size; i++)
598 if ((ccret = print_client_connections(clist.Pid[i])) < 0) {
599 printf("Can't get client's connections\n");
600 return ccret;
602 out:
603 return 1;
607 * hndl_connect - 'connect' handler
609 * @param cmdd - command description
610 * @param atoms - command atoms list
612 * @return >= 0 - on success
613 * @return tst_prg_err_t - on failure
615 int hndl_connect(struct cmd_desc *cmdd, struct atom *atoms)
617 int ccret;
618 SkelDrvrConnection conn;
620 if (atoms == (struct atom *)VERBOSE_HELP) {
621 printf("%s - shows connections of current pid\n"
622 "%s x - connect to mask on current module\n"
623 "%s x y - connect to mask x on module y\n",
624 cmdd->name, cmdd->name, cmdd->name);
625 goto out;
627 if ((++atoms)->type != Numeric) {
628 if ((ccret = print_client_connections(getpid())) < 0) {
629 printf("Could not get client's connections\n");
630 return ccret;
632 goto out;
634 conn.ConMask = atoms->val;
635 conn.Module = 0;
636 if (!is_last_atom(atoms)) {
637 if ((++atoms)->type != Numeric) {
638 printf("Invalid module number\n");
639 return -TST_ERR_WRONG_ARG;
641 conn.Module = atoms->val;
643 /* 0 == current module */
644 if (!WITHIN_RANGE(0, conn.Module, tst_glob_d.ma)) {
645 printf("Invalid module number\n");
646 return -TST_ERR_WRONG_ARG;
648 if (ioctl(_DNFD, SkelDrvrIoctlCONNECT, &conn) < 0) {
649 mperr("%s ioctl fails\n", "CONNECT");
650 return -TST_ERR_IOCTL;
652 if (conn.ConMask)
653 printf("Connected to 0x%08x on module %d\n", conn.ConMask,
654 !conn.Module ? tst_glob_d.mod : conn.Module);
655 else {
656 printf("Disconnected from all the interrupts on %s module%s",
657 !conn.Module ? "all the" : "", !conn.Module ? "s" : "");
658 if (conn.Module)
659 printf(" %d", conn.Module);
660 printf("\n");
662 out:
663 return 1;
667 * hndl_enable - 'enable' handler
669 * @param cmdd - command description
670 * @param atoms - command atoms list
672 * @return >= 0 - on success
673 * @return tst_prg_err_t - on failure
675 int hndl_enable(struct cmd_desc *cmdd, struct atom *atoms)
677 int enable;
679 if (atoms == (struct atom *)VERBOSE_HELP) {
680 printf("%s [1]- enable current module ('1' is not required)\n"
681 "%s 0 - disable current module\n",
682 cmdd->name, cmdd->name);
683 goto out;
685 if (is_last_atom(atoms)) {
686 enable = 1;
688 else {
689 if ((++atoms)->type != Numeric) {
690 printf("Invalid argument (must be an integer)\n");
691 return -TST_ERR_WRONG_ARG;
693 enable = !!atoms->val;
695 if (ioctl(_DNFD, SkelDrvrIoctlENABLE, &enable) < 0) {
696 mperr("%s ioctl fails\n", "ENABLE");
697 return -TST_ERR_IOCTL;
699 printf("Module %d %s\n", tst_glob_d.mod,
700 enable ? "enabled" : "disabled");
701 out:
702 return 1;
706 * hndl_reset - 'reset' handler
708 * @param cmdd - command description
709 * @param atoms - command atoms list
711 * @return >= 0 - on success
712 * @return tst_prg_err_t - on failure
714 int hndl_reset(struct cmd_desc* cmdd, struct atom *atoms)
716 if (atoms == (struct atom*)VERBOSE_HELP) {
717 printf("%s - reset current module\n", cmdd->name);
718 goto out;
720 if (!do_yes_no("Reset the current module. Are you sure", NULL))
721 goto out;
722 if (ioctl(_DNFD, SkelDrvrIoctlRESET, NULL) < 0) {
723 mperr("%s ioctl fails\n", "RESET");
724 return -TST_ERR_IOCTL;
726 printf("Module %d reset correctly\n", tst_glob_d.mod);
727 out:
728 return 1;
732 * hndl_getstatus - 'status' handler
734 * @param cmdd - command description
735 * @param atoms - command atoms list
737 * @return >= 0 - on success
738 * @return tst_prg_err_t - on failure
740 int hndl_getstatus(struct cmd_desc* cmdd, struct atom *atoms)
742 SkelDrvrStatus status;
744 if (atoms == (struct atom*)VERBOSE_HELP) {
745 printf("%s - print current status\n"
746 "Standard status can be:\n"
747 "\t0x001: NO_ISR\n"
748 "\t0x002: BUS_ERROR\n"
749 "\t0x004: DISABLED\n"
750 "\t0x008: HARDWARE_FAIL\n"
751 "\t0x010: WATCH_DOG\n"
752 "\t0x020: BUS_FAULT\n"
753 "\t0x040: FLASH_OPEN\n"
754 "\t0x080: EMULATION\n"
755 "\t0x100: NO_HARDWARE\n"
756 "\t0x200: IDLE\n"
757 "\t0x400: BUSY\n"
758 "\t0x800: READY\n"
759 "\t0x1000: HARDWARE_DBUG\n",
760 cmdd->name);
761 goto out;
763 if (ioctl(_DNFD, SkelDrvrIoctlGET_STATUS, &status) < 0) {
764 mperr("%s ioctl failed\n", "GET_STATUS");
765 return -TST_ERR_IOCTL;
767 printf("Hardware status: %d\n", status.HardwareStatus);
768 printf("Standard status flag: 0x%04x\n", status.StandardStatus);
769 out:
770 return 1;
774 * hndl_waitintr - connect to an interrupt via read()
776 * @param cmdd - command description
777 * @param atoms - command atoms list
779 * @return index of the next atom to parse in the current command
780 * @return -TST_ERR_IOCTL - IOCTL fails
782 int hndl_waitintr(struct cmd_desc* cmdd, struct atom *atoms)
784 SkelDrvrReadBuf rbuf;
785 int ret;
786 int nc; /* number of connections */
788 if (atoms == (struct atom*)VERBOSE_HELP) {
789 printf("%s - wait for any interrupts subscribed to\n",
790 cmdd->name);
791 goto out;
793 nc = print_client_connections(getpid());
794 if (!nc) {
795 printf("No connections for this client\n");
796 goto out;
798 printf("Waiting...\n");
799 ret = read(_DNFD, &rbuf, sizeof(SkelDrvrReadBuf));
800 if (ret <= 0) {
801 printf("Timeout or Interrupted call\n");
802 goto out;
804 printf("\nWoken up: Module[%d] Mask[0x%08x]\n"
805 " @@ %s"
806 " @@ %dns (EPOCH: %d)\n\n",
807 rbuf.Connection.Module, rbuf.Connection.ConMask,
808 ctime((time_t *)&rbuf.Time.Second), rbuf.Time.NanoSecond,
809 rbuf.Time.Second);
810 ret = print_queue();
811 if (ret < 0)
812 return ret;
813 out:
814 return 1;
818 * hndl_simintr - simulate an interrupt via write()
820 * @param cmdd - command description
821 * @param atoms - command atoms list
823 * @return index of the next atom to parse in the current command
824 * @return -TST_ERR_IOCTL - IOCTL fails
826 int hndl_simintr(struct cmd_desc* cmdd, struct atom *atoms)
828 SkelDrvrConnection wbuf;
829 int ret;
831 if (atoms == (struct atom*)VERBOSE_HELP) {
832 printf("%s mask - simulate a mask interrupt on current module\n"
833 "%s mask n - simulate a mask interrupt on module n\n",
834 cmdd->name, cmdd->name);
835 goto out;
837 atoms++;
838 if (atoms->type != Numeric) {
839 printf("Mask needed to simulate a certain interrupt\n");
840 goto out;
842 wbuf.ConMask = atoms->val;
843 wbuf.Module = tst_glob_d.mod;
844 if ((++atoms)->type == Numeric)
845 wbuf.Module = atoms->val;
846 ret = write(_DNFD, &wbuf, sizeof(SkelDrvrConnection));
847 if (ret <= 0) {
848 printf("Interrupt NOT simulated; write() failed (%s)\n",
849 strerror(ret));
850 goto out;
852 printf("Interrupt 0x%08x on module#%d sent\n",
853 wbuf.ConMask, wbuf.Module);
854 out:
855 return 1;
859 * @todo JTAG -- to be implemented
860 * The code below comes from old versions from extest; with it
861 * it should be relatively straight-forward to make it work
863 #if 0
865 * hndl_jtag_vhdl - JTAG VHDL code
867 * @cmdd command description
868 * @atoms command atoms list
870 * @return index of the next atom to parse in the current command, or
871 * index of the @ref Terminator atom to finish parsing.
872 * @return -TST_ERR_NO_MODULE - active module not set
873 * @return -TST_ERR_ARG_O_S - argument overflow/shortcoming
874 * @return -TST_ERR_NO_VECTOR - user doesn't provide ioctl number to be able
875 * to use this vector.
876 * @return -TST_ERR_IOCTL - ioctl call fails
877 * @return -TST_ERR_WRONG_ARG - wrong command argument
879 * @return
881 int hndl_jtag_vhdl(struct cmd_desc* cmdd, struct atom *atoms)
883 char cwd[MAXPATHLEN] = { 0 };
884 DIR *dir;
886 if (atoms == (struct atom*)VERBOSE_HELP) {
887 printf("%s filename - load VHDL from .xsvf file 'filename'\n",
888 cmdd->name);
889 goto out;
891 getcwd(cwd, sizeof(cwd));
892 dir = opendir(cwd);
894 if ((atoms++)->type == Alpha) /* user provides its own filename */
895 fname = atoms->text;
896 else
897 fname = ".xsvf";
898 while ( (direntry = readdir(dir)) ) {
899 snprintf(fname, sizeof(fname), "/dev/%s", direntry->d_name);
900 stat(fname, &fstat);
901 if (majordev(fstat.st_rdev) == devID) { /* bingo */
902 if ( nodeNm && (nodeCntr < elAm) )
903 strncpy(nodeNm[nodeCntr], fname,
904 sizeof(nodeNm[nodeCntr]));
905 nodeCntr++;
910 closedir(cwd);
913 xsvfExecute();
916 return cmdd->pa + 1; /* set index to the last (Terminator atom) */
919 int JtagLoader(char *fname) {
920 int cc;
921 CtrDrvrVersion version;
922 CtrDrvrTime t;
924 inp = fopen(fname,"r");
925 if (inp) {
926 if (ioctl(ctr,CtrDrvrJTAG_OPEN,NULL)) {
927 IErr("JTAG_OPEN",NULL);
928 return 1;
931 cc = xsvfExecute(); /* Play the xsvf file */
932 printf("\n");
933 if (cc) printf("Jtag: xsvfExecute: ReturnCode: %d Error\n",cc);
934 else printf("Jtag: xsvfExecute: ReturnCode: %d All OK\n",cc);
935 fclose(inp);
937 if (ioctl(ctr,CtrDrvrJTAG_CLOSE,NULL) < 0) {
938 IErr("JTAG_CLOSE",NULL);
939 return 1;
942 sleep(5); /* Wait for hardware to reconfigure */
944 bzero((void *) &version, sizeof(CtrDrvrVersion));
945 if (ioctl(ctr,CtrDrvrGET_VERSION,&version) < 0) {
946 IErr("GET_VERSION",NULL);
947 return 1;
949 t.Second = version.VhdlVersion;
950 printf("New VHDL bit-stream loaded, Version: [%u] %s\n",
951 (int) version.VhdlVersion,
952 TimeToStr(&t,0));
953 } else {
954 perror("fopen");
955 printf("Error: Could not open the file: %s for reading\n",fname);
956 return 1;
958 return cc;
960 #endif /* if 0 */