Back to home page

OSCL-LXR

 
 

    


0001 /*==========================================================================
0002   NinjaSCSI-3 message handler
0003       By: YOKOTA Hiroshi <yokota@netlab.is.tsukuba.ac.jp>
0004 
0005    This software may be used and distributed according to the terms of
0006    the GNU General Public License.
0007  */
0008 
0009 /* $Id: nsp_message.c,v 1.6 2003/07/26 14:21:09 elca Exp $ */
0010 
0011 static void nsp_message_in(struct scsi_cmnd *SCpnt)
0012 {
0013     unsigned int  base = SCpnt->device->host->io_port;
0014     nsp_hw_data  *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
0015     unsigned char data_reg, control_reg;
0016     int           ret, len;
0017 
0018     /*
0019      * XXX: NSP QUIRK
0020      * NSP invoke interrupts only in the case of scsi phase changes,
0021      * therefore we should poll the scsi phase here to catch 
0022      * the next "msg in" if exists (no scsi phase changes).
0023      */
0024     ret = 16;
0025     len = 0;
0026 
0027     nsp_dbg(NSP_DEBUG_MSGINOCCUR, "msgin loop");
0028     do {
0029         /* read data */
0030         data_reg = nsp_index_read(base, SCSIDATAIN);
0031 
0032         /* assert ACK */
0033         control_reg = nsp_index_read(base, SCSIBUSCTRL);
0034         control_reg |= SCSI_ACK;
0035         nsp_index_write(base, SCSIBUSCTRL, control_reg);
0036         nsp_negate_signal(SCpnt, BUSMON_REQ, "msgin<REQ>");
0037 
0038         data->MsgBuffer[len] = data_reg; len++;
0039 
0040         /* deassert ACK */
0041         control_reg =  nsp_index_read(base, SCSIBUSCTRL);
0042         control_reg &= ~SCSI_ACK;
0043         nsp_index_write(base, SCSIBUSCTRL, control_reg);
0044 
0045         /* catch a next signal */
0046         ret = nsp_expect_signal(SCpnt, BUSPHASE_MESSAGE_IN, BUSMON_REQ);
0047     } while (ret > 0 && MSGBUF_SIZE > len);
0048 
0049     data->MsgLen = len;
0050 
0051 }
0052 
0053 static void nsp_message_out(struct scsi_cmnd *SCpnt)
0054 {
0055     nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
0056     int ret = 1;
0057     int len = data->MsgLen;
0058 
0059     /*
0060      * XXX: NSP QUIRK
0061      * NSP invoke interrupts only in the case of scsi phase changes,
0062      * therefore we should poll the scsi phase here to catch 
0063      * the next "msg out" if exists (no scsi phase changes).
0064      */
0065 
0066     nsp_dbg(NSP_DEBUG_MSGOUTOCCUR, "msgout loop");
0067     do {
0068         if (nsp_xfer(SCpnt, BUSPHASE_MESSAGE_OUT)) {
0069             nsp_msg(KERN_DEBUG, "msgout: xfer short");
0070         }
0071 
0072         /* catch a next signal */
0073         ret = nsp_expect_signal(SCpnt, BUSPHASE_MESSAGE_OUT, BUSMON_REQ);
0074     } while (ret > 0 && len-- > 0);
0075 
0076 }
0077 
0078 /* end */