File: /usr/src/linux/drivers/scsi/pcmcia/nsp_message.c

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