nsp_message.c 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. /*==========================================================================
  2. NinjaSCSI-3 message handler
  3. By: YOKOTA Hiroshi <yokota@netlab.is.tsukuba.ac.jp>
  4. This software may be used and distributed according to the terms of
  5. the GNU General Public License.
  6. */
  7. /* $Id: nsp_message.c,v 1.6 2003/07/26 14:21:09 elca Exp $ */
  8. static void nsp_message_in(struct scsi_cmnd *SCpnt)
  9. {
  10. unsigned int base = SCpnt->device->host->io_port;
  11. nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
  12. unsigned char data_reg, control_reg;
  13. int ret, len;
  14. /*
  15. * XXX: NSP QUIRK
  16. * NSP invoke interrupts only in the case of scsi phase changes,
  17. * therefore we should poll the scsi phase here to catch
  18. * the next "msg in" if exists (no scsi phase changes).
  19. */
  20. ret = 16;
  21. len = 0;
  22. nsp_dbg(NSP_DEBUG_MSGINOCCUR, "msgin loop");
  23. do {
  24. /* read data */
  25. data_reg = nsp_index_read(base, SCSIDATAIN);
  26. /* assert ACK */
  27. control_reg = nsp_index_read(base, SCSIBUSCTRL);
  28. control_reg |= SCSI_ACK;
  29. nsp_index_write(base, SCSIBUSCTRL, control_reg);
  30. nsp_negate_signal(SCpnt, BUSMON_REQ, "msgin<REQ>");
  31. data->MsgBuffer[len] = data_reg; len++;
  32. /* deassert ACK */
  33. control_reg = nsp_index_read(base, SCSIBUSCTRL);
  34. control_reg &= ~SCSI_ACK;
  35. nsp_index_write(base, SCSIBUSCTRL, control_reg);
  36. /* catch a next signal */
  37. ret = nsp_expect_signal(SCpnt, BUSPHASE_MESSAGE_IN, BUSMON_REQ);
  38. } while (ret > 0 && MSGBUF_SIZE > len);
  39. data->MsgLen = len;
  40. }
  41. static void nsp_message_out(struct scsi_cmnd *SCpnt)
  42. {
  43. nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
  44. int ret = 1;
  45. int len = data->MsgLen;
  46. /*
  47. * XXX: NSP QUIRK
  48. * NSP invoke interrupts only in the case of scsi phase changes,
  49. * therefore we should poll the scsi phase here to catch
  50. * the next "msg out" if exists (no scsi phase changes).
  51. */
  52. nsp_dbg(NSP_DEBUG_MSGOUTOCCUR, "msgout loop");
  53. do {
  54. if (nsp_xfer(SCpnt, BUSPHASE_MESSAGE_OUT)) {
  55. nsp_msg(KERN_DEBUG, "msgout: xfer short");
  56. }
  57. /* catch a next signal */
  58. ret = nsp_expect_signal(SCpnt, BUSPHASE_MESSAGE_OUT, BUSMON_REQ);
  59. } while (ret > 0 && len-- > 0);
  60. }
  61. /* end */