ibWait.c 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. /***************************************************************************
  2. lib/ibWait.c
  3. -------------------
  4. copyright : (C) 2001,2002 by Frank Mori Hess
  5. email : fmhess@users.sourceforge.net
  6. ***************************************************************************/
  7. /***************************************************************************
  8. * *
  9. * This program is free software; you can redistribute it and/or modify *
  10. * it under the terms of the GNU General Public License as published by *
  11. * the Free Software Foundation; either version 2 of the License, or *
  12. * (at your option) any later version. *
  13. * *
  14. ***************************************************************************/
  15. #include "ib_internal.h"
  16. #include <pthread.h>
  17. void fixup_status_bits( const ibConf_t *conf, int *status )
  18. {
  19. const int board_wait_mask = board_status_mask & ~ERR;
  20. const int device_wait_mask = device_status_mask & ~ERR;
  21. if( conf->is_interface == 0 )
  22. {
  23. *status &= device_wait_mask;
  24. }else
  25. {
  26. *status &= board_wait_mask;
  27. if( interfaceBoard(conf)->use_event_queue )
  28. {
  29. *status &= ~DTAS & ~DCAS;
  30. }else
  31. {
  32. *status &= ~EVENT;
  33. }
  34. }
  35. }
  36. int my_wait( ibConf_t *conf, int wait_mask, int clear_mask, int set_mask, int *status )
  37. {
  38. ibBoard_t *board;
  39. int retval;
  40. wait_ioctl_t cmd;
  41. board = interfaceBoard( conf );
  42. if( conf->is_interface == 0 &&
  43. is_cic( board ) == 0 )
  44. {
  45. setIberr( ECIC );
  46. return -1;
  47. }
  48. cmd.handle = conf->handle;
  49. cmd.usec_timeout = conf->settings.usec_timeout;
  50. cmd.wait_mask = wait_mask;
  51. cmd.clear_mask = clear_mask;
  52. cmd.set_mask = set_mask;
  53. cmd.set_mask = 0;
  54. cmd.ibsta = 0;
  55. fixup_status_bits( conf, &cmd.wait_mask );
  56. if( conf->is_interface == 0 )
  57. {
  58. cmd.pad = conf->settings.pad;
  59. cmd.sad = conf->settings.sad;
  60. }else
  61. {
  62. cmd.pad = NOADDR;
  63. cmd.sad = NOADDR;
  64. //XXX additionally, clear wait mask depending on event queue enabled, etc */
  65. }
  66. if( wait_mask != cmd.wait_mask )
  67. {
  68. setIberr( EARG );
  69. return -1;
  70. }
  71. retval = ioctl(board->fileno, IBWAIT, &cmd);
  72. if( retval < 0 )
  73. {
  74. setIberr( EDVR );
  75. setIbcnt( errno );
  76. return -1;
  77. }
  78. fixup_status_bits( conf, &cmd.ibsta );
  79. if( conf->end ) //XXX
  80. cmd.ibsta |= END;
  81. setIbsta( cmd.ibsta );
  82. *status = cmd.ibsta;
  83. return 0;
  84. }
  85. int ibwait( int ud, int mask )
  86. {
  87. ibConf_t *conf;
  88. int retval;
  89. int status;
  90. int clear_mask;
  91. int error = 0;
  92. conf = general_enter_library( ud, 1, 0 );
  93. if( conf == NULL )
  94. return general_exit_library(ud, 1, 0, 0, 0, 0, 1);
  95. clear_mask = mask & ( DTAS | DCAS | SPOLL);
  96. retval = my_wait( conf, mask, clear_mask, 0, &status );
  97. if( retval < 0 )
  98. return general_exit_library(ud, 1, 0, 0, 0, 0, 1);
  99. //XXX
  100. if(conf->async.in_progress && (status & CMPL))
  101. {
  102. if( gpib_aio_join( &conf->async ) )
  103. error++;
  104. pthread_mutex_lock( &conf->async.lock );
  105. if( conf->async.ibsta & CMPL )
  106. {
  107. conf->async.in_progress = 0;
  108. setIbcnt( conf->async.ibcntl );
  109. setIberr( conf->async.iberr );
  110. if( conf->async.ibsta & ERR )
  111. {
  112. error++;
  113. }
  114. }
  115. pthread_mutex_unlock( &conf->async.lock );
  116. if(error && (ThreadIbsta() & ERR) == 0)
  117. {
  118. status |= ERR;
  119. setIbsta(status);
  120. }
  121. }
  122. general_exit_library( ud, error, 0, 1, 0, 0, 1);
  123. return status;
  124. }
  125. void WaitSRQ( int boardID, short *result )
  126. {
  127. ibConf_t *conf;
  128. int retval;
  129. int wait_mask;
  130. int status;
  131. conf = general_enter_library( boardID, 1, 0 );
  132. if( conf == NULL )
  133. {
  134. general_exit_library( boardID, 1, 0, 0, 0, 0, 1 );
  135. return;
  136. }
  137. if( conf->is_interface == 0 )
  138. {
  139. setIberr( EDVR );
  140. general_exit_library( boardID, 1, 0, 0, 0, 0, 1 );
  141. return;
  142. }
  143. wait_mask = SRQI | TIMO;
  144. retval = my_wait( conf, wait_mask, 0, 0, &status );
  145. if( retval < 0 )
  146. {
  147. general_exit_library( boardID, 1, 0, 0, 0, 0, 1 );
  148. return;
  149. }
  150. // XXX need better query of service request state, new ioctl?
  151. // should play nice with autopolling
  152. if( ThreadIbsta() & SRQI ) *result = 1;
  153. else *result = 0;
  154. general_exit_library( boardID, 0, 0, 0, 0, 0, 1 );
  155. }