xref: /dragonfly/sys/dev/disk/sili/sili.h (revision c2a27f530d06e2122e22253a8f88f45c8e4720a8)
1 /*
2  * Copyright (c) 2006 David Gwynne <dlg@openbsd.org>
3  *
4  * Permission to use, copy, modify, and distribute this software for any
5  * purpose with or without fee is hereby granted, provided that the above
6  * copyright notice and this permission notice appear in all copies.
7  *
8  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15  *
16  * $OpenBSD: sili.c,v 1.147 2009/02/16 21:19:07 miod Exp $
17  */
18 
19 #if defined(__DragonFly__)
20 #include "sili_dragonfly.h"
21 #else
22 #error "build for OS unknown"
23 #endif
24 #include "pmreg.h"
25 #include "atascsi.h"
26 
27 /* change to SILI_DEBUG for dmesg spam */
28 #define NO_SILI_DEBUG
29 
30 #ifdef SILI_DEBUG
31 #define DPRINTF(m, f...) do { if ((silidebug & (m)) == (m)) kprintf(f); } \
32     while (0)
33 #define SILI_D_TIMEOUT                  0x00
34 #define SILI_D_VERBOSE                  0x01
35 #define SILI_D_INTR           0x02
36 #define SILI_D_XFER           0x08
37 int silidebug = SILI_D_VERBOSE;
38 #else
39 #define DPRINTF(m, f...)
40 #endif
41 
42 /*
43  * BAR0 - Global Registers              128-byte aligned, 128-byte region
44  * BAR1 - Port Registers and LRAM       32KB-aligned
45  * BAR2 - Indirect I/O registers        (we don't use this)
46  */
47 
48 /*
49  * Port-N Slot Status.
50  *
51  * NOTE: Mirrors SILI_PREG_SLOTST
52  */
53 #define SILI_REG_SLOTST(n)    (0x0000 + ((n) * 4))
54 #define SILI_REG_SLOTST_ATTN  0x80000000          /* attention required */
55 
56 #define SILI_REG_GCTL                   0x0040              /* Global Control   */
57 #define SILI_REG_GCTL_PORTEN(n)         (1 << (n))          /* Port interrupt ena         */
58 #define SILI_REG_GCTL_300CAP  0x01000000          /* 3Gb/s capable (R)          */
59 #define SILI_REG_GCTL_I2C_IEN 0x20000000          /* I2C Int enable   */
60 #define SILI_REG_GCTL_MSIACK  0x40000000          /* MSI Ack W1C                */
61 #define SILI_REG_GCTL_GRESET  0x80000000          /* global reset */
62 
63 #define SILI_REG_GINT                   0x0044              /* Global Interrupt Status */
64 #define SILI_REG_GINT_I2C     0x20000000          /* I2C Int Status   */
65 #define SILI_REG_GINT_PORTST(n)         (1 << (n))          /* Port interrupt stat  */
66 #define SILI_REG_GINT_PORTMASK          0x0000FFFF
67 
68 /*
69  * Most bits in phyconf should not be modified.  Setting the low four bits
70  * to 1's, all channel Tx outputs spread spectrum clocking.
71  */
72 #define SILI_REG_PHYCONF      0x0048              /* PHY Configuration */
73 #define SILI_REG_PHYCONF_ALLSS          0x000F              /* spread spectrum tx */
74 
75 /*
76  * BIST_CTL_TEN -   Enable data paths for running data loopback BIST
77  * BIST_CTL_TPAT -  Select repeating pattern (1) or pseudo-random
78  *                            pattern (0)
79  * BIST_CTL_RXSEL-  Select the rx port for pattern comparison
80  * BIST_CTL_TXSEL-  Select the tx ports that transmit loopback data
81  */
82 #define SILI_REG_BIST_CTL     0x0050
83 #define SILI_REG_BIST_CTL_TEN 0x80000000
84 #define SILI_REG_BIST_CTL_TPAT          0x40000000
85 #define SILI_REG_BIST_CTL_RXSEL(n) ((n) << 16)
86 #define SILI_REG_BIST_CTL_TXSEL(n) (1 << (n))
87 
88 #define SILI_REG_BIST_PATTERN 0x0054    /* 32 bit pattern */
89 
90 /*
91  * GOOD is set to 1 on BIST initiation, and reset to 0 on the first
92  * comparison failure.
93  */
94 #define SILI_REG_BIST_STATUS  0x0058
95 #define SILI_REG_BIST_STATUS_CNT  0x000007FF      /* pattern counter */
96 #define SILI_REG_BIST_STATUS_GOOD 0x80000000      /* set to 0 on compare fail */
97 
98 #define SILI_REG_I2C_CTL      0x0060
99 #define SILI_REG_I2C_CTL_START          0x00000001
100 #define SILI_REG_I2C_CTL_STOP 0x00000002
101 #define SILI_REG_I2C_CTL_NACK 0x00000004          /* send nack on data byte rx */
102 #define SILI_REG_I2C_CTL_TFDATA         0x00000008          /* set to initiate txfer     */
103                                                             /* to/from data buffer             */
104 #define SILI_REG_I2C_CTL_MABORT         0x00000010          /* set w/STOP to send stop   */
105                                                             /* without first xfering a   */
106                                                             /* byte                            */
107 #define SILI_REG_I2C_CTL_SCLEN          0x00000020          /* clock-en for master mode  */
108 #define SILI_REG_I2C_CTL_UNITEN         0x00000040          /* enable controller               */
109 #define SILI_REG_I2C_CTL_GCALLD         0x00000080          /* Disable detect of a       */
110                                                             /* general call address      */
111 #define SILI_REG_I2C_CTL_TXBEI          0x00000100          /* xmit buffer empty int en  */
112 #define SILI_REG_I2C_CTL_RXBFI          0x00000200          /* rx buffer full int en     */
113 #define SILI_REG_I2C_CTL_BERRI          0x00000400          /* bus error int en      */
114 #define SILI_REG_I2C_CTL_STOPI          0x00000800          /* stop detect int en              */
115 #define SILI_REG_I2C_CTL_ARBLI          0x00001000          /* arb loss int en       */
116 #define SILI_REG_I2C_CTL_ARBDI          0x00002000          /* arb detect int en               */
117 #define SILI_REG_I2C_CTL_UNITRS         0x00004000          /* reset I2C controller            */
118 #define SILI_REG_I2C_CTL_FASTM          0x00008000          /* 400kbit/s (else 100kbit/s)*/
119 
120 #define SILI_REG_I2C_STS      0x0064
121 #define SILI_REG_I2C_STS_RW   0x00000001
122 #define SILI_REG_I2C_STS_ACKSTS         0x00000002          /* ack/nack status(R) last   */
123                                                             /* ack or nack sent or rcvd  */
124 #define SILI_REG_I2C_STS_UNTBSY         0x00000004          /* unit busy (R)         */
125 #define SILI_REG_I2C_STS_BUSBSY         0x00000008          /* bus busy with activity(R) */
126                                                             /* other then from controller*/
127 #define SILI_REG_I2C_STS_STOPDT         0x00000010          /* stop detect (R/W1C)             */
128 #define SILI_REG_I2C_STS_ARBLD          0x00000020          /* arb loss detect   (R/W1C) */
129 #define SILI_REG_I2C_STS_TXBED          0x00000040          /* tx buffer empty   (R)     */
130 #define SILI_REG_I2C_STS_RXBFD          0x00000080          /* rx buffer full    (R/W1C) */
131 #define SILI_REG_I2C_STS_GCALLD         0x00000100          /* Gen Call detect   (R/W1C) */
132 #define SILI_REG_I2C_STS_SADDRD         0x00000200          /* Slave addr detect (R/W1C) */
133 #define SILI_REG_I2C_STS_BERRD          0x00000400          /* Bus error detect  (R/W1C) */
134 
135 #define SILI_REG_I2C_SADDR    0x0068              /* our slave address         */
136 #define SILI_REG_I2C_SADDR_MASK         0x0000003F          /* 6 bits                    */
137 
138 #define SILI_REG_I2C_DATA     0x006C              /* data buffer (8 bits)      */
139 
140 #define SILI_REG_FLASH_ADDR   0x0070              /* Flash control & addr reg  */
141 #define SILI_REG_FLASH_ADDR_MEMPRS 0x04000000     /* Flash memory present            */
142 #define SILI_REG_FLASH_ADDR_GPIOEN 0x80000000     /* use flash data pins for   */
143                                                             /* GPIO */
144 #define SILI_REG_FLASH_ADDR_MEMST  0x02000000     /* Mem Access Start (R/W)    */
145                                                             /* (clears on op complete)   */
146 #define SILI_REG_FLASH_ADDR_MEMRD  0x01000000     /* 0=write, 1=read           */
147 #define SILI_REG_FLASH_ADDR_MASK   0x0003FFFF     /* 18 bit memory address     */
148 
149 /*
150  * NOTE: In order to set a GPIO pin to read the DATA bit must be written to
151  *       1and the DCTL (drain control) bit must be written to 1 as well
152  *       to make it open-drain only (drive on low only).
153  */
154 #define SILI_REG_GPIO                   0x0074
155 #define SILI_REG_GPIO_DATA_SHIFT        0         /* 8 bits Flash or GPIO data */
156 #define SILI_REG_GPIO_TDET_SHIFT        8         /* 8 bits transition detect  */
157 #define SILI_REG_GPIO_DCTL_SHIFT        16        /* 8 bits drain control      */
158 
159 /*
160  * Per-port registers
161  *
162  */
163 
164 #define SILI_PORT_REGION(port)          (8192 * (port))
165 #define SILI_PORT_SIZE                  8192
166 #define SILI_PREG_LRAM                  0x0000              /* 0x0000-0x0F7F         */
167 #define SILI_PREG_LRAM_SLOT(n)          (0x0000 + (128 * (n)))
168 
169 #define SILI_PREG_LRAM_SLOT_FIS         0x0000              /* Current FIS and Control   */
170 #define SILI_PREG_LRAM_DMA0   0x0020              /* DMA Entry 0 or ATAPI cmd  */
171 #define SILI_PREG_LRAM_DMA1   0x0030              /* DMA Entry 0 or ATAPI cmd  */
172 #define SILI_PREG_LRAM_CMDACT 0x0040              /* Cmd Act Reg (actual) 64b  */
173 #define SILI_PREG_LRAM_DMATAB 0x0040              /* Scatter Gather Table      */
174 
175 /*
176  * Each port has a port status and qactive register for each target behind
177  * the port multiplier, if there is a port multiplier.
178  *
179  * SERVICE - Service received from device, service command from controller
180  *             not yet acknowledged.
181  *
182  * LEGACY  - One or more legacy queued commands is outstanding.
183  *
184  * NATIVE  - One or more NCQ queued commands is outstanding.
185  *
186  * VBSY    - A virtual device busy indicating that a command has been issued
187  *             to the device and the device has not yet sent the final D2H
188  *             register FIS, or that a data transfer is in progress.
189  *
190  * The PM_QACTIVE register contains a demultiplexed bitmap of slots queued
191  * to each target behind the port multiplier.
192  *
193  */
194 #define SILI_PREG_PM_STATUS(n)          (0x0F80 + (8 * (n)))
195 #define SILI_PREG_PM_QACTIVE(n)         (0x0F84 + (8 * (n)))
196 
197 #define SILI_PREG_PM_STATUS_SERVICE     0x00010000          /* Service pending */
198 #define SILI_PREG_PM_STATUS_LEGACY      0x00008000          /* Legacy outstanding*/
199 #define SILI_PREG_PM_STATUS_NATIVE      0x00004000          /* NCQ outstanding */
200 #define SILI_PREG_PM_STATUS_VBSY        0x00002000          /* virtual dev busy */
201 #define SILI_PREG_PM_STATUS_EXEC_SHIFT  8                   /* last active slot */
202 #define SILI_PREG_PM_STATUS_EXEC_MASK   0x1F
203 #define SILI_PREG_PM_STATUS_PIO_MASK    0xFF                /* last PIO setup   */
204 
205 /*
206  * NOTE: SILI_PREG_STATUS uses the same address as SILI_PREG_CTL_SET,
207  * but for read.
208  */
209 #define SILI_PREG_STATUS      0x1000              /* Port Control Status (R)   */
210 #define SILI_PREG_STATUS_READY          0x80000000          /* Port Ready          (R)   */
211 #define SILI_PREG_STATUS_SLOT 0x001F0000          /* Active Slot         (R)   */
212 #define SILI_PREG_STATUS_SLOT_SHIFT     16        /* Shift value                     */
213 #define SILI_PREG_STATUS_MASK 0x0200FFFF          /* see PREG_CTL_xxx          */
214 
215 /*
216  * NOTE: Reset sequence.  Set CTL_RESET, Clear CTL_RESET, then Wait for
217  *       the port to become ready.
218  *
219  * NOTE: NOAUTOCC.  If set to 1 a 1 must be written to the command completion
220  *         bit in the port interrupt status register to clear it.  When set to
221  *         0 then reading the port slot status register will automatically clear
222  *       the command completion interrupt.
223  *
224  * NOTE: ATA16 controls whether a PACKET mode command is 12 or 16 bytes.
225  *
226  * NOTE: RESUME if set to 1 processing is enabled for outstanding commands
227  *       to additional targets connected to a port multiplier after a command
228  *         error has occured.  When set the internal BUSY status will be set
229  *         for the target that errored, preventing additional commands from
230  *       being sent until a Port Initialize operation is performed.
231  *
232  * NOTE: 32BITDMA if 1 causes a write to the low 32 bits of a Command
233  *         Activation register to  copy PREG_32BIT_ACTUA to the upper 32
234  *       bits and start command execution.  If 0 you must write to the
235  *       low 32 bits and then the high 32 bits and your write to the
236  *       high 32 bits will start command execution.
237  *
238  * NOTE: OOB_BYP is set on global reset and not changed by a port reset.
239  */
240 #define SILI_PREG_CTL_SET     0x1000              /* Port Control Set    (W1S) */
241 #define SILI_PREG_CTL_CLR     0x1004              /* Port Control Clear  (W1C) */
242 #define SILI_PREG_CTL_RESET   0x00000001          /* Hold port in reset        */
243 #define SILI_PREG_CTL_DEVRESET          0x00000002          /* Device reset              */
244                                                             /* (Self clearing)           */
245 #define SILI_PREG_CTL_INIT    0x00000004          /* Port initialize           */
246                                                             /* (Self clearing)           */
247 #define SILI_PREG_CTL_NOAUTOCC          0x00000008
248 #define SILI_PREG_CTL_NOLED   0x00000010          /* Disable the LED port      */
249                                                             /* activity indicator.       */
250 #define SILI_PREG_CTL_ATA16   0x00000020          /* 0=12 byte 1=16 byte       */
251 #define SILI_PREG_CTL_RESUME  0x00000040          /* PM special error handling */
252 #define SILI_PREG_CTL_TXBIST  0x00000080          /* transmit a BIST FIS       */
253 #define SILI_PREG_CTL_CONT_DIS          0x00000100          /* no CONT on repeat primitves*/
254 #define SILI_PREG_CTL_NOSCRAM 0x00000200          /* Disable link scrambler    */
255 #define SILI_PREG_CTL_32BITDMA          0x00000400          /* see above                       */
256 #define SILI_PREG_CTL_ACC_ILCK          0x00000800          /* accept interlocked FIS rx */
257                                                             /* (Self clearing)           */
258 #define SILI_PREG_CTL_REJ_ILCK          0x00001000          /* reject interlocked FIS rx */
259                                                             /* (Self clearing)           */
260 #define SILI_PREG_CTL_PMA     0x00002000          /* Enable PM support         */
261 #define SILI_PREG_CTL_AUTO_ILCK         0x00004000          /* Auto interlock accept     */
262 #define SILI_PREG_CTL_LEDON   0x00008000          /* LED on                */
263 #define SILI_PREG_CTL_OOB_BYP 0x02000000          /* Bypass OOB initialization */
264 
265 /*
266  * Status bits in the upper half of the register report the actual condition
267  * while the status bits in the lower half of the register are masked by
268  * the interrupt enable bits or threshold registers.  Writing a 1 to either
269  * version will clear it.
270  *
271  * NOTE: The steering bits written to INT_ENABLE will not show up in the
272  *       status register.  The INT_ENABLE/INT_DISABLE registers are R+W1S
273  *         or R+W1C and thus can be read.
274  *
275  * NOTE: PHYRDYCHG, COMWAKE, UNRECFIS, DEVEXCHG: Can be cleared by writing
276  *         W1C either here or via the DIAG.xxx bit bit in SError.
277  */
278 #define SILI_PREG_INT_STATUS  0x1008              /* Control clear         */
279 #define SILI_PREG_INT_ENABLE  0x1010              /* Interrupt Enable Set      */
280 #define SILI_PREG_INT_DISABLE 0x1014              /* Interrupt Enable Clear    */
281 
282 #define SILI_PREG_INT_STEER(n)          ((n) << 30)         /* Port Int -> INTA...INTD   */
283 #define SILI_PREG_INT_CCOMPLETE         0x00000001          /* one or more cmds completed*/
284 #define SILI_PREG_INT_CERROR  0x00000002          /* read port error register  */
285                                                             /* to get error              */
286 #define SILI_PREG_INT_READY   0x00000004          /* Port is ready for cmds    */
287 #define SILI_PREG_INT_PMCHANGE          0x00000008          /* Change in power mng state */
288 #define SILI_PREG_INT_PHYRDYCHG         0x00000010          /* Mirrors DIAG.N in SError  */
289 #define SILI_PREG_INT_COMWAKE 0x00000020          /* Mirrors DIAG.W in SError  */
290 #define SILI_PREG_INT_UNRECFIS          0x00000040          /* Mirrors DIAG.F in SError  */
291 #define SILI_PREG_INT_DEVEXCHG          0x00000080          /* Mirrors DIAG.X in SError  */
292 #define SILI_PREG_INT_DECODE  0x00000100          /* 8b/10b dec err  cnt > thr */
293 #define SILI_PREG_INT_CRC     0x00000200          /* CRC err       count > thr */
294 #define SILI_PREG_INT_HANDSHK 0x00000400          /* Handshake err count > thr */
295 #define SILI_PREG_INT_SDB     0x00000800          /* Set Device Bits (SNotify) */
296 #define SILI_PREG_INT_SHIFT   16                  /* shift upper bits of status*/
297 
298 #define SILI_PREG_IST_CCOMPLETE         0x00010000          /* one or more cmds completed*/
299 #define SILI_PREG_IST_CERROR  0x00020000          /* read port error register  */
300                                                             /* to get error              */
301 #define SILI_PREG_IST_READY   0x00040000          /* Port is ready for cmds    */
302 #define SILI_PREG_IST_PMCHANGE          0x00080000          /* Change in power mng state */
303 #define SILI_PREG_IST_PHYRDYCHG         0x00100000          /* Mirrors DIAG.N in SError  */
304 #define SILI_PREG_IST_COMWAKE 0x00200000          /* Mirrors DIAG.W in SError  */
305 #define SILI_PREG_IST_UNRECFIS          0x00400000          /* Mirrors DIAG.F in SError  */
306 #define SILI_PREG_IST_DEVEXCHG          0x00800000          /* Mirrors DIAG.X in SError  */
307 #define SILI_PREG_IST_DECODE  0x01000000          /* 8b/10b dec err  cnt > thr */
308 #define SILI_PREG_IST_CRC     0x02000000          /* CRC err       count > thr */
309 #define SILI_PREG_IST_HANDSHK 0x04000000          /* Handshake err count > thr */
310 #define SILI_PREG_IST_SDB     0x08000000          /* Set Device Bits (SNotify) */
311 
312 #define SILI_PREG_INT_MASK    (SILI_PREG_INT_CCOMPLETE |              \
313                                          SILI_PREG_INT_CERROR |                           \
314                                          SILI_PREG_INT_READY |                            \
315                                          SILI_PREG_INT_PMCHANGE |               \
316                                          SILI_PREG_INT_PHYRDYCHG |              \
317                                          SILI_PREG_INT_COMWAKE |                \
318                                          SILI_PREG_INT_UNRECFIS |               \
319                                          SILI_PREG_INT_DEVEXCHG |               \
320                                          SILI_PREG_INT_DECODE |                           \
321                                          SILI_PREG_INT_CRC |                              \
322                                          SILI_PREG_INT_HANDSHK |                \
323                                          SILI_PREG_INT_SDB)
324 #define SILI_PREG_IST_MASK    (SILI_PREG_INT_MASK << 16)
325 
326 #define SILI_PFMT_INT_STATUS  "\020"                        \
327                                         "\034SDB"           \
328                                         "\033HANDSHK"                 \
329                                         "\032CRC"           \
330                                         "\031DECODE"                  \
331                                         "\030DEVEXCHG"                \
332                                         "\027UNRECFIS"                \
333                                         "\026COMWAKE"                 \
334                                         "\025PHYRDYCHG"               \
335                                         "\024PMCHANGE"                \
336                                         "\023READY"                   \
337                                         "\022ERROR"                   \
338                                         "\021COMPLETE"                \
339                                                                       \
340                                         "\014SDBm"                    \
341                                         "\013HANDSHKm"                \
342                                         "\012CRCm"                    \
343                                         "\011DECODEm"                 \
344                                         "\010DEVEXCHGm"               \
345                                         "\007UNRECFISm"               \
346                                         "\006COMWAKEm"                \
347                                         "\005PHYRDYCHGm"    \
348                                         "\004PMCHANGEm"               \
349                                         "\003READYm"                  \
350                                         "\002ERRORm"                  \
351                                         "\001COMPLETEm"
352 
353 /*
354  * 32BIT_ACTUA is only used when DMA is 32 bits.  It is typically set to 0.
355  */
356 #define SILI_PREG_32BIT_ACTUA 0x101C              /* 32b activation upper addr */
357 
358 /*
359  * Writing a slot number 0-30 to CMD_FIFO starts the command from LRAM.
360  */
361 #define SILI_PREG_CMD_FIFO    0x1020              /* Command execution FIFO    */
362 
363 /*
364  * If the port is interrupted via INT_CERROR this register contains
365  * the error code.
366  *
367  * Most errors write the task file register back to the PRB slot for host
368  * scrutiny.
369  */
370 #define SILI_PREG_CERROR      0x1024              /* Command error             */
371 #define SILI_PREG_CERROR_DEVICE                   1         /* ERR set in D2H FIS        */
372 #define SILI_PREG_CERROR_SDBERROR       2         /* ERR set in SDB from device*/
373 #define SILI_PREG_CERROR_DATAFISERR     3         /* Sil3132 error on send     */
374 #define SILI_PREG_CERROR_SENDFISERR     4         /* Sil3132 error on send     */
375 #define SILI_PREG_CERROR_BADSTATE       5         /* Sil3132 inconsistency     */
376 #define SILI_PREG_CERROR_DIRECTION      6         /* DMA direction mismatch    */
377 #define SILI_PREG_CERROR_UNDERRUN       7         /* DMA SG H2D list too small */
378 #define SILI_PREG_CERROR_OVERRUN        8         /* DMA SG D2H list too small */
379 #define SILI_PREG_CERROR_LLOVERUN       9         /* Too much data from device */
380 #define SILI_PREG_CERROR_PKTPROTO       11        /* Packet protocol error     */
381 #define SILI_PREG_CERROR_BADALIGN       16        /* Bad SG list, not 8-byte   */
382                                                             /* aligned                   */
383 #define SILI_PREG_CERROR_PCITGTABRT     17        /* PCI target abort received */
384 #define SILI_PREG_CERROR_PCIMASABRT     18        /* PCI master abort received */
385 #define SILI_PREG_CERROR_PCIPARABRT     19        /* PCI parity abort received */
386 #define SILI_PREG_CERROR_PRBALIGN       24        /* PRB addr not 8-byte algned*/
387 #define SILI_PREG_CERROR_PCITGTABRT2    25        /* During fetch of PRB       */
388 #define SILI_PREG_CERROR_PCIMASABRT2    26        /* During fetch of PRB       */
389 #define SILI_PREG_CERROR_PCIPARABRT3    33        /* During data transfer      */
390 #define SILI_PREG_CERROR_PCITGTABRT3    34        /* During data transfer      */
391 #define SILI_PREG_CERROR_PCIMASABRT3    35        /* During data transfer      */
392 #define SILI_PREG_CERROR_SERVICE        36        /* FIS received during tx    */
393                                                             /* phase                     */
394 
395 /*
396  * Port FIS Configuration.  Fir each possible FIS type, a 2-bit code
397  * defines the desired reception behavior as follows.  Bits [1:0] define
398  * the code for all other FIS types not defined by [29:2].
399  *
400  *        00 Accept FIS without interlock
401  *        01 Reject FIS without interlock
402  *        10 Interlock FIS
403  *        11 (reserved)
404  *
405  * FIS Code         Name                          Start     Default
406  * --------         ------                        ------    -------
407  *    ----          (reserved)                    30
408  *    0x27          Register (H2D)                28        01
409  *    0x34          Register (D2H)                26        00
410  *    0x39          DMA Activate                  24        00
411  *    0x41          DMA Setup           22        00
412  *    0x46          Data                          20        00
413  *    0x58          BIST Activate                 18        00
414  *    0x5F          PIO Setup           16        00
415  *    0xA1          Set Device Bits               14        00
416  *    0xA6          (reserved)                    12        01
417  *    0xB8          (reserved)                    10        01
418  *    0xBF          (reserved)                    8         01
419  *    0xC7          (reserved)                    6         01
420  *    0xD4          (reserved)                    4         01
421  *    0xD9          (reserved)                    2         01
422  * ALL OTHERS       (reserved)                    0         01
423  */
424 #define SILI_PREG_FIS_CONFIG  0x1028              /* FIS configuration         */
425 
426 /*
427  * The data FIFO is 2KBytes in each direction.
428  *
429  * When DMAing from the device the Write Request Threshold is used.
430  * When DMAing to the device the Read Request Threshold is used.
431  *
432  * The threshold can be set from 1-2040 bytes (write 0-2039), in multiples
433  * of 8 bits.  The low 3 bits are hardwired to 0.  A value of 0 causes a
434  * request whenever possible.
435  */
436 #define SILI_PREG_FIFO_CTL    0x102C              /* PCIex request FIFO thresh */
437 #define SILI_PREG_FIFO_CTL_READ_SHIFT   0
438 #define SILI_PREG_FIFO_CTL_WRITE_SHIFT  16
439 #define SILI_PREG_FIFO_CTL_MASK         0xFF
440 #define SILI_PREG_FIFO_CTL_ENCODE(rlevel, wlevel)  (rlevel | (wlevel << 16))
441 
442 /*
443  * Error counters and thresholds.  The counter occupies the low 16 bits
444  * and the threshold occupies the high 16 bits.  The appropriate interrupt
445  * occurs when the counter exceeds the threshold.  Clearing the interrupt
446  * clears the counter as well.  A threshold of 0 disables the interrupt
447  * assertion and masks the interrupt status bit in the port interrupt status
448  * register.
449  */
450 #define SILI_PREG_CTR_DECODE  0x1040              /* 8B/10B Decode Error Ctr   */
451 #define SILI_PREG_CTR_CRC     0x1044              /* CRC Error Counter         */
452 #define SILI_PREG_CTR_HANDSHK 0x1048              /* Handshake Error Counter   */
453 
454 /*
455  * NOTE: This register is reset only by the global reset and will not be
456  *         reset by a port reset.
457  *
458  * NOTE: Bits 15:5 configure the PHY and should not be changed unless you
459  *         want to blow up the part.
460  *
461  *         Bits 4:0 define the nominal output swing for the transmitter
462  *         and are set to 0x0C by default.  Generally speaking, don't mess
463  *         with them.
464  */
465 #define SILI_PREG_PHY_CONFIG  0x1050              /* Handshake Error Counter   */
466 #define SILI_PREG_PHY_CONFIG_AMP_MASK   0x1F
467 
468 #define SILI_PREG_SLOTST      0x1800              /* Slot Status                     */
469 #define SILI_PREG_SLOTST_ATTN 0x80000000          /* 0-30 bit for each slot */
470 
471 /*
472  * Shadow command activation register, shadows low or high 32 bits
473  * of actual command activation register.
474  */
475 #define SILI_PREG_CMDACT(n)   (0x1C00 + (8 * (n)))
476 
477 /*
478  * Port Context Register.  Contains the port multipler target (0-15) and
479  * the command slot (0-31) for the PM port state machine.
480  *
481  * Upon a processing halt due to a device specific error, the port multipler
482  * target is the one that returned the error status.
483  *
484  * The command slot is NOT deterministic in this case and should not be
485  * assumed valid.  Use READ LOG EXTENDED to determine the tag number.
486  * However, the documentation does appear to indicate that for non-NCQ
487  * errors the command slot does contain the tag that errored (since there
488  * will be only one truely active).
489  */
490 #define SILI_PREG_CONTEXT               0x1E04
491 #define SILI_PREG_CONTEXT_SLOT_MASK     0x1F
492 #define SILI_PREG_CONTEXT_PMPORT_MASK   0x0F
493 #define SILI_PREG_CONTEXT_SLOT_SHIFT    0
494 #define SILI_PREG_CONTEXT_PMPORT_SHIFT  5
495 
496 /*
497  * SControl register - power management, speed negotiation, and COMRESET
498  *                         operation.
499  */
500 #define SILI_PREG_SCTL                            0x1F00
501 
502 /*
503  * PMP: Identify the PM port for accessing the SActive register and some
504  *        bit fields of the Diagnostic registers.
505  */
506 #define SILI_PREG_SCTL_PMP              0x000F0000
507 #define SILI_PREG_SCTL_PMP_SHIFT        16
508 
509 /*
510  * SPM: It is unclear from mode 4 is.  "Transition from a power management
511  *        state initiate (ComWake asserted)".  When setting a state, the field
512  *        will self-reset to 0 as soon as the action is initiated.
513  */
514 #define SILI_PREG_SCTL_SPM              0x0000F000
515 #define  SILI_PREG_SCTL_SPM_NONE        0x00000000
516 #define  SILI_PREG_SCTL_SPM_PARTIAL     0x00010000
517 #define  SILI_PREG_SCTL_SPM_SLUMBER     0x00020000
518 #define  SILI_PREG_SCTL_SPM_FROM        0x00040000
519 
520 /*
521  * IPM: Identify interface power management states not supported (bits).
522  */
523 #define SILI_PREG_SCTL_IPM              0x00000F00
524 #define  SILI_PREG_SCTL_IPM_NONE        0x00000000
525 #define  SILI_PREG_SCTL_IPM_NPARTIAL    0x00000100
526 #define  SILI_PREG_SCTL_IPM_NSLUMBER    0x00000200
527 
528 /*
529  * SPD: Limit speed negotiation (0000 for no restrictions)
530  */
531 #define   SILI_PREG_SCTL_SPD            0x000000F0
532 #define    SILI_PREG_SCTL_SPD_NONE      0x00000000
533 #define    SILI_PREG_SCTL_SPD_GEN1      0x00000010
534 #define    SILI_PREG_SCTL_SPD_GEN2      0x00000020
535 
536 /*
537  * DET: Control host adapter device detection and interface initialization
538  */
539 #define   SILI_PREG_SCTL_DET            0x0000000F
540 #define    SILI_PREG_SCTL_DET_NONE      0x00000000          /* nop/complete     */
541 #define    SILI_PREG_SCTL_DET_INIT      0x00000001          /* hold in COMRESET */
542 
543 /*
544  * SStatus register - Probe status
545  */
546 #define SILI_PREG_SSTS                            0x1F04
547 #define  SILI_PREG_SSTS_IPM             0x00000F00
548 #define  SILI_PREG_SSTS_IPM_NOCOMM      0x00000000
549 #define  SILI_PREG_SSTS_IPM_ACTIVE      0x00000100
550 #define  SILI_PREG_SSTS_IPM_PARTIAL     0x00000200
551 #define  SILI_PREG_SSTS_IPM_SLUMBER     0x00000600
552 
553 #define SILI_PREG_SSTS_SPD              0x000000F0
554 #define  SILI_PREG_SSTS_SPD_NONE        0x00000000
555 #define  SILI_PREG_SSTS_SPD_GEN1        0x00000010
556 #define  SILI_PREG_SSTS_SPD_GEN2        0x00000020
557 
558 #define SILI_PREG_SSTS_DET              0x0000000F
559 #define  SILI_PREG_SSTS_DET_NOPHY       0x00000000          /* no dev, no phy */
560 #define  SILI_PREG_SSTS_DET_DEV_NE      0x00000001          /* dev, no phy      */
561 #define  SILI_PREG_SSTS_DET_DEV                   0x00000003          /* dev and phy      */
562 #define  SILI_PREG_SSTS_DET_OFFLINE     0x00000004          /* BIST/LOOPBACK */
563 
564 /*
565  * These are mostly R/W1C bits.  "B", "C", and "H" operate independantly
566  * and depend on the corresponding error counter register.
567  */
568 #define SILI_PREG_SERR                            0x1F08
569 #define  SILI_PREG_SERR_ERR_I           (1<<0) /* Recovered Data Integrity */
570 #define  SILI_PREG_SERR_ERR_M           (1<<1) /* Recovered Communications */
571 #define  SILI_PREG_SERR_ERR_T           (1<<8) /* Transient Data Integrity */
572 #define  SILI_PREG_SERR_ERR_C           (1<<9) /* Persistent Comm/Data */
573 #define  SILI_PREG_SERR_ERR_P           (1<<10) /* Protocol */
574 #define  SILI_PREG_SERR_ERR_E           (1<<11) /* Internal */
575 #define  SILI_PREG_SERR_DIAG_N                    (1<<16) /* PhyRdy Change */
576 #define  SILI_PREG_SERR_DIAG_I                    (1<<17) /* Phy Internal Error */
577 #define  SILI_PREG_SERR_DIAG_W                    (1<<18) /* Comm Wake */
578 #define  SILI_PREG_SERR_DIAG_B                    (1<<19) /* 10B to 8B Decode Error */
579 #define  SILI_PREG_SERR_DIAG_D                    (1<<20) /* Disparity Error */
580 #define  SILI_PREG_SERR_DIAG_C                    (1<<21) /* CRC Error */
581 #define  SILI_PREG_SERR_DIAG_H                    (1<<22) /* Handshake Error */
582 #define  SILI_PREG_SERR_DIAG_S                    (1<<23) /* Link Sequence Error */
583 #define  SILI_PREG_SERR_DIAG_T                    (1<<24) /* Transport State Trans Err */
584 #define  SILI_PREG_SERR_DIAG_F                    (1<<25) /* Unknown FIS Type */
585 #define  SILI_PREG_SERR_DIAG_X                    (1<<26) /* Exchanged */
586 
587 #define  SILI_PFMT_SERR       "\020"    \
588                               "\033DIAG.X" "\032DIAG.F" "\031DIAG.T" "\030DIAG.S" \
589                               "\027DIAG.H" "\026DIAG.C" "\025DIAG.D" "\024DIAG.B" \
590                               "\023DIAG.W" "\022DIAG.I" "\021DIAG.N"                \
591                               "\014ERR.E" "\013ERR.P" "\012ERR.C" "\011ERR.T"       \
592                               "\002ERR.M" "\001ERR.I"
593 
594 /*
595  * SACT provides indirect access to the Port Device QActive registers.
596  * We have direct access and do not have to use this.
597  */
598 #define SILI_PREG_SACT                            0x1F0C
599 
600 /*
601  * Indicate which devices have sent a Set Device Bits FIS with Notifcation
602  * set.  R/W1C
603  */
604 #define SILI_PREG_SNTF                            0x1F10
605 
606 /*
607  * Internal register space indirect register access via the PCI I/O space.
608  * (This is for BIOSes running in 16-bit mode, we use the direct map).
609  *
610  * All offsets must be 4-byte aligned
611  */
612 #define SILI_BAR2_GRO                             0x0000    /* Global Register Offset */
613 #define SILI_BAR2_GRD                             0x0004    /* Global Register Data */
614 #define SILI_BAR2_PRO                             0x0008    /* Port Register Offset */
615 #define SILI_BAR2_PRD                             0x000C    /* Port Register Data */
616 
617 /*
618  * SILI mapped structures
619  */
620 struct sili_sge {
621           u_int64_t           sge_paddr;
622           u_int32_t           sge_count;
623           u_int32_t           sge_flags;
624 } __packed;
625 
626 #define SILI_SGE_FLAGS_TRM    0x80000000          /* last SGE associated w/cmd */
627 #define SILI_SGE_FLAGS_LNK    0x40000000          /* link to SGE array          */
628 #define SILI_SGE_FLAGS_DRD    0x20000000          /* discard (ign sge_paddr) */
629 #define SILI_SGE_FLAGS_XCF    0x10000000          /* external cmd fetch         */
630 
631 /*
632  * Each sge is 16 bytes.
633  *
634  * We want our prb structure to be power-of-2 aligned (it is required to be
635  * at least 8-byte aligned).  the prb base header is 4 SGE's but includes 2
636  * SGE's within it.
637  * The prb structure also can't cross a 64KB boundary, and thus can only
638  * have a maximum size of 65536 / 16 / 32  == ~128 entries (128 - 4)
639  */
640 #define SILI_MAX_SGET                   (128 - 4)
641 #define SILI_MAX_PMPORTS      16
642 #define SILI_MAXPHYS                    (256 * 1024)        /* 256 KB */
643 
644 #if SILI_MAXPHYS / PAGE_SIZE + 1 > (SILI_MAX_SGET * 3 / 4)
645 #error "SILI_MAX_SGET is not big enough"
646 #endif
647 
648 
649 /*
650  * The PRB
651  *
652  * NOTE: ATAPI PACKETS.  The packet is stored in prb_sge[0] and sge[1]
653  *                             is the first SGE.
654  *
655  * NOTE: LRAM PRB.  The PRB layout in the LRAM includes a single struct
656  *         sili_sge[4].  We could use the LRAM for the PRB and host memory
657  *         for an external SGE array, but LRAM in general has some serious
658  *         hardware bugs.
659  *
660  *         From linux: Reading the LRAM for a port while a command is
661  *         outstanding can corrupt DMA.  So we use a completely external PRB.
662  */
663 struct sili_prb {
664           u_int16_t           prb_control;
665           u_int16_t           prb_override;
666           u_int32_t           prb_xfer_count;
667           union {
668                     struct ata_fis_h2d  h2d;
669                     struct ata_fis_d2h  d2h;
670           } prb_fis;
671           u_int32_t           prb_reserved1c;
672           struct sili_sge               prb_sge_base[2];
673           struct sili_sge               prb_sge[SILI_MAX_SGET];
674 } __packed;
675 
676 #define prb_h2d               prb_fis.h2d
677 #define prb_d2h               prb_fis.d2h
678 #define prb_activation        prb_ext[0].sge_paddr
679 #define prb_packet(prb)       ((u_int8_t *)&(prb)->prb_sge[0])
680 #define prb_sge_normal        prb_sge_base[0]
681 #define prb_sge_packet        prb_sge_base[1]
682 
683 /*
684  * NOTE: override may be left 0 and the SIL3132 will decode the
685  *         8-bit ATA command and use the correct protocol.
686  */
687 #define SILI_PRB_CTRL_OVERRIDE          0x0001    /* use protocol field override          */
688 #define SILI_PRB_CTRL_REXMIT  0x0002    /* ok to rexmit ext command   */
689 #define SILI_PRB_CTRL_EXTCMD  0x0004    /* FIS fetched from host memory */
690                                                   /* (else from LRAM)           */
691 #define SILI_PRB_CTRL_RECEIVE 0x0008    /* Reserve cmd slot to receive          */
692                                                   /* an interlocked FIS                   */
693 #define SILI_PRB_CTRL_READ    0x0010    /* device to host data                  */
694 #define SILI_PRB_CTRL_WRITE   0x0020    /* host to device data                  */
695 #define SILI_PRB_CTRL_NOINT   0x0040    /* do not post int on completion*/
696 #define SILI_PRB_CTRL_SOFTRESET         0x0080    /* issue soft reset (special) */
697 
698 #define SILI_PRB_OVER_ATAPI   0x0001
699 #define SILI_PRB_OVER_ATA     0x0002
700 #define SILI_PRB_OVER_NCQ     0x0004
701 #define SILI_PRB_OVER_READ    0x0008    /* device to host data */
702 #define SILI_PRB_OVER_WRITE   0x0010    /* host to device data */
703 #define SILI_PRB_OVER_RAW     0x0020    /* no protocol special case */
704 
705 #define SILI_MAX_PORTS                  16
706 #define SILI_MAX_CMDS                   31        /* not 32 */
707 
708 struct sili_dmamem {
709           bus_dma_tag_t                 adm_tag;
710           bus_dmamap_t                  adm_map;
711           bus_dma_segment_t   adm_seg;
712           bus_addr_t                    adm_busaddr;
713           caddr_t                       adm_kva;
714 };
715 #define SILI_DMA_MAP(_adm)    ((_adm)->adm_map)
716 #define SILI_DMA_DVA(_adm)    ((_adm)->adm_busaddr)
717 #define SILI_DMA_KVA(_adm)    ((void *)(_adm)->adm_kva)
718 
719 struct sili_softc;
720 struct sili_port;
721 struct sili_device;
722 
723 struct sili_ccb {
724           /* ATA xfer associated with this CCB.  Must be 1st struct member. */
725           struct ata_xfer               ccb_xa;
726           struct callout          ccb_timeout;
727 
728           int                           ccb_slot;
729           struct sili_port    *ccb_port;
730 
731           bus_dmamap_t                  ccb_dmamap;
732           struct sili_prb               *ccb_prb;
733           struct sili_prb               *ccb_prb_lram;
734           u_int64_t           ccb_prb_paddr;      /* phys addr of prb */
735 
736           void                          (*ccb_done)(struct sili_ccb *);
737 
738           TAILQ_ENTRY(sili_ccb)         ccb_entry;
739 };
740 
741 struct sili_port {
742           struct sili_softc   *ap_sc;
743           bus_space_handle_t  ap_ioh;
744 
745           int                           ap_num;
746           int                           ap_pmcount;
747           int                           ap_flags;
748 #define AP_F_BUS_REGISTERED   0x0001
749 #define AP_F_CAM_ATTACHED     0x0002
750 #define AP_F_IN_RESET                   0x0004
751 #define AP_F_SCAN_RUNNING     0x0008
752 #define AP_F_SCAN_REQUESTED   0x0010
753 #define AP_F_SCAN_COMPLETED   0x0020
754 #define AP_F_IGNORE_IFS                 0x0040
755 #define AP_F_UNUSED0200                 0x0200
756 #define AP_F_ERR_CCB_RESERVED 0x0400
757 #define AP_F_REINIT_ACTIVE    0x0800
758           int                           ap_signal;          /* os per-port thread sig */
759           thread_t            ap_thread;          /* os per-port thread */
760           struct lock                   ap_lock;  /* os per-port lock */
761           struct lock                   ap_sim_lock;        /* cam sim lock */
762           struct lock                   ap_sig_lock;        /* signal thread */
763 #define AP_SIGF_INIT                    0x0001
764 #define AP_SIGF_TIMEOUT                 0x0002
765 #define AP_SIGF_PORTINT                 0x0004
766 #define AP_SIGF_STOP                    0x8000
767           struct cam_sim                *ap_sim;
768 
769           struct sili_prb               *ap_prbs;
770 
771           struct sili_dmamem  *ap_dmamem_prbs;/* separate sge tables  */
772 
773           u_int32_t           ap_active;          /* active bmask               */
774           u_int32_t           ap_active_cnt;      /* active count               */
775           u_int32_t           ap_expired;         /* deferred expired bmask */
776           struct sili_ccb               *ap_ccbs;
777           struct sili_ccb               *ap_err_ccb;        /* used to read LOG page  */
778           int                           ap_run_flags;       /* used to check excl mode */
779 
780           TAILQ_HEAD(, sili_ccb)        ap_ccb_free;
781           TAILQ_HEAD(, sili_ccb)        ap_ccb_pending;
782           struct lock                   ap_ccb_lock;
783 
784           int                           ap_type;  /* ATA_PORT_T_xxx */
785           int                           ap_probe; /* ATA_PROBE_xxx */
786           struct ata_port               *ap_ata;
787 
788           u_int32_t           ap_state;
789 #define AP_S_NORMAL                     0
790 #define AP_S_FATAL_ERROR                1
791 
792           /* For error recovery. */
793           u_int8_t            *ap_err_scratch;
794 
795           char                          ap_name[16];
796 };
797 
798 #define PORTNAME(_ap)                   ((_ap)->ap_name)
799 #define ATANAME(_ap, _at)     ((_at) ? (_at)->at_name : (_ap)->ap_name)
800 
801 struct sili_softc {
802           device_t            sc_dev;
803           const struct sili_device *sc_ad;        /* special casing */
804 
805           struct resource               *sc_irq;  /* bus resources */
806           struct resource               *sc_regs; /* bus resources */
807           struct resource               *sc_pregs;          /* bus resources */
808           bus_space_tag_t               sc_iot;             /* split from sc_regs */
809           bus_space_handle_t  sc_ioh;             /* split from sc_regs */
810           bus_space_tag_t               sc_piot;  /* split from sc_pregs */
811           bus_space_handle_t  sc_pioh;  /* split from sc_pregs */
812 
813           int                           sc_irq_type;
814           int                           sc_rid_irq;         /* saved bus RIDs */
815           int                           sc_rid_regs;
816           int                           sc_rid_pregs;
817 
818           void                          *sc_irq_handle;     /* installed irq vector */
819 
820           bus_dma_tag_t                 sc_tag_prbs;
821           bus_dma_tag_t                 sc_tag_data;
822 
823           int                           sc_flags;
824 #define SILI_F_NO_NCQ                             0x0001
825 #define SILI_F_IGN_FR                             0x0002
826 #define SILI_F_INT_GOOD                           0x0004
827 #define SILI_F_64BIT                              0x0008
828 #define SILI_F_300                      0x0010
829 #define SILI_F_NCQ                      0x0020
830 #define SILI_F_SSNTF                              0x0040
831 #define SILI_F_SPM                      0x0080
832 
833           u_int                         sc_ncmds; /* max 31, NOT 32 */
834 
835           struct sili_port    *sc_ports[SILI_MAX_PORTS];
836 };
837 #define DEVNAME(_s)           ((_s)->sc_dev.dv_xname)
838 
839 struct sili_device {
840           pci_vendor_id_t               ad_vendor;
841           pci_product_id_t    ad_product;
842           int                           ad_nports;
843           int                           (*ad_attach)(device_t dev);
844           int                           (*ad_detach)(device_t dev);
845           char                          *name;
846 };
847 
848 /* Wait for all bits in _b to be cleared */
849 #define sili_pwait_clr(_ap, _r, _b) \
850           sili_pwait_eq((_ap), SILI_PWAIT_TIMEOUT, (_r), (_b), 0)
851 #define sili_pwait_clr_to(_ap, _to,  _r, _b) \
852           sili_pwait_eq((_ap), _to, (_r), (_b), 0)
853 
854 /* Wait for all bits in _b to be set */
855 #define sili_pwait_set(_ap, _r, _b) \
856           sili_pwait_eq((_ap), SILI_PWAIT_TIMEOUT, (_r), (_b), (_b))
857 #define sili_pwait_set_to(_ap, _to, _r, _b) \
858           sili_pwait_eq((_ap), _to, (_r), (_b), (_b))
859 
860 /*
861  * Misc defines
862  */
863 #define SILI_PWAIT_TIMEOUT      1000
864 
865 /*
866  * Prototypes
867  */
868 const struct sili_device *sili_lookup_device(device_t dev);
869 int       sili_init(struct sili_softc *);
870 int       sili_port_init(struct sili_port *ap);
871 int       sili_port_alloc(struct sili_softc *, u_int);
872 void      sili_port_state_machine(struct sili_port *ap, int initial);
873 void      sili_port_free(struct sili_softc *, u_int);
874 int       sili_port_reset(struct sili_port *, struct ata_port *at, int);
875 void      sili_exclusive_access(struct sili_port *ap);
876 
877 u_int32_t sili_read(struct sili_softc *, bus_size_t);
878 void      sili_write(struct sili_softc *, bus_size_t, u_int32_t);
879 int       sili_wait_ne(struct sili_softc *, bus_size_t, u_int32_t, u_int32_t);
880 u_int32_t sili_pread(struct sili_port *, bus_size_t);
881 void      sili_pwrite(struct sili_port *, bus_size_t, u_int32_t);
882 int       sili_pwait_eq(struct sili_port *, int, bus_size_t,
883                               u_int32_t, u_int32_t);
884 void      sili_intr(void *);
885 void      sili_port_intr(struct sili_port *ap, int blockable);
886 
887 int       sili_cam_attach(struct sili_port *ap);
888 void      sili_cam_changed(struct sili_port *ap, struct ata_port *at, int found);
889 void      sili_cam_detach(struct sili_port *ap);
890 int       sili_cam_probe(struct sili_port *ap, struct ata_port *at);
891 
892 struct ata_xfer *sili_ata_get_xfer(struct sili_port *ap, struct ata_port *at);
893 void      sili_ata_put_xfer(struct ata_xfer *xa);
894 int       sili_ata_cmd(struct ata_xfer *xa);
895 
896 int       sili_pm_port_probe(struct sili_port *ap, int);
897 int       sili_pm_port_init(struct sili_port *ap, struct ata_port *at);
898 int       sili_pm_identify(struct sili_port *ap);
899 int       sili_pm_set_feature(struct sili_port *ap, int feature, int enable);
900 int       sili_pm_hardreset(struct sili_port *ap, int target, int hard);
901 int       sili_pm_softreset(struct sili_port *ap, int target);
902 int       sili_pm_phy_status(struct sili_port *ap, int target, u_int32_t *datap);
903 int       sili_pm_read(struct sili_port *ap, int target,
904                               int which, u_int32_t *res);
905 int       sili_pm_write(struct sili_port *ap, int target,
906                               int which, u_int32_t data);
907 void      sili_pm_check_good(struct sili_port *ap, int target);
908 void      sili_ata_cmd_timeout(struct sili_ccb *ccb);
909 void      sili_quick_timeout(struct sili_ccb *ccb);
910 struct sili_ccb *sili_get_ccb(struct sili_port *ap);
911 void      sili_put_ccb(struct sili_ccb *ccb);
912 struct sili_ccb *sili_get_err_ccb(struct sili_port *);
913 void      sili_put_err_ccb(struct sili_ccb *);
914 int       sili_poll(struct sili_ccb *ccb, int timeout,
915                               void (*timeout_fn)(struct sili_ccb *));
916 
917 int     sili_port_signature(struct sili_port *ap, struct ata_port *at,
918                               u_int32_t sig);
919 void      sili_port_thread_core(struct sili_port *ap, int mask);
920 
921 void      sili_os_sleep(int ms);
922 void      sili_os_hardsleep(int us);
923 int       sili_os_softsleep(void);
924 void      sili_os_start_port(struct sili_port *ap);
925 void      sili_os_stop_port(struct sili_port *ap);
926 void      sili_os_signal_port_thread(struct sili_port *ap, int mask);
927 void      sili_os_lock_port(struct sili_port *ap);
928 int       sili_os_lock_port_nb(struct sili_port *ap);
929 void      sili_os_unlock_port(struct sili_port *ap);
930 
931 extern u_int32_t SiliForceGen1;
932 extern u_int32_t SiliNoFeatures;
933