tnt4882_read.c 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  1. /***************************************************************************
  2. tnt4882_read.c - description
  3. -------------------
  4. copyright : (C) 2003 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 "tnt4882.h"
  16. #include <linux/delay.h>
  17. static int fifo_word_available( tnt4882_private_t *tnt_priv )
  18. {
  19. int status2;
  20. int retval;
  21. status2 = tnt_readb( tnt_priv, STS2 );
  22. retval = ( status2 & AEFN ) && ( status2 & BEFN );
  23. return retval;
  24. }
  25. static int fifo_byte_available( tnt4882_private_t *tnt_priv )
  26. {
  27. int status2;
  28. int retval;
  29. status2 = tnt_readb( tnt_priv, STS2 );
  30. retval = ( status2 & AEFN ) || ( status2 & BEFN );
  31. return retval;
  32. }
  33. static int fifo_xfer_done( tnt4882_private_t *tnt_priv )
  34. {
  35. int status1;
  36. int retval;
  37. status1 = tnt_readb( tnt_priv, STS1 );
  38. retval = status1 & ( S_DONE | S_HALT );
  39. return retval;
  40. }
  41. static int drain_fifo_words(tnt4882_private_t *tnt_priv, uint8_t *buffer, int num_bytes)
  42. {
  43. int count = 0;
  44. nec7210_private_t *nec_priv = &tnt_priv->nec7210_priv;
  45. while(fifo_word_available( tnt_priv ) && count + 2 <= num_bytes)
  46. {
  47. short word;
  48. word = tnt_priv->io_readw( nec_priv->iobase + FIFOB );
  49. buffer[ count++ ] = word & 0xff;
  50. buffer[ count++ ] = ( word >> 8 ) & 0xff;
  51. }
  52. return count;
  53. }
  54. static void tnt4882_release_holdoff(gpib_board_t *board, tnt4882_private_t *tnt_priv)
  55. {
  56. nec7210_private_t *nec_priv = &tnt_priv->nec7210_priv;
  57. unsigned short sasr_bits;
  58. sasr_bits = tnt_readb(tnt_priv, SASR);
  59. /*tnt4882 not in one-chip mode won't always release holdoff unless we
  60. * are in the right mode when release handshake command is given */
  61. if(sasr_bits & AEHS_BIT) /* holding off due to holdoff on end mode*/
  62. {
  63. nec7210_set_handshake_mode(board, nec_priv, HR_HLDE);
  64. write_byte(nec_priv, AUX_FH, AUXMR);
  65. }else if(sasr_bits & ANHS1_BIT) /* held off due to holdoff on all data mode*/
  66. {
  67. nec7210_set_handshake_mode(board, nec_priv, HR_HLDA);
  68. write_byte(nec_priv, AUX_FH, AUXMR);
  69. nec7210_set_handshake_mode(board, nec_priv, HR_HLDE);
  70. }else /* held off due to holdoff immediately command */
  71. {
  72. nec7210_set_handshake_mode(board, nec_priv, HR_HLDE);
  73. write_byte(nec_priv, AUX_FH, AUXMR);
  74. }
  75. }
  76. int tnt4882_accel_read( gpib_board_t *board, uint8_t *buffer, size_t length, int *end, size_t *bytes_read)
  77. {
  78. size_t count = 0;
  79. ssize_t retval = 0;
  80. tnt4882_private_t *tnt_priv = board->private_data;
  81. nec7210_private_t *nec_priv = &tnt_priv->nec7210_priv;
  82. unsigned int bits, imr0_bits, imr1_bits, imr2_bits;
  83. int32_t hw_count;
  84. unsigned long flags;
  85. *bytes_read = 0;
  86. // FIXME: really, DEV_CLEAR_BN should happen elsewhere to prevent race
  87. clear_bit(DEV_CLEAR_BN, &nec_priv->state);
  88. imr1_bits = nec_priv->reg_bits[ IMR1 ];
  89. imr2_bits = nec_priv->reg_bits[ IMR2 ];
  90. nec7210_set_reg_bits( nec_priv, IMR1, 0xff, HR_ENDIE | HR_DECIE );
  91. if( nec_priv->type != TNT4882 )
  92. nec7210_set_reg_bits( nec_priv, IMR2, 0xff, HR_DMAI );
  93. else
  94. nec7210_set_reg_bits( nec_priv, IMR2, 0xff, 0 );
  95. imr0_bits = tnt_priv->imr0_bits;
  96. tnt_priv->imr0_bits &= ~TNT_ATNI_BIT;
  97. tnt_writeb(tnt_priv, tnt_priv->imr0_bits, IMR0);
  98. tnt_writeb( tnt_priv, nec_priv->auxa_bits | HR_HLDA, CCR );
  99. bits = TNT_TLCHE | TNT_B_16BIT | TNT_IN | TNT_CCEN;
  100. tnt_writeb( tnt_priv, bits, CFG );
  101. tnt_writeb( tnt_priv, RESET_FIFO, CMDR );
  102. udelay(1);
  103. // load 2's complement of count into hardware counters
  104. hw_count = -length;
  105. tnt_writeb( tnt_priv, hw_count & 0xff, CNT0 );
  106. tnt_writeb( tnt_priv, ( hw_count >> 8 ) & 0xff, CNT1 );
  107. tnt_writeb( tnt_priv, ( hw_count >> 16 ) & 0xff, CNT2 );
  108. tnt_writeb( tnt_priv, ( hw_count >> 24 ) & 0xff, CNT3 );
  109. tnt4882_release_holdoff(board, tnt_priv);
  110. tnt_writeb( tnt_priv, GO, CMDR );
  111. udelay(1);
  112. spin_lock_irqsave( &board->spinlock, flags );
  113. tnt_priv->imr3_bits |= HR_DONE | HR_NEF;
  114. tnt_writeb( tnt_priv, tnt_priv->imr3_bits, IMR3 );
  115. spin_unlock_irqrestore( &board->spinlock, flags );
  116. while(count + 2 <= length &&
  117. test_bit( RECEIVED_END_BN, &nec_priv->state ) == 0 &&
  118. fifo_xfer_done(tnt_priv) == 0)
  119. {
  120. // wait until a word is ready
  121. if( wait_event_interruptible( board->wait,
  122. fifo_word_available( tnt_priv ) ||
  123. fifo_xfer_done( tnt_priv ) ||
  124. test_bit( RECEIVED_END_BN, &nec_priv->state ) ||
  125. test_bit( DEV_CLEAR_BN, &nec_priv->state ) ||
  126. test_bit( TIMO_NUM, &board->status ) ) )
  127. {
  128. printk("tnt4882: read interrupted\n");
  129. retval = -ERESTARTSYS;
  130. break;
  131. }
  132. if( test_bit( TIMO_NUM, &board->status ) )
  133. {
  134. printk("tnt4882: minor %i read timed out\n", board->minor);
  135. retval = -ETIMEDOUT;
  136. break;
  137. }
  138. if( test_bit( DEV_CLEAR_BN, &nec_priv->state ) )
  139. {
  140. printk("tnt4882: device clear interrupted read\n");
  141. retval = -EINTR;
  142. break;
  143. }
  144. spin_lock_irqsave( &board->spinlock, flags );
  145. count += drain_fifo_words(tnt_priv, &buffer[count], length - count);
  146. tnt_priv->imr3_bits |= HR_NEF;
  147. tnt_writeb( tnt_priv, tnt_priv->imr3_bits, IMR3 );
  148. spin_unlock_irqrestore( &board->spinlock, flags );
  149. if(need_resched())
  150. schedule();
  151. }
  152. // wait for last byte
  153. if( count < length )
  154. {
  155. spin_lock_irqsave( &board->spinlock, flags );
  156. tnt_priv->imr3_bits |= HR_DONE | HR_NEF;
  157. tnt_writeb( tnt_priv, tnt_priv->imr3_bits, IMR3 );
  158. spin_unlock_irqrestore( &board->spinlock, flags );
  159. if( wait_event_interruptible( board->wait,
  160. fifo_xfer_done( tnt_priv ) ||
  161. test_bit( RECEIVED_END_BN, &nec_priv->state ) ||
  162. test_bit( DEV_CLEAR_BN, &nec_priv->state ) ||
  163. test_bit( TIMO_NUM, &board->status ) ) )
  164. {
  165. printk("tnt4882: read interrupted\n");
  166. retval = -ERESTARTSYS;
  167. }
  168. if( test_bit( TIMO_NUM, &board->status ) )
  169. {
  170. printk("tnt4882: read timed out\n");
  171. retval = -ETIMEDOUT;
  172. }
  173. if( test_bit( DEV_CLEAR_BN, &nec_priv->state ) )
  174. {
  175. printk("tnt4882: device clear interrupted read\n");
  176. retval = -EINTR;
  177. }
  178. count += drain_fifo_words(tnt_priv, &buffer[count], length - count);
  179. if(fifo_byte_available( tnt_priv ) && count < length)
  180. {
  181. buffer[ count++ ] = tnt_readb( tnt_priv, FIFOB );
  182. }
  183. }
  184. if(count < length)
  185. tnt_writeb( tnt_priv, STOP, CMDR );
  186. udelay(1);
  187. nec7210_set_reg_bits( nec_priv, IMR1, 0xff, imr1_bits );
  188. nec7210_set_reg_bits( nec_priv, IMR2, 0xff, imr2_bits );
  189. tnt_priv->imr0_bits = imr0_bits;
  190. tnt_writeb(tnt_priv, tnt_priv->imr0_bits, IMR0);
  191. /* force handling of any pending interrupts (seems to be needed
  192. * to keep interrupts from getting hosed, plus for syncing
  193. * with RECEIVED_END below) */
  194. tnt4882_internal_interrupt(board);
  195. /* RECEIVED_END should be in sync now */
  196. if( test_and_clear_bit( RECEIVED_END_BN, &nec_priv->state ) )
  197. {
  198. *end = 1;
  199. }
  200. if( retval < 0 )
  201. {
  202. // force immediate holdoff
  203. write_byte( nec_priv, AUX_HLDI, AUXMR );
  204. set_bit( RFD_HOLDOFF_BN, &nec_priv->state );
  205. }
  206. *bytes_read = count;
  207. return retval;
  208. }