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