1 /* $NetBSD: sfasvar.h,v 1.9 2021/08/21 11:55:24 andvar Exp $ */
2 
3 /*
4  * Copyright (c) 1995 Daniel Widenfalk
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 Daniel Widenfalk
17  *      for the NetBSD Project.
18  * 4. The name of the author may not be used to endorse or promote products
19  *    derived from this software without specific prior written permission
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
25  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32 
33 #ifndef _SFASVAR_H_
34 #define _SFASVAR_H_
35 
36 #ifndef _SFASREG_H_
37 #include <acorn32/podulebus/sfasreg.h>
38 #endif
39 
40 /*
41  * MAXCHAIN is the anticipated maximum number of chain blocks needed. This
42  * assumes that we are NEVER requested to transfer more than MAXPHYS bytes.
43  */
44 #define MAXCHAIN    (MAXPHYS/PAGE_SIZE+2)
45 
46 /*
47  * Maximum number of requests standing by. Could be anything, but I think 9
48  * looks nice :-) NOTE: This does NOT include requests already started!
49  */
50 #define MAXPENDING  9         /* 7 IDs + 2 extra */
51 
52 /*
53  * DMA chain block. If flg == SFAS_CHAIN_PRG or flg == SFAS_CHAIN_BUMP then
54  * ptr is a VIRTUAL address. If flg == SFAS_CHAIN_DMA then ptr is a PHYSICAL
55  * address.
56  */
57 struct    sfas_dma_chain {
58           void                *ptr;
59           u_short             len;
60           short               flg;
61 };
62 #define SFAS_CHAIN_DMA        0x00
63 #define SFAS_CHAIN_BUMP       0x01
64 #define SFAS_CHAIN_PRG        0x02
65 
66 
67 /*
68  * This struct contains the necessary info for a pending request. Pointer to
69  * a scsipi_xfer struct.
70  */
71 struct    sfas_pending {
72           TAILQ_ENTRY(sfas_pending) link;
73           struct scsipi_xfer   *xs;
74 };
75 
76 /*
77  * nexus contains all active data for one SCSI unit. Parts of the info in this
78  * struct survives between scsi commands.
79  */
80 struct nexus {
81           struct    scsipi_xfer         *xs;                /* Pointer to request */
82 
83           u_char                         ID;                /* ID message to be sent */
84           u_char                         clen;              /* scsi command length + */
85           u_char                         cbuf[14];          /* the actual command bytes */
86 
87           struct sfas_dma_chain          dma[MAXCHAIN];     /* DMA chain blocks */
88           short                          max_link;          /* Maximum used of above */
89           short                          cur_link;          /* Currently handled block */
90 
91           u_char                        *buf;               /* Virtual address of data */
92           int                            len;               /* Bytes left to transfer */
93 
94           void                          *dma_buf; /* Current DMA address */
95           int                            dma_len; /* Current DMA length */
96 
97           void                          *dma_blk_ptr;       /* Current chain address */
98           int                            dma_blk_len;       /* Current chain length */
99           u_char                         dma_blk_flg;       /* Current chain flags */
100 
101           u_char                         state;             /* Nexus state, see below */
102           u_short                        flags;             /* Nexus flags, see below */
103 
104           short                          period;  /* Sync period to request */
105           u_char                         offset;  /* Sync offset to request */
106 
107           u_char                         syncper; /* FAS216 variable storage */
108           u_char                         syncoff; /* FAS216 variable storage */
109           u_char                         config3; /* FAS216 variable storage */
110 
111           u_char                         lun_unit;          /* (Lun<<4) | Unit of nexus */
112           u_char                         status;  /* Status byte from unit*/
113 };
114 
115 /* SCSI nexus_states */
116 #define SFAS_NS_IDLE                    0         /* Nexus idle */
117 #define SFAS_NS_SELECTED      1         /* Last command was a SELECT command */
118 #define SFAS_NS_DATA_IN                 2         /* Last command was a TRANSFER_INFO */
119                                                   /* command during a data in phase */
120 #define SFAS_NS_DATA_OUT      3         /* Last command was a TRANSFER_INFO */
121                                                   /* command during a data out phase */
122 #define SFAS_NS_STATUS                  4         /* We have send a COMMAND_COMPLETE */
123                                                   /* command and are awaiting status */
124 #define SFAS_NS_MSG_IN                  5         /* Last phase was MESSAGE IN */
125 #define SFAS_NS_MSG_OUT                 6         /* Last phase was MESSAGE OUT */
126 #define SFAS_NS_SVC           7         /* We have sent the command */
127 #define SFAS_NS_DISCONNECTING 8         /* We have received a disconnect msg */
128 #define SFAS_NS_DISCONNECTED  9         /* We are disconnected */
129 #define SFAS_NS_RESELECTED    10        /* We was reselected */
130 #define SFAS_NS_DONE                    11        /* Done. Prephsase to FINISHED */
131 #define SFAS_NS_FINISHED      12        /* Really done. Call scsi_done */
132 #define SFAS_NS_RESET                   13        /* We are resetting this unit */
133 
134 /* SCSI nexus flags */
135 #define SFAS_NF_UNIT_BUSY     0x0001    /* Unit is not available */
136 
137 #define SFAS_NF_SELECT_ME     0x0002    /* Nexus is set up, waiting for bus */
138 
139 #define SFAS_NF_HAS_MSG                 0x0010    /* We have received a complete msg */
140 
141 #define SFAS_NF_DO_SDTR                 0x0020    /* We should send a SDTR */
142 #define SFAS_NF_SDTR_SENT     0x0040    /* We have sent a SDTR */
143 #define SFAS_NF_SYNC_TESTED   0x0080    /* We have negotiated sync */
144 
145 #define SFAS_NF_RESET                   0x0100    /* Reset this nexus */
146 #define SFAS_NF_IMMEDIATE     0x0200    /* We are operating from sfasicmd */
147 
148 #define SFAS_NF_RETRY_SELECT  0x1000    /* Selection needs retrying */
149 
150 #define SFAS_NF_DEBUG                   0x8000    /* As it says: DEBUG */
151 
152 struct    sfas_softc {
153           device_t             sc_dev;  /* System required struct */
154           struct    scsipi_channel       sc_channel;
155           struct    scsipi_adapter       sc_adapter;
156           void                           *sc_ih;
157           struct evcnt                   sc_intrcnt;
158 
159           TAILQ_HEAD(,sfas_pending) sc_xs_pending;
160           TAILQ_HEAD(,sfas_pending) sc_xs_free;
161           struct    sfas_pending         sc_xs_store[MAXPENDING];
162 
163           sfas_regmap_p                  sc_fas;  /* FAS216 Address */
164           void                          *sc_spec; /* Board-specific data */
165 
166           u_char                        *sc_bump_va;        /* Bumpbuf virtual adr */
167           void                          *sc_bump_pa;        /* Bumpbuf physical adr */
168           int                            sc_bump_sz;        /* Bumpbuf size */
169 
170 /* Configuration registers, must be set BEFORE sfasinitialize */
171           u_char                         sc_clock_freq;
172           u_short                        sc_timeout;
173           u_char                         sc_host_id;
174           u_char                         sc_config_flags;
175 
176 /* Generic DMA functions */
177           int                        (*sc_setup_dma)(void *, void *, int, int);
178           int                        (*sc_build_dma_chain)(void *, void *, void *,
179                                                                  int);
180           int                        (*sc_need_bump)(void *, void *, int);
181 
182 /* Optional replacement ixfer */
183           void                       (*sc_ixfer)(void *, int);
184 
185 /* Generic Led data */
186           int                            sc_led_status;
187           void                       (*sc_led)(void *, int);
188 
189 /* Nexus list */
190           struct nexus                   sc_nexus[8];
191           struct nexus                  *sc_cur_nexus;
192           struct nexus                  *sc_sel_nexus;
193 
194 /* Current transfer data */
195           u_char                        *sc_buf;  /* va */
196           int                            sc_len;
197 
198           void                          *sc_dma_buf;        /* pa */
199           int                            sc_dma_len;
200           void                          *sc_dma_blk_ptr;
201           int                            sc_dma_blk_len;
202           short                          sc_dma_blk_flg;
203 
204           struct sfas_dma_chain         *sc_chain;          /* Current DMA chain */
205           short                          sc_max_link;
206           short                          sc_cur_link;
207 
208 /* Interrupt registers */
209           u_char                         sc_status;
210           u_char                         sc_interrupt;
211           u_char                         sc_resel[2];
212 
213           u_char                         sc_units_disconnected;
214 
215 /* Storage for FAS216 config registers (current values) */
216           u_char                         sc_config1;
217           u_char                         sc_config2;
218           u_char                         sc_config3;
219           u_char                         sc_clock_conv_fact;
220           u_char                         sc_timeout_val;
221           u_char                         sc_clock_period;
222 
223           u_char                         sc_msg_in[7];
224           u_char                         sc_msg_in_len;
225 
226           u_char                         sc_msg_out[7];
227           u_char                         sc_msg_out_len;
228 
229           u_char                         sc_unit;
230           u_char                         sc_lun;
231           u_char                         sc_flags;
232 };
233 
234 #define SFAS_DMA_READ         0
235 #define SFAS_DMA_WRITE        1
236 #define SFAS_DMA_CLEAR        2
237 
238 /* sc_flags */
239 #define SFAS_ACTIVE  0x01
240 #define SFAS_DONT_WAIT         0x02
241 
242 /* SCSI Selection modes */
243 #define SFAS_SELECT 0x00      /* Normal selection: No sync, no resel */
244 #define SFAS_SELECT_R         0x01      /* Reselection allowed */
245 #define SFAS_SELECT_S         0x02      /* Synchronous transfer allowed */
246 #define SFAS_SELECT_I         0x04      /* Selection for sfasicmd */
247 #define SFAS_SELECT_K         0x08      /* Send a BUS DEVICE RESET message (Kill) */
248 
249 /* Nice abbreviations of the above */
250 #define SFAS_SELECT_RS        (SFAS_SELECT_R|SFAS_SELECT_S)
251 #define SFAS_SELECT_RI        (SFAS_SELECT_R|SFAS_SELECT_I)
252 #define SFAS_SELECT_SI        (SFAS_SELECT_S|SFAS_SELECT_I)
253 #define SFAS_SELECT_RSI       (SFAS_SELECT_R|SFAS_SELECT_S|SFAS_SELECT_I)
254 
255 /* sc_config_flags */
256 #define SFAS_NO_SYNCH          0x01     /* Disable synchronous transfer */
257 #define SFAS_NO_DMA  0x02     /* Do not use DMA! EVER! */
258 #define SFAS_NO_RESELECT 0x04 /* Do not allow relesection */
259 #define SFAS_SLOW_CABLE        0x08     /* Cable is "unsafe" for fast scsi-2 */
260 #define SFAS_SLOW_START        0x10     /* There are slow starters on the bus */
261 
262 void      sfasinitialize(struct sfas_softc *sc);
263 void      sfas_minphys(struct buf *bp);
264 void      sfas_scsi_request(struct scsipi_channel *,
265                                         scsipi_adapter_req_t, void *);
266 void      sfasintr(struct sfas_softc *dev);
267 
268 #endif /* _SFASVAR_H_ */
269