ines_write.c 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. /***************************************************************************
  2. ines_write.c - description
  3. -------------------
  4. copyright : (C) 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 "ines.h"
  16. #include <linux/sched.h>
  17. static const int out_fifo_size = 0xff;
  18. static inline unsigned short num_out_fifo_bytes( ines_private_t *ines_priv )
  19. {
  20. return ines_inb( ines_priv, OUT_FIFO_COUNT );
  21. }
  22. static int ines_write_wait( gpib_board_t *board, ines_private_t *ines_priv,
  23. unsigned int fifo_threshold )
  24. {
  25. nec7210_private_t *nec_priv = &ines_priv->nec7210_priv;
  26. // wait until byte is ready to be sent
  27. if( wait_event_interruptible( board->wait,
  28. num_out_fifo_bytes( ines_priv ) < fifo_threshold ||
  29. test_bit( BUS_ERROR_BN, &nec_priv->state ) ||
  30. test_bit( DEV_CLEAR_BN, &nec_priv->state ) ||
  31. test_bit( TIMO_NUM, &board->status ) ) )
  32. {
  33. GPIB_DPRINTK( "gpib write interrupted\n" );
  34. return -ERESTARTSYS;
  35. }
  36. if( test_bit( BUS_ERROR_BN, &nec_priv->state ) )
  37. return -EIO;
  38. if( test_bit( DEV_CLEAR_BN, &nec_priv->state ) )
  39. return -EINTR;
  40. if( test_bit( TIMO_NUM, &board->status ) )
  41. return -ETIMEDOUT;
  42. return 0;
  43. }
  44. int ines_accel_write( gpib_board_t *board, uint8_t *buffer, size_t length, int send_eoi, size_t *bytes_written)
  45. {
  46. size_t count = 0;
  47. ssize_t retval = 0;
  48. ines_private_t *ines_priv = board->private_data;
  49. nec7210_private_t *nec_priv = &ines_priv->nec7210_priv;
  50. unsigned int num_bytes, i;
  51. *bytes_written = 0;
  52. //clear out fifo
  53. nec7210_set_reg_bits(nec_priv, ADMR, OUT_FIFO_ENABLE_BIT, 0);
  54. nec7210_set_reg_bits(nec_priv, ADMR, OUT_FIFO_ENABLE_BIT, OUT_FIFO_ENABLE_BIT);
  55. ines_priv->extend_mode_bits |= XFER_COUNTER_OUTPUT_BIT;
  56. ines_priv->extend_mode_bits &= ~XFER_COUNTER_ENABLE_BIT;
  57. ines_priv->extend_mode_bits &= ~LAST_BYTE_HANDLING_BIT;
  58. ines_outb( ines_priv, ines_priv->extend_mode_bits, EXTEND_MODE );
  59. ines_set_xfer_counter( ines_priv, length );
  60. if(send_eoi)
  61. ines_priv->extend_mode_bits |= LAST_BYTE_HANDLING_BIT;
  62. ines_priv->extend_mode_bits |= XFER_COUNTER_ENABLE_BIT;
  63. ines_outb( ines_priv, ines_priv->extend_mode_bits, EXTEND_MODE );
  64. while(count < length)
  65. {
  66. retval = ines_write_wait( board, ines_priv, out_fifo_size );
  67. if( retval < 0 )
  68. break;
  69. num_bytes = out_fifo_size - num_out_fifo_bytes( ines_priv );
  70. if( num_bytes + count > length )
  71. num_bytes = length - count;
  72. for( i = 0; i < num_bytes; i++ )
  73. {
  74. write_byte( nec_priv, buffer[ count++ ], CDOR );
  75. }
  76. }
  77. if( retval < 0 )
  78. {
  79. ines_priv->extend_mode_bits &= ~XFER_COUNTER_ENABLE_BIT;
  80. ines_outb( ines_priv, ines_priv->extend_mode_bits, EXTEND_MODE );
  81. *bytes_written = length - num_out_fifo_bytes(ines_priv);
  82. return retval;
  83. }
  84. // wait last byte has been sent
  85. retval = ines_write_wait( board, ines_priv, 1 );
  86. ines_priv->extend_mode_bits &= ~XFER_COUNTER_ENABLE_BIT;
  87. ines_outb( ines_priv, ines_priv->extend_mode_bits, EXTEND_MODE );
  88. *bytes_written = length - num_out_fifo_bytes(ines_priv);
  89. return retval;
  90. }