1 /*        $NetBSD: mhavar.h,v 1.12 2024/01/07 07:58:33 isaki Exp $    */
2 
3 /*
4  * Copyright (c) 1994 Peter Galbavy.  All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  * 3. All advertising materials mentioning features or use of this software
15  *    must display the following acknowledgement:
16  *        This product includes software developed by Peter Galbavy.
17  * 4. The name of the author may not be used to endorse or promote products
18  *    derived from this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
21  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
22  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
23  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
24  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
29  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30  */
31 
32 /*
33  * ACB. Holds additional information for each SCSI command Comments: We
34  * need a separate scsi command block because we may need to overwrite it
35  * with a request sense command.  Basically, we refrain from fiddling with
36  * the scsi_xfer struct (except do the expected updating of return values).
37  * We'll generally update: xs->{flags,resid,error,sense,status} and
38  * occasionally xs->retries.
39  */
40 struct acb {
41           TAILQ_ENTRY(acb) chain;
42           struct scsipi_xfer *xs;       /* SCSI xfer ctrl block from above */
43           int                 flags;    /* Status */
44 #define ACB_QNONE   0
45 #define ACB_QFREE   1
46 #define ACB_QREADY  2
47 #define ACB_QNEXUS  3
48 
49 #define ACB_QBITS   0x07
50 #define ACB_CHKSENSE          0x08
51 #define   ACB_ABORTED         0x10
52 #define   ACB_RESET 0x80
53 #define ACB_SETQ(e, q)        do (e)->flags = ((e)->flags&~ACB_QBITS)|(q); while(0)
54           struct scsipi_generic cmd;  /* SCSI command block */
55           int        clen;
56           char      *daddr;             /* Saved data pointer */
57           int        dleft;             /* Residue */
58           u_char     stat;              /* SCSI status byte */
59 
60 /*        struct spc_dma_seg dma[SPC_NSEG];*/ /* Physical addresses+len */
61 };
62 
63 /*
64  * Some info about each (possible) target on the SCSI bus.  This should
65  * probably have been a "per target+lunit" structure, but we'll leave it at
66  * this for now.
67  */
68 struct spc_tinfo {
69           int       cmds;               /* #commands processed */
70           int       dconns;             /* #disconnects */
71           int       touts;              /* #timeouts */
72           int       perrs;              /* #parity errors */
73           int       senses;             /* #request sense commands sent */
74           ushort    lubusy;             /* What local units/subr. are busy? */
75           u_char  flags;
76 #define T_NEED_TO_RESET       0x01      /* Should send a BUS_DEV_RESET */
77 #define T_NEGOTIATE 0x02      /* (Re)Negotiate synchronous options */
78 #define T_BUSY                0x04      /* Target is busy, i.e. cmd in progress */
79 #define T_SYNCMODE  0x08      /* sync mode has been negotiated */
80 #define T_SYNCHOFF  0x10      /* .. */
81 #define T_RSELECTOFF          0x20      /* .. */
82           u_char  period;               /* Period suggestion */
83           u_char  offset;               /* Offset suggestion */
84           u_char    width;              /* Width suggestion */
85 };
86 
87 struct mha_softc {
88           device_t sc_dev;
89           volatile void *sc_iobase;
90           volatile u_char     *sc_pc;
91           volatile u_short *sc_ps;
92           volatile u_char *sc_pcx;
93 
94           struct scsipi_channel sc_channel;
95           struct scsipi_adapter sc_adapter;
96 
97           TAILQ_HEAD(, acb) free_list, ready_list, nexus_list;
98           struct acb *sc_nexus;         /* current command */
99           struct acb sc_acb[8];         /* one per target */
100           struct spc_tinfo sc_tinfo[8];
101 
102           /* Data about the current nexus (updated for every cmd switch) */
103           u_char    *sc_dp;             /* Current data pointer */
104           size_t    sc_dleft; /* Data bytes left to transfer */
105 
106           u_char    *sc_cp;             /* Current command pointer */
107           size_t    sc_cleft; /* Command bytes left to transfer */
108 
109           /* Adapter state */
110           int       sc_phase; /* Copy of what bus phase we are in */
111           int       sc_prevphase;       /* Copy of what bus phase we were in */
112           u_char    sc_state; /* State applicable to the adapter */
113           u_char    sc_flags;
114           u_char    sc_selid; /* Reselection ID */
115           volatile u_char     sc_spcinitialized;  /* */
116 
117           /* Message stuff */
118           u_char    sc_msgpriq;         /* Messages we want to send */
119           u_char    sc_msgout;          /* What message is on its way out? */
120           u_char    sc_msgoutq;         /* Messages sent during last MESSAGE OUT */
121           u_char    sc_lastmsg;         /* Message last transmitted */
122           u_char    sc_currmsg;         /* Message currently ready to transmit */
123 #define SPC_MAX_MSG_LEN 8
124           u_char    sc_omess[SPC_MAX_MSG_LEN];
125           u_char    *sc_omp;            /* Outgoing message pointer */
126           u_char    sc_imess[SPC_MAX_MSG_LEN];
127           u_char    *sc_imp;            /* Incoming message pointer */
128           size_t    sc_imlen;
129 
130           /* Hardware stuff */
131           int       sc_freq;            /* Clock frequency in MHz */
132           int       sc_id;                        /* our scsi id */
133           int       sc_minsync;                   /* Minimum sync period / 4 */
134           int       sc_maxsync;                   /* Maximum sync period / 4 */
135 
136           /* DMA buffer */
137           bus_dma_tag_t                 sc_dmat;
138           bus_dma_segment_t   sc_dmaseg[1];
139           int                           sc_ndmasegs;
140           bus_dmamap_t                  sc_dmamap;
141           void *                        sc_dmabuf;
142           u_char                        *sc_p;
143           u_int32_t           sc_dmasize;
144 };
145 
146 /* values for sc_state */
147 #define   SPC_INIT  0x00
148 #define SPC_IDLE    0x01      /* waiting for something to do */
149 #define ESP_TMP_UNAVAIL       0x02      /* Don't accept SCSI commands */
150 #define SPC_SELECTING         0x03      /* SCSI command is arbiting  */
151 #define SPC_RESELECTED        0x04      /* Has been reselected */
152 #define SPC_HASNEXUS          0x05      /* Actively using the SCSI bus */
153 #define SPC_CLEANING          0x06
154 #define ESP_SBR               0x07      /* Expect a SCSI RST because we commanded it */
155 #define SPC_CONNECTED         0x08      /* Actively using the SCSI bus */
156 #define   SPC_DISCONNECT      0x09      /* MSG_DISCONNECT received */
157 #define   SPC_CMDCOMPLETE     0x0a      /* MSG_CMDCOMPLETE received */
158 
159 
160 /* values for sc_flags */
161 #define SPC_DROP_MSGI         0x01      /* Discard all msgs (parity err detected) */
162 #define SPC_DOINGDMA          0x02      /* The FIFO data path is active! */
163 #define SPC_BUSFREE_OK        0x04      /* Bus free phase is OK. */
164 #define SPC_SYNCHNEGO         0x08      /* Synch negotiation in progress. */
165 #define SPC_DISCON  0x10      /* Target sent DISCONNECT msg */
166 #define   SPC_ABORTING        0x20      /* Bailing out */
167 #define ESP_ICCS    0x40      /* Expect status phase results */
168 #define ESP_WAITI   0x80      /* Waiting for non-DMA data to arrive */
169 
170 
171 /* values for sc_msgout */
172 #define SEND_DEV_RESET                  0x01
173 #define SEND_PARITY_ERROR     0x02
174 #define SEND_INIT_DET_ERR     0x04
175 #define SEND_REJECT           0x08
176 #define SEND_IDENTIFY                   0x10
177 #define SEND_ABORT            0x20
178 #define SEND_SDTR             0x40
179 #define   SEND_WDTR           0x80
180 
181 /* SCSI Status codes */
182 #define ST_GOOD                         0x00
183 #define ST_CHKCOND            0x02
184 #define ST_CONDMET            0x04
185 #define ST_BUSY                         0x08
186 #define ST_INTERMED           0x10
187 #define ST_INTERMED_CONDMET   0x14
188 #define ST_RESERVATION_CONFLICT         0x18
189 #define ST_CMD_TERM           0x22
190 #define ST_QUEUE_FULL                   0x28
191 
192 #define ST_MASK                         0x3e /* bit 0,6,7 is reserved */
193 
194 /* phase bits */
195 #define IOI                             0x01
196 #define CDI                             0x02
197 #define MSGI                            0x04
198 
199 /* Information transfer phases */
200 #define DATA_OUT_PHASE                  (0)
201 #define DATA_IN_PHASE                   (IOI)
202 #define COMMAND_PHASE                   (CDI)
203 #define STATUS_PHASE                    (CDI|IOI)
204 #define MESSAGE_OUT_PHASE     (MSGI|CDI)
205 #define MESSAGE_IN_PHASE      (MSGI|CDI|IOI)
206 
207 #define PHASE_MASK            (MSGI|CDI|IOI)
208 
209 /* Some pseudo phases for getphase()*/
210 #define BUSFREE_PHASE                   0x100     /* Re/Selection no longer valid */
211 #define INVALID_PHASE                   0x101     /* Re/Selection valid, but no REQ yet */
212 #define PSEUDO_PHASE                    0x100     /* "pseudo" bit */
213