1 /*        $NetBSD: ninjascsi32var.h,v 1.8 2021/10/06 20:42:44 andvar Exp $      */
2 
3 /*-
4  * Copyright (c) 2004, 2007 The NetBSD Foundation, Inc.
5  * All rights reserved.
6  *
7  * This code is derived from software contributed to The NetBSD Foundation
8  * by ITOH Yasufumi.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29  * POSSIBILITY OF SUCH DAMAGE.
30  */
31 
32 #ifndef _NJSC32VAR_H_
33 #define _NJSC32VAR_H_
34 
35 typedef unsigned    njsc32_model_t;
36 #define NJSC32_MODEL_MASK     0xff
37 #define NJSC32_MODEL_INVALID  0
38 #define NJSC32_MODEL_32BI     1
39 #define NJSC32_MODEL_32UDE    2
40 #define NJSC32_FLAG_DUALEDGE  0x100     /* supports DualEdge */
41 
42 /*
43  * time parameters (25us per unit?)
44  */
45 #define NJSC32_SEL_TIMEOUT_TIME                   20000     /* selection timeout (500ms) */
46 #define NJSC32_ARBITRATION_RETRY_TIME   4         /* 100us */
47 
48 /* in microseconds */
49 #define NJSC32_REQ_TIMEOUT              10000     /* 10ms */
50 #define NJSC32_RESET_HOLD_TIME                    26        /* 25us min */
51 
52 /*
53  * DMA page
54  */
55 #ifdef NJSC32_AUTOPARAM
56 #define NJSC32_NUM_CMD        14        /* # simultaneous commands */
57 #else
58 #define NJSC32_NUM_CMD        15        /* # simultaneous commands */
59 #endif
60 #define NJSC32_NUM_SG         17        /* # scatter/gather table entries per command */
61 
62 struct njsc32_dma_page {
63           /*
64            * scatter/gather transfer table
65            */
66           struct njsc32_sgtable         dp_sg[NJSC32_NUM_CMD][NJSC32_NUM_SG];
67 #define NJSC32_SIZE_SGT \
68           (sizeof(struct njsc32_sgtable) * NJSC32_NUM_SG)
69 
70 #ifdef NJSC32_AUTOPARAM
71           /*
72            * device reads parameters from this structure (autoparam)
73            */
74           struct njsc32_autoparam       dp_ap;
75 #endif
76 };
77 
78 /* per command */
79 struct njsc32_cmd {
80           TAILQ_ENTRY(njsc32_cmd)       c_q;
81           struct njsc32_softc *c_sc;
82 
83           /* on transfer */
84           struct scsipi_xfer  *c_xs;
85           struct njsc32_target          *c_target;
86           struct njsc32_lu    *c_lu;
87           u_int32_t           c_datacnt;          /* I/O buffer length */
88 
89           /* command status */
90           int                 c_flags;
91 #define NJSC32_CMD_DMA_MAPPED 0x01
92 #define NJSC32_CMD_TAGGED     0x02
93 #define NJSC32_CMD_TAGGED_HEAD          0x04
94 
95           /* SCSI pointer */
96           u_int32_t c_dp_cur; /* current (or active) data pointer */
97           u_int32_t c_dp_saved;         /* saved data pointer */
98           u_int32_t c_dp_max; /* max value of data pointer */
99 
100           /* last loaded scatter/gather table */
101           unsigned  c_sgoffset;         /* # skip entries */
102           u_int32_t c_sgfixcnt;         /* # skip bytes in the top entry */
103 
104           /* command start/restart parameter */
105           u_int8_t  c_msg_identify;     /* Identify message */
106           u_int16_t c_xferctl;
107           u_int32_t c_sgtdmaaddr;
108 
109           /* DMA resource */
110           struct njsc32_sgtable         *c_sgt;             /* for host */
111           bus_addr_t                    c_sgt_dma;          /* for device */
112 #define NJSC32_CMD_DMAADDR_SGT(cmd, n)  \
113                     ((cmd)->c_sgt_dma + sizeof(struct njsc32_sgtable) * (n))
114           bus_dmamap_t                  c_dmamap_xfer;
115 };
116 
117 /* -1 for unaligned access */
118 #define NJSC32_MAX_XFER       ((NJSC32_NUM_SG - 1) << PGSHIFT)
119 
120 struct njsc32_softc {
121           device_t            sc_dev;
122 
123           /* device spec */
124           njsc32_model_t                sc_model;
125 
126           int                           sc_clk;             /* one of following */
127 #define NJSC32_CLK_40M                  NJSC32_CLOCK_DIV_4  /* 20MB/s */
128 #define NJSC32_CLK_20M                  NJSC32_CLOCK_DIV_2  /* 10MB/s */
129 #define NJSC32_CLK_PCI_33M    NJSC32_CLOCK_PCICLK /* 16.6MB/s */
130 
131           /* device register */
132           bus_space_tag_t               sc_regt;
133           bus_space_handle_t  sc_regh;
134 
135           unsigned            sc_flags;
136 #define NJSC32_IO_MAPPED                0x00000001
137 #define NJSC32_MEM_MAPPED               0x00000002
138 #define NJSC32_CMDPG_MAPPED             0x00000004
139 #define NJSC32_CANNOT_SUPPLY_TERMPWR    0x00000100
140 
141           /*
142            * controller state
143            */
144           enum njsc32_stat {
145                     NJSC32_STAT_IDLE,
146                     NJSC32_STAT_ARBIT,  /* initiator started arbitration */
147                     NJSC32_STAT_CONNECT,          /* command is active (connection) */
148                     NJSC32_STAT_RESEL,  /* a target did Reselection */
149                     NJSC32_STAT_RESEL_LUN,        /* received Identify message */
150                     NJSC32_STAT_RECONNECT,        /* command is active (reconnection) */
151                     NJSC32_STAT_RESET,  /* resetting bus */
152                     NJSC32_STAT_RESET1, /* waiting for bus reset release */
153                     NJSC32_STAT_RESET2, /* waiting for bus reset release */
154                     NJSC32_STAT_DETACH  /* detaching */
155           } sc_stat;
156 
157           /* interrupt handle */
158           void                          *sc_ih;
159 
160           /* for DMA */
161           bus_dma_tag_t                 sc_dmat;
162           struct njsc32_dma_page        *sc_cmdpg;          /* scatter/gather table page */
163 #if 0
164           bus_addr_t                    sc_cmdpg_dma;
165 #endif
166           bus_dma_segment_t   sc_cmdpg_seg;
167           bus_dmamap_t                  sc_dmamap_cmdpg;
168           int                           sc_cmdpg_nsegs;
169 
170 #ifdef NJSC32_AUTOPARAM
171           u_int32_t           sc_ap_dma;          /* autoparam DMA address */
172 #endif
173 
174           /* for monitoring bus reset */
175           struct callout                sc_callout;
176 
177           /*
178            * command control structure
179            */
180           struct njsc32_cmd   sc_cmds[NJSC32_NUM_CMD];
181           TAILQ_HEAD(njsc32_cmd_head, njsc32_cmd)
182                                         sc_freecmd,         /* free list */
183                                         sc_reqcmd;          /* waiting commands */
184 
185           struct njsc32_cmd   *sc_curcmd;         /* currently active command */
186           int                           sc_ncmd;  /* total # commands available */
187           int                           sc_nusedcmds;       /* # used commands */
188 
189           /* reselection */
190           int                           sc_reselid, sc_resellun;
191 
192           /* message in buffer */
193 #define NJSC32_MSGIN_LEN      20
194           u_int8_t            sc_msginbuf[NJSC32_MSGIN_LEN];
195           int                           sc_msgincnt;
196 
197           /* message out buffer */
198 #define NJSC32_MSGOUT_LEN     16
199           u_int8_t            sc_msgout[NJSC32_MSGOUT_LEN];
200           size_t                        sc_msgoutlen;
201           size_t                        sc_msgoutidx;
202 
203           /* sync timing table */
204           const struct njsc32_sync_param {
205                     u_int8_t  sp_period;          /* transfer period */
206                     u_int8_t  sp_ackw;  /* ACK width parameter */
207                     u_int8_t  sp_sample;          /* sampling period */
208           } *sc_synct;
209           int       sc_sync_max;
210 
211           /* for scsipi layer */
212           device_t            sc_scsi;
213           struct scsipi_adapter         sc_adapter;
214           struct scsipi_channel         sc_channel;
215 
216           /* per-target */
217           struct njsc32_target {
218                     enum njsc32_tarst {
219                               NJSC32_TARST_DONE,  /* negotiation done */
220                               NJSC32_TARST_INIT,
221                               NJSC32_TARST_DE,    /* negotiating DualEdge */
222                               NJSC32_TARST_WDTR,  /* negotiating width */
223                               NJSC32_TARST_SDTR,  /* negotiating sync */
224                               NJSC32_TARST_ASYNC  /* negotiating async */
225                     } t_state;
226                     int       t_flags;
227 #define NJSC32_TARF_TAG                 0x0001    /* tagged queueing is enabled */
228 #define NJSC32_TARF_SYNC      0x0002    /* negotiate for sync transfer */
229 #define NJSC32_TARF_DE                  0x0004    /* negotiate for DualEdge transfer */
230 
231                     int                 t_syncperiod;
232                     int                 t_syncoffset;
233 
234                     u_int8_t  t_sync;
235                     u_int8_t  t_ackwidth;
236                     u_int8_t  t_targetid;         /* initiator and target id */
237                     u_int8_t  t_sample;
238 
239                     u_int16_t t_xferctl;          /* DualEdge flag */
240 
241                     /* per logical unit */
242                     struct njsc32_lu {
243                               /*
244                                * disconnected commands
245                                */
246                               struct njsc32_cmd *lu_cmd;    /* untagged command */
247                               struct njsc32_cmd_head        lu_q;     /* tagged commands */
248                     } t_lus[NJSC32_NLU];
249           } sc_targets[NJSC32_MAX_TARGET_ID + 1];
250 };
251 
252 #ifdef _KERNEL
253 void      njsc32_attach(struct njsc32_softc *);
254 int       njsc32_detach(struct njsc32_softc *, int);
255 int       njsc32_intr(void *);
256 #endif
257 
258 #endif    /* _NJSC32VAR_H_ */
259