mirror of https://github.com/Qortal/Brooklyn
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
78 lines
2.1 KiB
78 lines
2.1 KiB
/*========================================================================== |
|
NinjaSCSI-3 message handler |
|
By: YOKOTA Hiroshi <[email protected]> |
|
|
|
This software may be used and distributed according to the terms of |
|
the GNU General Public License. |
|
*/ |
|
|
|
/* $Id: nsp_message.c,v 1.6 2003/07/26 14:21:09 elca Exp $ */ |
|
|
|
static void nsp_message_in(struct scsi_cmnd *SCpnt) |
|
{ |
|
unsigned int base = SCpnt->device->host->io_port; |
|
nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata; |
|
unsigned char data_reg, control_reg; |
|
int ret, len; |
|
|
|
/* |
|
* XXX: NSP QUIRK |
|
* NSP invoke interrupts only in the case of scsi phase changes, |
|
* therefore we should poll the scsi phase here to catch |
|
* the next "msg in" if exists (no scsi phase changes). |
|
*/ |
|
ret = 16; |
|
len = 0; |
|
|
|
nsp_dbg(NSP_DEBUG_MSGINOCCUR, "msgin loop"); |
|
do { |
|
/* read data */ |
|
data_reg = nsp_index_read(base, SCSIDATAIN); |
|
|
|
/* assert ACK */ |
|
control_reg = nsp_index_read(base, SCSIBUSCTRL); |
|
control_reg |= SCSI_ACK; |
|
nsp_index_write(base, SCSIBUSCTRL, control_reg); |
|
nsp_negate_signal(SCpnt, BUSMON_REQ, "msgin<REQ>"); |
|
|
|
data->MsgBuffer[len] = data_reg; len++; |
|
|
|
/* deassert ACK */ |
|
control_reg = nsp_index_read(base, SCSIBUSCTRL); |
|
control_reg &= ~SCSI_ACK; |
|
nsp_index_write(base, SCSIBUSCTRL, control_reg); |
|
|
|
/* catch a next signal */ |
|
ret = nsp_expect_signal(SCpnt, BUSPHASE_MESSAGE_IN, BUSMON_REQ); |
|
} while (ret > 0 && MSGBUF_SIZE > len); |
|
|
|
data->MsgLen = len; |
|
|
|
} |
|
|
|
static void nsp_message_out(struct scsi_cmnd *SCpnt) |
|
{ |
|
nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata; |
|
int ret = 1; |
|
int len = data->MsgLen; |
|
|
|
/* |
|
* XXX: NSP QUIRK |
|
* NSP invoke interrupts only in the case of scsi phase changes, |
|
* therefore we should poll the scsi phase here to catch |
|
* the next "msg out" if exists (no scsi phase changes). |
|
*/ |
|
|
|
nsp_dbg(NSP_DEBUG_MSGOUTOCCUR, "msgout loop"); |
|
do { |
|
if (nsp_xfer(SCpnt, BUSPHASE_MESSAGE_OUT)) { |
|
nsp_msg(KERN_DEBUG, "msgout: xfer short"); |
|
} |
|
|
|
/* catch a next signal */ |
|
ret = nsp_expect_signal(SCpnt, BUSPHASE_MESSAGE_OUT, BUSMON_REQ); |
|
} while (ret > 0 && len-- > 0); |
|
|
|
} |
|
|
|
/* end */
|
|
|