1 | /* $NetBSD: satalink.c,v 1.53 2016/08/23 09:46:45 msaitoh Exp $ */ |
2 | |
3 | /*- |
4 | * Copyright (c) 2003 The NetBSD Foundation, Inc. |
5 | * All rights reserved. |
6 | * |
7 | * This code is derived from software contributed to The NetBSD Foundation |
8 | * by Jason R. Thorpe of Wasabi Systems, Inc. |
9 | * |
10 | * Redistribution and use in source and binary forms, with or without |
11 | * modification, are permitted provided that the following conditions |
12 | * are met: |
13 | * 1. Redistributions of source code must retain the above copyright |
14 | * notice, this list of conditions and the following disclaimer. |
15 | * 2. Redistributions in binary form must reproduce the above copyright |
16 | * notice, this list of conditions and the following disclaimer in the |
17 | * documentation and/or other materials provided with the distribution. |
18 | * |
19 | * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS |
20 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED |
21 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
22 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS |
23 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
24 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
25 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
26 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
27 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
28 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
29 | * POSSIBILITY OF SUCH DAMAGE. |
30 | */ |
31 | |
32 | #include <sys/cdefs.h> |
33 | __KERNEL_RCSID(0, "$NetBSD: satalink.c,v 1.53 2016/08/23 09:46:45 msaitoh Exp $" ); |
34 | |
35 | #include <sys/param.h> |
36 | #include <sys/systm.h> |
37 | #include <sys/malloc.h> |
38 | |
39 | #include <dev/pci/pcivar.h> |
40 | #include <dev/pci/pcidevs.h> |
41 | #include <dev/pci/pciidereg.h> |
42 | #include <dev/pci/pciidevar.h> |
43 | #include <dev/pci/pciide_sii3112_reg.h> |
44 | |
45 | #include <dev/ata/satareg.h> |
46 | #include <dev/ata/satavar.h> |
47 | #include <dev/ata/atareg.h> |
48 | |
49 | /* |
50 | * Register map for BA5 register space, indexed by channel. |
51 | */ |
52 | static const struct { |
53 | bus_addr_t ba5_IDEDMA_CMD; |
54 | bus_addr_t ba5_IDEDMA_CTL; |
55 | bus_addr_t ba5_IDEDMA_TBL; |
56 | bus_addr_t ba5_IDEDMA_CMD2; |
57 | bus_addr_t ba5_IDEDMA_CTL2; |
58 | bus_addr_t ba5_IDE_TF0; |
59 | bus_addr_t ba5_IDE_TF1; |
60 | bus_addr_t ba5_IDE_TF2; |
61 | bus_addr_t ba5_IDE_TF3; |
62 | bus_addr_t ba5_IDE_TF4; |
63 | bus_addr_t ba5_IDE_TF5; |
64 | bus_addr_t ba5_IDE_TF6; |
65 | bus_addr_t ba5_IDE_TF7; |
66 | bus_addr_t ba5_IDE_TF8; |
67 | bus_addr_t ba5_IDE_RAD; |
68 | bus_addr_t ba5_IDE_TF9; |
69 | bus_addr_t ba5_IDE_TF10; |
70 | bus_addr_t ba5_IDE_TF11; |
71 | bus_addr_t ba5_IDE_TF12; |
72 | bus_addr_t ba5_IDE_TF13; |
73 | bus_addr_t ba5_IDE_TF14; |
74 | bus_addr_t ba5_IDE_TF15; |
75 | bus_addr_t ba5_IDE_TF16; |
76 | bus_addr_t ba5_IDE_TF17; |
77 | bus_addr_t ba5_IDE_TF18; |
78 | bus_addr_t ba5_IDE_TF19; |
79 | bus_addr_t ba5_IDE_RABC; |
80 | bus_addr_t ba5_IDE_CMD_STS; |
81 | bus_addr_t ba5_IDE_CFG_STS; |
82 | bus_addr_t ba5_IDE_DTM; |
83 | bus_addr_t ba5_SControl; |
84 | bus_addr_t ba5_SStatus; |
85 | bus_addr_t ba5_SError; |
86 | bus_addr_t ba5_SActive; /* 3114 */ |
87 | bus_addr_t ba5_SMisc; |
88 | bus_addr_t ba5_PHY_CONFIG; |
89 | bus_addr_t ba5_SIEN; |
90 | bus_addr_t ba5_SFISCfg; |
91 | } satalink_ba5_regmap[] = { |
92 | { /* Channel 0 */ |
93 | .ba5_IDEDMA_CMD = 0x000, |
94 | .ba5_IDEDMA_CTL = 0x002, |
95 | .ba5_IDEDMA_TBL = 0x004, |
96 | .ba5_IDEDMA_CMD2 = 0x010, |
97 | .ba5_IDEDMA_CTL2 = 0x012, |
98 | .ba5_IDE_TF0 = 0x080, /* wd_data */ |
99 | .ba5_IDE_TF1 = 0x081, /* wd_error */ |
100 | .ba5_IDE_TF2 = 0x082, /* wd_seccnt */ |
101 | .ba5_IDE_TF3 = 0x083, /* wd_sector */ |
102 | .ba5_IDE_TF4 = 0x084, /* wd_cyl_lo */ |
103 | .ba5_IDE_TF5 = 0x085, /* wd_cyl_hi */ |
104 | .ba5_IDE_TF6 = 0x086, /* wd_sdh */ |
105 | .ba5_IDE_TF7 = 0x087, /* wd_command */ |
106 | .ba5_IDE_TF8 = 0x08a, /* wd_altsts */ |
107 | .ba5_IDE_RAD = 0x08c, |
108 | .ba5_IDE_TF9 = 0x091, /* Features 2 */ |
109 | .ba5_IDE_TF10 = 0x092, /* Sector Count 2 */ |
110 | .ba5_IDE_TF11 = 0x093, /* Start Sector 2 */ |
111 | .ba5_IDE_TF12 = 0x094, /* Cylinder Low 2 */ |
112 | .ba5_IDE_TF13 = 0x095, /* Cylinder High 2 */ |
113 | .ba5_IDE_TF14 = 0x096, /* Device/Head 2 */ |
114 | .ba5_IDE_TF15 = 0x097, /* Cmd Sts 2 */ |
115 | .ba5_IDE_TF16 = 0x098, /* Sector Count 2 ext */ |
116 | .ba5_IDE_TF17 = 0x099, /* Start Sector 2 ext */ |
117 | .ba5_IDE_TF18 = 0x09a, /* Cyl Low 2 ext */ |
118 | .ba5_IDE_TF19 = 0x09b, /* Cyl High 2 ext */ |
119 | .ba5_IDE_RABC = 0x09c, |
120 | .ba5_IDE_CMD_STS = 0x0a0, |
121 | .ba5_IDE_CFG_STS = 0x0a1, |
122 | .ba5_IDE_DTM = 0x0b4, |
123 | .ba5_SControl = 0x100, |
124 | .ba5_SStatus = 0x104, |
125 | .ba5_SError = 0x108, |
126 | .ba5_SActive = 0x10c, |
127 | .ba5_SMisc = 0x140, |
128 | .ba5_PHY_CONFIG = 0x144, |
129 | .ba5_SIEN = 0x148, |
130 | .ba5_SFISCfg = 0x14c, |
131 | }, |
132 | { /* Channel 1 */ |
133 | .ba5_IDEDMA_CMD = 0x008, |
134 | .ba5_IDEDMA_CTL = 0x00a, |
135 | .ba5_IDEDMA_TBL = 0x00c, |
136 | .ba5_IDEDMA_CMD2 = 0x018, |
137 | .ba5_IDEDMA_CTL2 = 0x01a, |
138 | .ba5_IDE_TF0 = 0x0c0, /* wd_data */ |
139 | .ba5_IDE_TF1 = 0x0c1, /* wd_error */ |
140 | .ba5_IDE_TF2 = 0x0c2, /* wd_seccnt */ |
141 | .ba5_IDE_TF3 = 0x0c3, /* wd_sector */ |
142 | .ba5_IDE_TF4 = 0x0c4, /* wd_cyl_lo */ |
143 | .ba5_IDE_TF5 = 0x0c5, /* wd_cyl_hi */ |
144 | .ba5_IDE_TF6 = 0x0c6, /* wd_sdh */ |
145 | .ba5_IDE_TF7 = 0x0c7, /* wd_command */ |
146 | .ba5_IDE_TF8 = 0x0ca, /* wd_altsts */ |
147 | .ba5_IDE_RAD = 0x0cc, |
148 | .ba5_IDE_TF9 = 0x0d1, /* Features 2 */ |
149 | .ba5_IDE_TF10 = 0x0d2, /* Sector Count 2 */ |
150 | .ba5_IDE_TF11 = 0x0d3, /* Start Sector 2 */ |
151 | .ba5_IDE_TF12 = 0x0d4, /* Cylinder Low 2 */ |
152 | .ba5_IDE_TF13 = 0x0d5, /* Cylinder High 2 */ |
153 | .ba5_IDE_TF14 = 0x0d6, /* Device/Head 2 */ |
154 | .ba5_IDE_TF15 = 0x0d7, /* Cmd Sts 2 */ |
155 | .ba5_IDE_TF16 = 0x0d8, /* Sector Count 2 ext */ |
156 | .ba5_IDE_TF17 = 0x0d9, /* Start Sector 2 ext */ |
157 | .ba5_IDE_TF18 = 0x0da, /* Cyl Low 2 ext */ |
158 | .ba5_IDE_TF19 = 0x0db, /* Cyl High 2 ext */ |
159 | .ba5_IDE_RABC = 0x0dc, |
160 | .ba5_IDE_CMD_STS = 0x0e0, |
161 | .ba5_IDE_CFG_STS = 0x0e1, |
162 | .ba5_IDE_DTM = 0x0f4, |
163 | .ba5_SControl = 0x180, |
164 | .ba5_SStatus = 0x184, |
165 | .ba5_SError = 0x188, |
166 | .ba5_SActive = 0x18c, |
167 | .ba5_SMisc = 0x1c0, |
168 | .ba5_PHY_CONFIG = 0x1c4, |
169 | .ba5_SIEN = 0x1c8, |
170 | .ba5_SFISCfg = 0x1cc, |
171 | }, |
172 | { /* Channel 2 (3114) */ |
173 | .ba5_IDEDMA_CMD = 0x200, |
174 | .ba5_IDEDMA_CTL = 0x202, |
175 | .ba5_IDEDMA_TBL = 0x204, |
176 | .ba5_IDEDMA_CMD2 = 0x210, |
177 | .ba5_IDEDMA_CTL2 = 0x212, |
178 | .ba5_IDE_TF0 = 0x280, /* wd_data */ |
179 | .ba5_IDE_TF1 = 0x281, /* wd_error */ |
180 | .ba5_IDE_TF2 = 0x282, /* wd_seccnt */ |
181 | .ba5_IDE_TF3 = 0x283, /* wd_sector */ |
182 | .ba5_IDE_TF4 = 0x284, /* wd_cyl_lo */ |
183 | .ba5_IDE_TF5 = 0x285, /* wd_cyl_hi */ |
184 | .ba5_IDE_TF6 = 0x286, /* wd_sdh */ |
185 | .ba5_IDE_TF7 = 0x287, /* wd_command */ |
186 | .ba5_IDE_TF8 = 0x28a, /* wd_altsts */ |
187 | .ba5_IDE_RAD = 0x28c, |
188 | .ba5_IDE_TF9 = 0x291, /* Features 2 */ |
189 | .ba5_IDE_TF10 = 0x292, /* Sector Count 2 */ |
190 | .ba5_IDE_TF11 = 0x293, /* Start Sector 2 */ |
191 | .ba5_IDE_TF12 = 0x294, /* Cylinder Low 2 */ |
192 | .ba5_IDE_TF13 = 0x295, /* Cylinder High 2 */ |
193 | .ba5_IDE_TF14 = 0x296, /* Device/Head 2 */ |
194 | .ba5_IDE_TF15 = 0x297, /* Cmd Sts 2 */ |
195 | .ba5_IDE_TF16 = 0x298, /* Sector Count 2 ext */ |
196 | .ba5_IDE_TF17 = 0x299, /* Start Sector 2 ext */ |
197 | .ba5_IDE_TF18 = 0x29a, /* Cyl Low 2 ext */ |
198 | .ba5_IDE_TF19 = 0x29b, /* Cyl High 2 ext */ |
199 | .ba5_IDE_RABC = 0x29c, |
200 | .ba5_IDE_CMD_STS = 0x2a0, |
201 | .ba5_IDE_CFG_STS = 0x2a1, |
202 | .ba5_IDE_DTM = 0x2b4, |
203 | .ba5_SControl = 0x300, |
204 | .ba5_SStatus = 0x304, |
205 | .ba5_SError = 0x308, |
206 | .ba5_SActive = 0x30c, |
207 | .ba5_SMisc = 0x340, |
208 | .ba5_PHY_CONFIG = 0x344, |
209 | .ba5_SIEN = 0x348, |
210 | .ba5_SFISCfg = 0x34c, |
211 | }, |
212 | { /* Channel 3 (3114) */ |
213 | .ba5_IDEDMA_CMD = 0x208, |
214 | .ba5_IDEDMA_CTL = 0x20a, |
215 | .ba5_IDEDMA_TBL = 0x20c, |
216 | .ba5_IDEDMA_CMD2 = 0x218, |
217 | .ba5_IDEDMA_CTL2 = 0x21a, |
218 | .ba5_IDE_TF0 = 0x2c0, /* wd_data */ |
219 | .ba5_IDE_TF1 = 0x2c1, /* wd_error */ |
220 | .ba5_IDE_TF2 = 0x2c2, /* wd_seccnt */ |
221 | .ba5_IDE_TF3 = 0x2c3, /* wd_sector */ |
222 | .ba5_IDE_TF4 = 0x2c4, /* wd_cyl_lo */ |
223 | .ba5_IDE_TF5 = 0x2c5, /* wd_cyl_hi */ |
224 | .ba5_IDE_TF6 = 0x2c6, /* wd_sdh */ |
225 | .ba5_IDE_TF7 = 0x2c7, /* wd_command */ |
226 | .ba5_IDE_TF8 = 0x2ca, /* wd_altsts */ |
227 | .ba5_IDE_RAD = 0x2cc, |
228 | .ba5_IDE_TF9 = 0x2d1, /* Features 2 */ |
229 | .ba5_IDE_TF10 = 0x2d2, /* Sector Count 2 */ |
230 | .ba5_IDE_TF11 = 0x2d3, /* Start Sector 2 */ |
231 | .ba5_IDE_TF12 = 0x2d4, /* Cylinder Low 2 */ |
232 | .ba5_IDE_TF13 = 0x2d5, /* Cylinder High 2 */ |
233 | .ba5_IDE_TF14 = 0x2d6, /* Device/Head 2 */ |
234 | .ba5_IDE_TF15 = 0x2d7, /* Cmd Sts 2 */ |
235 | .ba5_IDE_TF16 = 0x2d8, /* Sector Count 2 ext */ |
236 | .ba5_IDE_TF17 = 0x2d9, /* Start Sector 2 ext */ |
237 | .ba5_IDE_TF18 = 0x2da, /* Cyl Low 2 ext */ |
238 | .ba5_IDE_TF19 = 0x2db, /* Cyl High 2 ext */ |
239 | .ba5_IDE_RABC = 0x2dc, |
240 | .ba5_IDE_CMD_STS = 0x2e0, |
241 | .ba5_IDE_CFG_STS = 0x2e1, |
242 | .ba5_IDE_DTM = 0x2f4, |
243 | .ba5_SControl = 0x380, |
244 | .ba5_SStatus = 0x384, |
245 | .ba5_SError = 0x388, |
246 | .ba5_SActive = 0x38c, |
247 | .ba5_SMisc = 0x3c0, |
248 | .ba5_PHY_CONFIG = 0x3c4, |
249 | .ba5_SIEN = 0x3c8, |
250 | .ba5_SFISCfg = 0x3cc, |
251 | }, |
252 | }; |
253 | |
254 | #define ba5_SIS 0x214 /* summary interrupt status */ |
255 | |
256 | /* Interrupt steering bit in BA5[0x200]. */ |
257 | #define IDEDMA_CMD_INT_STEER (1U << 1) |
258 | |
259 | static int satalink_match(device_t, cfdata_t, void *); |
260 | static void satalink_attach(device_t, device_t, void *); |
261 | |
262 | CFATTACH_DECL_NEW(satalink, sizeof(struct pciide_softc), |
263 | satalink_match, satalink_attach, pciide_detach, NULL); |
264 | |
265 | static void sii3112_chip_map(struct pciide_softc*, |
266 | const struct pci_attach_args*); |
267 | static void sii3114_chip_map(struct pciide_softc*, |
268 | const struct pci_attach_args*); |
269 | static void sii3112_drv_probe(struct ata_channel*); |
270 | static void sii3112_setup_channel(struct ata_channel*); |
271 | |
272 | static const struct pciide_product_desc pciide_satalink_products[] = { |
273 | { PCI_PRODUCT_CMDTECH_3112, |
274 | 0, |
275 | "Silicon Image SATALink 3112" , |
276 | sii3112_chip_map, |
277 | }, |
278 | { PCI_PRODUCT_CMDTECH_3512, |
279 | 0, |
280 | "Silicon Image SATALink 3512" , |
281 | sii3112_chip_map, |
282 | }, |
283 | { PCI_PRODUCT_CMDTECH_AAR_1210SA, |
284 | 0, |
285 | "Adaptec AAR-1210SA serial ATA RAID controller" , |
286 | sii3112_chip_map, |
287 | }, |
288 | { PCI_PRODUCT_CMDTECH_3114, |
289 | 0, |
290 | "Silicon Image SATALink 3114" , |
291 | sii3114_chip_map, |
292 | }, |
293 | { PCI_PRODUCT_ATI_IXP_SATA_300, |
294 | 0, |
295 | "ATI IXP 300 SATA" , |
296 | sii3112_chip_map, |
297 | }, |
298 | { 0, |
299 | 0, |
300 | NULL, |
301 | NULL |
302 | } |
303 | }; |
304 | |
305 | static int |
306 | satalink_match(device_t parent, cfdata_t match, void *aux) |
307 | { |
308 | struct pci_attach_args *pa = aux; |
309 | |
310 | if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_CMDTECH) { |
311 | if (pciide_lookup_product(pa->pa_id, pciide_satalink_products)) |
312 | return (2); |
313 | } |
314 | return (0); |
315 | } |
316 | |
317 | static void |
318 | satalink_attach(device_t parent, device_t self, void *aux) |
319 | { |
320 | struct pci_attach_args *pa = aux; |
321 | struct pciide_softc *sc = device_private(self); |
322 | |
323 | sc->sc_wdcdev.sc_atac.atac_dev = self; |
324 | |
325 | pciide_common_attach(sc, pa, |
326 | pciide_lookup_product(pa->pa_id, pciide_satalink_products)); |
327 | |
328 | } |
329 | |
330 | static inline uint32_t |
331 | ba5_read_4_ind(struct pciide_softc *sc, bus_addr_t reg) |
332 | { |
333 | uint32_t rv; |
334 | int s; |
335 | |
336 | s = splbio(); |
337 | pci_conf_write(sc->sc_pc, sc->sc_tag, SII3112_BA5_IND_ADDR, reg); |
338 | rv = pci_conf_read(sc->sc_pc, sc->sc_tag, SII3112_BA5_IND_DATA); |
339 | splx(s); |
340 | |
341 | return (rv); |
342 | } |
343 | |
344 | static inline uint32_t |
345 | ba5_read_4(struct pciide_softc *sc, bus_addr_t reg) |
346 | { |
347 | |
348 | if (__predict_true(sc->sc_ba5_en != 0)) |
349 | return (bus_space_read_4(sc->sc_ba5_st, sc->sc_ba5_sh, reg)); |
350 | |
351 | return (ba5_read_4_ind(sc, reg)); |
352 | } |
353 | |
354 | #define BA5_READ_4(sc, chan, reg) \ |
355 | ba5_read_4((sc), satalink_ba5_regmap[(chan)].reg) |
356 | |
357 | static inline void |
358 | ba5_write_4_ind(struct pciide_softc *sc, bus_addr_t reg, uint32_t val) |
359 | { |
360 | int s; |
361 | |
362 | s = splbio(); |
363 | pci_conf_write(sc->sc_pc, sc->sc_tag, SII3112_BA5_IND_ADDR, reg); |
364 | pci_conf_write(sc->sc_pc, sc->sc_tag, SII3112_BA5_IND_DATA, val); |
365 | splx(s); |
366 | } |
367 | |
368 | static inline void |
369 | ba5_write_4(struct pciide_softc *sc, bus_addr_t reg, uint32_t val) |
370 | { |
371 | |
372 | if (__predict_true(sc->sc_ba5_en != 0)) |
373 | bus_space_write_4(sc->sc_ba5_st, sc->sc_ba5_sh, reg, val); |
374 | else |
375 | ba5_write_4_ind(sc, reg, val); |
376 | } |
377 | |
378 | #define BA5_WRITE_4(sc, chan, reg, val) \ |
379 | ba5_write_4((sc), satalink_ba5_regmap[(chan)].reg, (val)) |
380 | |
381 | /* |
382 | * When the Silicon Image 3112 retries a PCI memory read command, |
383 | * it may retry it as a memory read multiple command under some |
384 | * circumstances. This can totally confuse some PCI controllers, |
385 | * so ensure that it will never do this by making sure that the |
386 | * Read Threshold (FIFO Read Request Control) field of the FIFO |
387 | * Valid Byte Count and Control registers for both channels (BA5 |
388 | * offset 0x40 and 0x44) are set to be at least as large as the |
389 | * cacheline size register. |
390 | * This may also happen on the 3114 (ragge 050527) |
391 | */ |
392 | static void |
393 | sii_fixup_cacheline(struct pciide_softc *sc, const struct pci_attach_args *pa, |
394 | int n) |
395 | { |
396 | pcireg_t cls, reg; |
397 | int i; |
398 | static bus_addr_t addr[] = { 0x40, 0x44, 0x240, 0x244 }; |
399 | |
400 | cls = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_BHLC_REG); |
401 | cls = (cls >> PCI_CACHELINE_SHIFT) & PCI_CACHELINE_MASK; |
402 | cls *= 4; |
403 | if (cls > 224) { |
404 | cls = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_BHLC_REG); |
405 | cls &= ~(PCI_CACHELINE_MASK << PCI_CACHELINE_SHIFT); |
406 | cls |= ((224/4) << PCI_CACHELINE_SHIFT); |
407 | pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_BHLC_REG, cls); |
408 | cls = 224; |
409 | } |
410 | if (cls < 32) |
411 | cls = 32; |
412 | cls = (cls + 31) / 32; |
413 | for (i = 0; i < n; i++) { |
414 | reg = ba5_read_4(sc, addr[i]); |
415 | if ((reg & 0x7) < cls) |
416 | ba5_write_4(sc, addr[i], (reg & 0x07) | cls); |
417 | } |
418 | } |
419 | |
420 | static void |
421 | sii3112_chip_map(struct pciide_softc *sc, const struct pci_attach_args *pa) |
422 | { |
423 | struct pciide_channel *cp; |
424 | pcireg_t interface, scs_cmd, cfgctl; |
425 | int channel; |
426 | |
427 | if (pciide_chipen(sc, pa) == 0) |
428 | return; |
429 | |
430 | #define SII3112_RESET_BITS \ |
431 | (SCS_CMD_PBM_RESET | SCS_CMD_ARB_RESET | \ |
432 | SCS_CMD_FF1_RESET | SCS_CMD_FF0_RESET | \ |
433 | SCS_CMD_IDE1_RESET | SCS_CMD_IDE0_RESET) |
434 | |
435 | /* |
436 | * Reset everything and then unblock all of the interrupts. |
437 | */ |
438 | scs_cmd = pci_conf_read(pa->pa_pc, pa->pa_tag, SII3112_SCS_CMD); |
439 | pci_conf_write(pa->pa_pc, pa->pa_tag, SII3112_SCS_CMD, |
440 | scs_cmd | SII3112_RESET_BITS); |
441 | delay(50 * 1000); |
442 | pci_conf_write(pa->pa_pc, pa->pa_tag, SII3112_SCS_CMD, |
443 | scs_cmd & SCS_CMD_BA5_EN); |
444 | delay(50 * 1000); |
445 | |
446 | if (scs_cmd & SCS_CMD_BA5_EN) { |
447 | aprint_verbose_dev(sc->sc_wdcdev.sc_atac.atac_dev, |
448 | "SATALink BA5 register space enabled\n" ); |
449 | if (pci_mapreg_map(pa, PCI_MAPREG_START + 0x14, |
450 | PCI_MAPREG_TYPE_MEM| |
451 | PCI_MAPREG_MEM_TYPE_32BIT, 0, |
452 | &sc->sc_ba5_st, &sc->sc_ba5_sh, |
453 | NULL, &sc->sc_ba5_ss) != 0) |
454 | aprint_error_dev(sc->sc_wdcdev.sc_atac.atac_dev, |
455 | "unable to map SATALink BA5 register space\n" ); |
456 | else |
457 | sc->sc_ba5_en = 1; |
458 | } else { |
459 | aprint_verbose_dev(sc->sc_wdcdev.sc_atac.atac_dev, |
460 | "SATALink BA5 register space disabled\n" ); |
461 | |
462 | cfgctl = pci_conf_read(pa->pa_pc, pa->pa_tag, |
463 | SII3112_PCI_CFGCTL); |
464 | pci_conf_write(pa->pa_pc, pa->pa_tag, SII3112_PCI_CFGCTL, |
465 | cfgctl | CFGCTL_BA5INDEN); |
466 | } |
467 | |
468 | aprint_verbose_dev(sc->sc_wdcdev.sc_atac.atac_dev, |
469 | "bus-master DMA support present" ); |
470 | pciide_mapreg_dma(sc, pa); |
471 | aprint_verbose("\n" ); |
472 | |
473 | /* |
474 | * Rev. <= 0x01 of the 3112 have a bug that can cause data |
475 | * corruption if DMA transfers cross an 8K boundary. This is |
476 | * apparently hard to tickle, but we'll go ahead and play it |
477 | * safe. |
478 | */ |
479 | if ((PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_CMDTECH_3112 || |
480 | PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_CMDTECH_AAR_1210SA) && |
481 | PCI_REVISION(pa->pa_class) <= 0x01) { |
482 | sc->sc_dma_maxsegsz = 8192; |
483 | sc->sc_dma_boundary = 8192; |
484 | } |
485 | |
486 | sii_fixup_cacheline(sc, pa, 2); |
487 | |
488 | sc->sc_wdcdev.sc_atac.atac_cap |= ATAC_CAP_DATA16 | ATAC_CAP_DATA32; |
489 | sc->sc_wdcdev.sc_atac.atac_pio_cap = 4; |
490 | if (sc->sc_dma_ok) { |
491 | sc->sc_wdcdev.sc_atac.atac_cap |= ATAC_CAP_DMA | ATAC_CAP_UDMA; |
492 | sc->sc_wdcdev.irqack = pciide_irqack; |
493 | sc->sc_wdcdev.sc_atac.atac_dma_cap = 2; |
494 | sc->sc_wdcdev.sc_atac.atac_udma_cap = 6; |
495 | } |
496 | sc->sc_wdcdev.sc_atac.atac_set_modes = sii3112_setup_channel; |
497 | |
498 | /* We can use SControl and SStatus to probe for drives. */ |
499 | sc->sc_wdcdev.sc_atac.atac_probe = sii3112_drv_probe; |
500 | |
501 | sc->sc_wdcdev.sc_atac.atac_channels = sc->wdc_chanarray; |
502 | sc->sc_wdcdev.sc_atac.atac_nchannels = PCIIDE_NUM_CHANNELS; |
503 | sc->sc_wdcdev.wdc_maxdrives = 1; |
504 | |
505 | wdc_allocate_regs(&sc->sc_wdcdev); |
506 | |
507 | /* |
508 | * The 3112 either identifies itself as a RAID storage device |
509 | * or a Misc storage device. Fake up the interface bits for |
510 | * what our driver expects. |
511 | */ |
512 | if (PCI_SUBCLASS(pa->pa_class) == PCI_SUBCLASS_MASS_STORAGE_IDE) { |
513 | interface = PCI_INTERFACE(pa->pa_class); |
514 | } else { |
515 | interface = PCIIDE_INTERFACE_BUS_MASTER_DMA | |
516 | PCIIDE_INTERFACE_PCI(0) | PCIIDE_INTERFACE_PCI(1); |
517 | } |
518 | |
519 | for (channel = 0; channel < sc->sc_wdcdev.sc_atac.atac_nchannels; |
520 | channel++) { |
521 | cp = &sc->pciide_channels[channel]; |
522 | if (pciide_chansetup(sc, channel, interface) == 0) |
523 | continue; |
524 | pciide_mapchan(pa, cp, interface, pciide_pci_intr); |
525 | } |
526 | } |
527 | |
528 | static void |
529 | sii3114_mapreg_dma(struct pciide_softc *sc, const struct pci_attach_args *pa) |
530 | { |
531 | struct pciide_channel *pc; |
532 | int chan, reg; |
533 | bus_size_t size; |
534 | |
535 | sc->sc_wdcdev.dma_arg = sc; |
536 | sc->sc_wdcdev.dma_init = pciide_dma_init; |
537 | sc->sc_wdcdev.dma_start = pciide_dma_start; |
538 | sc->sc_wdcdev.dma_finish = pciide_dma_finish; |
539 | |
540 | if (device_cfdata(sc->sc_wdcdev.sc_atac.atac_dev)->cf_flags & |
541 | PCIIDE_OPTIONS_NODMA) { |
542 | aprint_verbose( |
543 | ", but unused (forced off by config file)" ); |
544 | sc->sc_dma_ok = 0; |
545 | return; |
546 | } |
547 | |
548 | /* |
549 | * Slice off a subregion of BA5 for each of the channel's DMA |
550 | * registers. |
551 | */ |
552 | |
553 | sc->sc_dma_iot = sc->sc_ba5_st; |
554 | for (chan = 0; chan < 4; chan++) { |
555 | pc = &sc->pciide_channels[chan]; |
556 | for (reg = 0; reg < IDEDMA_NREGS; reg++) { |
557 | size = 4; |
558 | if (size > (IDEDMA_SCH_OFFSET - reg)) |
559 | size = IDEDMA_SCH_OFFSET - reg; |
560 | if (bus_space_subregion(sc->sc_ba5_st, |
561 | sc->sc_ba5_sh, |
562 | satalink_ba5_regmap[chan].ba5_IDEDMA_CMD + reg, |
563 | size, &pc->dma_iohs[reg]) != 0) { |
564 | sc->sc_dma_ok = 0; |
565 | aprint_verbose(", but can't subregion offset " |
566 | "%lu size %lu" , |
567 | (u_long) satalink_ba5_regmap[ |
568 | chan].ba5_IDEDMA_CMD + reg, |
569 | (u_long) size); |
570 | return; |
571 | } |
572 | } |
573 | } |
574 | |
575 | /* DMA registers all set up! */ |
576 | sc->sc_dmat = pa->pa_dmat; |
577 | sc->sc_dma_ok = 1; |
578 | } |
579 | |
580 | static int |
581 | sii3114_chansetup(struct pciide_softc *sc, int channel) |
582 | { |
583 | static const char *channel_names[] = { |
584 | "port 0" , |
585 | "port 1" , |
586 | "port 2" , |
587 | "port 3" , |
588 | }; |
589 | struct pciide_channel *cp = &sc->pciide_channels[channel]; |
590 | |
591 | sc->wdc_chanarray[channel] = &cp->ata_channel; |
592 | |
593 | /* |
594 | * We must always keep the Interrupt Steering bit set in channel 2's |
595 | * IDEDMA_CMD register. |
596 | */ |
597 | if (channel == 2) |
598 | cp->idedma_cmd = IDEDMA_CMD_INT_STEER; |
599 | |
600 | cp->name = channel_names[channel]; |
601 | cp->ata_channel.ch_channel = channel; |
602 | cp->ata_channel.ch_atac = &sc->sc_wdcdev.sc_atac; |
603 | cp->ata_channel.ch_queue = |
604 | malloc(sizeof(struct ata_queue), M_DEVBUF, M_NOWAIT); |
605 | if (cp->ata_channel.ch_queue == NULL) { |
606 | aprint_error("%s %s channel: " |
607 | "can't allocate memory for command queue" , |
608 | device_xname(sc->sc_wdcdev.sc_atac.atac_dev), cp->name); |
609 | return (0); |
610 | } |
611 | return (1); |
612 | } |
613 | |
614 | static void |
615 | sii3114_mapchan(struct pciide_channel *cp) |
616 | { |
617 | struct ata_channel *wdc_cp = &cp->ata_channel; |
618 | struct pciide_softc *sc = CHAN_TO_PCIIDE(wdc_cp); |
619 | struct wdc_regs *wdr = CHAN_TO_WDC_REGS(wdc_cp); |
620 | int i; |
621 | |
622 | cp->compat = 0; |
623 | cp->ih = sc->sc_pci_ih; |
624 | |
625 | wdr->cmd_iot = sc->sc_ba5_st; |
626 | if (bus_space_subregion(sc->sc_ba5_st, sc->sc_ba5_sh, |
627 | satalink_ba5_regmap[wdc_cp->ch_channel].ba5_IDE_TF0, |
628 | 9, &wdr->cmd_baseioh) != 0) { |
629 | aprint_error_dev(sc->sc_wdcdev.sc_atac.atac_dev, |
630 | "couldn't subregion %s cmd base\n" , cp->name); |
631 | goto bad; |
632 | } |
633 | |
634 | wdr->ctl_iot = sc->sc_ba5_st; |
635 | if (bus_space_subregion(sc->sc_ba5_st, sc->sc_ba5_sh, |
636 | satalink_ba5_regmap[wdc_cp->ch_channel].ba5_IDE_TF8, |
637 | 1, &cp->ctl_baseioh) != 0) { |
638 | aprint_error_dev(sc->sc_wdcdev.sc_atac.atac_dev, |
639 | "couldn't subregion %s ctl base\n" , cp->name); |
640 | goto bad; |
641 | } |
642 | wdr->ctl_ioh = cp->ctl_baseioh; |
643 | |
644 | for (i = 0; i < WDC_NREG; i++) { |
645 | if (bus_space_subregion(wdr->cmd_iot, wdr->cmd_baseioh, |
646 | i, i == 0 ? 4 : 1, |
647 | &wdr->cmd_iohs[i]) != 0) { |
648 | aprint_error_dev(sc->sc_wdcdev.sc_atac.atac_dev, |
649 | "couldn't subregion %s channel cmd regs\n" , |
650 | cp->name); |
651 | goto bad; |
652 | } |
653 | } |
654 | wdc_init_shadow_regs(wdc_cp); |
655 | wdr->data32iot = wdr->cmd_iot; |
656 | wdr->data32ioh = wdr->cmd_iohs[0]; |
657 | wdcattach(wdc_cp); |
658 | return; |
659 | |
660 | bad: |
661 | cp->ata_channel.ch_flags |= ATACH_DISABLED; |
662 | } |
663 | |
664 | static void |
665 | sii3114_chip_map(struct pciide_softc *sc, const struct pci_attach_args *pa) |
666 | { |
667 | struct pciide_channel *cp; |
668 | pcireg_t scs_cmd; |
669 | pci_intr_handle_t intrhandle; |
670 | const char *intrstr; |
671 | int channel; |
672 | char intrbuf[PCI_INTRSTR_LEN]; |
673 | |
674 | if (pciide_chipen(sc, pa) == 0) |
675 | return; |
676 | |
677 | #define SII3114_RESET_BITS \ |
678 | (SCS_CMD_PBM_RESET | SCS_CMD_ARB_RESET | \ |
679 | SCS_CMD_FF1_RESET | SCS_CMD_FF0_RESET | \ |
680 | SCS_CMD_FF3_RESET | SCS_CMD_FF2_RESET | \ |
681 | SCS_CMD_IDE1_RESET | SCS_CMD_IDE0_RESET | \ |
682 | SCS_CMD_IDE3_RESET | SCS_CMD_IDE2_RESET) |
683 | |
684 | /* |
685 | * Reset everything and then unblock all of the interrupts. |
686 | */ |
687 | scs_cmd = pci_conf_read(pa->pa_pc, pa->pa_tag, SII3112_SCS_CMD); |
688 | pci_conf_write(pa->pa_pc, pa->pa_tag, SII3112_SCS_CMD, |
689 | scs_cmd | SII3114_RESET_BITS); |
690 | delay(50 * 1000); |
691 | pci_conf_write(pa->pa_pc, pa->pa_tag, SII3112_SCS_CMD, |
692 | scs_cmd & SCS_CMD_M66EN); |
693 | delay(50 * 1000); |
694 | |
695 | /* |
696 | * On the 3114, the BA5 register space is always enabled. In |
697 | * order to use the 3114 in any sane way, we must use this BA5 |
698 | * register space, and so we consider it an error if we cannot |
699 | * map it. |
700 | * |
701 | * As a consequence of using BA5, our register mapping is different |
702 | * from a normal PCI IDE controller's, and so we are unable to use |
703 | * most of the common PCI IDE register mapping functions. |
704 | */ |
705 | if (pci_mapreg_map(pa, PCI_MAPREG_START + 0x14, |
706 | PCI_MAPREG_TYPE_MEM| |
707 | PCI_MAPREG_MEM_TYPE_32BIT, 0, |
708 | &sc->sc_ba5_st, &sc->sc_ba5_sh, |
709 | NULL, &sc->sc_ba5_ss) != 0) { |
710 | aprint_error_dev(sc->sc_wdcdev.sc_atac.atac_dev, |
711 | "unable to map SATALink BA5 register space\n" ); |
712 | return; |
713 | } |
714 | sc->sc_ba5_en = 1; |
715 | |
716 | aprint_verbose_dev(sc->sc_wdcdev.sc_atac.atac_dev, |
717 | "%dMHz PCI bus\n" , (scs_cmd & SCS_CMD_M66EN) ? 66 : 33); |
718 | |
719 | /* |
720 | * Set the Interrupt Steering bit in the IDEDMA_CMD register of |
721 | * channel 2. This is required at all times for proper operation |
722 | * when using the BA5 register space (otherwise interrupts from |
723 | * all 4 channels won't work). |
724 | */ |
725 | BA5_WRITE_4(sc, 2, ba5_IDEDMA_CMD, IDEDMA_CMD_INT_STEER); |
726 | |
727 | aprint_verbose_dev(sc->sc_wdcdev.sc_atac.atac_dev, |
728 | "bus-master DMA support present" ); |
729 | sii3114_mapreg_dma(sc, pa); |
730 | aprint_verbose("\n" ); |
731 | |
732 | sii_fixup_cacheline(sc, pa, 4); |
733 | |
734 | sc->sc_wdcdev.sc_atac.atac_cap |= ATAC_CAP_DATA16 | ATAC_CAP_DATA32; |
735 | sc->sc_wdcdev.sc_atac.atac_pio_cap = 4; |
736 | if (sc->sc_dma_ok) { |
737 | sc->sc_wdcdev.sc_atac.atac_cap |= ATAC_CAP_DMA | ATAC_CAP_UDMA; |
738 | sc->sc_wdcdev.irqack = pciide_irqack; |
739 | sc->sc_wdcdev.sc_atac.atac_dma_cap = 2; |
740 | sc->sc_wdcdev.sc_atac.atac_udma_cap = 6; |
741 | } |
742 | sc->sc_wdcdev.sc_atac.atac_set_modes = sii3112_setup_channel; |
743 | |
744 | /* We can use SControl and SStatus to probe for drives. */ |
745 | sc->sc_wdcdev.sc_atac.atac_probe = sii3112_drv_probe; |
746 | |
747 | sc->sc_wdcdev.sc_atac.atac_channels = sc->wdc_chanarray; |
748 | sc->sc_wdcdev.sc_atac.atac_nchannels = 4; |
749 | sc->sc_wdcdev.wdc_maxdrives = 1; |
750 | |
751 | wdc_allocate_regs(&sc->sc_wdcdev); |
752 | |
753 | /* Map and establish the interrupt handler. */ |
754 | if (pci_intr_map(pa, &intrhandle) != 0) { |
755 | aprint_error_dev(sc->sc_wdcdev.sc_atac.atac_dev, |
756 | "couldn't map native-PCI interrupt\n" ); |
757 | return; |
758 | } |
759 | intrstr = pci_intr_string(pa->pa_pc, intrhandle, intrbuf, sizeof(intrbuf)); |
760 | sc->sc_pci_ih = pci_intr_establish(pa->pa_pc, intrhandle, IPL_BIO, |
761 | /* XXX */ |
762 | pciide_pci_intr, sc); |
763 | if (sc->sc_pci_ih != NULL) { |
764 | aprint_normal_dev(sc->sc_wdcdev.sc_atac.atac_dev, |
765 | "using %s for native-PCI interrupt\n" , |
766 | intrstr ? intrstr : "unknown interrupt" ); |
767 | } else { |
768 | aprint_error_dev(sc->sc_wdcdev.sc_atac.atac_dev, |
769 | "couldn't establish native-PCI interrupt" ); |
770 | if (intrstr != NULL) |
771 | aprint_error(" at %s" , intrstr); |
772 | aprint_error("\n" ); |
773 | return; |
774 | } |
775 | |
776 | for (channel = 0; channel < sc->sc_wdcdev.sc_atac.atac_nchannels; |
777 | channel++) { |
778 | cp = &sc->pciide_channels[channel]; |
779 | if (sii3114_chansetup(sc, channel) == 0) |
780 | continue; |
781 | sii3114_mapchan(cp); |
782 | } |
783 | } |
784 | |
785 | /* Probe the drives using SATA registers. |
786 | * Note we can't use wdc_sataprobe as we may not be able to map ba5 |
787 | */ |
788 | static void |
789 | sii3112_drv_probe(struct ata_channel *chp) |
790 | { |
791 | struct pciide_softc *sc = CHAN_TO_PCIIDE(chp); |
792 | struct wdc_regs *wdr = CHAN_TO_WDC_REGS(chp); |
793 | uint32_t scontrol, sstatus; |
794 | uint8_t /* scnt, sn, */ cl, ch; |
795 | int s; |
796 | |
797 | /* |
798 | * The 3112 is a 2-port part, and only has one drive per channel |
799 | * (each port emulates a master drive). |
800 | * |
801 | * The 3114 is similar, but has 4 channels. |
802 | */ |
803 | |
804 | /* |
805 | * Request communication initialization sequence, any speed. |
806 | * Performing this is the equivalent of an ATA Reset. |
807 | */ |
808 | scontrol = SControl_DET_INIT | SControl_SPD_ANY; |
809 | |
810 | /* |
811 | * XXX We don't yet support SATA power management; disable all |
812 | * power management state transitions. |
813 | */ |
814 | scontrol |= SControl_IPM_NONE; |
815 | |
816 | BA5_WRITE_4(sc, chp->ch_channel, ba5_SControl, scontrol); |
817 | delay(50 * 1000); |
818 | scontrol &= ~SControl_DET_INIT; |
819 | BA5_WRITE_4(sc, chp->ch_channel, ba5_SControl, scontrol); |
820 | delay(50 * 1000); |
821 | |
822 | sstatus = BA5_READ_4(sc, chp->ch_channel, ba5_SStatus); |
823 | #if 0 |
824 | aprint_normal_dev(sc->sc_wdcdev.sc_atac.atac_dev, |
825 | "port %d: SStatus=0x%08x, SControl=0x%08x\n" , |
826 | chp->ch_channel, sstatus, |
827 | BA5_READ_4(sc, chp->ch_channel, ba5_SControl)); |
828 | #endif |
829 | switch (sstatus & SStatus_DET_mask) { |
830 | case SStatus_DET_NODEV: |
831 | /* No device; be silent. */ |
832 | break; |
833 | |
834 | case SStatus_DET_DEV_NE: |
835 | aprint_error_dev(sc->sc_wdcdev.sc_atac.atac_dev, |
836 | "port %d: device connected, but " |
837 | "communication not established\n" , chp->ch_channel); |
838 | break; |
839 | |
840 | case SStatus_DET_OFFLINE: |
841 | aprint_error_dev(sc->sc_wdcdev.sc_atac.atac_dev, |
842 | "port %d: PHY offline\n" , chp->ch_channel); |
843 | break; |
844 | |
845 | case SStatus_DET_DEV: |
846 | /* |
847 | * XXX ATAPI detection doesn't currently work. Don't |
848 | * XXX know why. But, it's not like the standard method |
849 | * XXX can detect an ATAPI device connected via a SATA/PATA |
850 | * XXX bridge, so at least this is no worse. --thorpej |
851 | */ |
852 | bus_space_write_1(wdr->cmd_iot, wdr->cmd_iohs[wd_sdh], 0, |
853 | WDSD_IBM | (0 << 4)); |
854 | delay(10); /* 400ns delay */ |
855 | /* Save register contents. */ |
856 | #if 0 |
857 | scnt = bus_space_read_1(wdr->cmd_iot, |
858 | wdr->cmd_iohs[wd_seccnt], 0); |
859 | sn = bus_space_read_1(wdr->cmd_iot, |
860 | wdr->cmd_iohs[wd_sector], 0); |
861 | #endif |
862 | cl = bus_space_read_1(wdr->cmd_iot, |
863 | wdr->cmd_iohs[wd_cyl_lo], 0); |
864 | ch = bus_space_read_1(wdr->cmd_iot, |
865 | wdr->cmd_iohs[wd_cyl_hi], 0); |
866 | #if 0 |
867 | printf("%s: port %d: scnt=0x%x sn=0x%x cl=0x%x ch=0x%x\n" , |
868 | device_xname(sc->sc_wdcdev.sc_atac.atac_dev), chp->ch_channel, |
869 | scnt, sn, cl, ch); |
870 | #endif |
871 | if (atabus_alloc_drives(chp, 1) != 0) |
872 | return; |
873 | /* |
874 | * scnt and sn are supposed to be 0x1 for ATAPI, but in some |
875 | * cases we get wrong values here, so ignore it. |
876 | */ |
877 | s = splbio(); |
878 | if (cl == 0x14 && ch == 0xeb) |
879 | chp->ch_drive[0].drive_type = ATA_DRIVET_ATAPI; |
880 | else |
881 | chp->ch_drive[0].drive_type = ATA_DRIVET_ATA; |
882 | splx(s); |
883 | |
884 | aprint_normal_dev(sc->sc_wdcdev.sc_atac.atac_dev, |
885 | "port %d: device present, speed: %s\n" , |
886 | chp->ch_channel, |
887 | sata_speed(sstatus)); |
888 | break; |
889 | |
890 | default: |
891 | aprint_error_dev(sc->sc_wdcdev.sc_atac.atac_dev, |
892 | "port %d: unknown SStatus: 0x%08x\n" , |
893 | chp->ch_channel, sstatus); |
894 | } |
895 | } |
896 | |
897 | static void |
898 | sii3112_setup_channel(struct ata_channel *chp) |
899 | { |
900 | struct ata_drive_datas *drvp; |
901 | int drive, s; |
902 | u_int32_t idedma_ctl, dtm; |
903 | struct pciide_channel *cp = CHAN_TO_PCHAN(chp); |
904 | struct pciide_softc *sc = CHAN_TO_PCIIDE(chp); |
905 | |
906 | /* setup DMA if needed */ |
907 | pciide_channel_dma_setup(cp); |
908 | |
909 | idedma_ctl = 0; |
910 | dtm = 0; |
911 | |
912 | for (drive = 0; drive < 2; drive++) { |
913 | drvp = &chp->ch_drive[drive]; |
914 | /* If no drive, skip */ |
915 | if (drvp->drive_type == ATA_DRIVET_NONE) |
916 | continue; |
917 | if (drvp->drive_flags & ATA_DRIVE_UDMA) { |
918 | /* use Ultra/DMA */ |
919 | s = splbio(); |
920 | drvp->drive_flags &= ~ATA_DRIVE_DMA; |
921 | splx(s); |
922 | idedma_ctl |= IDEDMA_CTL_DRV_DMA(drive); |
923 | dtm |= DTM_IDEx_DMA; |
924 | } else if (drvp->drive_flags & ATA_DRIVE_DMA) { |
925 | idedma_ctl |= IDEDMA_CTL_DRV_DMA(drive); |
926 | dtm |= DTM_IDEx_DMA; |
927 | } else { |
928 | dtm |= DTM_IDEx_PIO; |
929 | } |
930 | } |
931 | |
932 | /* |
933 | * Nothing to do to setup modes; it is meaningless in S-ATA |
934 | * (but many S-ATA drives still want to get the SET_FEATURE |
935 | * command). |
936 | */ |
937 | if (idedma_ctl != 0) { |
938 | /* Add software bits in status register */ |
939 | bus_space_write_1(sc->sc_dma_iot, cp->dma_iohs[IDEDMA_CTL], 0, |
940 | idedma_ctl); |
941 | } |
942 | BA5_WRITE_4(sc, chp->ch_channel, ba5_IDE_DTM, dtm); |
943 | } |
944 | |