Commit | Line | Data |
---|---|---|
1ac8d5ba MD |
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 | |
2102f407 | 440 | #define SILI_PREG_FIFO_CTL_ENCODE(rlevel, wlevel) (rlevel | (wlevel << 16)) |
1ac8d5ba MD |
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 | */ | |
2102f407 | 475 | #define SILI_PREG_CMDACT(n) (0x1C00 + (8 * (n))) |
1ac8d5ba MD |
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 | ||
2102f407 MD |
631 | /* |
632 | * Each sge is 16 bytes. We need to accomodate MAXPHYS (128K) which is | |
633 | * at least 32 entries, plus one for page slop, plus one more for every | |
634 | * 3 entries for the link entry. | |
635 | * | |
636 | * We want our prb structure to be power-of-2 aligned (it is required to be | |
637 | * at least 8-byte aligned). the prb base header is 4 SGE's but includes 2 | |
638 | * SGE's within it. | |
639 | */ | |
640 | #define SILI_MAX_SGET (64 - 4) | |
641 | #define SILI_MAX_PMPORTS 16 | |
642 | ||
643 | #if MAXPHYS / PAGE_SIZE + 1 > (SILI_MAX_SGET * 3 / 4) | |
644 | #error "SILI_MAX_SGET is not big enough" | |
645 | #endif | |
646 | ||
647 | ||
1ac8d5ba MD |
648 | /* |
649 | * The PRB | |
650 | * | |
651 | * NOTE: ATAPI PACKETS. The packet is stored in prb_sge[0] and sge[1] | |
652 | * is the first SGE. | |
2102f407 MD |
653 | * |
654 | * NOTE: LRAM PRB. The PRB layout in the LRAM includes a single struct | |
655 | * sili_sge[4]. We could use the LRAM for the PRB and host memory | |
656 | * for an external SGE array, but LRAM in general has some serious | |
657 | * hardware bugs. | |
658 | * | |
659 | * From linux: Reading the LRAM for a port while a command is | |
660 | * outstanding can corrupt DMA. So we use a completely external PRB. | |
1ac8d5ba MD |
661 | */ |
662 | struct sili_prb { | |
663 | u_int16_t prb_control; | |
664 | u_int16_t prb_override; | |
665 | u_int32_t prb_xfer_count; | |
666 | union { | |
667 | struct ata_fis_h2d h2d; | |
668 | struct ata_fis_d2h d2h; | |
669 | } prb_fis; | |
670 | u_int32_t prb_reserved1c; | |
2102f407 MD |
671 | struct sili_sge prb_sge_base[2]; |
672 | struct sili_sge prb_sge[SILI_MAX_SGET]; | |
1ac8d5ba MD |
673 | } __packed; |
674 | ||
675 | #define prb_h2d prb_fis.h2d | |
676 | #define prb_d2h prb_fis.d2h | |
677 | #define prb_activation prb_ext[0].sge_paddr | |
678 | #define prb_packet(prb) ((u_int8_t *)&(prb)->prb_sge[0]) | |
2102f407 MD |
679 | #define prb_sge_normal prb_sge_base[0] |
680 | #define prb_sge_packet prb_sge_base[1] | |
1ac8d5ba MD |
681 | |
682 | /* | |
683 | * NOTE: override may be left 0 and the SIL3132 will decode the | |
684 | * 8-bit ATA command and use the correct protocol. | |
685 | */ | |
686 | #define SILI_PRB_CTRL_OVERRIDE 0x0001 /* use protocol field override */ | |
687 | #define SILI_PRB_CTRL_REXMIT 0x0002 /* ok to rexmit ext command */ | |
688 | #define SILI_PRB_CTRL_EXTCMD 0x0004 /* FIS fetched from host memory */ | |
689 | /* (else from LRAM) */ | |
690 | #define SILI_PRB_CTRL_RECEIVE 0x0008 /* Reserve cmd slot to receive */ | |
691 | /* an interlocked FIS */ | |
692 | #define SILI_PRB_CTRL_READ 0x0010 /* device to host data */ | |
693 | #define SILI_PRB_CTRL_WRITE 0x0020 /* host to device data */ | |
694 | #define SILI_PRB_CTRL_NOINT 0x0040 /* do not post int on completion*/ | |
695 | #define SILI_PRB_CTRL_SOFTRESET 0x0080 /* issue soft reset (special) */ | |
696 | ||
697 | #define SILI_PRB_OVER_ATAPI 0x0001 | |
698 | #define SILI_PRB_OVER_ATA 0x0002 | |
699 | #define SILI_PRB_OVER_NCQ 0x0004 | |
700 | #define SILI_PRB_OVER_READ 0x0008 /* device to host data */ | |
701 | #define SILI_PRB_OVER_WRITE 0x0010 /* host to device data */ | |
702 | #define SILI_PRB_OVER_RAW 0x0020 /* no protocol special case */ | |
703 | ||
1ac8d5ba MD |
704 | #define SILI_MAX_PORTS 16 |
705 | #define SILI_MAX_CMDS 31 /* not 32 */ | |
706 | ||
707 | struct sili_dmamem { | |
708 | bus_dma_tag_t adm_tag; | |
709 | bus_dmamap_t adm_map; | |
710 | bus_dma_segment_t adm_seg; | |
711 | bus_addr_t adm_busaddr; | |
712 | caddr_t adm_kva; | |
713 | }; | |
714 | #define SILI_DMA_MAP(_adm) ((_adm)->adm_map) | |
715 | #define SILI_DMA_DVA(_adm) ((_adm)->adm_busaddr) | |
716 | #define SILI_DMA_KVA(_adm) ((void *)(_adm)->adm_kva) | |
717 | ||
718 | struct sili_softc; | |
719 | struct sili_port; | |
720 | struct sili_device; | |
721 | ||
722 | struct sili_ccb { | |
723 | /* ATA xfer associated with this CCB. Must be 1st struct member. */ | |
724 | struct ata_xfer ccb_xa; | |
725 | struct callout ccb_timeout; | |
726 | ||
727 | int ccb_slot; | |
728 | struct sili_port *ccb_port; | |
729 | ||
730 | bus_dmamap_t ccb_dmamap; | |
731 | struct sili_prb *ccb_prb; | |
4383d440 | 732 | struct sili_prb *ccb_prb_lram; |
2102f407 | 733 | u_int64_t ccb_prb_paddr; /* phys addr of prb */ |
1ac8d5ba MD |
734 | |
735 | void (*ccb_done)(struct sili_ccb *); | |
736 | ||
737 | TAILQ_ENTRY(sili_ccb) ccb_entry; | |
738 | }; | |
739 | ||
740 | struct sili_port { | |
741 | struct sili_softc *ap_sc; | |
742 | bus_space_handle_t ap_ioh; | |
743 | ||
744 | int ap_num; | |
745 | int ap_pmcount; | |
746 | int ap_flags; | |
747 | #define AP_F_BUS_REGISTERED 0x0001 | |
748 | #define AP_F_CAM_ATTACHED 0x0002 | |
749 | #define AP_F_IN_RESET 0x0004 | |
750 | #define AP_F_SCAN_RUNNING 0x0008 | |
751 | #define AP_F_SCAN_REQUESTED 0x0010 | |
752 | #define AP_F_SCAN_COMPLETED 0x0020 | |
753 | #define AP_F_IGNORE_IFS 0x0040 | |
4383d440 | 754 | #define AP_F_UNUSED0200 0x0200 |
1ac8d5ba MD |
755 | #define AP_F_ERR_CCB_RESERVED 0x0400 |
756 | int ap_signal; /* os per-port thread sig */ | |
757 | thread_t ap_thread; /* os per-port thread */ | |
758 | struct lock ap_lock; /* os per-port lock */ | |
759 | #define AP_SIGF_INIT 0x0001 | |
760 | #define AP_SIGF_TIMEOUT 0x0002 | |
761 | #define AP_SIGF_PORTINT 0x0004 | |
762 | #define AP_SIGF_STOP 0x8000 | |
763 | struct cam_sim *ap_sim; | |
764 | ||
2102f407 | 765 | struct sili_prb *ap_prbs; |
1ac8d5ba | 766 | |
2102f407 | 767 | struct sili_dmamem *ap_dmamem_prbs;/* separate sge tables */ |
1ac8d5ba MD |
768 | |
769 | u_int32_t ap_active; /* active bmask */ | |
770 | u_int32_t ap_active_cnt; /* active count */ | |
771 | u_int32_t ap_expired; /* deferred expired bmask */ | |
772 | struct sili_ccb *ap_ccbs; | |
773 | struct sili_ccb *ap_err_ccb; /* used to read LOG page */ | |
4383d440 | 774 | struct sili_ccb *ap_last_ccb; /* used to check excl mode*/ |
1ac8d5ba MD |
775 | |
776 | TAILQ_HEAD(, sili_ccb) ap_ccb_free; | |
777 | TAILQ_HEAD(, sili_ccb) ap_ccb_pending; | |
778 | struct lock ap_ccb_lock; | |
779 | ||
780 | int ap_type; /* ATA_PORT_T_xxx */ | |
781 | int ap_probe; /* ATA_PROBE_xxx */ | |
782 | struct ata_port *ap_ata; | |
783 | ||
784 | u_int32_t ap_state; | |
785 | #define AP_S_NORMAL 0 | |
786 | #define AP_S_FATAL_ERROR 1 | |
787 | ||
788 | /* For error recovery. */ | |
789 | #ifdef DIAGNOSTIC | |
790 | int ap_err_busy; | |
791 | #endif | |
792 | u_int8_t ap_err_scratch[512]; | |
793 | ||
794 | char ap_name[16]; | |
795 | }; | |
796 | ||
797 | #define PORTNAME(_ap) ((_ap)->ap_name) | |
798 | #define ATANAME(_ap, _at) ((_at) ? (_at)->at_name : (_ap)->ap_name) | |
799 | ||
800 | struct sili_softc { | |
801 | device_t sc_dev; | |
802 | const struct sili_device *sc_ad; /* special casing */ | |
803 | ||
804 | struct resource *sc_irq; /* bus resources */ | |
805 | struct resource *sc_regs; /* bus resources */ | |
806 | struct resource *sc_pregs; /* bus resources */ | |
807 | bus_space_tag_t sc_iot; /* split from sc_regs */ | |
808 | bus_space_handle_t sc_ioh; /* split from sc_regs */ | |
809 | bus_space_tag_t sc_piot; /* split from sc_pregs */ | |
810 | bus_space_handle_t sc_pioh; /* split from sc_pregs */ | |
811 | ||
812 | int sc_rid_irq; /* saved bus RIDs */ | |
813 | int sc_rid_regs; | |
814 | int sc_rid_pregs; | |
815 | ||
816 | void *sc_irq_handle; /* installed irq vector */ | |
817 | ||
2102f407 | 818 | bus_dma_tag_t sc_tag_prbs; |
1ac8d5ba MD |
819 | bus_dma_tag_t sc_tag_data; |
820 | ||
821 | int sc_flags; | |
822 | #define SILI_F_NO_NCQ 0x0001 | |
823 | #define SILI_F_IGN_FR 0x0002 | |
824 | #define SILI_F_INT_GOOD 0x0004 | |
825 | #define SILI_F_64BIT 0x0008 | |
826 | #define SILI_F_300 0x0010 | |
827 | #define SILI_F_NCQ 0x0020 | |
828 | #define SILI_F_SSNTF 0x0040 | |
829 | #define SILI_F_SPM 0x0080 | |
830 | ||
831 | u_int sc_ncmds; /* max 31, NOT 32 */ | |
832 | ||
833 | struct sili_port *sc_ports[SILI_MAX_PORTS]; | |
834 | }; | |
835 | #define DEVNAME(_s) ((_s)->sc_dev.dv_xname) | |
836 | ||
837 | struct sili_device { | |
838 | pci_vendor_id_t ad_vendor; | |
839 | pci_product_id_t ad_product; | |
840 | int ad_nports; | |
841 | int (*ad_attach)(device_t dev); | |
842 | int (*ad_detach)(device_t dev); | |
843 | char *name; | |
844 | }; | |
845 | ||
846 | const struct sili_device *sili_lookup_device(device_t dev); | |
847 | int sili_init(struct sili_softc *); | |
848 | int sili_port_init(struct sili_port *ap, struct ata_port *at); | |
849 | int sili_port_alloc(struct sili_softc *, u_int); | |
850 | void sili_port_state_machine(struct sili_port *ap, int initial); | |
851 | void sili_port_free(struct sili_softc *, u_int); | |
852 | int sili_port_reset(struct sili_port *, struct ata_port *at, int); | |
853 | ||
854 | u_int32_t sili_read(struct sili_softc *, bus_size_t); | |
855 | void sili_write(struct sili_softc *, bus_size_t, u_int32_t); | |
856 | int sili_wait_ne(struct sili_softc *, bus_size_t, u_int32_t, u_int32_t); | |
857 | u_int32_t sili_pread(struct sili_port *, bus_size_t); | |
858 | void sili_pwrite(struct sili_port *, bus_size_t, u_int32_t); | |
859 | int sili_pwait_eq(struct sili_port *, int, bus_size_t, | |
860 | u_int32_t, u_int32_t); | |
861 | void sili_intr(void *); | |
862 | void sili_port_intr(struct sili_port *ap, int blockable); | |
863 | ||
864 | int sili_cam_attach(struct sili_port *ap); | |
865 | void sili_cam_changed(struct sili_port *ap, struct ata_port *at, int found); | |
866 | void sili_cam_detach(struct sili_port *ap); | |
867 | int sili_cam_probe(struct sili_port *ap, struct ata_port *at); | |
868 | ||
869 | struct ata_xfer *sili_ata_get_xfer(struct sili_port *ap, struct ata_port *at); | |
870 | void sili_ata_put_xfer(struct ata_xfer *xa); | |
871 | int sili_ata_cmd(struct ata_xfer *xa); | |
872 | ||
873 | int sili_pm_identify(struct sili_port *ap); | |
874 | int sili_pm_set_feature(struct sili_port *ap, int feature, int enable); | |
875 | int sili_pm_hardreset(struct sili_port *ap, int target, int hard); | |
876 | int sili_pm_softreset(struct sili_port *ap, int target); | |
877 | int sili_pm_phy_status(struct sili_port *ap, int target, u_int32_t *datap); | |
878 | int sili_pm_read(struct sili_port *ap, int target, | |
879 | int which, u_int32_t *res); | |
880 | int sili_pm_write(struct sili_port *ap, int target, | |
881 | int which, u_int32_t data); | |
882 | void sili_pm_check_good(struct sili_port *ap, int target); | |
883 | void sili_ata_cmd_timeout(struct sili_ccb *ccb); | |
884 | struct sili_ccb *sili_get_ccb(struct sili_port *ap); | |
885 | void sili_put_ccb(struct sili_ccb *ccb); | |
886 | struct sili_ccb *sili_get_err_ccb(struct sili_port *); | |
887 | void sili_put_err_ccb(struct sili_ccb *); | |
888 | int sili_poll(struct sili_ccb *ccb, int timeout, | |
889 | void (*timeout_fn)(struct sili_ccb *)); | |
890 | ||
891 | int sili_port_signature(struct sili_port *ap, struct ata_port *at, | |
892 | u_int32_t sig); | |
893 | void sili_port_thread_core(struct sili_port *ap, int mask); | |
894 | ||
895 | void sili_os_sleep(int ms); | |
896 | void sili_os_hardsleep(int us); | |
897 | int sili_os_softsleep(void); | |
898 | void sili_os_start_port(struct sili_port *ap); | |
899 | void sili_os_stop_port(struct sili_port *ap); | |
900 | void sili_os_signal_port_thread(struct sili_port *ap, int mask); | |
901 | void sili_os_lock_port(struct sili_port *ap); | |
902 | int sili_os_lock_port_nb(struct sili_port *ap); | |
903 | void sili_os_unlock_port(struct sili_port *ap); | |
904 | ||
905 | extern u_int32_t SiliForceGen1; | |
906 | extern u_int32_t SiliNoFeatures; |