File: | dev/pci/pciide.c |
Warning: | line 8042, column 15 The result of the left shift is undefined because the right operand is negative |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* $OpenBSD: pciide.c,v 1.363 2022/03/11 18:00:51 mpi Exp $ */ | |||
2 | /* $NetBSD: pciide.c,v 1.127 2001/08/03 01:31:08 tsutsui Exp $ */ | |||
3 | ||||
4 | /* | |||
5 | * Copyright (c) 1999, 2000, 2001 Manuel Bouyer. | |||
6 | * | |||
7 | * Redistribution and use in source and binary forms, with or without | |||
8 | * modification, are permitted provided that the following conditions | |||
9 | * are met: | |||
10 | * 1. Redistributions of source code must retain the above copyright | |||
11 | * notice, this list of conditions and the following disclaimer. | |||
12 | * 2. Redistributions in binary form must reproduce the above copyright | |||
13 | * notice, this list of conditions and the following disclaimer in the | |||
14 | * documentation and/or other materials provided with the distribution. | |||
15 | * | |||
16 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR | |||
17 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | |||
18 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | |||
19 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | |||
20 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | |||
21 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |||
22 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |||
23 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | |||
25 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
26 | * | |||
27 | */ | |||
28 | ||||
29 | /* | |||
30 | * Copyright (c) 1996, 1998 Christopher G. Demetriou. All rights reserved. | |||
31 | * | |||
32 | * Redistribution and use in source and binary forms, with or without | |||
33 | * modification, are permitted provided that the following conditions | |||
34 | * are met: | |||
35 | * 1. Redistributions of source code must retain the above copyright | |||
36 | * notice, this list of conditions and the following disclaimer. | |||
37 | * 2. Redistributions in binary form must reproduce the above copyright | |||
38 | * notice, this list of conditions and the following disclaimer in the | |||
39 | * documentation and/or other materials provided with the distribution. | |||
40 | * 3. All advertising materials mentioning features or use of this software | |||
41 | * must display the following acknowledgement: | |||
42 | * This product includes software developed by Christopher G. Demetriou | |||
43 | * for the NetBSD Project. | |||
44 | * 4. The name of the author may not be used to endorse or promote products | |||
45 | * derived from this software without specific prior written permission | |||
46 | * | |||
47 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR | |||
48 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | |||
49 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | |||
50 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | |||
51 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | |||
52 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |||
53 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |||
54 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |||
55 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | |||
56 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
57 | */ | |||
58 | ||||
59 | /* | |||
60 | * PCI IDE controller driver. | |||
61 | * | |||
62 | * Author: Christopher G. Demetriou, March 2, 1998 (derived from NetBSD | |||
63 | * sys/dev/pci/ppb.c, revision 1.16). | |||
64 | * | |||
65 | * See "PCI IDE Controller Specification, Revision 1.0 3/4/94" and | |||
66 | * "Programming Interface for Bus Master IDE Controller, Revision 1.0 | |||
67 | * 5/16/94" from the PCI SIG. | |||
68 | * | |||
69 | */ | |||
70 | ||||
71 | #define DEBUG_DMA0x01 0x01 | |||
72 | #define DEBUG_XFERS0x02 0x02 | |||
73 | #define DEBUG_FUNCS0x08 0x08 | |||
74 | #define DEBUG_PROBE0x10 0x10 | |||
75 | ||||
76 | #ifdef WDCDEBUG | |||
77 | #ifndef WDCDEBUG_PCIIDE_MASK | |||
78 | #define WDCDEBUG_PCIIDE_MASK 0x00 | |||
79 | #endif | |||
80 | int wdcdebug_pciide_mask = WDCDEBUG_PCIIDE_MASK; | |||
81 | #define WDCDEBUG_PRINT(args, level) do { \ | |||
82 | if ((wdcdebug_pciide_mask & (level)) != 0) \ | |||
83 | printf args; \ | |||
84 | } while (0) | |||
85 | #else | |||
86 | #define WDCDEBUG_PRINT(args, level) | |||
87 | #endif | |||
88 | #include <sys/param.h> | |||
89 | #include <sys/systm.h> | |||
90 | #include <sys/device.h> | |||
91 | #include <sys/malloc.h> | |||
92 | #include <sys/endian.h> | |||
93 | ||||
94 | #include <machine/bus.h> | |||
95 | ||||
96 | #include <dev/ata/atavar.h> | |||
97 | #include <dev/ata/satareg.h> | |||
98 | #include <dev/ic/wdcreg.h> | |||
99 | #include <dev/ic/wdcvar.h> | |||
100 | ||||
101 | #include <dev/pci/pcireg.h> | |||
102 | #include <dev/pci/pcivar.h> | |||
103 | #include <dev/pci/pcidevs.h> | |||
104 | ||||
105 | #include <dev/pci/pciidereg.h> | |||
106 | #include <dev/pci/pciidevar.h> | |||
107 | #include <dev/pci/pciide_piix_reg.h> | |||
108 | #include <dev/pci/pciide_amd_reg.h> | |||
109 | #include <dev/pci/pciide_apollo_reg.h> | |||
110 | #include <dev/pci/pciide_cmd_reg.h> | |||
111 | #include <dev/pci/pciide_sii3112_reg.h> | |||
112 | #include <dev/pci/pciide_cy693_reg.h> | |||
113 | #include <dev/pci/pciide_sis_reg.h> | |||
114 | #include <dev/pci/pciide_acer_reg.h> | |||
115 | #include <dev/pci/pciide_pdc202xx_reg.h> | |||
116 | #include <dev/pci/pciide_opti_reg.h> | |||
117 | #include <dev/pci/pciide_hpt_reg.h> | |||
118 | #include <dev/pci/pciide_acard_reg.h> | |||
119 | #include <dev/pci/pciide_natsemi_reg.h> | |||
120 | #include <dev/pci/pciide_nforce_reg.h> | |||
121 | #include <dev/pci/pciide_ite_reg.h> | |||
122 | #include <dev/pci/pciide_ixp_reg.h> | |||
123 | #include <dev/pci/pciide_svwsata_reg.h> | |||
124 | #include <dev/pci/pciide_jmicron_reg.h> | |||
125 | #include <dev/pci/pciide_rdc_reg.h> | |||
126 | #include <dev/pci/cy82c693var.h> | |||
127 | ||||
128 | int pciide_skip_ata; | |||
129 | int pciide_skip_atapi; | |||
130 | ||||
131 | /* functions for reading/writing 8-bit PCI registers */ | |||
132 | ||||
133 | u_int8_t pciide_pci_read(pci_chipset_tag_t, pcitag_t, | |||
134 | int); | |||
135 | void pciide_pci_write(pci_chipset_tag_t, pcitag_t, | |||
136 | int, u_int8_t); | |||
137 | ||||
138 | u_int8_t | |||
139 | pciide_pci_read(pci_chipset_tag_t pc, pcitag_t pa, int reg) | |||
140 | { | |||
141 | return (pci_conf_read(pc, pa, (reg & ~0x03)) >> | |||
142 | ((reg & 0x03) * 8) & 0xff); | |||
143 | } | |||
144 | ||||
145 | void | |||
146 | pciide_pci_write(pci_chipset_tag_t pc, pcitag_t pa, int reg, u_int8_t val) | |||
147 | { | |||
148 | pcireg_t pcival; | |||
149 | ||||
150 | pcival = pci_conf_read(pc, pa, (reg & ~0x03)); | |||
151 | pcival &= ~(0xff << ((reg & 0x03) * 8)); | |||
152 | pcival |= (val << ((reg & 0x03) * 8)); | |||
153 | pci_conf_write(pc, pa, (reg & ~0x03), pcival); | |||
154 | } | |||
155 | ||||
156 | void default_chip_map(struct pciide_softc *, struct pci_attach_args *); | |||
157 | ||||
158 | void sata_chip_map(struct pciide_softc *, struct pci_attach_args *); | |||
159 | void sata_setup_channel(struct channel_softc *); | |||
160 | ||||
161 | void piix_chip_map(struct pciide_softc *, struct pci_attach_args *); | |||
162 | void piixsata_chip_map(struct pciide_softc *, struct pci_attach_args *); | |||
163 | void piix_setup_channel(struct channel_softc *); | |||
164 | void piix3_4_setup_channel(struct channel_softc *); | |||
165 | void piix_timing_debug(struct pciide_softc *); | |||
166 | ||||
167 | u_int32_t piix_setup_idetim_timings(u_int8_t, u_int8_t, u_int8_t); | |||
168 | u_int32_t piix_setup_idetim_drvs(struct ata_drive_datas *); | |||
169 | u_int32_t piix_setup_sidetim_timings(u_int8_t, u_int8_t, u_int8_t); | |||
170 | ||||
171 | void amd756_chip_map(struct pciide_softc *, struct pci_attach_args *); | |||
172 | void amd756_setup_channel(struct channel_softc *); | |||
173 | ||||
174 | void apollo_chip_map(struct pciide_softc *, struct pci_attach_args *); | |||
175 | void apollo_setup_channel(struct channel_softc *); | |||
176 | ||||
177 | void cmd_chip_map(struct pciide_softc *, struct pci_attach_args *); | |||
178 | void cmd0643_9_chip_map(struct pciide_softc *, struct pci_attach_args *); | |||
179 | void cmd0643_9_setup_channel(struct channel_softc *); | |||
180 | void cmd680_chip_map(struct pciide_softc *, struct pci_attach_args *); | |||
181 | void cmd680_setup_channel(struct channel_softc *); | |||
182 | void cmd680_channel_map(struct pci_attach_args *, struct pciide_softc *, int); | |||
183 | void cmd_channel_map(struct pci_attach_args *, | |||
184 | struct pciide_softc *, int); | |||
185 | int cmd_pci_intr(void *); | |||
186 | void cmd646_9_irqack(struct channel_softc *); | |||
187 | ||||
188 | void sii_fixup_cacheline(struct pciide_softc *, struct pci_attach_args *); | |||
189 | void sii3112_chip_map(struct pciide_softc *, struct pci_attach_args *); | |||
190 | void sii3112_setup_channel(struct channel_softc *); | |||
191 | void sii3112_drv_probe(struct channel_softc *); | |||
192 | void sii3114_chip_map(struct pciide_softc *, struct pci_attach_args *); | |||
193 | void sii3114_mapreg_dma(struct pciide_softc *, struct pci_attach_args *); | |||
194 | int sii3114_chansetup(struct pciide_softc *, int); | |||
195 | void sii3114_mapchan(struct pciide_channel *); | |||
196 | u_int8_t sii3114_dmacmd_read(struct pciide_softc *, int); | |||
197 | void sii3114_dmacmd_write(struct pciide_softc *, int, u_int8_t); | |||
198 | u_int8_t sii3114_dmactl_read(struct pciide_softc *, int); | |||
199 | void sii3114_dmactl_write(struct pciide_softc *, int, u_int8_t); | |||
200 | void sii3114_dmatbl_write(struct pciide_softc *, int, u_int32_t); | |||
201 | ||||
202 | void cy693_chip_map(struct pciide_softc *, struct pci_attach_args *); | |||
203 | void cy693_setup_channel(struct channel_softc *); | |||
204 | ||||
205 | void sis_chip_map(struct pciide_softc *, struct pci_attach_args *); | |||
206 | void sis_setup_channel(struct channel_softc *); | |||
207 | void sis96x_setup_channel(struct channel_softc *); | |||
208 | int sis_hostbr_match(struct pci_attach_args *); | |||
209 | int sis_south_match(struct pci_attach_args *); | |||
210 | ||||
211 | void natsemi_chip_map(struct pciide_softc *, struct pci_attach_args *); | |||
212 | void natsemi_setup_channel(struct channel_softc *); | |||
213 | int natsemi_pci_intr(void *); | |||
214 | void natsemi_irqack(struct channel_softc *); | |||
215 | void ns_scx200_chip_map(struct pciide_softc *, struct pci_attach_args *); | |||
216 | void ns_scx200_setup_channel(struct channel_softc *); | |||
217 | ||||
218 | void acer_chip_map(struct pciide_softc *, struct pci_attach_args *); | |||
219 | void acer_setup_channel(struct channel_softc *); | |||
220 | int acer_pci_intr(void *); | |||
221 | int acer_dma_init(void *, int, int, void *, size_t, int); | |||
222 | ||||
223 | void pdc202xx_chip_map(struct pciide_softc *, struct pci_attach_args *); | |||
224 | void pdc202xx_setup_channel(struct channel_softc *); | |||
225 | void pdc20268_setup_channel(struct channel_softc *); | |||
226 | int pdc202xx_pci_intr(void *); | |||
227 | int pdc20265_pci_intr(void *); | |||
228 | void pdc20262_dma_start(void *, int, int); | |||
229 | int pdc20262_dma_finish(void *, int, int, int); | |||
230 | ||||
231 | u_int8_t pdc268_config_read(struct channel_softc *, int); | |||
232 | ||||
233 | void pdcsata_chip_map(struct pciide_softc *, struct pci_attach_args *); | |||
234 | void pdc203xx_setup_channel(struct channel_softc *); | |||
235 | int pdc203xx_pci_intr(void *); | |||
236 | void pdc203xx_irqack(struct channel_softc *); | |||
237 | void pdc203xx_dma_start(void *,int ,int); | |||
238 | int pdc203xx_dma_finish(void *, int, int, int); | |||
239 | int pdc205xx_pci_intr(void *); | |||
240 | void pdc205xx_do_reset(struct channel_softc *); | |||
241 | void pdc205xx_drv_probe(struct channel_softc *); | |||
242 | ||||
243 | void opti_chip_map(struct pciide_softc *, struct pci_attach_args *); | |||
244 | void opti_setup_channel(struct channel_softc *); | |||
245 | ||||
246 | void hpt_chip_map(struct pciide_softc *, struct pci_attach_args *); | |||
247 | void hpt_setup_channel(struct channel_softc *); | |||
248 | int hpt_pci_intr(void *); | |||
249 | ||||
250 | void acard_chip_map(struct pciide_softc *, struct pci_attach_args *); | |||
251 | void acard_setup_channel(struct channel_softc *); | |||
252 | ||||
253 | void serverworks_chip_map(struct pciide_softc *, struct pci_attach_args *); | |||
254 | void serverworks_setup_channel(struct channel_softc *); | |||
255 | int serverworks_pci_intr(void *); | |||
256 | ||||
257 | void svwsata_chip_map(struct pciide_softc *, struct pci_attach_args *); | |||
258 | void svwsata_mapreg_dma(struct pciide_softc *, struct pci_attach_args *); | |||
259 | void svwsata_mapchan(struct pciide_channel *); | |||
260 | u_int8_t svwsata_dmacmd_read(struct pciide_softc *, int); | |||
261 | void svwsata_dmacmd_write(struct pciide_softc *, int, u_int8_t); | |||
262 | u_int8_t svwsata_dmactl_read(struct pciide_softc *, int); | |||
263 | void svwsata_dmactl_write(struct pciide_softc *, int, u_int8_t); | |||
264 | void svwsata_dmatbl_write(struct pciide_softc *, int, u_int32_t); | |||
265 | void svwsata_drv_probe(struct channel_softc *); | |||
266 | ||||
267 | void nforce_chip_map(struct pciide_softc *, struct pci_attach_args *); | |||
268 | void nforce_setup_channel(struct channel_softc *); | |||
269 | int nforce_pci_intr(void *); | |||
270 | ||||
271 | void artisea_chip_map(struct pciide_softc *, struct pci_attach_args *); | |||
272 | ||||
273 | void ite_chip_map(struct pciide_softc *, struct pci_attach_args *); | |||
274 | void ite_setup_channel(struct channel_softc *); | |||
275 | ||||
276 | void ixp_chip_map(struct pciide_softc *, struct pci_attach_args *); | |||
277 | void ixp_setup_channel(struct channel_softc *); | |||
278 | ||||
279 | void jmicron_chip_map(struct pciide_softc *, struct pci_attach_args *); | |||
280 | void jmicron_setup_channel(struct channel_softc *); | |||
281 | ||||
282 | void phison_chip_map(struct pciide_softc *, struct pci_attach_args *); | |||
283 | void phison_setup_channel(struct channel_softc *); | |||
284 | ||||
285 | void sch_chip_map(struct pciide_softc *, struct pci_attach_args *); | |||
286 | void sch_setup_channel(struct channel_softc *); | |||
287 | ||||
288 | void rdc_chip_map(struct pciide_softc *, struct pci_attach_args *); | |||
289 | void rdc_setup_channel(struct channel_softc *); | |||
290 | ||||
291 | struct pciide_product_desc { | |||
292 | u_int32_t ide_product; | |||
293 | u_short ide_flags; | |||
294 | /* map and setup chip, probe drives */ | |||
295 | void (*chip_map)(struct pciide_softc *, struct pci_attach_args *); | |||
296 | }; | |||
297 | ||||
298 | /* Flags for ide_flags */ | |||
299 | #define IDE_PCI_CLASS_OVERRIDE0x0001 0x0001 /* accept even if class != pciide */ | |||
300 | #define IDE_16BIT_IOSPACE0x0002 0x0002 /* I/O space BARS ignore upper word */ | |||
301 | ||||
302 | /* Default product description for devices not known from this controller */ | |||
303 | const struct pciide_product_desc default_product_desc = { | |||
304 | 0, /* Generic PCI IDE controller */ | |||
305 | 0, | |||
306 | default_chip_map | |||
307 | }; | |||
308 | ||||
309 | const struct pciide_product_desc pciide_intel_products[] = { | |||
310 | { PCI_PRODUCT_INTEL_312440x3200, /* Intel 31244 SATA */ | |||
311 | 0, | |||
312 | artisea_chip_map | |||
313 | }, | |||
314 | { PCI_PRODUCT_INTEL_82092AA0x1222, /* Intel 82092AA IDE */ | |||
315 | 0, | |||
316 | default_chip_map | |||
317 | }, | |||
318 | { PCI_PRODUCT_INTEL_82371FB_IDE0x1230, /* Intel 82371FB IDE (PIIX) */ | |||
319 | 0, | |||
320 | piix_chip_map | |||
321 | }, | |||
322 | { PCI_PRODUCT_INTEL_82371FB_ISA0x122e, /* Intel 82371FB IDE (PIIX) */ | |||
323 | 0, | |||
324 | piix_chip_map | |||
325 | }, | |||
326 | { PCI_PRODUCT_INTEL_82372FB_IDE0x7601, /* Intel 82372FB IDE (PIIX4) */ | |||
327 | 0, | |||
328 | piix_chip_map | |||
329 | }, | |||
330 | { PCI_PRODUCT_INTEL_82371SB_IDE0x7010, /* Intel 82371SB IDE (PIIX3) */ | |||
331 | 0, | |||
332 | piix_chip_map | |||
333 | }, | |||
334 | { PCI_PRODUCT_INTEL_82371AB_IDE0x7111, /* Intel 82371AB IDE (PIIX4) */ | |||
335 | 0, | |||
336 | piix_chip_map | |||
337 | }, | |||
338 | { PCI_PRODUCT_INTEL_82371MX0x1234, /* Intel 82371MX IDE */ | |||
339 | 0, | |||
340 | piix_chip_map | |||
341 | }, | |||
342 | { PCI_PRODUCT_INTEL_82440MX_IDE0x7199, /* Intel 82440MX IDE */ | |||
343 | 0, | |||
344 | piix_chip_map | |||
345 | }, | |||
346 | { PCI_PRODUCT_INTEL_82451NX0x84ca, /* Intel 82451NX (PIIX4) IDE */ | |||
347 | 0, | |||
348 | piix_chip_map | |||
349 | }, | |||
350 | { PCI_PRODUCT_INTEL_82801AA_IDE0x2411, /* Intel 82801AA IDE (ICH) */ | |||
351 | 0, | |||
352 | piix_chip_map | |||
353 | }, | |||
354 | { PCI_PRODUCT_INTEL_82801AB_IDE0x2421, /* Intel 82801AB IDE (ICH0) */ | |||
355 | 0, | |||
356 | piix_chip_map | |||
357 | }, | |||
358 | { PCI_PRODUCT_INTEL_82801BAM_IDE0x244a, /* Intel 82801BAM IDE (ICH2) */ | |||
359 | 0, | |||
360 | piix_chip_map | |||
361 | }, | |||
362 | { PCI_PRODUCT_INTEL_82801BA_IDE0x244b, /* Intel 82801BA IDE (ICH2) */ | |||
363 | 0, | |||
364 | piix_chip_map | |||
365 | }, | |||
366 | { PCI_PRODUCT_INTEL_82801CAM_IDE0x248a, /* Intel 82801CAM IDE (ICH3) */ | |||
367 | 0, | |||
368 | piix_chip_map | |||
369 | }, | |||
370 | { PCI_PRODUCT_INTEL_82801CA_IDE0x248b, /* Intel 82801CA IDE (ICH3) */ | |||
371 | 0, | |||
372 | piix_chip_map | |||
373 | }, | |||
374 | { PCI_PRODUCT_INTEL_82801DB_IDE0x24cb, /* Intel 82801DB IDE (ICH4) */ | |||
375 | 0, | |||
376 | piix_chip_map | |||
377 | }, | |||
378 | { PCI_PRODUCT_INTEL_82801DBL_IDE0x24c1, /* Intel 82801DBL IDE (ICH4-L) */ | |||
379 | 0, | |||
380 | piix_chip_map | |||
381 | }, | |||
382 | { PCI_PRODUCT_INTEL_82801DBM_IDE0x24ca, /* Intel 82801DBM IDE (ICH4-M) */ | |||
383 | 0, | |||
384 | piix_chip_map | |||
385 | }, | |||
386 | { PCI_PRODUCT_INTEL_82801EB_IDE0x24db, /* Intel 82801EB/ER (ICH5/5R) IDE */ | |||
387 | 0, | |||
388 | piix_chip_map | |||
389 | }, | |||
390 | { PCI_PRODUCT_INTEL_82801EB_SATA0x24d1, /* Intel 82801EB (ICH5) SATA */ | |||
391 | 0, | |||
392 | piixsata_chip_map | |||
393 | }, | |||
394 | { PCI_PRODUCT_INTEL_82801ER_SATA0x24df, /* Intel 82801ER (ICH5R) SATA */ | |||
395 | 0, | |||
396 | piixsata_chip_map | |||
397 | }, | |||
398 | { PCI_PRODUCT_INTEL_6300ESB_IDE0x25a2, /* Intel 6300ESB IDE */ | |||
399 | 0, | |||
400 | piix_chip_map | |||
401 | }, | |||
402 | { PCI_PRODUCT_INTEL_6300ESB_SATA0x25a3, /* Intel 6300ESB SATA */ | |||
403 | 0, | |||
404 | piixsata_chip_map | |||
405 | }, | |||
406 | { PCI_PRODUCT_INTEL_6300ESB_SATA20x25b0, /* Intel 6300ESB SATA */ | |||
407 | 0, | |||
408 | piixsata_chip_map | |||
409 | }, | |||
410 | { PCI_PRODUCT_INTEL_6321ESB_IDE0x269e, /* Intel 6321ESB IDE */ | |||
411 | 0, | |||
412 | piix_chip_map | |||
413 | }, | |||
414 | { PCI_PRODUCT_INTEL_82801FB_IDE0x266f, /* Intel 82801FB (ICH6) IDE */ | |||
415 | 0, | |||
416 | piix_chip_map | |||
417 | }, | |||
418 | { PCI_PRODUCT_INTEL_82801FBM_SATA0x2653, /* Intel 82801FBM (ICH6M) SATA */ | |||
419 | 0, | |||
420 | piixsata_chip_map | |||
421 | }, | |||
422 | { PCI_PRODUCT_INTEL_82801FB_SATA0x2651, /* Intel 82801FB (ICH6) SATA */ | |||
423 | 0, | |||
424 | piixsata_chip_map | |||
425 | }, | |||
426 | { PCI_PRODUCT_INTEL_82801FR_SATA0x2652, /* Intel 82801FR (ICH6R) SATA */ | |||
427 | 0, | |||
428 | piixsata_chip_map | |||
429 | }, | |||
430 | { PCI_PRODUCT_INTEL_82801GB_IDE0x27df, /* Intel 82801GB (ICH7) IDE */ | |||
431 | 0, | |||
432 | piix_chip_map | |||
433 | }, | |||
434 | { PCI_PRODUCT_INTEL_82801GB_SATA0x27c0, /* Intel 82801GB (ICH7) SATA */ | |||
435 | 0, | |||
436 | piixsata_chip_map | |||
437 | }, | |||
438 | { PCI_PRODUCT_INTEL_82801GR_AHCI0x27c1, /* Intel 82801GR (ICH7R) AHCI */ | |||
439 | 0, | |||
440 | piixsata_chip_map | |||
441 | }, | |||
442 | { PCI_PRODUCT_INTEL_82801GR_RAID0x27c3, /* Intel 82801GR (ICH7R) RAID */ | |||
443 | 0, | |||
444 | piixsata_chip_map | |||
445 | }, | |||
446 | { PCI_PRODUCT_INTEL_82801GBM_SATA0x27c4, /* Intel 82801GBM (ICH7M) SATA */ | |||
447 | 0, | |||
448 | piixsata_chip_map | |||
449 | }, | |||
450 | { PCI_PRODUCT_INTEL_82801GBM_AHCI0x27c5, /* Intel 82801GBM (ICH7M) AHCI */ | |||
451 | 0, | |||
452 | piixsata_chip_map | |||
453 | }, | |||
454 | { PCI_PRODUCT_INTEL_82801GHM_RAID0x27c6, /* Intel 82801GHM (ICH7M DH) RAID */ | |||
455 | 0, | |||
456 | piixsata_chip_map | |||
457 | }, | |||
458 | { PCI_PRODUCT_INTEL_82801H_SATA_10x2820, /* Intel 82801H (ICH8) SATA */ | |||
459 | 0, | |||
460 | piixsata_chip_map | |||
461 | }, | |||
462 | { PCI_PRODUCT_INTEL_82801H_AHCI_6P0x2821, /* Intel 82801H (ICH8) AHCI */ | |||
463 | 0, | |||
464 | piixsata_chip_map | |||
465 | }, | |||
466 | { PCI_PRODUCT_INTEL_82801H_RAID0x2822, /* Intel 82801H (ICH8) RAID */ | |||
467 | 0, | |||
468 | piixsata_chip_map | |||
469 | }, | |||
470 | { PCI_PRODUCT_INTEL_82801H_AHCI_4P0x2824, /* Intel 82801H (ICH8) AHCI */ | |||
471 | 0, | |||
472 | piixsata_chip_map | |||
473 | }, | |||
474 | { PCI_PRODUCT_INTEL_82801H_SATA_20x2825, /* Intel 82801H (ICH8) SATA */ | |||
475 | 0, | |||
476 | piixsata_chip_map | |||
477 | }, | |||
478 | { PCI_PRODUCT_INTEL_82801HBM_SATA0x2828, /* Intel 82801HBM (ICH8M) SATA */ | |||
479 | 0, | |||
480 | piixsata_chip_map | |||
481 | }, | |||
482 | { PCI_PRODUCT_INTEL_82801HBM_AHCI0x2829, /* Intel 82801HBM (ICH8M) AHCI */ | |||
483 | 0, | |||
484 | piixsata_chip_map | |||
485 | }, | |||
486 | { PCI_PRODUCT_INTEL_82801HBM_RAID0x282a, /* Intel 82801HBM (ICH8M) RAID */ | |||
487 | 0, | |||
488 | piixsata_chip_map | |||
489 | }, | |||
490 | { PCI_PRODUCT_INTEL_82801HBM_IDE0x2850, /* Intel 82801HBM (ICH8M) IDE */ | |||
491 | 0, | |||
492 | piix_chip_map | |||
493 | }, | |||
494 | { PCI_PRODUCT_INTEL_82801I_SATA_10x2920, /* Intel 82801I (ICH9) SATA */ | |||
495 | 0, | |||
496 | piixsata_chip_map | |||
497 | }, | |||
498 | { PCI_PRODUCT_INTEL_82801I_SATA_20x2921, /* Intel 82801I (ICH9) SATA */ | |||
499 | 0, | |||
500 | piixsata_chip_map | |||
501 | }, | |||
502 | { PCI_PRODUCT_INTEL_82801I_SATA_30x2926, /* Intel 82801I (ICH9) SATA */ | |||
503 | 0, | |||
504 | piixsata_chip_map | |||
505 | }, | |||
506 | { PCI_PRODUCT_INTEL_82801I_SATA_40x2928, /* Intel 82801I (ICH9) SATA */ | |||
507 | 0, | |||
508 | piixsata_chip_map | |||
509 | }, | |||
510 | { PCI_PRODUCT_INTEL_82801I_SATA_50x292d, /* Intel 82801I (ICH9M) SATA */ | |||
511 | 0, | |||
512 | piixsata_chip_map | |||
513 | }, | |||
514 | { PCI_PRODUCT_INTEL_82801I_SATA_60x292e, /* Intel 82801I (ICH9M) SATA */ | |||
515 | 0, | |||
516 | piixsata_chip_map | |||
517 | }, | |||
518 | { PCI_PRODUCT_INTEL_82801JD_SATA_10x3a00, /* Intel 82801JD (ICH10) SATA */ | |||
519 | 0, | |||
520 | piixsata_chip_map | |||
521 | }, | |||
522 | { PCI_PRODUCT_INTEL_82801JD_SATA_20x3a06, /* Intel 82801JD (ICH10) SATA */ | |||
523 | 0, | |||
524 | piixsata_chip_map | |||
525 | }, | |||
526 | { PCI_PRODUCT_INTEL_82801JI_SATA_10x3a20, /* Intel 82801JI (ICH10) SATA */ | |||
527 | 0, | |||
528 | piixsata_chip_map | |||
529 | }, | |||
530 | { PCI_PRODUCT_INTEL_82801JI_SATA_20x3a26, /* Intel 82801JI (ICH10) SATA */ | |||
531 | 0, | |||
532 | piixsata_chip_map | |||
533 | }, | |||
534 | { PCI_PRODUCT_INTEL_6321ESB_SATA0x2680, /* Intel 6321ESB SATA */ | |||
535 | 0, | |||
536 | piixsata_chip_map | |||
537 | }, | |||
538 | { PCI_PRODUCT_INTEL_3400_SATA_10x3b20, /* Intel 3400 SATA */ | |||
539 | 0, | |||
540 | piixsata_chip_map | |||
541 | }, | |||
542 | { PCI_PRODUCT_INTEL_3400_SATA_20x3b21, /* Intel 3400 SATA */ | |||
543 | 0, | |||
544 | piixsata_chip_map | |||
545 | }, | |||
546 | { PCI_PRODUCT_INTEL_3400_SATA_30x3b26, /* Intel 3400 SATA */ | |||
547 | 0, | |||
548 | piixsata_chip_map | |||
549 | }, | |||
550 | { PCI_PRODUCT_INTEL_3400_SATA_40x3b28, /* Intel 3400 SATA */ | |||
551 | 0, | |||
552 | piixsata_chip_map | |||
553 | }, | |||
554 | { PCI_PRODUCT_INTEL_3400_SATA_50x3b2d, /* Intel 3400 SATA */ | |||
555 | 0, | |||
556 | piixsata_chip_map | |||
557 | }, | |||
558 | { PCI_PRODUCT_INTEL_3400_SATA_60x3b2e, /* Intel 3400 SATA */ | |||
559 | 0, | |||
560 | piixsata_chip_map | |||
561 | }, | |||
562 | { PCI_PRODUCT_INTEL_C600_SATA0x1d00, /* Intel C600 SATA */ | |||
563 | 0, | |||
564 | piixsata_chip_map | |||
565 | }, | |||
566 | { PCI_PRODUCT_INTEL_C610_SATA_10x8d00, /* Intel C610 SATA */ | |||
567 | 0, | |||
568 | piixsata_chip_map | |||
569 | }, | |||
570 | { PCI_PRODUCT_INTEL_C610_SATA_20x8d08, /* Intel C610 SATA */ | |||
571 | 0, | |||
572 | piixsata_chip_map | |||
573 | }, | |||
574 | { PCI_PRODUCT_INTEL_C610_SATA_30x8d60, /* Intel C610 SATA */ | |||
575 | 0, | |||
576 | piixsata_chip_map | |||
577 | }, | |||
578 | { PCI_PRODUCT_INTEL_6SERIES_SATA_10x1c00, /* Intel 6 Series SATA */ | |||
579 | 0, | |||
580 | piixsata_chip_map | |||
581 | }, | |||
582 | { PCI_PRODUCT_INTEL_6SERIES_SATA_20x1c01, /* Intel 6 Series SATA */ | |||
583 | 0, | |||
584 | piixsata_chip_map | |||
585 | }, | |||
586 | { PCI_PRODUCT_INTEL_6SERIES_SATA_30x1c08, /* Intel 6 Series SATA */ | |||
587 | 0, | |||
588 | piixsata_chip_map | |||
589 | }, | |||
590 | { PCI_PRODUCT_INTEL_6SERIES_SATA_40x1c09, /* Intel 6 Series SATA */ | |||
591 | 0, | |||
592 | piixsata_chip_map | |||
593 | }, | |||
594 | { PCI_PRODUCT_INTEL_7SERIES_SATA_10x1e00, /* Intel 7 Series SATA */ | |||
595 | 0, | |||
596 | piixsata_chip_map | |||
597 | }, | |||
598 | { PCI_PRODUCT_INTEL_7SERIES_SATA_20x1e01, /* Intel 7 Series SATA */ | |||
599 | 0, | |||
600 | piixsata_chip_map | |||
601 | }, | |||
602 | { PCI_PRODUCT_INTEL_7SERIES_SATA_30x1e08, /* Intel 7 Series SATA */ | |||
603 | 0, | |||
604 | piixsata_chip_map | |||
605 | }, | |||
606 | { PCI_PRODUCT_INTEL_7SERIES_SATA_40x1e09, /* Intel 7 Series SATA */ | |||
607 | 0, | |||
608 | piixsata_chip_map | |||
609 | }, | |||
610 | { PCI_PRODUCT_INTEL_8SERIES_SATA_10x8c00, /* Intel 8 Series SATA */ | |||
611 | 0, | |||
612 | piixsata_chip_map | |||
613 | }, | |||
614 | { PCI_PRODUCT_INTEL_8SERIES_SATA_20x8c01, /* Intel 8 Series SATA */ | |||
615 | 0, | |||
616 | piixsata_chip_map | |||
617 | }, | |||
618 | { PCI_PRODUCT_INTEL_8SERIES_SATA_30x8c08, /* Intel 8 Series SATA */ | |||
619 | 0, | |||
620 | piixsata_chip_map | |||
621 | }, | |||
622 | { PCI_PRODUCT_INTEL_8SERIES_SATA_40x8c09, /* Intel 8 Series SATA */ | |||
623 | 0, | |||
624 | piixsata_chip_map | |||
625 | }, | |||
626 | { PCI_PRODUCT_INTEL_8SERIES_LP_SATA_10x9c00, /* Intel 8 Series SATA */ | |||
627 | 0, | |||
628 | piixsata_chip_map | |||
629 | }, | |||
630 | { PCI_PRODUCT_INTEL_8SERIES_LP_SATA_20x9c01, /* Intel 8 Series SATA */ | |||
631 | 0, | |||
632 | piixsata_chip_map | |||
633 | }, | |||
634 | { PCI_PRODUCT_INTEL_8SERIES_LP_SATA_30x9c08, /* Intel 8 Series SATA */ | |||
635 | 0, | |||
636 | piixsata_chip_map | |||
637 | }, | |||
638 | { PCI_PRODUCT_INTEL_8SERIES_LP_SATA_40x9c09, /* Intel 8 Series SATA */ | |||
639 | 0, | |||
640 | piixsata_chip_map | |||
641 | }, | |||
642 | { PCI_PRODUCT_INTEL_9SERIES_SATA_10x8c80, /* Intel 9 Series SATA */ | |||
643 | 0, | |||
644 | piixsata_chip_map | |||
645 | }, | |||
646 | { PCI_PRODUCT_INTEL_9SERIES_SATA_20x8c88, /* Intel 9 Series SATA */ | |||
647 | 0, | |||
648 | piixsata_chip_map | |||
649 | }, | |||
650 | { PCI_PRODUCT_INTEL_ATOMC2000_SATA_10x1f20, /* Intel Atom C2000 SATA */ | |||
651 | 0, | |||
652 | piixsata_chip_map | |||
653 | }, | |||
654 | { PCI_PRODUCT_INTEL_ATOMC2000_SATA_20x1f21, /* Intel Atom C2000 SATA */ | |||
655 | 0, | |||
656 | piixsata_chip_map | |||
657 | }, | |||
658 | { PCI_PRODUCT_INTEL_ATOMC2000_SATA_30x1f30, /* Intel Atom C2000 SATA */ | |||
659 | 0, | |||
660 | piixsata_chip_map | |||
661 | }, | |||
662 | { PCI_PRODUCT_INTEL_ATOMC2000_SATA_40x1f31, /* Intel Atom C2000 SATA */ | |||
663 | 0, | |||
664 | piixsata_chip_map | |||
665 | }, | |||
666 | { PCI_PRODUCT_INTEL_BAYTRAIL_SATA_10x0f20, /* Intel Baytrail SATA */ | |||
667 | 0, | |||
668 | piixsata_chip_map | |||
669 | }, | |||
670 | { PCI_PRODUCT_INTEL_BAYTRAIL_SATA_20x0f21, /* Intel Baytrail SATA */ | |||
671 | 0, | |||
672 | piixsata_chip_map | |||
673 | }, | |||
674 | { PCI_PRODUCT_INTEL_EP80579_SATA0x5028, /* Intel EP80579 SATA */ | |||
675 | 0, | |||
676 | piixsata_chip_map | |||
677 | }, | |||
678 | { PCI_PRODUCT_INTEL_DH8900_SATA_10x2326, /* Intel DH8900 SATA */ | |||
679 | 0, | |||
680 | piixsata_chip_map | |||
681 | }, | |||
682 | { PCI_PRODUCT_INTEL_DH8900_SATA_20x23a6, /* Intel DH8900 SATA */ | |||
683 | 0, | |||
684 | piixsata_chip_map | |||
685 | }, | |||
686 | { PCI_PRODUCT_INTEL_SCH_IDE0x811a, /* Intel SCH IDE */ | |||
687 | 0, | |||
688 | sch_chip_map | |||
689 | } | |||
690 | }; | |||
691 | ||||
692 | const struct pciide_product_desc pciide_amd_products[] = { | |||
693 | { PCI_PRODUCT_AMD_PBC756_IDE0x7409, /* AMD 756 */ | |||
694 | 0, | |||
695 | amd756_chip_map | |||
696 | }, | |||
697 | { PCI_PRODUCT_AMD_766_IDE0x7411, /* AMD 766 */ | |||
698 | 0, | |||
699 | amd756_chip_map | |||
700 | }, | |||
701 | { PCI_PRODUCT_AMD_PBC768_IDE0x7441, | |||
702 | 0, | |||
703 | amd756_chip_map | |||
704 | }, | |||
705 | { PCI_PRODUCT_AMD_8111_IDE0x7469, | |||
706 | 0, | |||
707 | amd756_chip_map | |||
708 | }, | |||
709 | { PCI_PRODUCT_AMD_CS5536_IDE0x209a, | |||
710 | 0, | |||
711 | amd756_chip_map | |||
712 | }, | |||
713 | { PCI_PRODUCT_AMD_HUDSON2_IDE0x780c, | |||
714 | 0, | |||
715 | ixp_chip_map | |||
716 | } | |||
717 | }; | |||
718 | ||||
719 | const struct pciide_product_desc pciide_cmd_products[] = { | |||
720 | { PCI_PRODUCT_CMDTECH_6400x0640, /* CMD Technology PCI0640 */ | |||
721 | 0, | |||
722 | cmd_chip_map | |||
723 | }, | |||
724 | { PCI_PRODUCT_CMDTECH_6430x0643, /* CMD Technology PCI0643 */ | |||
725 | 0, | |||
726 | cmd0643_9_chip_map | |||
727 | }, | |||
728 | { PCI_PRODUCT_CMDTECH_6460x0646, /* CMD Technology PCI0646 */ | |||
729 | 0, | |||
730 | cmd0643_9_chip_map | |||
731 | }, | |||
732 | { PCI_PRODUCT_CMDTECH_6480x0648, /* CMD Technology PCI0648 */ | |||
733 | 0, | |||
734 | cmd0643_9_chip_map | |||
735 | }, | |||
736 | { PCI_PRODUCT_CMDTECH_6490x0649, /* CMD Technology PCI0649 */ | |||
737 | 0, | |||
738 | cmd0643_9_chip_map | |||
739 | }, | |||
740 | { PCI_PRODUCT_CMDTECH_6800x0680, /* CMD Technology PCI0680 */ | |||
741 | IDE_PCI_CLASS_OVERRIDE0x0001, | |||
742 | cmd680_chip_map | |||
743 | }, | |||
744 | { PCI_PRODUCT_CMDTECH_31120x3112, /* SiI3112 SATA */ | |||
745 | 0, | |||
746 | sii3112_chip_map | |||
747 | }, | |||
748 | { PCI_PRODUCT_CMDTECH_35120x3512, /* SiI3512 SATA */ | |||
749 | 0, | |||
750 | sii3112_chip_map | |||
751 | }, | |||
752 | { PCI_PRODUCT_CMDTECH_AAR_1210SA0x0240, /* Adaptec AAR-1210SA */ | |||
753 | 0, | |||
754 | sii3112_chip_map | |||
755 | }, | |||
756 | { PCI_PRODUCT_CMDTECH_31140x3114, /* SiI3114 SATA */ | |||
757 | 0, | |||
758 | sii3114_chip_map | |||
759 | } | |||
760 | }; | |||
761 | ||||
762 | const struct pciide_product_desc pciide_via_products[] = { | |||
763 | { PCI_PRODUCT_VIATECH_VT82C4160x1571, /* VIA VT82C416 IDE */ | |||
764 | 0, | |||
765 | apollo_chip_map | |||
766 | }, | |||
767 | { PCI_PRODUCT_VIATECH_VT82C5710x0571, /* VIA VT82C571 IDE */ | |||
768 | 0, | |||
769 | apollo_chip_map | |||
770 | }, | |||
771 | { PCI_PRODUCT_VIATECH_VT64100x3164, /* VIA VT6410 IDE */ | |||
772 | IDE_PCI_CLASS_OVERRIDE0x0001, | |||
773 | apollo_chip_map | |||
774 | }, | |||
775 | { PCI_PRODUCT_VIATECH_VT64150x0415, /* VIA VT6415 IDE */ | |||
776 | IDE_PCI_CLASS_OVERRIDE0x0001, | |||
777 | apollo_chip_map | |||
778 | }, | |||
779 | { PCI_PRODUCT_VIATECH_CX700_IDE0x5324, /* VIA CX700 IDE */ | |||
780 | 0, | |||
781 | apollo_chip_map | |||
782 | }, | |||
783 | { PCI_PRODUCT_VIATECH_VX700_IDE0x0581, /* VIA VX700 IDE */ | |||
784 | 0, | |||
785 | apollo_chip_map | |||
786 | }, | |||
787 | { PCI_PRODUCT_VIATECH_VX855_IDE0xc409, /* VIA VX855 IDE */ | |||
788 | 0, | |||
789 | apollo_chip_map | |||
790 | }, | |||
791 | { PCI_PRODUCT_VIATECH_VX900_IDE0x9001, /* VIA VX900 IDE */ | |||
792 | 0, | |||
793 | apollo_chip_map | |||
794 | }, | |||
795 | { PCI_PRODUCT_VIATECH_VT6420_SATA0x3149, /* VIA VT6420 SATA */ | |||
796 | 0, | |||
797 | sata_chip_map | |||
798 | }, | |||
799 | { PCI_PRODUCT_VIATECH_VT6421_SATA0x3249, /* VIA VT6421 SATA */ | |||
800 | 0, | |||
801 | sata_chip_map | |||
802 | }, | |||
803 | { PCI_PRODUCT_VIATECH_VT8237A_SATA0x0591, /* VIA VT8237A SATA */ | |||
804 | 0, | |||
805 | sata_chip_map | |||
806 | }, | |||
807 | { PCI_PRODUCT_VIATECH_VT8237A_SATA_20x5337, /* VIA VT8237A SATA */ | |||
808 | 0, | |||
809 | sata_chip_map | |||
810 | }, | |||
811 | { PCI_PRODUCT_VIATECH_VT8237S_SATA0x5372, /* VIA VT8237S SATA */ | |||
812 | 0, | |||
813 | sata_chip_map | |||
814 | }, | |||
815 | { PCI_PRODUCT_VIATECH_VT8251_SATA0x3349, /* VIA VT8251 SATA */ | |||
816 | 0, | |||
817 | sata_chip_map | |||
818 | } | |||
819 | }; | |||
820 | ||||
821 | const struct pciide_product_desc pciide_cypress_products[] = { | |||
822 | { PCI_PRODUCT_CONTAQ_82C6930xc693, /* Contaq CY82C693 IDE */ | |||
823 | IDE_16BIT_IOSPACE0x0002, | |||
824 | cy693_chip_map | |||
825 | } | |||
826 | }; | |||
827 | ||||
828 | const struct pciide_product_desc pciide_sis_products[] = { | |||
829 | { PCI_PRODUCT_SIS_55130x5513, /* SIS 5513 EIDE */ | |||
830 | 0, | |||
831 | sis_chip_map | |||
832 | }, | |||
833 | { PCI_PRODUCT_SIS_1800x0180, /* SIS 180 SATA */ | |||
834 | 0, | |||
835 | sata_chip_map | |||
836 | }, | |||
837 | { PCI_PRODUCT_SIS_1810x0181, /* SIS 181 SATA */ | |||
838 | 0, | |||
839 | sata_chip_map | |||
840 | }, | |||
841 | { PCI_PRODUCT_SIS_1820x0182, /* SIS 182 SATA */ | |||
842 | 0, | |||
843 | sata_chip_map | |||
844 | }, | |||
845 | { PCI_PRODUCT_SIS_11830x1183, /* SIS 1183 SATA */ | |||
846 | 0, | |||
847 | sata_chip_map | |||
848 | } | |||
849 | }; | |||
850 | ||||
851 | /* | |||
852 | * The National/AMD CS5535 requires MSRs to set DMA/PIO modes so it | |||
853 | * has been banished to the MD i386 pciide_machdep | |||
854 | */ | |||
855 | const struct pciide_product_desc pciide_natsemi_products[] = { | |||
856 | #ifdef __i386__ | |||
857 | { PCI_PRODUCT_NS_CS5535_IDE0x002d, /* National/AMD CS5535 IDE */ | |||
858 | 0, | |||
859 | gcsc_chip_map | |||
860 | }, | |||
861 | #endif | |||
862 | { PCI_PRODUCT_NS_PC874150x0002, /* National Semi PC87415 IDE */ | |||
863 | 0, | |||
864 | natsemi_chip_map | |||
865 | }, | |||
866 | { PCI_PRODUCT_NS_SCX200_IDE0x0502, /* National Semi SCx200 IDE */ | |||
867 | 0, | |||
868 | ns_scx200_chip_map | |||
869 | } | |||
870 | }; | |||
871 | ||||
872 | const struct pciide_product_desc pciide_acer_products[] = { | |||
873 | { PCI_PRODUCT_ALI_M52290x5229, /* Acer Labs M5229 UDMA IDE */ | |||
874 | 0, | |||
875 | acer_chip_map | |||
876 | } | |||
877 | }; | |||
878 | ||||
879 | const struct pciide_product_desc pciide_triones_products[] = { | |||
880 | { PCI_PRODUCT_TRIONES_HPT3660x0004, /* Highpoint HPT36x/37x IDE */ | |||
881 | IDE_PCI_CLASS_OVERRIDE0x0001, | |||
882 | hpt_chip_map, | |||
883 | }, | |||
884 | { PCI_PRODUCT_TRIONES_HPT372A0x0005, /* Highpoint HPT372A IDE */ | |||
885 | IDE_PCI_CLASS_OVERRIDE0x0001, | |||
886 | hpt_chip_map | |||
887 | }, | |||
888 | { PCI_PRODUCT_TRIONES_HPT3020x0006, /* Highpoint HPT302 IDE */ | |||
889 | IDE_PCI_CLASS_OVERRIDE0x0001, | |||
890 | hpt_chip_map | |||
891 | }, | |||
892 | { PCI_PRODUCT_TRIONES_HPT3710x0007, /* Highpoint HPT371 IDE */ | |||
893 | IDE_PCI_CLASS_OVERRIDE0x0001, | |||
894 | hpt_chip_map | |||
895 | }, | |||
896 | { PCI_PRODUCT_TRIONES_HPT3740x0008, /* Highpoint HPT374 IDE */ | |||
897 | IDE_PCI_CLASS_OVERRIDE0x0001, | |||
898 | hpt_chip_map | |||
899 | } | |||
900 | }; | |||
901 | ||||
902 | const struct pciide_product_desc pciide_promise_products[] = { | |||
903 | { PCI_PRODUCT_PROMISE_PDC202460x4d33, | |||
904 | IDE_PCI_CLASS_OVERRIDE0x0001, | |||
905 | pdc202xx_chip_map, | |||
906 | }, | |||
907 | { PCI_PRODUCT_PROMISE_PDC202620x4d38, | |||
908 | IDE_PCI_CLASS_OVERRIDE0x0001, | |||
909 | pdc202xx_chip_map, | |||
910 | }, | |||
911 | { PCI_PRODUCT_PROMISE_PDC202650x0d30, | |||
912 | IDE_PCI_CLASS_OVERRIDE0x0001, | |||
913 | pdc202xx_chip_map, | |||
914 | }, | |||
915 | { PCI_PRODUCT_PROMISE_PDC202670x4d30, | |||
916 | IDE_PCI_CLASS_OVERRIDE0x0001, | |||
917 | pdc202xx_chip_map, | |||
918 | }, | |||
919 | { PCI_PRODUCT_PROMISE_PDC202680x4d68, | |||
920 | IDE_PCI_CLASS_OVERRIDE0x0001, | |||
921 | pdc202xx_chip_map, | |||
922 | }, | |||
923 | { PCI_PRODUCT_PROMISE_PDC20268R0x6268, | |||
924 | IDE_PCI_CLASS_OVERRIDE0x0001, | |||
925 | pdc202xx_chip_map, | |||
926 | }, | |||
927 | { PCI_PRODUCT_PROMISE_PDC202690x4d69, | |||
928 | IDE_PCI_CLASS_OVERRIDE0x0001, | |||
929 | pdc202xx_chip_map, | |||
930 | }, | |||
931 | { PCI_PRODUCT_PROMISE_PDC202710x6269, | |||
932 | IDE_PCI_CLASS_OVERRIDE0x0001, | |||
933 | pdc202xx_chip_map, | |||
934 | }, | |||
935 | { PCI_PRODUCT_PROMISE_PDC202750x1275, | |||
936 | IDE_PCI_CLASS_OVERRIDE0x0001, | |||
937 | pdc202xx_chip_map, | |||
938 | }, | |||
939 | { PCI_PRODUCT_PROMISE_PDC202760x5275, | |||
940 | IDE_PCI_CLASS_OVERRIDE0x0001, | |||
941 | pdc202xx_chip_map, | |||
942 | }, | |||
943 | { PCI_PRODUCT_PROMISE_PDC202770x7275, | |||
944 | IDE_PCI_CLASS_OVERRIDE0x0001, | |||
945 | pdc202xx_chip_map, | |||
946 | }, | |||
947 | { PCI_PRODUCT_PROMISE_PDC203180x3318, | |||
948 | IDE_PCI_CLASS_OVERRIDE0x0001, | |||
949 | pdcsata_chip_map, | |||
950 | }, | |||
951 | { PCI_PRODUCT_PROMISE_PDC203190x3319, | |||
952 | IDE_PCI_CLASS_OVERRIDE0x0001, | |||
953 | pdcsata_chip_map, | |||
954 | }, | |||
955 | { PCI_PRODUCT_PROMISE_PDC203710x3371, | |||
956 | IDE_PCI_CLASS_OVERRIDE0x0001, | |||
957 | pdcsata_chip_map, | |||
958 | }, | |||
959 | { PCI_PRODUCT_PROMISE_PDC203750x3375, | |||
960 | IDE_PCI_CLASS_OVERRIDE0x0001, | |||
961 | pdcsata_chip_map, | |||
962 | }, | |||
963 | { PCI_PRODUCT_PROMISE_PDC203760x3376, | |||
964 | IDE_PCI_CLASS_OVERRIDE0x0001, | |||
965 | pdcsata_chip_map, | |||
966 | }, | |||
967 | { PCI_PRODUCT_PROMISE_PDC203770x3377, | |||
968 | IDE_PCI_CLASS_OVERRIDE0x0001, | |||
969 | pdcsata_chip_map, | |||
970 | }, | |||
971 | { PCI_PRODUCT_PROMISE_PDC203780x3373, | |||
972 | IDE_PCI_CLASS_OVERRIDE0x0001, | |||
973 | pdcsata_chip_map, | |||
974 | }, | |||
975 | { PCI_PRODUCT_PROMISE_PDC203790x3372, | |||
976 | IDE_PCI_CLASS_OVERRIDE0x0001, | |||
977 | pdcsata_chip_map, | |||
978 | }, | |||
979 | { PCI_PRODUCT_PROMISE_PDC405180x3d18, | |||
980 | IDE_PCI_CLASS_OVERRIDE0x0001, | |||
981 | pdcsata_chip_map, | |||
982 | }, | |||
983 | { PCI_PRODUCT_PROMISE_PDC405190x3519, | |||
984 | IDE_PCI_CLASS_OVERRIDE0x0001, | |||
985 | pdcsata_chip_map, | |||
986 | }, | |||
987 | { PCI_PRODUCT_PROMISE_PDC407180x3d17, | |||
988 | IDE_PCI_CLASS_OVERRIDE0x0001, | |||
989 | pdcsata_chip_map, | |||
990 | }, | |||
991 | { PCI_PRODUCT_PROMISE_PDC407190x3515, | |||
992 | IDE_PCI_CLASS_OVERRIDE0x0001, | |||
993 | pdcsata_chip_map, | |||
994 | }, | |||
995 | { PCI_PRODUCT_PROMISE_PDC407790x3577, | |||
996 | IDE_PCI_CLASS_OVERRIDE0x0001, | |||
997 | pdcsata_chip_map, | |||
998 | }, | |||
999 | { PCI_PRODUCT_PROMISE_PDC205710x3571, | |||
1000 | IDE_PCI_CLASS_OVERRIDE0x0001, | |||
1001 | pdcsata_chip_map, | |||
1002 | }, | |||
1003 | { PCI_PRODUCT_PROMISE_PDC205750x3d75, | |||
1004 | IDE_PCI_CLASS_OVERRIDE0x0001, | |||
1005 | pdcsata_chip_map, | |||
1006 | }, | |||
1007 | { PCI_PRODUCT_PROMISE_PDC205790x3574, | |||
1008 | IDE_PCI_CLASS_OVERRIDE0x0001, | |||
1009 | pdcsata_chip_map, | |||
1010 | }, | |||
1011 | { PCI_PRODUCT_PROMISE_PDC207710x3570, | |||
1012 | IDE_PCI_CLASS_OVERRIDE0x0001, | |||
1013 | pdcsata_chip_map, | |||
1014 | }, | |||
1015 | { PCI_PRODUCT_PROMISE_PDC207750x3d73, | |||
1016 | IDE_PCI_CLASS_OVERRIDE0x0001, | |||
1017 | pdcsata_chip_map, | |||
1018 | } | |||
1019 | }; | |||
1020 | ||||
1021 | const struct pciide_product_desc pciide_acard_products[] = { | |||
1022 | { PCI_PRODUCT_ACARD_ATP850U0x0005, /* Acard ATP850U Ultra33 Controller */ | |||
1023 | IDE_PCI_CLASS_OVERRIDE0x0001, | |||
1024 | acard_chip_map, | |||
1025 | }, | |||
1026 | { PCI_PRODUCT_ACARD_ATP8600x0006, /* Acard ATP860 Ultra66 Controller */ | |||
1027 | IDE_PCI_CLASS_OVERRIDE0x0001, | |||
1028 | acard_chip_map, | |||
1029 | }, | |||
1030 | { PCI_PRODUCT_ACARD_ATP860A0x0007, /* Acard ATP860-A Ultra66 Controller */ | |||
1031 | IDE_PCI_CLASS_OVERRIDE0x0001, | |||
1032 | acard_chip_map, | |||
1033 | }, | |||
1034 | { PCI_PRODUCT_ACARD_ATP865A0x0008, /* Acard ATP865-A Ultra133 Controller */ | |||
1035 | IDE_PCI_CLASS_OVERRIDE0x0001, | |||
1036 | acard_chip_map, | |||
1037 | }, | |||
1038 | { PCI_PRODUCT_ACARD_ATP865R0x0009, /* Acard ATP865-R Ultra133 Controller */ | |||
1039 | IDE_PCI_CLASS_OVERRIDE0x0001, | |||
1040 | acard_chip_map, | |||
1041 | } | |||
1042 | }; | |||
1043 | ||||
1044 | const struct pciide_product_desc pciide_serverworks_products[] = { | |||
1045 | { PCI_PRODUCT_RCC_OSB4_IDE0x0211, | |||
1046 | 0, | |||
1047 | serverworks_chip_map, | |||
1048 | }, | |||
1049 | { PCI_PRODUCT_RCC_CSB5_IDE0x0212, | |||
1050 | 0, | |||
1051 | serverworks_chip_map, | |||
1052 | }, | |||
1053 | { PCI_PRODUCT_RCC_CSB6_IDE0x0217, | |||
1054 | 0, | |||
1055 | serverworks_chip_map, | |||
1056 | }, | |||
1057 | { PCI_PRODUCT_RCC_CSB6_RAID_IDE0x0213, | |||
1058 | 0, | |||
1059 | serverworks_chip_map, | |||
1060 | }, | |||
1061 | { PCI_PRODUCT_RCC_HT_1000_IDE0x0214, | |||
1062 | 0, | |||
1063 | serverworks_chip_map, | |||
1064 | }, | |||
1065 | { PCI_PRODUCT_RCC_K2_SATA0x0240, | |||
1066 | 0, | |||
1067 | svwsata_chip_map, | |||
1068 | }, | |||
1069 | { PCI_PRODUCT_RCC_FRODO4_SATA0x0241, | |||
1070 | 0, | |||
1071 | svwsata_chip_map, | |||
1072 | }, | |||
1073 | { PCI_PRODUCT_RCC_FRODO8_SATA0x0242, | |||
1074 | 0, | |||
1075 | svwsata_chip_map, | |||
1076 | }, | |||
1077 | { PCI_PRODUCT_RCC_HT_1000_SATA_10x024a, | |||
1078 | 0, | |||
1079 | svwsata_chip_map, | |||
1080 | }, | |||
1081 | { PCI_PRODUCT_RCC_HT_1000_SATA_20x024b, | |||
1082 | 0, | |||
1083 | svwsata_chip_map, | |||
1084 | } | |||
1085 | }; | |||
1086 | ||||
1087 | const struct pciide_product_desc pciide_nvidia_products[] = { | |||
1088 | { PCI_PRODUCT_NVIDIA_NFORCE_IDE0x01bc, | |||
1089 | 0, | |||
1090 | nforce_chip_map | |||
1091 | }, | |||
1092 | { PCI_PRODUCT_NVIDIA_NFORCE2_IDE0x0065, | |||
1093 | 0, | |||
1094 | nforce_chip_map | |||
1095 | }, | |||
1096 | { PCI_PRODUCT_NVIDIA_NFORCE2_400_IDE0x0085, | |||
1097 | 0, | |||
1098 | nforce_chip_map | |||
1099 | }, | |||
1100 | { PCI_PRODUCT_NVIDIA_NFORCE3_IDE0x00d5, | |||
1101 | 0, | |||
1102 | nforce_chip_map | |||
1103 | }, | |||
1104 | { PCI_PRODUCT_NVIDIA_NFORCE3_250_IDE0x00e5, | |||
1105 | 0, | |||
1106 | nforce_chip_map | |||
1107 | }, | |||
1108 | { PCI_PRODUCT_NVIDIA_NFORCE4_ATA1330x0053, | |||
1109 | 0, | |||
1110 | nforce_chip_map | |||
1111 | }, | |||
1112 | { PCI_PRODUCT_NVIDIA_MCP04_IDE0x0035, | |||
1113 | 0, | |||
1114 | nforce_chip_map | |||
1115 | }, | |||
1116 | { PCI_PRODUCT_NVIDIA_MCP51_IDE0x0265, | |||
1117 | 0, | |||
1118 | nforce_chip_map | |||
1119 | }, | |||
1120 | { PCI_PRODUCT_NVIDIA_MCP55_IDE0x036e, | |||
1121 | 0, | |||
1122 | nforce_chip_map | |||
1123 | }, | |||
1124 | { PCI_PRODUCT_NVIDIA_MCP61_IDE0x03ec, | |||
1125 | 0, | |||
1126 | nforce_chip_map | |||
1127 | }, | |||
1128 | { PCI_PRODUCT_NVIDIA_MCP65_IDE0x0448, | |||
1129 | 0, | |||
1130 | nforce_chip_map | |||
1131 | }, | |||
1132 | { PCI_PRODUCT_NVIDIA_MCP67_IDE0x0560, | |||
1133 | 0, | |||
1134 | nforce_chip_map | |||
1135 | }, | |||
1136 | { PCI_PRODUCT_NVIDIA_MCP73_IDE0x056c, | |||
1137 | 0, | |||
1138 | nforce_chip_map | |||
1139 | }, | |||
1140 | { PCI_PRODUCT_NVIDIA_MCP77_IDE0x0759, | |||
1141 | 0, | |||
1142 | nforce_chip_map | |||
1143 | }, | |||
1144 | { PCI_PRODUCT_NVIDIA_NFORCE2_400_SATA0x008e, | |||
1145 | 0, | |||
1146 | sata_chip_map | |||
1147 | }, | |||
1148 | { PCI_PRODUCT_NVIDIA_NFORCE3_250_SATA0x00e3, | |||
1149 | 0, | |||
1150 | sata_chip_map | |||
1151 | }, | |||
1152 | { PCI_PRODUCT_NVIDIA_NFORCE3_250_SATA20x00ee, | |||
1153 | 0, | |||
1154 | sata_chip_map | |||
1155 | }, | |||
1156 | { PCI_PRODUCT_NVIDIA_NFORCE4_SATA10x0054, | |||
1157 | 0, | |||
1158 | sata_chip_map | |||
1159 | }, | |||
1160 | { PCI_PRODUCT_NVIDIA_NFORCE4_SATA20x0055, | |||
1161 | 0, | |||
1162 | sata_chip_map | |||
1163 | }, | |||
1164 | { PCI_PRODUCT_NVIDIA_MCP04_SATA0x0036, | |||
1165 | 0, | |||
1166 | sata_chip_map | |||
1167 | }, | |||
1168 | { PCI_PRODUCT_NVIDIA_MCP04_SATA20x003e, | |||
1169 | 0, | |||
1170 | sata_chip_map | |||
1171 | }, | |||
1172 | { PCI_PRODUCT_NVIDIA_MCP51_SATA0x0266, | |||
1173 | 0, | |||
1174 | sata_chip_map | |||
1175 | }, | |||
1176 | { PCI_PRODUCT_NVIDIA_MCP51_SATA20x0267, | |||
1177 | 0, | |||
1178 | sata_chip_map | |||
1179 | }, | |||
1180 | { PCI_PRODUCT_NVIDIA_MCP55_SATA0x037e, | |||
1181 | 0, | |||
1182 | sata_chip_map | |||
1183 | }, | |||
1184 | { PCI_PRODUCT_NVIDIA_MCP55_SATA20x037f, | |||
1185 | 0, | |||
1186 | sata_chip_map | |||
1187 | }, | |||
1188 | { PCI_PRODUCT_NVIDIA_MCP61_SATA0x03e7, | |||
1189 | 0, | |||
1190 | sata_chip_map | |||
1191 | }, | |||
1192 | { PCI_PRODUCT_NVIDIA_MCP61_SATA20x03f6, | |||
1193 | 0, | |||
1194 | sata_chip_map | |||
1195 | }, | |||
1196 | { PCI_PRODUCT_NVIDIA_MCP61_SATA30x03f7, | |||
1197 | 0, | |||
1198 | sata_chip_map | |||
1199 | }, | |||
1200 | { PCI_PRODUCT_NVIDIA_MCP65_SATA_10x045c, | |||
1201 | 0, | |||
1202 | sata_chip_map | |||
1203 | }, | |||
1204 | { PCI_PRODUCT_NVIDIA_MCP65_SATA_20x045d, | |||
1205 | 0, | |||
1206 | sata_chip_map | |||
1207 | }, | |||
1208 | { PCI_PRODUCT_NVIDIA_MCP65_SATA_30x045e, | |||
1209 | 0, | |||
1210 | sata_chip_map | |||
1211 | }, | |||
1212 | { PCI_PRODUCT_NVIDIA_MCP65_SATA_40x045f, | |||
1213 | 0, | |||
1214 | sata_chip_map | |||
1215 | }, | |||
1216 | { PCI_PRODUCT_NVIDIA_MCP67_SATA_10x0550, | |||
1217 | 0, | |||
1218 | sata_chip_map | |||
1219 | }, | |||
1220 | { PCI_PRODUCT_NVIDIA_MCP67_SATA_20x0551, | |||
1221 | 0, | |||
1222 | sata_chip_map | |||
1223 | }, | |||
1224 | { PCI_PRODUCT_NVIDIA_MCP67_SATA_30x0552, | |||
1225 | 0, | |||
1226 | sata_chip_map | |||
1227 | }, | |||
1228 | { PCI_PRODUCT_NVIDIA_MCP67_SATA_40x0553, | |||
1229 | 0, | |||
1230 | sata_chip_map | |||
1231 | }, | |||
1232 | { PCI_PRODUCT_NVIDIA_MCP77_SATA_10x0ad0, | |||
1233 | 0, | |||
1234 | sata_chip_map | |||
1235 | }, | |||
1236 | { PCI_PRODUCT_NVIDIA_MCP79_SATA_10x0ab4, | |||
1237 | 0, | |||
1238 | sata_chip_map | |||
1239 | }, | |||
1240 | { PCI_PRODUCT_NVIDIA_MCP79_SATA_20x0ab5, | |||
1241 | 0, | |||
1242 | sata_chip_map | |||
1243 | }, | |||
1244 | { PCI_PRODUCT_NVIDIA_MCP79_SATA_30x0ab6, | |||
1245 | 0, | |||
1246 | sata_chip_map | |||
1247 | }, | |||
1248 | { PCI_PRODUCT_NVIDIA_MCP79_SATA_40x0ab7, | |||
1249 | 0, | |||
1250 | sata_chip_map | |||
1251 | }, | |||
1252 | { PCI_PRODUCT_NVIDIA_MCP89_SATA_10x0d84, | |||
1253 | 0, | |||
1254 | sata_chip_map | |||
1255 | }, | |||
1256 | { PCI_PRODUCT_NVIDIA_MCP89_SATA_20x0d85, | |||
1257 | 0, | |||
1258 | sata_chip_map | |||
1259 | }, | |||
1260 | { PCI_PRODUCT_NVIDIA_MCP89_SATA_30x0d86, | |||
1261 | 0, | |||
1262 | sata_chip_map | |||
1263 | }, | |||
1264 | { PCI_PRODUCT_NVIDIA_MCP89_SATA_40x0d87, | |||
1265 | 0, | |||
1266 | sata_chip_map | |||
1267 | } | |||
1268 | }; | |||
1269 | ||||
1270 | const struct pciide_product_desc pciide_ite_products[] = { | |||
1271 | { PCI_PRODUCT_ITEXPRESS_IT8211F0x8211, | |||
1272 | IDE_PCI_CLASS_OVERRIDE0x0001, | |||
1273 | ite_chip_map | |||
1274 | }, | |||
1275 | { PCI_PRODUCT_ITEXPRESS_IT8212F0x8212, | |||
1276 | IDE_PCI_CLASS_OVERRIDE0x0001, | |||
1277 | ite_chip_map | |||
1278 | } | |||
1279 | }; | |||
1280 | ||||
1281 | const struct pciide_product_desc pciide_ati_products[] = { | |||
1282 | { PCI_PRODUCT_ATI_SB200_IDE0x4349, | |||
1283 | 0, | |||
1284 | ixp_chip_map | |||
1285 | }, | |||
1286 | { PCI_PRODUCT_ATI_SB300_IDE0x4369, | |||
1287 | 0, | |||
1288 | ixp_chip_map | |||
1289 | }, | |||
1290 | { PCI_PRODUCT_ATI_SB400_IDE0x4376, | |||
1291 | 0, | |||
1292 | ixp_chip_map | |||
1293 | }, | |||
1294 | { PCI_PRODUCT_ATI_SB600_IDE0x438c, | |||
1295 | 0, | |||
1296 | ixp_chip_map | |||
1297 | }, | |||
1298 | { PCI_PRODUCT_ATI_SB700_IDE0x439c, | |||
1299 | 0, | |||
1300 | ixp_chip_map | |||
1301 | }, | |||
1302 | { PCI_PRODUCT_ATI_SB300_SATA0x436e, | |||
1303 | 0, | |||
1304 | sii3112_chip_map | |||
1305 | }, | |||
1306 | { PCI_PRODUCT_ATI_SB400_SATA_10x4379, | |||
1307 | 0, | |||
1308 | sii3112_chip_map | |||
1309 | }, | |||
1310 | { PCI_PRODUCT_ATI_SB400_SATA_20x437a, | |||
1311 | 0, | |||
1312 | sii3112_chip_map | |||
1313 | } | |||
1314 | }; | |||
1315 | ||||
1316 | const struct pciide_product_desc pciide_jmicron_products[] = { | |||
1317 | { PCI_PRODUCT_JMICRON_JMB3610x2361, | |||
1318 | 0, | |||
1319 | jmicron_chip_map | |||
1320 | }, | |||
1321 | { PCI_PRODUCT_JMICRON_JMB3630x2363, | |||
1322 | 0, | |||
1323 | jmicron_chip_map | |||
1324 | }, | |||
1325 | { PCI_PRODUCT_JMICRON_JMB3650x2365, | |||
1326 | 0, | |||
1327 | jmicron_chip_map | |||
1328 | }, | |||
1329 | { PCI_PRODUCT_JMICRON_JMB3660x2366, | |||
1330 | 0, | |||
1331 | jmicron_chip_map | |||
1332 | }, | |||
1333 | { PCI_PRODUCT_JMICRON_JMB3680x2368, | |||
1334 | 0, | |||
1335 | jmicron_chip_map | |||
1336 | } | |||
1337 | }; | |||
1338 | ||||
1339 | const struct pciide_product_desc pciide_phison_products[] = { | |||
1340 | { PCI_PRODUCT_PHISON_PS50000x5000, | |||
1341 | 0, | |||
1342 | phison_chip_map | |||
1343 | }, | |||
1344 | }; | |||
1345 | ||||
1346 | const struct pciide_product_desc pciide_rdc_products[] = { | |||
1347 | { PCI_PRODUCT_RDC_R1012_IDE0x1012, | |||
1348 | 0, | |||
1349 | rdc_chip_map | |||
1350 | }, | |||
1351 | }; | |||
1352 | ||||
1353 | struct pciide_vendor_desc { | |||
1354 | u_int32_t ide_vendor; | |||
1355 | const struct pciide_product_desc *ide_products; | |||
1356 | int ide_nproducts; | |||
1357 | }; | |||
1358 | ||||
1359 | const struct pciide_vendor_desc pciide_vendors[] = { | |||
1360 | { PCI_VENDOR_INTEL0x8086, pciide_intel_products, | |||
1361 | nitems(pciide_intel_products)(sizeof((pciide_intel_products)) / sizeof((pciide_intel_products )[0])) }, | |||
1362 | { PCI_VENDOR_AMD0x1022, pciide_amd_products, | |||
1363 | nitems(pciide_amd_products)(sizeof((pciide_amd_products)) / sizeof((pciide_amd_products) [0])) }, | |||
1364 | { PCI_VENDOR_CMDTECH0x1095, pciide_cmd_products, | |||
1365 | nitems(pciide_cmd_products)(sizeof((pciide_cmd_products)) / sizeof((pciide_cmd_products) [0])) }, | |||
1366 | { PCI_VENDOR_VIATECH0x1106, pciide_via_products, | |||
1367 | nitems(pciide_via_products)(sizeof((pciide_via_products)) / sizeof((pciide_via_products) [0])) }, | |||
1368 | { PCI_VENDOR_CONTAQ0x1080, pciide_cypress_products, | |||
1369 | nitems(pciide_cypress_products)(sizeof((pciide_cypress_products)) / sizeof((pciide_cypress_products )[0])) }, | |||
1370 | { PCI_VENDOR_SIS0x1039, pciide_sis_products, | |||
1371 | nitems(pciide_sis_products)(sizeof((pciide_sis_products)) / sizeof((pciide_sis_products) [0])) }, | |||
1372 | { PCI_VENDOR_NS0x100b, pciide_natsemi_products, | |||
1373 | nitems(pciide_natsemi_products)(sizeof((pciide_natsemi_products)) / sizeof((pciide_natsemi_products )[0])) }, | |||
1374 | { PCI_VENDOR_ALI0x10b9, pciide_acer_products, | |||
1375 | nitems(pciide_acer_products)(sizeof((pciide_acer_products)) / sizeof((pciide_acer_products )[0])) }, | |||
1376 | { PCI_VENDOR_TRIONES0x1103, pciide_triones_products, | |||
1377 | nitems(pciide_triones_products)(sizeof((pciide_triones_products)) / sizeof((pciide_triones_products )[0])) }, | |||
1378 | { PCI_VENDOR_ACARD0x1191, pciide_acard_products, | |||
1379 | nitems(pciide_acard_products)(sizeof((pciide_acard_products)) / sizeof((pciide_acard_products )[0])) }, | |||
1380 | { PCI_VENDOR_RCC0x1166, pciide_serverworks_products, | |||
1381 | nitems(pciide_serverworks_products)(sizeof((pciide_serverworks_products)) / sizeof((pciide_serverworks_products )[0])) }, | |||
1382 | { PCI_VENDOR_PROMISE0x105a, pciide_promise_products, | |||
1383 | nitems(pciide_promise_products)(sizeof((pciide_promise_products)) / sizeof((pciide_promise_products )[0])) }, | |||
1384 | { PCI_VENDOR_NVIDIA0x10de, pciide_nvidia_products, | |||
1385 | nitems(pciide_nvidia_products)(sizeof((pciide_nvidia_products)) / sizeof((pciide_nvidia_products )[0])) }, | |||
1386 | { PCI_VENDOR_ITEXPRESS0x1283, pciide_ite_products, | |||
1387 | nitems(pciide_ite_products)(sizeof((pciide_ite_products)) / sizeof((pciide_ite_products) [0])) }, | |||
1388 | { PCI_VENDOR_ATI0x1002, pciide_ati_products, | |||
1389 | nitems(pciide_ati_products)(sizeof((pciide_ati_products)) / sizeof((pciide_ati_products) [0])) }, | |||
1390 | { PCI_VENDOR_JMICRON0x197b, pciide_jmicron_products, | |||
1391 | nitems(pciide_jmicron_products)(sizeof((pciide_jmicron_products)) / sizeof((pciide_jmicron_products )[0])) }, | |||
1392 | { PCI_VENDOR_PHISON0x1987, pciide_phison_products, | |||
1393 | nitems(pciide_phison_products)(sizeof((pciide_phison_products)) / sizeof((pciide_phison_products )[0])) }, | |||
1394 | { PCI_VENDOR_RDC0x17f3, pciide_rdc_products, | |||
1395 | nitems(pciide_rdc_products)(sizeof((pciide_rdc_products)) / sizeof((pciide_rdc_products) [0])) } | |||
1396 | }; | |||
1397 | ||||
1398 | /* options passed via the 'flags' config keyword */ | |||
1399 | #define PCIIDE_OPTIONS_DMA0x01 0x01 | |||
1400 | ||||
1401 | int pciide_match(struct device *, void *, void *); | |||
1402 | void pciide_attach(struct device *, struct device *, void *); | |||
1403 | int pciide_detach(struct device *, int); | |||
1404 | int pciide_activate(struct device *, int); | |||
1405 | ||||
1406 | const struct cfattach pciide_pci_ca = { | |||
1407 | sizeof(struct pciide_softc), pciide_match, pciide_attach, | |||
1408 | pciide_detach, pciide_activate | |||
1409 | }; | |||
1410 | ||||
1411 | const struct cfattach pciide_jmb_ca = { | |||
1412 | sizeof(struct pciide_softc), pciide_match, pciide_attach, | |||
1413 | pciide_detach, pciide_activate | |||
1414 | }; | |||
1415 | ||||
1416 | struct cfdriver pciide_cd = { | |||
1417 | NULL((void *)0), "pciide", DV_DULL | |||
1418 | }; | |||
1419 | ||||
1420 | const struct pciide_product_desc *pciide_lookup_product(u_int32_t); | |||
1421 | ||||
1422 | const struct pciide_product_desc * | |||
1423 | pciide_lookup_product(u_int32_t id) | |||
1424 | { | |||
1425 | const struct pciide_product_desc *pp; | |||
1426 | const struct pciide_vendor_desc *vp; | |||
1427 | int i; | |||
1428 | ||||
1429 | for (i = 0, vp = pciide_vendors; i < nitems(pciide_vendors)(sizeof((pciide_vendors)) / sizeof((pciide_vendors)[0])); vp++, i++) | |||
1430 | if (PCI_VENDOR(id)(((id) >> 0) & 0xffff) == vp->ide_vendor) | |||
1431 | break; | |||
1432 | ||||
1433 | if (i == nitems(pciide_vendors)(sizeof((pciide_vendors)) / sizeof((pciide_vendors)[0]))) | |||
1434 | return (NULL((void *)0)); | |||
1435 | ||||
1436 | for (pp = vp->ide_products, i = 0; i < vp->ide_nproducts; pp++, i++) | |||
1437 | if (PCI_PRODUCT(id)(((id) >> 16) & 0xffff) == pp->ide_product) | |||
1438 | break; | |||
1439 | ||||
1440 | if (i == vp->ide_nproducts) | |||
1441 | return (NULL((void *)0)); | |||
1442 | return (pp); | |||
1443 | } | |||
1444 | ||||
1445 | int | |||
1446 | pciide_match(struct device *parent, void *match, void *aux) | |||
1447 | { | |||
1448 | struct pci_attach_args *pa = aux; | |||
1449 | const struct pciide_product_desc *pp; | |||
1450 | ||||
1451 | /* | |||
1452 | * Some IDE controllers have severe bugs when used in PCI mode. | |||
1453 | * We punt and attach them to the ISA bus instead. | |||
1454 | */ | |||
1455 | if (PCI_VENDOR(pa->pa_id)(((pa->pa_id) >> 0) & 0xffff) == PCI_VENDOR_PCTECH0x1042 && | |||
1456 | PCI_PRODUCT(pa->pa_id)(((pa->pa_id) >> 16) & 0xffff) == PCI_PRODUCT_PCTECH_RZ10000x1000) | |||
1457 | return (0); | |||
1458 | ||||
1459 | /* | |||
1460 | * Some controllers (e.g. promise Ultra-33) don't claim to be PCI IDE | |||
1461 | * controllers. Let see if we can deal with it anyway. | |||
1462 | */ | |||
1463 | pp = pciide_lookup_product(pa->pa_id); | |||
1464 | if (pp && (pp->ide_flags & IDE_PCI_CLASS_OVERRIDE0x0001)) | |||
1465 | return (1); | |||
1466 | ||||
1467 | /* | |||
1468 | * Check the ID register to see that it's a PCI IDE controller. | |||
1469 | * If it is, we assume that we can deal with it; it _should_ | |||
1470 | * work in a standardized way... | |||
1471 | */ | |||
1472 | if (PCI_CLASS(pa->pa_class)(((pa->pa_class) >> 24) & 0xff) == PCI_CLASS_MASS_STORAGE0x01) { | |||
1473 | switch (PCI_SUBCLASS(pa->pa_class)(((pa->pa_class) >> 16) & 0xff)) { | |||
1474 | case PCI_SUBCLASS_MASS_STORAGE_IDE0x01: | |||
1475 | return (1); | |||
1476 | ||||
1477 | /* | |||
1478 | * We only match these if we know they have | |||
1479 | * a match, as we may not support native interfaces | |||
1480 | * on them. | |||
1481 | */ | |||
1482 | case PCI_SUBCLASS_MASS_STORAGE_SATA0x06: | |||
1483 | case PCI_SUBCLASS_MASS_STORAGE_RAID0x04: | |||
1484 | case PCI_SUBCLASS_MASS_STORAGE_MISC0x80: | |||
1485 | if (pp) | |||
1486 | return (1); | |||
1487 | else | |||
1488 | return (0); | |||
1489 | break; | |||
1490 | } | |||
1491 | } | |||
1492 | ||||
1493 | return (0); | |||
1494 | } | |||
1495 | ||||
1496 | void | |||
1497 | pciide_attach(struct device *parent, struct device *self, void *aux) | |||
1498 | { | |||
1499 | struct pciide_softc *sc = (struct pciide_softc *)self; | |||
1500 | struct pci_attach_args *pa = aux; | |||
1501 | ||||
1502 | sc->sc_pp = pciide_lookup_product(pa->pa_id); | |||
1503 | if (sc->sc_pp == NULL((void *)0)) | |||
1504 | sc->sc_pp = &default_product_desc; | |||
1505 | sc->sc_rev = PCI_REVISION(pa->pa_class)(((pa->pa_class) >> 0) & 0xff); | |||
1506 | ||||
1507 | sc->sc_pc = pa->pa_pc; | |||
1508 | sc->sc_tag = pa->pa_tag; | |||
1509 | ||||
1510 | /* Set up DMA defaults; these might be adjusted by chip_map. */ | |||
1511 | sc->sc_dma_maxsegsz = IDEDMA_BYTE_COUNT_MAX0x00010000; | |||
1512 | sc->sc_dma_boundary = IDEDMA_BYTE_COUNT_ALIGN0x00010000; | |||
1513 | ||||
1514 | sc->sc_dmacmd_read = pciide_dmacmd_read; | |||
1515 | sc->sc_dmacmd_write = pciide_dmacmd_write; | |||
1516 | sc->sc_dmactl_read = pciide_dmactl_read; | |||
1517 | sc->sc_dmactl_write = pciide_dmactl_write; | |||
1518 | sc->sc_dmatbl_write = pciide_dmatbl_write; | |||
1519 | ||||
1520 | WDCDEBUG_PRINT((" sc_pc=%p, sc_tag=0x%x, pa_class=0x%x\n", sc->sc_pc, | |||
1521 | (u_int32_t)sc->sc_tag, pa->pa_class), DEBUG_PROBE); | |||
1522 | ||||
1523 | if (pciide_skip_ata) | |||
1524 | sc->sc_wdcdev.quirks |= WDC_QUIRK_NOATA0x0002; | |||
1525 | if (pciide_skip_atapi) | |||
1526 | sc->sc_wdcdev.quirks |= WDC_QUIRK_NOATAPI0x0004; | |||
1527 | ||||
1528 | sc->sc_pp->chip_map(sc, pa); | |||
1529 | ||||
1530 | WDCDEBUG_PRINT(("pciide: command/status register=0x%x\n", | |||
1531 | pci_conf_read(sc->sc_pc, sc->sc_tag, PCI_COMMAND_STATUS_REG)), | |||
1532 | DEBUG_PROBE); | |||
1533 | } | |||
1534 | ||||
1535 | int | |||
1536 | pciide_detach(struct device *self, int flags) | |||
1537 | { | |||
1538 | struct pciide_softc *sc = (struct pciide_softc *)self; | |||
1539 | if (sc->chip_unmap == NULL((void *)0)) | |||
1540 | panic("unmap not yet implemented for this chipset"); | |||
1541 | else | |||
1542 | sc->chip_unmap(sc, flags); | |||
1543 | ||||
1544 | return 0; | |||
1545 | } | |||
1546 | ||||
1547 | int | |||
1548 | pciide_activate(struct device *self, int act) | |||
1549 | { | |||
1550 | int rv = 0; | |||
1551 | struct pciide_softc *sc = (struct pciide_softc *)self; | |||
1552 | int i; | |||
1553 | ||||
1554 | switch (act) { | |||
1555 | case DVACT_SUSPEND3: | |||
1556 | rv = config_activate_children(self, act); | |||
1557 | ||||
1558 | for (i = 0; i < nitems(sc->sc_save)(sizeof((sc->sc_save)) / sizeof((sc->sc_save)[0])); i++) | |||
1559 | sc->sc_save[i] = pci_conf_read(sc->sc_pc, | |||
1560 | sc->sc_tag, PCI_MAPREG_END0x28 + 0x18 + (i * 4)); | |||
1561 | ||||
1562 | if (sc->sc_pp->chip_map == sch_chip_map) { | |||
1563 | sc->sc_save2[0] = pci_conf_read(sc->sc_pc, | |||
1564 | sc->sc_tag, SCH_D0TIM0x80); | |||
1565 | sc->sc_save2[1] = pci_conf_read(sc->sc_pc, | |||
1566 | sc->sc_tag, SCH_D1TIM0x84); | |||
1567 | } else if (sc->sc_pp->chip_map == piixsata_chip_map) { | |||
1568 | sc->sc_save2[0] = pciide_pci_read(sc->sc_pc, | |||
1569 | sc->sc_tag, ICH5_SATA_MAP0x90); | |||
1570 | sc->sc_save2[1] = pciide_pci_read(sc->sc_pc, | |||
1571 | sc->sc_tag, ICH5_SATA_PI0x09); | |||
1572 | sc->sc_save2[2] = pciide_pci_read(sc->sc_pc, | |||
1573 | sc->sc_tag, ICH_SATA_PCS0x92); | |||
1574 | } else if (sc->sc_pp->chip_map == sii3112_chip_map) { | |||
1575 | sc->sc_save2[0] = pci_conf_read(sc->sc_pc, | |||
1576 | sc->sc_tag, SII3112_SCS_CMD0x88); | |||
1577 | sc->sc_save2[1] = pci_conf_read(sc->sc_pc, | |||
1578 | sc->sc_tag, SII3112_PCI_CFGCTL0x40); | |||
1579 | } else if (sc->sc_pp->chip_map == ite_chip_map) { | |||
1580 | sc->sc_save2[0] = pci_conf_read(sc->sc_pc, | |||
1581 | sc->sc_tag, IT_TIM(0)((0) ? 0x58 : 0x54)); | |||
1582 | } else if (sc->sc_pp->chip_map == nforce_chip_map) { | |||
1583 | sc->sc_save2[0] = pci_conf_read(sc->sc_pc, | |||
1584 | sc->sc_tag, NFORCE_PIODMATIM0x58); | |||
1585 | sc->sc_save2[1] = pci_conf_read(sc->sc_pc, | |||
1586 | sc->sc_tag, NFORCE_PIOTIM0x5c); | |||
1587 | sc->sc_save2[2] = pci_conf_read(sc->sc_pc, | |||
1588 | sc->sc_tag, NFORCE_UDMATIM0x60); | |||
1589 | } | |||
1590 | break; | |||
1591 | case DVACT_RESUME4: | |||
1592 | for (i = 0; i < nitems(sc->sc_save)(sizeof((sc->sc_save)) / sizeof((sc->sc_save)[0])); i++) | |||
1593 | pci_conf_write(sc->sc_pc, sc->sc_tag, | |||
1594 | PCI_MAPREG_END0x28 + 0x18 + (i * 4), | |||
1595 | sc->sc_save[i]); | |||
1596 | ||||
1597 | if (sc->sc_pp->chip_map == default_chip_map || | |||
1598 | sc->sc_pp->chip_map == sata_chip_map || | |||
1599 | sc->sc_pp->chip_map == piix_chip_map || | |||
1600 | sc->sc_pp->chip_map == amd756_chip_map || | |||
1601 | sc->sc_pp->chip_map == phison_chip_map || | |||
1602 | sc->sc_pp->chip_map == rdc_chip_map || | |||
1603 | sc->sc_pp->chip_map == ixp_chip_map || | |||
1604 | sc->sc_pp->chip_map == acard_chip_map || | |||
1605 | sc->sc_pp->chip_map == apollo_chip_map || | |||
1606 | sc->sc_pp->chip_map == sis_chip_map) { | |||
1607 | /* nothing to restore -- uses only 0x40 - 0x56 */ | |||
1608 | } else if (sc->sc_pp->chip_map == sch_chip_map) { | |||
1609 | pci_conf_write(sc->sc_pc, sc->sc_tag, | |||
1610 | SCH_D0TIM0x80, sc->sc_save2[0]); | |||
1611 | pci_conf_write(sc->sc_pc, sc->sc_tag, | |||
1612 | SCH_D1TIM0x84, sc->sc_save2[1]); | |||
1613 | } else if (sc->sc_pp->chip_map == piixsata_chip_map) { | |||
1614 | pciide_pci_write(sc->sc_pc, sc->sc_tag, | |||
1615 | ICH5_SATA_MAP0x90, sc->sc_save2[0]); | |||
1616 | pciide_pci_write(sc->sc_pc, sc->sc_tag, | |||
1617 | ICH5_SATA_PI0x09, sc->sc_save2[1]); | |||
1618 | pciide_pci_write(sc->sc_pc, sc->sc_tag, | |||
1619 | ICH_SATA_PCS0x92, sc->sc_save2[2]); | |||
1620 | } else if (sc->sc_pp->chip_map == sii3112_chip_map) { | |||
1621 | pci_conf_write(sc->sc_pc, sc->sc_tag, | |||
1622 | SII3112_SCS_CMD0x88, sc->sc_save2[0]); | |||
1623 | delay(50 * 1000)(*delay_func)(50 * 1000); | |||
1624 | pci_conf_write(sc->sc_pc, sc->sc_tag, | |||
1625 | SII3112_PCI_CFGCTL0x40, sc->sc_save2[1]); | |||
1626 | delay(50 * 1000)(*delay_func)(50 * 1000); | |||
1627 | } else if (sc->sc_pp->chip_map == ite_chip_map) { | |||
1628 | pci_conf_write(sc->sc_pc, sc->sc_tag, | |||
1629 | IT_TIM(0)((0) ? 0x58 : 0x54), sc->sc_save2[0]); | |||
1630 | } else if (sc->sc_pp->chip_map == nforce_chip_map) { | |||
1631 | pci_conf_write(sc->sc_pc, sc->sc_tag, | |||
1632 | NFORCE_PIODMATIM0x58, sc->sc_save2[0]); | |||
1633 | pci_conf_write(sc->sc_pc, sc->sc_tag, | |||
1634 | NFORCE_PIOTIM0x5c, sc->sc_save2[1]); | |||
1635 | pci_conf_write(sc->sc_pc, sc->sc_tag, | |||
1636 | NFORCE_UDMATIM0x60, sc->sc_save2[2]); | |||
1637 | } else { | |||
1638 | printf("%s: restore for unknown chip map %x\n", | |||
1639 | sc->sc_wdcdev.sc_dev.dv_xname, | |||
1640 | sc->sc_pp->ide_product); | |||
1641 | } | |||
1642 | ||||
1643 | rv = config_activate_children(self, act); | |||
1644 | break; | |||
1645 | default: | |||
1646 | rv = config_activate_children(self, act); | |||
1647 | break; | |||
1648 | } | |||
1649 | return (rv); | |||
1650 | } | |||
1651 | ||||
1652 | int | |||
1653 | pciide_mapregs_compat(struct pci_attach_args *pa, struct pciide_channel *cp, | |||
1654 | int compatchan, bus_size_t *cmdsizep, bus_size_t *ctlsizep) | |||
1655 | { | |||
1656 | struct pciide_softc *sc = (struct pciide_softc *)cp->wdc_channel.wdc; | |||
1657 | struct channel_softc *wdc_cp = &cp->wdc_channel; | |||
1658 | pcireg_t csr; | |||
1659 | ||||
1660 | cp->compat = 1; | |||
1661 | *cmdsizep = PCIIDE_COMPAT_CMD_SIZE8; | |||
1662 | *ctlsizep = PCIIDE_COMPAT_CTL_SIZE1; | |||
1663 | ||||
1664 | csr = pci_conf_read(sc->sc_pc, sc->sc_tag, PCI_COMMAND_STATUS_REG0x04); | |||
1665 | pci_conf_write(sc->sc_pc, sc->sc_tag, PCI_COMMAND_STATUS_REG0x04, | |||
1666 | csr | PCI_COMMAND_IO_ENABLE0x00000001 | PCI_COMMAND_MASTER_ENABLE0x00000004); | |||
1667 | ||||
1668 | wdc_cp->cmd_iot = pa->pa_iot; | |||
1669 | ||||
1670 | if (bus_space_map(wdc_cp->cmd_iot, PCIIDE_COMPAT_CMD_BASE(compatchan)((compatchan) == 0 ? 0x1f0 : 0x170), | |||
1671 | PCIIDE_COMPAT_CMD_SIZE8, 0, &wdc_cp->cmd_ioh) != 0) { | |||
1672 | printf("%s: couldn't map %s cmd regs\n", | |||
1673 | sc->sc_wdcdev.sc_dev.dv_xname, cp->name); | |||
1674 | return (0); | |||
1675 | } | |||
1676 | ||||
1677 | wdc_cp->ctl_iot = pa->pa_iot; | |||
1678 | ||||
1679 | if (bus_space_map(wdc_cp->ctl_iot, PCIIDE_COMPAT_CTL_BASE(compatchan)((compatchan) == 0 ? 0x3f6 : 0x376), | |||
1680 | PCIIDE_COMPAT_CTL_SIZE1, 0, &wdc_cp->ctl_ioh) != 0) { | |||
1681 | printf("%s: couldn't map %s ctl regs\n", | |||
1682 | sc->sc_wdcdev.sc_dev.dv_xname, cp->name); | |||
1683 | bus_space_unmap(wdc_cp->cmd_iot, wdc_cp->cmd_ioh, | |||
1684 | PCIIDE_COMPAT_CMD_SIZE8); | |||
1685 | return (0); | |||
1686 | } | |||
1687 | wdc_cp->cmd_iosz = *cmdsizep; | |||
1688 | wdc_cp->ctl_iosz = *ctlsizep; | |||
1689 | ||||
1690 | return (1); | |||
1691 | } | |||
1692 | ||||
1693 | int | |||
1694 | pciide_unmapregs_compat(struct pciide_softc *sc, struct pciide_channel *cp) | |||
1695 | { | |||
1696 | struct channel_softc *wdc_cp = &cp->wdc_channel; | |||
1697 | ||||
1698 | bus_space_unmap(wdc_cp->cmd_iot, wdc_cp->cmd_ioh, wdc_cp->cmd_iosz); | |||
1699 | bus_space_unmap(wdc_cp->ctl_iot, wdc_cp->cmd_ioh, wdc_cp->ctl_iosz); | |||
1700 | ||||
1701 | if (sc->sc_pci_ih != NULL((void *)0)) { | |||
1702 | pciide_machdep_compat_intr_disestablish(sc->sc_pc, sc->sc_pci_ih); | |||
1703 | sc->sc_pci_ih = NULL((void *)0); | |||
1704 | } | |||
1705 | ||||
1706 | return (0); | |||
1707 | } | |||
1708 | ||||
1709 | int | |||
1710 | pciide_mapregs_native(struct pci_attach_args *pa, struct pciide_channel *cp, | |||
1711 | bus_size_t *cmdsizep, bus_size_t *ctlsizep, int (*pci_intr)(void *)) | |||
1712 | { | |||
1713 | struct pciide_softc *sc = (struct pciide_softc *)cp->wdc_channel.wdc; | |||
1714 | struct channel_softc *wdc_cp = &cp->wdc_channel; | |||
1715 | const char *intrstr; | |||
1716 | pci_intr_handle_t intrhandle; | |||
1717 | pcireg_t maptype; | |||
1718 | ||||
1719 | cp->compat = 0; | |||
1720 | ||||
1721 | if (sc->sc_pci_ih == NULL((void *)0)) { | |||
1722 | if (pci_intr_map(pa, &intrhandle) != 0) { | |||
1723 | printf("%s: couldn't map native-PCI interrupt\n", | |||
1724 | sc->sc_wdcdev.sc_dev.dv_xname); | |||
1725 | return (0); | |||
1726 | } | |||
1727 | intrstr = pci_intr_string(pa->pa_pc, intrhandle); | |||
1728 | sc->sc_pci_ih = pci_intr_establish(pa->pa_pc, | |||
1729 | intrhandle, IPL_BIO0x3, pci_intr, sc, | |||
1730 | sc->sc_wdcdev.sc_dev.dv_xname); | |||
1731 | if (sc->sc_pci_ih != NULL((void *)0)) { | |||
1732 | printf("%s: using %s for native-PCI interrupt\n", | |||
1733 | sc->sc_wdcdev.sc_dev.dv_xname, | |||
1734 | intrstr ? intrstr : "unknown interrupt"); | |||
1735 | } else { | |||
1736 | printf("%s: couldn't establish native-PCI interrupt", | |||
1737 | sc->sc_wdcdev.sc_dev.dv_xname); | |||
1738 | if (intrstr != NULL((void *)0)) | |||
1739 | printf(" at %s", intrstr); | |||
1740 | printf("\n"); | |||
1741 | return (0); | |||
1742 | } | |||
1743 | } | |||
1744 | cp->ih = sc->sc_pci_ih; | |||
1745 | sc->sc_pc = pa->pa_pc; | |||
1746 | ||||
1747 | maptype = pci_mapreg_type(pa->pa_pc, pa->pa_tag, | |||
1748 | PCIIDE_REG_CMD_BASE(wdc_cp->channel)(0x10 + (8 * (wdc_cp->channel)))); | |||
1749 | WDCDEBUG_PRINT(("%s: %s cmd regs mapping: %s\n", | |||
1750 | sc->sc_wdcdev.sc_dev.dv_xname, cp->name, | |||
1751 | (maptype == PCI_MAPREG_TYPE_IO ? "I/O" : "memory")), DEBUG_PROBE); | |||
1752 | if (pci_mapreg_map(pa, PCIIDE_REG_CMD_BASE(wdc_cp->channel)(0x10 + (8 * (wdc_cp->channel))), | |||
1753 | maptype, 0, | |||
1754 | &wdc_cp->cmd_iot, &wdc_cp->cmd_ioh, NULL((void *)0), cmdsizep, 0) != 0) { | |||
1755 | printf("%s: couldn't map %s cmd regs\n", | |||
1756 | sc->sc_wdcdev.sc_dev.dv_xname, cp->name); | |||
1757 | return (0); | |||
1758 | } | |||
1759 | ||||
1760 | maptype = pci_mapreg_type(pa->pa_pc, pa->pa_tag, | |||
1761 | PCIIDE_REG_CTL_BASE(wdc_cp->channel)(0x14 + (8 * (wdc_cp->channel)))); | |||
1762 | WDCDEBUG_PRINT(("%s: %s ctl regs mapping: %s\n", | |||
1763 | sc->sc_wdcdev.sc_dev.dv_xname, cp->name, | |||
1764 | (maptype == PCI_MAPREG_TYPE_IO ? "I/O": "memory")), DEBUG_PROBE); | |||
1765 | if (pci_mapreg_map(pa, PCIIDE_REG_CTL_BASE(wdc_cp->channel)(0x14 + (8 * (wdc_cp->channel))), | |||
1766 | maptype, 0, | |||
1767 | &wdc_cp->ctl_iot, &cp->ctl_baseioh, NULL((void *)0), ctlsizep, 0) != 0) { | |||
1768 | printf("%s: couldn't map %s ctl regs\n", | |||
1769 | sc->sc_wdcdev.sc_dev.dv_xname, cp->name); | |||
1770 | bus_space_unmap(wdc_cp->cmd_iot, wdc_cp->cmd_ioh, *cmdsizep); | |||
1771 | return (0); | |||
1772 | } | |||
1773 | /* | |||
1774 | * In native mode, 4 bytes of I/O space are mapped for the control | |||
1775 | * register, the control register is at offset 2. Pass the generic | |||
1776 | * code a handle for only one byte at the right offset. | |||
1777 | */ | |||
1778 | if (bus_space_subregion(wdc_cp->ctl_iot, cp->ctl_baseioh, 2, 1, | |||
1779 | &wdc_cp->ctl_ioh) != 0) { | |||
1780 | printf("%s: unable to subregion %s ctl regs\n", | |||
1781 | sc->sc_wdcdev.sc_dev.dv_xname, cp->name); | |||
1782 | bus_space_unmap(wdc_cp->cmd_iot, wdc_cp->cmd_ioh, *cmdsizep); | |||
1783 | bus_space_unmap(wdc_cp->cmd_iot, cp->ctl_baseioh, *ctlsizep); | |||
1784 | return (0); | |||
1785 | } | |||
1786 | wdc_cp->cmd_iosz = *cmdsizep; | |||
1787 | wdc_cp->ctl_iosz = *ctlsizep; | |||
1788 | ||||
1789 | return (1); | |||
1790 | } | |||
1791 | ||||
1792 | int | |||
1793 | pciide_unmapregs_native(struct pciide_softc *sc, struct pciide_channel *cp) | |||
1794 | { | |||
1795 | struct channel_softc *wdc_cp = &cp->wdc_channel; | |||
1796 | ||||
1797 | bus_space_unmap(wdc_cp->cmd_iot, wdc_cp->cmd_ioh, wdc_cp->cmd_iosz); | |||
1798 | ||||
1799 | /* Unmap the whole control space, not just the sub-region */ | |||
1800 | bus_space_unmap(wdc_cp->ctl_iot, cp->ctl_baseioh, wdc_cp->ctl_iosz); | |||
1801 | ||||
1802 | if (sc->sc_pci_ih != NULL((void *)0)) { | |||
1803 | pci_intr_disestablish(sc->sc_pc, sc->sc_pci_ih); | |||
1804 | sc->sc_pci_ih = NULL((void *)0); | |||
1805 | } | |||
1806 | ||||
1807 | return (0); | |||
1808 | } | |||
1809 | ||||
1810 | void | |||
1811 | pciide_mapreg_dma(struct pciide_softc *sc, struct pci_attach_args *pa) | |||
1812 | { | |||
1813 | pcireg_t maptype; | |||
1814 | bus_addr_t addr; | |||
1815 | ||||
1816 | /* | |||
1817 | * Map DMA registers | |||
1818 | * | |||
1819 | * Note that sc_dma_ok is the right variable to test to see if | |||
1820 | * DMA can be done. If the interface doesn't support DMA, | |||
1821 | * sc_dma_ok will never be non-zero. If the DMA regs couldn't | |||
1822 | * be mapped, it'll be zero. I.e., sc_dma_ok will only be | |||
1823 | * non-zero if the interface supports DMA and the registers | |||
1824 | * could be mapped. | |||
1825 | * | |||
1826 | * XXX Note that despite the fact that the Bus Master IDE specs | |||
1827 | * XXX say that "The bus master IDE function uses 16 bytes of IO | |||
1828 | * XXX space", some controllers (at least the United | |||
1829 | * XXX Microelectronics UM8886BF) place it in memory space. | |||
1830 | */ | |||
1831 | ||||
1832 | maptype = pci_mapreg_type(pa->pa_pc, pa->pa_tag, | |||
1833 | PCIIDE_REG_BUS_MASTER_DMA0x20); | |||
1834 | ||||
1835 | switch (maptype) { | |||
1836 | case PCI_MAPREG_TYPE_IO0x00000001: | |||
1837 | sc->sc_dma_ok = (pci_mapreg_info(pa->pa_pc, pa->pa_tag, | |||
1838 | PCIIDE_REG_BUS_MASTER_DMA0x20, PCI_MAPREG_TYPE_IO0x00000001, | |||
1839 | &addr, NULL((void *)0), NULL((void *)0)) == 0); | |||
1840 | if (sc->sc_dma_ok == 0) { | |||
1841 | printf(", unused (couldn't query registers)"); | |||
1842 | break; | |||
1843 | } | |||
1844 | if ((sc->sc_pp->ide_flags & IDE_16BIT_IOSPACE0x0002) | |||
1845 | && addr >= 0x10000) { | |||
1846 | sc->sc_dma_ok = 0; | |||
1847 | printf(", unused (registers at unsafe address %#lx)", addr); | |||
1848 | break; | |||
1849 | } | |||
1850 | /* FALLTHROUGH */ | |||
1851 | ||||
1852 | case PCI_MAPREG_MEM_TYPE_32BIT0x00000000: | |||
1853 | sc->sc_dma_ok = (pci_mapreg_map(pa, | |||
1854 | PCIIDE_REG_BUS_MASTER_DMA0x20, maptype, 0, | |||
1855 | &sc->sc_dma_iot, &sc->sc_dma_ioh, NULL((void *)0), &sc->sc_dma_iosz, | |||
1856 | 0) == 0); | |||
1857 | sc->sc_dmat = pa->pa_dmat; | |||
1858 | if (sc->sc_dma_ok == 0) { | |||
1859 | printf(", unused (couldn't map registers)"); | |||
1860 | } else { | |||
1861 | sc->sc_wdcdev.dma_arg = sc; | |||
1862 | sc->sc_wdcdev.dma_init = pciide_dma_init; | |||
1863 | sc->sc_wdcdev.dma_start = pciide_dma_start; | |||
1864 | sc->sc_wdcdev.dma_finish = pciide_dma_finish; | |||
1865 | } | |||
1866 | break; | |||
1867 | ||||
1868 | default: | |||
1869 | sc->sc_dma_ok = 0; | |||
1870 | printf(", (unsupported maptype 0x%x)", maptype); | |||
1871 | break; | |||
1872 | } | |||
1873 | } | |||
1874 | ||||
1875 | void | |||
1876 | pciide_unmapreg_dma(struct pciide_softc *sc) | |||
1877 | { | |||
1878 | bus_space_unmap(sc->sc_dma_iot, sc->sc_dma_ioh, sc->sc_dma_iosz); | |||
1879 | } | |||
1880 | ||||
1881 | int | |||
1882 | pciide_intr_flag(struct pciide_channel *cp) | |||
1883 | { | |||
1884 | struct pciide_softc *sc = (struct pciide_softc *)cp->wdc_channel.wdc; | |||
1885 | int chan = cp->wdc_channel.channel; | |||
1886 | ||||
1887 | if (cp->dma_in_progress) { | |||
1888 | int retry = 10; | |||
1889 | int status; | |||
1890 | ||||
1891 | /* Check the status register */ | |||
1892 | for (retry = 10; retry > 0; retry--) { | |||
1893 | status = PCIIDE_DMACTL_READ(sc, chan)(sc)->sc_dmactl_read((sc), (chan)); | |||
1894 | if (status & IDEDMA_CTL_INTR0x04) { | |||
1895 | break; | |||
1896 | } | |||
1897 | DELAY(5)(*delay_func)(5); | |||
1898 | } | |||
1899 | ||||
1900 | /* Not for us. */ | |||
1901 | if (retry == 0) | |||
1902 | return (0); | |||
1903 | ||||
1904 | return (1); | |||
1905 | } | |||
1906 | ||||
1907 | return (-1); | |||
1908 | } | |||
1909 | ||||
1910 | int | |||
1911 | pciide_compat_intr(void *arg) | |||
1912 | { | |||
1913 | struct pciide_channel *cp = arg; | |||
1914 | ||||
1915 | if (pciide_intr_flag(cp) == 0) | |||
1916 | return (0); | |||
1917 | ||||
1918 | #ifdef DIAGNOSTIC1 | |||
1919 | /* should only be called for a compat channel */ | |||
1920 | if (cp->compat == 0) | |||
1921 | panic("pciide compat intr called for non-compat chan %p", cp); | |||
1922 | #endif | |||
1923 | return (wdcintr(&cp->wdc_channel)); | |||
1924 | } | |||
1925 | ||||
1926 | int | |||
1927 | pciide_pci_intr(void *arg) | |||
1928 | { | |||
1929 | struct pciide_softc *sc = arg; | |||
1930 | struct pciide_channel *cp; | |||
1931 | struct channel_softc *wdc_cp; | |||
1932 | int i, rv, crv; | |||
1933 | ||||
1934 | rv = 0; | |||
1935 | for (i = 0; i < sc->sc_wdcdev.nchannels; i++) { | |||
1936 | cp = &sc->pciide_channels[i]; | |||
1937 | wdc_cp = &cp->wdc_channel; | |||
1938 | ||||
1939 | /* If a compat channel skip. */ | |||
1940 | if (cp->compat) | |||
1941 | continue; | |||
1942 | ||||
1943 | if (cp->hw_ok == 0) | |||
1944 | continue; | |||
1945 | ||||
1946 | if (pciide_intr_flag(cp) == 0) | |||
1947 | continue; | |||
1948 | ||||
1949 | crv = wdcintr(wdc_cp); | |||
1950 | if (crv == 0) | |||
1951 | ; /* leave rv alone */ | |||
1952 | else if (crv == 1) | |||
1953 | rv = 1; /* claim the intr */ | |||
1954 | else if (rv == 0) /* crv should be -1 in this case */ | |||
1955 | rv = crv; /* if we've done no better, take it */ | |||
1956 | } | |||
1957 | return (rv); | |||
1958 | } | |||
1959 | ||||
1960 | u_int8_t | |||
1961 | pciide_dmacmd_read(struct pciide_softc *sc, int chan) | |||
1962 | { | |||
1963 | return (bus_space_read_1(sc->sc_dma_iot, sc->sc_dma_ioh,((sc->sc_dma_iot)->read_1((sc->sc_dma_ioh), ((0x00 + 0x08 * (chan))))) | |||
1964 | IDEDMA_CMD(chan))((sc->sc_dma_iot)->read_1((sc->sc_dma_ioh), ((0x00 + 0x08 * (chan)))))); | |||
1965 | } | |||
1966 | ||||
1967 | void | |||
1968 | pciide_dmacmd_write(struct pciide_softc *sc, int chan, u_int8_t val) | |||
1969 | { | |||
1970 | bus_space_write_1(sc->sc_dma_iot, sc->sc_dma_ioh,((sc->sc_dma_iot)->write_1((sc->sc_dma_ioh), ((0x00 + 0x08 * (chan))), (val))) | |||
1971 | IDEDMA_CMD(chan), val)((sc->sc_dma_iot)->write_1((sc->sc_dma_ioh), ((0x00 + 0x08 * (chan))), (val))); | |||
1972 | } | |||
1973 | ||||
1974 | u_int8_t | |||
1975 | pciide_dmactl_read(struct pciide_softc *sc, int chan) | |||
1976 | { | |||
1977 | return (bus_space_read_1(sc->sc_dma_iot, sc->sc_dma_ioh,((sc->sc_dma_iot)->read_1((sc->sc_dma_ioh), ((0x02 + 0x08 * (chan))))) | |||
1978 | IDEDMA_CTL(chan))((sc->sc_dma_iot)->read_1((sc->sc_dma_ioh), ((0x02 + 0x08 * (chan)))))); | |||
1979 | } | |||
1980 | ||||
1981 | void | |||
1982 | pciide_dmactl_write(struct pciide_softc *sc, int chan, u_int8_t val) | |||
1983 | { | |||
1984 | bus_space_write_1(sc->sc_dma_iot, sc->sc_dma_ioh,((sc->sc_dma_iot)->write_1((sc->sc_dma_ioh), ((0x02 + 0x08 * (chan))), (val))) | |||
1985 | IDEDMA_CTL(chan), val)((sc->sc_dma_iot)->write_1((sc->sc_dma_ioh), ((0x02 + 0x08 * (chan))), (val))); | |||
1986 | } | |||
1987 | ||||
1988 | void | |||
1989 | pciide_dmatbl_write(struct pciide_softc *sc, int chan, u_int32_t val) | |||
1990 | { | |||
1991 | bus_space_write_4(sc->sc_dma_iot, sc->sc_dma_ioh,((sc->sc_dma_iot)->write_4((sc->sc_dma_ioh), ((0x04 + 0x08 * (chan))), (val))) | |||
1992 | IDEDMA_TBL(chan), val)((sc->sc_dma_iot)->write_4((sc->sc_dma_ioh), ((0x04 + 0x08 * (chan))), (val))); | |||
1993 | } | |||
1994 | ||||
1995 | void | |||
1996 | pciide_channel_dma_setup(struct pciide_channel *cp) | |||
1997 | { | |||
1998 | int drive; | |||
1999 | struct pciide_softc *sc = (struct pciide_softc *)cp->wdc_channel.wdc; | |||
2000 | struct ata_drive_datas *drvp; | |||
2001 | ||||
2002 | for (drive = 0; drive < 2; drive++) { | |||
2003 | drvp = &cp->wdc_channel.ch_drive[drive]; | |||
2004 | /* If no drive, skip */ | |||
2005 | if ((drvp->drive_flags & DRIVE(0x0001|0x0002|0x0004)) == 0) | |||
2006 | continue; | |||
2007 | /* setup DMA if needed */ | |||
2008 | if (((drvp->drive_flags & DRIVE_DMA0x0010) == 0 && | |||
2009 | (drvp->drive_flags & DRIVE_UDMA0x0020) == 0) || | |||
2010 | sc->sc_dma_ok == 0) { | |||
2011 | drvp->drive_flags &= ~(DRIVE_DMA0x0010 | DRIVE_UDMA0x0020); | |||
2012 | continue; | |||
2013 | } | |||
2014 | if (pciide_dma_table_setup(sc, cp->wdc_channel.channel, drive) | |||
2015 | != 0) { | |||
2016 | /* Abort DMA setup */ | |||
2017 | drvp->drive_flags &= ~(DRIVE_DMA0x0010 | DRIVE_UDMA0x0020); | |||
2018 | continue; | |||
2019 | } | |||
2020 | } | |||
2021 | } | |||
2022 | ||||
2023 | int | |||
2024 | pciide_dma_table_setup(struct pciide_softc *sc, int channel, int drive) | |||
2025 | { | |||
2026 | bus_dma_segment_t seg; | |||
2027 | int error, rseg; | |||
2028 | const bus_size_t dma_table_size = | |||
2029 | sizeof(struct idedma_table) * NIDEDMA_TABLES((64 * 1024)/(1 << 12) + 1); | |||
2030 | struct pciide_dma_maps *dma_maps = | |||
2031 | &sc->pciide_channels[channel].dma_maps[drive]; | |||
2032 | ||||
2033 | /* If table was already allocated, just return */ | |||
2034 | if (dma_maps->dma_table) | |||
2035 | return (0); | |||
2036 | ||||
2037 | /* Allocate memory for the DMA tables and map it */ | |||
2038 | if ((error = bus_dmamem_alloc(sc->sc_dmat, dma_table_size,(*(sc->sc_dmat)->_dmamem_alloc)((sc->sc_dmat), (dma_table_size ), (0x00010000), (0x00010000), (&seg), (1), (&rseg), ( 0x0001)) | |||
2039 | IDEDMA_TBL_ALIGN, IDEDMA_TBL_ALIGN, &seg, 1, &rseg,(*(sc->sc_dmat)->_dmamem_alloc)((sc->sc_dmat), (dma_table_size ), (0x00010000), (0x00010000), (&seg), (1), (&rseg), ( 0x0001)) | |||
2040 | BUS_DMA_NOWAIT)(*(sc->sc_dmat)->_dmamem_alloc)((sc->sc_dmat), (dma_table_size ), (0x00010000), (0x00010000), (&seg), (1), (&rseg), ( 0x0001))) != 0) { | |||
2041 | printf("%s:%d: unable to allocate table DMA for " | |||
2042 | "drive %d, error=%d\n", sc->sc_wdcdev.sc_dev.dv_xname, | |||
2043 | channel, drive, error); | |||
2044 | return (error); | |||
2045 | } | |||
2046 | ||||
2047 | if ((error = bus_dmamem_map(sc->sc_dmat, &seg, rseg,(*(sc->sc_dmat)->_dmamem_map)((sc->sc_dmat), (&seg ), (rseg), (dma_table_size), ((caddr_t *)&dma_maps->dma_table ), (0x0001|0x0004)) | |||
2048 | dma_table_size,(*(sc->sc_dmat)->_dmamem_map)((sc->sc_dmat), (&seg ), (rseg), (dma_table_size), ((caddr_t *)&dma_maps->dma_table ), (0x0001|0x0004)) | |||
2049 | (caddr_t *)&dma_maps->dma_table,(*(sc->sc_dmat)->_dmamem_map)((sc->sc_dmat), (&seg ), (rseg), (dma_table_size), ((caddr_t *)&dma_maps->dma_table ), (0x0001|0x0004)) | |||
2050 | BUS_DMA_NOWAIT|BUS_DMA_COHERENT)(*(sc->sc_dmat)->_dmamem_map)((sc->sc_dmat), (&seg ), (rseg), (dma_table_size), ((caddr_t *)&dma_maps->dma_table ), (0x0001|0x0004))) != 0) { | |||
2051 | printf("%s:%d: unable to map table DMA for" | |||
2052 | "drive %d, error=%d\n", sc->sc_wdcdev.sc_dev.dv_xname, | |||
2053 | channel, drive, error); | |||
2054 | return (error); | |||
2055 | } | |||
2056 | ||||
2057 | WDCDEBUG_PRINT(("pciide_dma_table_setup: table at %p len %ld, " | |||
2058 | "phy 0x%lx\n", dma_maps->dma_table, dma_table_size, | |||
2059 | seg.ds_addr), DEBUG_PROBE); | |||
2060 | ||||
2061 | /* Create and load table DMA map for this disk */ | |||
2062 | if ((error = bus_dmamap_create(sc->sc_dmat, dma_table_size,(*(sc->sc_dmat)->_dmamap_create)((sc->sc_dmat), (dma_table_size ), (1), (dma_table_size), (0x00010000), (0x0001), (&dma_maps ->dmamap_table)) | |||
2063 | 1, dma_table_size, IDEDMA_TBL_ALIGN, BUS_DMA_NOWAIT,(*(sc->sc_dmat)->_dmamap_create)((sc->sc_dmat), (dma_table_size ), (1), (dma_table_size), (0x00010000), (0x0001), (&dma_maps ->dmamap_table)) | |||
2064 | &dma_maps->dmamap_table)(*(sc->sc_dmat)->_dmamap_create)((sc->sc_dmat), (dma_table_size ), (1), (dma_table_size), (0x00010000), (0x0001), (&dma_maps ->dmamap_table))) != 0) { | |||
2065 | printf("%s:%d: unable to create table DMA map for " | |||
2066 | "drive %d, error=%d\n", sc->sc_wdcdev.sc_dev.dv_xname, | |||
2067 | channel, drive, error); | |||
2068 | return (error); | |||
2069 | } | |||
2070 | if ((error = bus_dmamap_load(sc->sc_dmat,(*(sc->sc_dmat)->_dmamap_load)((sc->sc_dmat), (dma_maps ->dmamap_table), (dma_maps->dma_table), (dma_table_size ), (((void *)0)), (0x0001)) | |||
2071 | dma_maps->dmamap_table,(*(sc->sc_dmat)->_dmamap_load)((sc->sc_dmat), (dma_maps ->dmamap_table), (dma_maps->dma_table), (dma_table_size ), (((void *)0)), (0x0001)) | |||
2072 | dma_maps->dma_table,(*(sc->sc_dmat)->_dmamap_load)((sc->sc_dmat), (dma_maps ->dmamap_table), (dma_maps->dma_table), (dma_table_size ), (((void *)0)), (0x0001)) | |||
2073 | dma_table_size, NULL, BUS_DMA_NOWAIT)(*(sc->sc_dmat)->_dmamap_load)((sc->sc_dmat), (dma_maps ->dmamap_table), (dma_maps->dma_table), (dma_table_size ), (((void *)0)), (0x0001))) != 0) { | |||
2074 | printf("%s:%d: unable to load table DMA map for " | |||
2075 | "drive %d, error=%d\n", sc->sc_wdcdev.sc_dev.dv_xname, | |||
2076 | channel, drive, error); | |||
2077 | return (error); | |||
2078 | } | |||
2079 | WDCDEBUG_PRINT(("pciide_dma_table_setup: phy addr of table 0x%lx\n", | |||
2080 | dma_maps->dmamap_table->dm_segs[0].ds_addr), DEBUG_PROBE); | |||
2081 | /* Create a xfer DMA map for this drive */ | |||
2082 | if ((error = bus_dmamap_create(sc->sc_dmat, IDEDMA_BYTE_COUNT_MAX,(*(sc->sc_dmat)->_dmamap_create)((sc->sc_dmat), (0x00010000 ), (((64 * 1024)/(1 << 12) + 1)), (sc->sc_dma_maxsegsz ), (sc->sc_dma_boundary), (0x0001 | 0x0002), (&dma_maps ->dmamap_xfer)) | |||
2083 | NIDEDMA_TABLES, sc->sc_dma_maxsegsz, sc->sc_dma_boundary,(*(sc->sc_dmat)->_dmamap_create)((sc->sc_dmat), (0x00010000 ), (((64 * 1024)/(1 << 12) + 1)), (sc->sc_dma_maxsegsz ), (sc->sc_dma_boundary), (0x0001 | 0x0002), (&dma_maps ->dmamap_xfer)) | |||
2084 | BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW,(*(sc->sc_dmat)->_dmamap_create)((sc->sc_dmat), (0x00010000 ), (((64 * 1024)/(1 << 12) + 1)), (sc->sc_dma_maxsegsz ), (sc->sc_dma_boundary), (0x0001 | 0x0002), (&dma_maps ->dmamap_xfer)) | |||
2085 | &dma_maps->dmamap_xfer)(*(sc->sc_dmat)->_dmamap_create)((sc->sc_dmat), (0x00010000 ), (((64 * 1024)/(1 << 12) + 1)), (sc->sc_dma_maxsegsz ), (sc->sc_dma_boundary), (0x0001 | 0x0002), (&dma_maps ->dmamap_xfer))) != 0) { | |||
2086 | printf("%s:%d: unable to create xfer DMA map for " | |||
2087 | "drive %d, error=%d\n", sc->sc_wdcdev.sc_dev.dv_xname, | |||
2088 | channel, drive, error); | |||
2089 | return (error); | |||
2090 | } | |||
2091 | return (0); | |||
2092 | } | |||
2093 | ||||
2094 | int | |||
2095 | pciide_dma_init(void *v, int channel, int drive, void *databuf, | |||
2096 | size_t datalen, int flags) | |||
2097 | { | |||
2098 | struct pciide_softc *sc = v; | |||
2099 | int error, seg; | |||
2100 | struct pciide_channel *cp = &sc->pciide_channels[channel]; | |||
2101 | struct pciide_dma_maps *dma_maps = | |||
2102 | &sc->pciide_channels[channel].dma_maps[drive]; | |||
2103 | #ifndef BUS_DMA_RAW0 | |||
2104 | #define BUS_DMA_RAW0 0 | |||
2105 | #endif | |||
2106 | ||||
2107 | error = bus_dmamap_load(sc->sc_dmat,(*(sc->sc_dmat)->_dmamap_load)((sc->sc_dmat), (dma_maps ->dmamap_xfer), (databuf), (datalen), (((void *)0)), (0x0001 |0)) | |||
2108 | dma_maps->dmamap_xfer,(*(sc->sc_dmat)->_dmamap_load)((sc->sc_dmat), (dma_maps ->dmamap_xfer), (databuf), (datalen), (((void *)0)), (0x0001 |0)) | |||
2109 | databuf, datalen, NULL, BUS_DMA_NOWAIT|BUS_DMA_RAW)(*(sc->sc_dmat)->_dmamap_load)((sc->sc_dmat), (dma_maps ->dmamap_xfer), (databuf), (datalen), (((void *)0)), (0x0001 |0)); | |||
2110 | if (error) { | |||
2111 | printf("%s:%d: unable to load xfer DMA map for " | |||
2112 | "drive %d, error=%d\n", sc->sc_wdcdev.sc_dev.dv_xname, | |||
2113 | channel, drive, error); | |||
2114 | return (error); | |||
2115 | } | |||
2116 | ||||
2117 | bus_dmamap_sync(sc->sc_dmat, dma_maps->dmamap_xfer, 0,(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (dma_maps ->dmamap_xfer), (0), (dma_maps->dmamap_xfer->dm_mapsize ), ((flags & 0x01) ? 0x01 : 0x04)) | |||
2118 | dma_maps->dmamap_xfer->dm_mapsize,(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (dma_maps ->dmamap_xfer), (0), (dma_maps->dmamap_xfer->dm_mapsize ), ((flags & 0x01) ? 0x01 : 0x04)) | |||
2119 | (flags & WDC_DMA_READ) ?(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (dma_maps ->dmamap_xfer), (0), (dma_maps->dmamap_xfer->dm_mapsize ), ((flags & 0x01) ? 0x01 : 0x04)) | |||
2120 | BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE)(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (dma_maps ->dmamap_xfer), (0), (dma_maps->dmamap_xfer->dm_mapsize ), ((flags & 0x01) ? 0x01 : 0x04)); | |||
2121 | ||||
2122 | for (seg = 0; seg < dma_maps->dmamap_xfer->dm_nsegs; seg++) { | |||
2123 | #ifdef DIAGNOSTIC1 | |||
2124 | /* A segment must not cross a 64k boundary */ | |||
2125 | { | |||
2126 | u_long phys = dma_maps->dmamap_xfer->dm_segs[seg].ds_addr; | |||
2127 | u_long len = dma_maps->dmamap_xfer->dm_segs[seg].ds_len; | |||
2128 | if ((phys & ~IDEDMA_BYTE_COUNT_MASK0x0000FFFF) != | |||
2129 | ((phys + len - 1) & ~IDEDMA_BYTE_COUNT_MASK0x0000FFFF)) { | |||
2130 | printf("pciide_dma: segment %d physical addr 0x%lx" | |||
2131 | " len 0x%lx not properly aligned\n", | |||
2132 | seg, phys, len); | |||
2133 | panic("pciide_dma: buf align"); | |||
2134 | } | |||
2135 | } | |||
2136 | #endif | |||
2137 | dma_maps->dma_table[seg].base_addr = | |||
2138 | htole32(dma_maps->dmamap_xfer->dm_segs[seg].ds_addr)((__uint32_t)(dma_maps->dmamap_xfer->dm_segs[seg].ds_addr )); | |||
2139 | dma_maps->dma_table[seg].byte_count = | |||
2140 | htole32(dma_maps->dmamap_xfer->dm_segs[seg].ds_len &((__uint32_t)(dma_maps->dmamap_xfer->dm_segs[seg].ds_len & 0x0000FFFF)) | |||
2141 | IDEDMA_BYTE_COUNT_MASK)((__uint32_t)(dma_maps->dmamap_xfer->dm_segs[seg].ds_len & 0x0000FFFF)); | |||
2142 | WDCDEBUG_PRINT(("\t seg %d len %d addr 0x%x\n", | |||
2143 | seg, letoh32(dma_maps->dma_table[seg].byte_count), | |||
2144 | letoh32(dma_maps->dma_table[seg].base_addr)), DEBUG_DMA); | |||
2145 | ||||
2146 | } | |||
2147 | dma_maps->dma_table[dma_maps->dmamap_xfer->dm_nsegs -1].byte_count |= | |||
2148 | htole32(IDEDMA_BYTE_COUNT_EOT)((__uint32_t)(0x80000000)); | |||
2149 | ||||
2150 | bus_dmamap_sync(sc->sc_dmat, dma_maps->dmamap_table, 0,(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (dma_maps ->dmamap_table), (0), (dma_maps->dmamap_table->dm_mapsize ), (0x04)) | |||
2151 | dma_maps->dmamap_table->dm_mapsize,(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (dma_maps ->dmamap_table), (0), (dma_maps->dmamap_table->dm_mapsize ), (0x04)) | |||
2152 | BUS_DMASYNC_PREWRITE)(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (dma_maps ->dmamap_table), (0), (dma_maps->dmamap_table->dm_mapsize ), (0x04)); | |||
2153 | ||||
2154 | /* Maps are ready. Start DMA function */ | |||
2155 | #ifdef DIAGNOSTIC1 | |||
2156 | if (dma_maps->dmamap_table->dm_segs[0].ds_addr & ~IDEDMA_TBL_MASK0xfffffffc) { | |||
2157 | printf("pciide_dma_init: addr 0x%lx not properly aligned\n", | |||
2158 | dma_maps->dmamap_table->dm_segs[0].ds_addr); | |||
2159 | panic("pciide_dma_init: table align"); | |||
2160 | } | |||
2161 | #endif | |||
2162 | ||||
2163 | /* Clear status bits */ | |||
2164 | PCIIDE_DMACTL_WRITE(sc, channel, PCIIDE_DMACTL_READ(sc, channel))(sc)->sc_dmactl_write((sc), (channel), ((sc)->sc_dmactl_read ((sc), (channel)))); | |||
2165 | /* Write table addr */ | |||
2166 | PCIIDE_DMATBL_WRITE(sc, channel,(sc)->sc_dmatbl_write((sc), (channel), (dma_maps->dmamap_table ->dm_segs[0].ds_addr)) | |||
2167 | dma_maps->dmamap_table->dm_segs[0].ds_addr)(sc)->sc_dmatbl_write((sc), (channel), (dma_maps->dmamap_table ->dm_segs[0].ds_addr)); | |||
2168 | /* set read/write */ | |||
2169 | PCIIDE_DMACMD_WRITE(sc, channel,(sc)->sc_dmacmd_write((sc), (channel), (((flags & 0x01 ) ? 0x08 : 0) | cp->idedma_cmd)) | |||
2170 | ((flags & WDC_DMA_READ) ? IDEDMA_CMD_WRITE : 0) | cp->idedma_cmd)(sc)->sc_dmacmd_write((sc), (channel), (((flags & 0x01 ) ? 0x08 : 0) | cp->idedma_cmd)); | |||
2171 | /* remember flags */ | |||
2172 | dma_maps->dma_flags = flags; | |||
2173 | return (0); | |||
2174 | } | |||
2175 | ||||
2176 | void | |||
2177 | pciide_dma_start(void *v, int channel, int drive) | |||
2178 | { | |||
2179 | struct pciide_softc *sc = v; | |||
2180 | ||||
2181 | WDCDEBUG_PRINT(("pciide_dma_start\n"), DEBUG_XFERS); | |||
2182 | PCIIDE_DMACMD_WRITE(sc, channel, PCIIDE_DMACMD_READ(sc, channel) |(sc)->sc_dmacmd_write((sc), (channel), ((sc)->sc_dmacmd_read ((sc), (channel)) | 0x01)) | |||
2183 | IDEDMA_CMD_START)(sc)->sc_dmacmd_write((sc), (channel), ((sc)->sc_dmacmd_read ((sc), (channel)) | 0x01)); | |||
2184 | ||||
2185 | sc->pciide_channels[channel].dma_in_progress = 1; | |||
2186 | } | |||
2187 | ||||
2188 | int | |||
2189 | pciide_dma_finish(void *v, int channel, int drive, int force) | |||
2190 | { | |||
2191 | struct pciide_softc *sc = v; | |||
2192 | struct pciide_channel *cp = &sc->pciide_channels[channel]; | |||
2193 | u_int8_t status; | |||
2194 | int error = 0; | |||
2195 | struct pciide_dma_maps *dma_maps = | |||
2196 | &sc->pciide_channels[channel].dma_maps[drive]; | |||
2197 | ||||
2198 | status = PCIIDE_DMACTL_READ(sc, channel)(sc)->sc_dmactl_read((sc), (channel)); | |||
2199 | WDCDEBUG_PRINT(("pciide_dma_finish: status 0x%x\n", status), | |||
2200 | DEBUG_XFERS); | |||
2201 | if (status == 0xff) | |||
2202 | return (status); | |||
2203 | ||||
2204 | if (force == 0 && (status & IDEDMA_CTL_INTR0x04) == 0) { | |||
2205 | error = WDC_DMAST_NOIRQ0x01; | |||
2206 | goto done; | |||
2207 | } | |||
2208 | ||||
2209 | /* stop DMA channel */ | |||
2210 | PCIIDE_DMACMD_WRITE(sc, channel,(sc)->sc_dmacmd_write((sc), (channel), (((dma_maps->dma_flags & 0x01) ? 0x00 : 0x08) | cp->idedma_cmd)) | |||
2211 | ((dma_maps->dma_flags & WDC_DMA_READ) ?(sc)->sc_dmacmd_write((sc), (channel), (((dma_maps->dma_flags & 0x01) ? 0x00 : 0x08) | cp->idedma_cmd)) | |||
2212 | 0x00 : IDEDMA_CMD_WRITE) | cp->idedma_cmd)(sc)->sc_dmacmd_write((sc), (channel), (((dma_maps->dma_flags & 0x01) ? 0x00 : 0x08) | cp->idedma_cmd)); | |||
2213 | ||||
2214 | /* Unload the map of the data buffer */ | |||
2215 | bus_dmamap_sync(sc->sc_dmat, dma_maps->dmamap_xfer, 0,(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (dma_maps ->dmamap_xfer), (0), (dma_maps->dmamap_xfer->dm_mapsize ), ((dma_maps->dma_flags & 0x01) ? 0x02 : 0x08)) | |||
2216 | dma_maps->dmamap_xfer->dm_mapsize,(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (dma_maps ->dmamap_xfer), (0), (dma_maps->dmamap_xfer->dm_mapsize ), ((dma_maps->dma_flags & 0x01) ? 0x02 : 0x08)) | |||
2217 | (dma_maps->dma_flags & WDC_DMA_READ) ?(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (dma_maps ->dmamap_xfer), (0), (dma_maps->dmamap_xfer->dm_mapsize ), ((dma_maps->dma_flags & 0x01) ? 0x02 : 0x08)) | |||
2218 | BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE)(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (dma_maps ->dmamap_xfer), (0), (dma_maps->dmamap_xfer->dm_mapsize ), ((dma_maps->dma_flags & 0x01) ? 0x02 : 0x08)); | |||
2219 | bus_dmamap_unload(sc->sc_dmat, dma_maps->dmamap_xfer)(*(sc->sc_dmat)->_dmamap_unload)((sc->sc_dmat), (dma_maps ->dmamap_xfer)); | |||
2220 | ||||
2221 | /* Clear status bits */ | |||
2222 | PCIIDE_DMACTL_WRITE(sc, channel, status)(sc)->sc_dmactl_write((sc), (channel), (status)); | |||
2223 | ||||
2224 | if ((status & IDEDMA_CTL_ERR0x02) != 0) { | |||
2225 | printf("%s:%d:%d: bus-master DMA error: status=0x%x\n", | |||
2226 | sc->sc_wdcdev.sc_dev.dv_xname, channel, drive, status); | |||
2227 | error |= WDC_DMAST_ERR0x02; | |||
2228 | } | |||
2229 | ||||
2230 | if ((status & IDEDMA_CTL_INTR0x04) == 0) { | |||
2231 | printf("%s:%d:%d: bus-master DMA error: missing interrupt, " | |||
2232 | "status=0x%x\n", sc->sc_wdcdev.sc_dev.dv_xname, channel, | |||
2233 | drive, status); | |||
2234 | error |= WDC_DMAST_NOIRQ0x01; | |||
2235 | } | |||
2236 | ||||
2237 | if ((status & IDEDMA_CTL_ACT0x01) != 0) { | |||
2238 | /* data underrun, may be a valid condition for ATAPI */ | |||
2239 | error |= WDC_DMAST_UNDER0x04; | |||
2240 | } | |||
2241 | ||||
2242 | done: | |||
2243 | sc->pciide_channels[channel].dma_in_progress = 0; | |||
2244 | return (error); | |||
2245 | } | |||
2246 | ||||
2247 | void | |||
2248 | pciide_irqack(struct channel_softc *chp) | |||
2249 | { | |||
2250 | struct pciide_channel *cp = (struct pciide_channel *)chp; | |||
2251 | struct pciide_softc *sc = (struct pciide_softc *)cp->wdc_channel.wdc; | |||
2252 | int chan = chp->channel; | |||
2253 | ||||
2254 | /* clear status bits in IDE DMA registers */ | |||
2255 | PCIIDE_DMACTL_WRITE(sc, chan, PCIIDE_DMACTL_READ(sc, chan))(sc)->sc_dmactl_write((sc), (chan), ((sc)->sc_dmactl_read ((sc), (chan)))); | |||
2256 | } | |||
2257 | ||||
2258 | /* some common code used by several chip_map */ | |||
2259 | int | |||
2260 | pciide_chansetup(struct pciide_softc *sc, int channel, pcireg_t interface) | |||
2261 | { | |||
2262 | struct pciide_channel *cp = &sc->pciide_channels[channel]; | |||
2263 | sc->wdc_chanarray[channel] = &cp->wdc_channel; | |||
2264 | cp->name = PCIIDE_CHANNEL_NAME(channel)((channel) == 0 ? "channel 0" : "channel 1"); | |||
2265 | cp->wdc_channel.channel = channel; | |||
2266 | cp->wdc_channel.wdc = &sc->sc_wdcdev; | |||
2267 | cp->wdc_channel.ch_queue = wdc_alloc_queue(); | |||
2268 | if (cp->wdc_channel.ch_queue == NULL((void *)0)) { | |||
2269 | printf("%s: %s " | |||
2270 | "cannot allocate channel queue", | |||
2271 | sc->sc_wdcdev.sc_dev.dv_xname, cp->name); | |||
2272 | return (0); | |||
2273 | } | |||
2274 | cp->hw_ok = 1; | |||
2275 | ||||
2276 | return (1); | |||
2277 | } | |||
2278 | ||||
2279 | void | |||
2280 | pciide_chanfree(struct pciide_softc *sc, int channel) | |||
2281 | { | |||
2282 | struct pciide_channel *cp = &sc->pciide_channels[channel]; | |||
2283 | if (cp->wdc_channel.ch_queue) | |||
2284 | wdc_free_queue(cp->wdc_channel.ch_queue); | |||
2285 | } | |||
2286 | ||||
2287 | /* some common code used by several chip channel_map */ | |||
2288 | void | |||
2289 | pciide_mapchan(struct pci_attach_args *pa, struct pciide_channel *cp, | |||
2290 | pcireg_t interface, bus_size_t *cmdsizep, bus_size_t *ctlsizep, | |||
2291 | int (*pci_intr)(void *)) | |||
2292 | { | |||
2293 | struct channel_softc *wdc_cp = &cp->wdc_channel; | |||
2294 | ||||
2295 | if (interface & PCIIDE_INTERFACE_PCI(wdc_cp->channel)(0x01 << (2 * (wdc_cp->channel)))) | |||
2296 | cp->hw_ok = pciide_mapregs_native(pa, cp, cmdsizep, ctlsizep, | |||
2297 | pci_intr); | |||
2298 | else | |||
2299 | cp->hw_ok = pciide_mapregs_compat(pa, cp, | |||
2300 | wdc_cp->channel, cmdsizep, ctlsizep); | |||
2301 | if (cp->hw_ok == 0) | |||
2302 | return; | |||
2303 | wdc_cp->data32iot = wdc_cp->cmd_iot; | |||
2304 | wdc_cp->data32ioh = wdc_cp->cmd_ioh; | |||
2305 | wdcattach(wdc_cp); | |||
2306 | } | |||
2307 | ||||
2308 | void | |||
2309 | pciide_unmap_chan(struct pciide_softc *sc, struct pciide_channel *cp, int flags) | |||
2310 | { | |||
2311 | struct channel_softc *wdc_cp = &cp->wdc_channel; | |||
2312 | ||||
2313 | wdcdetach(wdc_cp, flags); | |||
2314 | ||||
2315 | if (cp->compat != 0) | |||
2316 | pciide_unmapregs_compat(sc, cp); | |||
2317 | else | |||
2318 | pciide_unmapregs_native(sc, cp); | |||
2319 | } | |||
2320 | ||||
2321 | /* | |||
2322 | * Generic code to call to know if a channel can be disabled. Return 1 | |||
2323 | * if channel can be disabled, 0 if not | |||
2324 | */ | |||
2325 | int | |||
2326 | pciide_chan_candisable(struct pciide_channel *cp) | |||
2327 | { | |||
2328 | struct pciide_softc *sc = (struct pciide_softc *)cp->wdc_channel.wdc; | |||
2329 | struct channel_softc *wdc_cp = &cp->wdc_channel; | |||
2330 | ||||
2331 | if ((wdc_cp->ch_drive[0].drive_flags & DRIVE(0x0001|0x0002|0x0004)) == 0 && | |||
2332 | (wdc_cp->ch_drive[1].drive_flags & DRIVE(0x0001|0x0002|0x0004)) == 0) { | |||
2333 | printf("%s: %s disabled (no drives)\n", | |||
2334 | sc->sc_wdcdev.sc_dev.dv_xname, cp->name); | |||
2335 | cp->hw_ok = 0; | |||
2336 | return (1); | |||
2337 | } | |||
2338 | return (0); | |||
2339 | } | |||
2340 | ||||
2341 | /* | |||
2342 | * generic code to map the compat intr if hw_ok=1 and it is a compat channel. | |||
2343 | * Set hw_ok=0 on failure | |||
2344 | */ | |||
2345 | void | |||
2346 | pciide_map_compat_intr(struct pci_attach_args *pa, struct pciide_channel *cp, | |||
2347 | int compatchan, int interface) | |||
2348 | { | |||
2349 | struct pciide_softc *sc = (struct pciide_softc *)cp->wdc_channel.wdc; | |||
2350 | struct channel_softc *wdc_cp = &cp->wdc_channel; | |||
2351 | ||||
2352 | if ((interface & PCIIDE_INTERFACE_PCI(wdc_cp->channel)(0x01 << (2 * (wdc_cp->channel)))) != 0) | |||
2353 | return; | |||
2354 | ||||
2355 | cp->compat = 1; | |||
2356 | cp->ih = pciide_machdep_compat_intr_establish(&sc->sc_wdcdev.sc_dev, | |||
2357 | pa, compatchan, pciide_compat_intr, cp); | |||
2358 | if (cp->ih == NULL((void *)0)) { | |||
2359 | printf("%s: no compatibility interrupt for use by %s\n", | |||
2360 | sc->sc_wdcdev.sc_dev.dv_xname, cp->name); | |||
2361 | cp->hw_ok = 0; | |||
2362 | } | |||
2363 | } | |||
2364 | ||||
2365 | /* | |||
2366 | * generic code to unmap the compat intr if hw_ok=1 and it is a compat channel. | |||
2367 | * Set hw_ok=0 on failure | |||
2368 | */ | |||
2369 | void | |||
2370 | pciide_unmap_compat_intr(struct pci_attach_args *pa, struct pciide_channel *cp, | |||
2371 | int compatchan, int interface) | |||
2372 | { | |||
2373 | struct channel_softc *wdc_cp = &cp->wdc_channel; | |||
2374 | ||||
2375 | if ((interface & PCIIDE_INTERFACE_PCI(wdc_cp->channel)(0x01 << (2 * (wdc_cp->channel)))) != 0) | |||
2376 | return; | |||
2377 | ||||
2378 | pciide_machdep_compat_intr_disestablish(pa->pa_pc, cp->ih); | |||
2379 | } | |||
2380 | ||||
2381 | void | |||
2382 | pciide_print_channels(int nchannels, pcireg_t interface) | |||
2383 | { | |||
2384 | int i; | |||
2385 | ||||
2386 | for (i = 0; i < nchannels; i++) { | |||
2387 | printf(", %s %s to %s", PCIIDE_CHANNEL_NAME(i)((i) == 0 ? "channel 0" : "channel 1"), | |||
2388 | (interface & PCIIDE_INTERFACE_SETTABLE(i)(0x02 << (2 * (i)))) ? | |||
2389 | "configured" : "wired", | |||
2390 | (interface & PCIIDE_INTERFACE_PCI(i)(0x01 << (2 * (i)))) ? "native-PCI" : | |||
2391 | "compatibility"); | |||
2392 | } | |||
2393 | ||||
2394 | printf("\n"); | |||
2395 | } | |||
2396 | ||||
2397 | void | |||
2398 | pciide_print_modes(struct pciide_channel *cp) | |||
2399 | { | |||
2400 | wdc_print_current_modes(&cp->wdc_channel); | |||
2401 | } | |||
2402 | ||||
2403 | void | |||
2404 | default_chip_map(struct pciide_softc *sc, struct pci_attach_args *pa) | |||
2405 | { | |||
2406 | struct pciide_channel *cp; | |||
2407 | pcireg_t interface = PCI_INTERFACE(pa->pa_class)(((pa->pa_class) >> 8) & 0xff); | |||
2408 | pcireg_t csr; | |||
2409 | int channel, drive; | |||
2410 | struct ata_drive_datas *drvp; | |||
2411 | u_int8_t idedma_ctl; | |||
2412 | bus_size_t cmdsize, ctlsize; | |||
2413 | char *failreason; | |||
2414 | ||||
2415 | if (interface & PCIIDE_INTERFACE_BUS_MASTER_DMA0x80) { | |||
2416 | printf(": DMA"); | |||
2417 | if (sc->sc_pp == &default_product_desc && | |||
2418 | (sc->sc_wdcdev.sc_dev.dv_cfdata->cf_flags & | |||
2419 | PCIIDE_OPTIONS_DMA0x01) == 0) { | |||
2420 | printf(" (unsupported)"); | |||
2421 | sc->sc_dma_ok = 0; | |||
2422 | } else { | |||
2423 | pciide_mapreg_dma(sc, pa); | |||
2424 | if (sc->sc_dma_ok != 0) | |||
2425 | printf(", (partial support)"); | |||
2426 | } | |||
2427 | } else { | |||
2428 | printf(": no DMA"); | |||
2429 | sc->sc_dma_ok = 0; | |||
2430 | } | |||
2431 | if (sc->sc_dma_ok) { | |||
2432 | sc->sc_wdcdev.cap |= WDC_CAPABILITY_DMA0x0008 | WDC_CAPABILITY_IRQACK0x0400; | |||
2433 | sc->sc_wdcdev.irqack = pciide_irqack; | |||
2434 | } | |||
2435 | sc->sc_wdcdev.PIO_cap = 0; | |||
2436 | sc->sc_wdcdev.DMA_cap = 0; | |||
2437 | sc->sc_wdcdev.channels = sc->wdc_chanarray; | |||
2438 | sc->sc_wdcdev.nchannels = PCIIDE_NUM_CHANNELS2; | |||
2439 | sc->sc_wdcdev.cap |= WDC_CAPABILITY_DATA160x0001; | |||
2440 | ||||
2441 | pciide_print_channels(sc->sc_wdcdev.nchannels, interface); | |||
2442 | ||||
2443 | for (channel = 0; channel < sc->sc_wdcdev.nchannels; channel++) { | |||
2444 | cp = &sc->pciide_channels[channel]; | |||
2445 | if (pciide_chansetup(sc, channel, interface) == 0) | |||
2446 | continue; | |||
2447 | if (interface & PCIIDE_INTERFACE_PCI(channel)(0x01 << (2 * (channel)))) { | |||
2448 | cp->hw_ok = pciide_mapregs_native(pa, cp, &cmdsize, | |||
2449 | &ctlsize, pciide_pci_intr); | |||
2450 | } else { | |||
2451 | cp->hw_ok = pciide_mapregs_compat(pa, cp, | |||
2452 | channel, &cmdsize, &ctlsize); | |||
2453 | } | |||
2454 | if (cp->hw_ok == 0) | |||
2455 | continue; | |||
2456 | /* | |||
2457 | * Check to see if something appears to be there. | |||
2458 | */ | |||
2459 | failreason = NULL((void *)0); | |||
2460 | pciide_map_compat_intr(pa, cp, channel, interface); | |||
2461 | if (cp->hw_ok == 0) | |||
2462 | continue; | |||
2463 | if (!wdcprobe(&cp->wdc_channel)) { | |||
2464 | failreason = "not responding; disabled or no drives?"; | |||
2465 | goto next; | |||
2466 | } | |||
2467 | /* | |||
2468 | * Now, make sure it's actually attributable to this PCI IDE | |||
2469 | * channel by trying to access the channel again while the | |||
2470 | * PCI IDE controller's I/O space is disabled. (If the | |||
2471 | * channel no longer appears to be there, it belongs to | |||
2472 | * this controller.) YUCK! | |||
2473 | */ | |||
2474 | csr = pci_conf_read(sc->sc_pc, sc->sc_tag, | |||
2475 | PCI_COMMAND_STATUS_REG0x04); | |||
2476 | pci_conf_write(sc->sc_pc, sc->sc_tag, PCI_COMMAND_STATUS_REG0x04, | |||
2477 | csr & ~PCI_COMMAND_IO_ENABLE0x00000001); | |||
2478 | if (wdcprobe(&cp->wdc_channel)) | |||
2479 | failreason = "other hardware responding at addresses"; | |||
2480 | pci_conf_write(sc->sc_pc, sc->sc_tag, | |||
2481 | PCI_COMMAND_STATUS_REG0x04, csr); | |||
2482 | next: | |||
2483 | if (failreason) { | |||
2484 | printf("%s: %s ignored (%s)\n", | |||
2485 | sc->sc_wdcdev.sc_dev.dv_xname, cp->name, | |||
2486 | failreason); | |||
2487 | cp->hw_ok = 0; | |||
2488 | pciide_unmap_compat_intr(pa, cp, channel, interface); | |||
2489 | bus_space_unmap(cp->wdc_channel.cmd_iot, | |||
2490 | cp->wdc_channel.cmd_ioh, cmdsize); | |||
2491 | if (interface & PCIIDE_INTERFACE_PCI(channel)(0x01 << (2 * (channel)))) | |||
2492 | bus_space_unmap(cp->wdc_channel.ctl_iot, | |||
2493 | cp->ctl_baseioh, ctlsize); | |||
2494 | else | |||
2495 | bus_space_unmap(cp->wdc_channel.ctl_iot, | |||
2496 | cp->wdc_channel.ctl_ioh, ctlsize); | |||
2497 | } | |||
2498 | if (cp->hw_ok) { | |||
2499 | cp->wdc_channel.data32iot = cp->wdc_channel.cmd_iot; | |||
2500 | cp->wdc_channel.data32ioh = cp->wdc_channel.cmd_ioh; | |||
2501 | wdcattach(&cp->wdc_channel); | |||
2502 | } | |||
2503 | } | |||
2504 | ||||
2505 | if (sc->sc_dma_ok == 0) | |||
2506 | return; | |||
2507 | ||||
2508 | /* Allocate DMA maps */ | |||
2509 | for (channel = 0; channel < sc->sc_wdcdev.nchannels; channel++) { | |||
2510 | idedma_ctl = 0; | |||
2511 | cp = &sc->pciide_channels[channel]; | |||
2512 | for (drive = 0; drive < 2; drive++) { | |||
2513 | drvp = &cp->wdc_channel.ch_drive[drive]; | |||
2514 | /* If no drive, skip */ | |||
2515 | if ((drvp->drive_flags & DRIVE(0x0001|0x0002|0x0004)) == 0) | |||
2516 | continue; | |||
2517 | if ((drvp->drive_flags & DRIVE_DMA0x0010) == 0) | |||
2518 | continue; | |||
2519 | if (pciide_dma_table_setup(sc, channel, drive) != 0) { | |||
2520 | /* Abort DMA setup */ | |||
2521 | printf("%s:%d:%d: cannot allocate DMA maps, " | |||
2522 | "using PIO transfers\n", | |||
2523 | sc->sc_wdcdev.sc_dev.dv_xname, | |||
2524 | channel, drive); | |||
2525 | drvp->drive_flags &= ~DRIVE_DMA0x0010; | |||
2526 | } | |||
2527 | printf("%s:%d:%d: using DMA data transfers\n", | |||
2528 | sc->sc_wdcdev.sc_dev.dv_xname, | |||
2529 | channel, drive); | |||
2530 | idedma_ctl |= IDEDMA_CTL_DRV_DMA(drive)(0x20 << (drive)); | |||
2531 | } | |||
2532 | if (idedma_ctl != 0) { | |||
2533 | /* Add software bits in status register */ | |||
2534 | PCIIDE_DMACTL_WRITE(sc, channel, idedma_ctl)(sc)->sc_dmactl_write((sc), (channel), (idedma_ctl)); | |||
2535 | } | |||
2536 | } | |||
2537 | } | |||
2538 | ||||
2539 | void | |||
2540 | default_chip_unmap(struct pciide_softc *sc, int flags) | |||
2541 | { | |||
2542 | struct pciide_channel *cp; | |||
2543 | int channel; | |||
2544 | ||||
2545 | for (channel = 0; channel < sc->sc_wdcdev.nchannels; channel++) { | |||
2546 | cp = &sc->pciide_channels[channel]; | |||
2547 | pciide_unmap_chan(sc, cp, flags); | |||
2548 | pciide_chanfree(sc, channel); | |||
2549 | } | |||
2550 | ||||
2551 | pciide_unmapreg_dma(sc); | |||
2552 | ||||
2553 | if (sc->sc_cookie) | |||
2554 | free(sc->sc_cookie, M_DEVBUF2, sc->sc_cookielen); | |||
2555 | } | |||
2556 | ||||
2557 | void | |||
2558 | sata_chip_map(struct pciide_softc *sc, struct pci_attach_args *pa) | |||
2559 | { | |||
2560 | struct pciide_channel *cp; | |||
2561 | pcireg_t interface = PCI_INTERFACE(pa->pa_class)(((pa->pa_class) >> 8) & 0xff); | |||
2562 | int channel; | |||
2563 | bus_size_t cmdsize, ctlsize; | |||
2564 | ||||
2565 | if (interface == 0) { | |||
2566 | WDCDEBUG_PRINT(("sata_chip_map interface == 0\n"), | |||
2567 | DEBUG_PROBE); | |||
2568 | interface = PCIIDE_INTERFACE_BUS_MASTER_DMA0x80 | | |||
2569 | PCIIDE_INTERFACE_PCI(0)(0x01 << (2 * (0))) | PCIIDE_INTERFACE_PCI(1)(0x01 << (2 * (1))); | |||
2570 | } | |||
2571 | ||||
2572 | printf(": DMA"); | |||
2573 | pciide_mapreg_dma(sc, pa); | |||
2574 | printf("\n"); | |||
2575 | ||||
2576 | if (sc->sc_dma_ok) { | |||
2577 | sc->sc_wdcdev.cap |= WDC_CAPABILITY_UDMA0x0010 | | |||
2578 | WDC_CAPABILITY_DMA0x0008 | WDC_CAPABILITY_IRQACK0x0400; | |||
2579 | sc->sc_wdcdev.irqack = pciide_irqack; | |||
2580 | } | |||
2581 | sc->sc_wdcdev.PIO_cap = 4; | |||
2582 | sc->sc_wdcdev.DMA_cap = 2; | |||
2583 | sc->sc_wdcdev.UDMA_cap = 6; | |||
2584 | ||||
2585 | sc->sc_wdcdev.channels = sc->wdc_chanarray; | |||
2586 | sc->sc_wdcdev.nchannels = PCIIDE_NUM_CHANNELS2; | |||
2587 | sc->sc_wdcdev.cap |= WDC_CAPABILITY_DATA160x0001 | WDC_CAPABILITY_DATA320x0002 | | |||
2588 | WDC_CAPABILITY_MODE0x0004 | WDC_CAPABILITY_SATA0x2000; | |||
2589 | sc->sc_wdcdev.set_modes = sata_setup_channel; | |||
2590 | sc->chip_unmap = default_chip_unmap; | |||
2591 | ||||
2592 | for (channel = 0; channel < sc->sc_wdcdev.nchannels; channel++) { | |||
2593 | cp = &sc->pciide_channels[channel]; | |||
2594 | if (pciide_chansetup(sc, channel, interface) == 0) | |||
2595 | continue; | |||
2596 | pciide_mapchan(pa, cp, interface, &cmdsize, &ctlsize, | |||
2597 | pciide_pci_intr); | |||
2598 | sata_setup_channel(&cp->wdc_channel); | |||
2599 | } | |||
2600 | } | |||
2601 | ||||
2602 | void | |||
2603 | sata_setup_channel(struct channel_softc *chp) | |||
2604 | { | |||
2605 | struct ata_drive_datas *drvp; | |||
2606 | int drive; | |||
2607 | u_int32_t idedma_ctl; | |||
2608 | struct pciide_channel *cp = (struct pciide_channel *)chp; | |||
2609 | struct pciide_softc *sc = (struct pciide_softc *)cp->wdc_channel.wdc; | |||
2610 | ||||
2611 | /* setup DMA if needed */ | |||
2612 | pciide_channel_dma_setup(cp); | |||
2613 | ||||
2614 | idedma_ctl = 0; | |||
2615 | ||||
2616 | for (drive = 0; drive < 2; drive++) { | |||
2617 | drvp = &chp->ch_drive[drive]; | |||
2618 | /* If no drive, skip */ | |||
2619 | if ((drvp->drive_flags & DRIVE(0x0001|0x0002|0x0004)) == 0) | |||
2620 | continue; | |||
2621 | if (drvp->drive_flags & DRIVE_UDMA0x0020) { | |||
2622 | /* use Ultra/DMA */ | |||
2623 | drvp->drive_flags &= ~DRIVE_DMA0x0010; | |||
2624 | idedma_ctl |= IDEDMA_CTL_DRV_DMA(drive)(0x20 << (drive)); | |||
2625 | } else if (drvp->drive_flags & DRIVE_DMA0x0010) { | |||
2626 | idedma_ctl |= IDEDMA_CTL_DRV_DMA(drive)(0x20 << (drive)); | |||
2627 | } | |||
2628 | } | |||
2629 | ||||
2630 | /* | |||
2631 | * Nothing to do to setup modes; it is meaningless in S-ATA | |||
2632 | * (but many S-ATA drives still want to get the SET_FEATURE | |||
2633 | * command). | |||
2634 | */ | |||
2635 | if (idedma_ctl != 0) { | |||
2636 | /* Add software bits in status register */ | |||
2637 | PCIIDE_DMACTL_WRITE(sc, chp->channel, idedma_ctl)(sc)->sc_dmactl_write((sc), (chp->channel), (idedma_ctl )); | |||
2638 | } | |||
2639 | pciide_print_modes(cp); | |||
2640 | } | |||
2641 | ||||
2642 | void | |||
2643 | piix_timing_debug(struct pciide_softc *sc) | |||
2644 | { | |||
2645 | WDCDEBUG_PRINT(("piix_setup_chip: idetim=0x%x", | |||
2646 | pci_conf_read(sc->sc_pc, sc->sc_tag, PIIX_IDETIM)), | |||
2647 | DEBUG_PROBE); | |||
2648 | if (sc->sc_pp->ide_product != PCI_PRODUCT_INTEL_82371FB_IDE0x1230 && | |||
2649 | sc->sc_pp->ide_product != PCI_PRODUCT_INTEL_82371FB_ISA0x122e) { | |||
2650 | WDCDEBUG_PRINT((", sidetim=0x%x", | |||
2651 | pci_conf_read(sc->sc_pc, sc->sc_tag, PIIX_SIDETIM)), | |||
2652 | DEBUG_PROBE); | |||
2653 | if (sc->sc_wdcdev.cap & WDC_CAPABILITY_UDMA0x0010) { | |||
2654 | WDCDEBUG_PRINT((", udmareg 0x%x", | |||
2655 | pci_conf_read(sc->sc_pc, sc->sc_tag, PIIX_UDMAREG)), | |||
2656 | DEBUG_PROBE); | |||
2657 | } | |||
2658 | if (sc->sc_pp->ide_product == PCI_PRODUCT_INTEL_6300ESB_IDE0x25a2 || | |||
2659 | sc->sc_pp->ide_product == PCI_PRODUCT_INTEL_6321ESB_IDE0x269e || | |||
2660 | sc->sc_pp->ide_product == PCI_PRODUCT_INTEL_82801AA_IDE0x2411 || | |||
2661 | sc->sc_pp->ide_product == PCI_PRODUCT_INTEL_82801AB_IDE0x2421 || | |||
2662 | sc->sc_pp->ide_product == PCI_PRODUCT_INTEL_82801BAM_IDE0x244a || | |||
2663 | sc->sc_pp->ide_product == PCI_PRODUCT_INTEL_82801BA_IDE0x244b || | |||
2664 | sc->sc_pp->ide_product == PCI_PRODUCT_INTEL_82801CAM_IDE0x248a || | |||
2665 | sc->sc_pp->ide_product == PCI_PRODUCT_INTEL_82801CA_IDE0x248b || | |||
2666 | sc->sc_pp->ide_product == PCI_PRODUCT_INTEL_82801DB_IDE0x24cb || | |||
2667 | sc->sc_pp->ide_product == PCI_PRODUCT_INTEL_82801DBL_IDE0x24c1 || | |||
2668 | sc->sc_pp->ide_product == PCI_PRODUCT_INTEL_82801DBM_IDE0x24ca || | |||
2669 | sc->sc_pp->ide_product == PCI_PRODUCT_INTEL_82801EB_IDE0x24db || | |||
2670 | sc->sc_pp->ide_product == PCI_PRODUCT_INTEL_82801FB_IDE0x266f || | |||
2671 | sc->sc_pp->ide_product == PCI_PRODUCT_INTEL_82801GB_IDE0x27df || | |||
2672 | sc->sc_pp->ide_product == PCI_PRODUCT_INTEL_82801HBM_IDE0x2850 || | |||
2673 | sc->sc_pp->ide_product == PCI_PRODUCT_INTEL_82372FB_IDE0x7601) { | |||
2674 | WDCDEBUG_PRINT((", IDE_CONTROL 0x%x", | |||
2675 | pci_conf_read(sc->sc_pc, sc->sc_tag, PIIX_CONFIG)), | |||
2676 | DEBUG_PROBE); | |||
2677 | } | |||
2678 | } | |||
2679 | WDCDEBUG_PRINT(("\n"), DEBUG_PROBE); | |||
2680 | } | |||
2681 | ||||
2682 | void | |||
2683 | piix_chip_map(struct pciide_softc *sc, struct pci_attach_args *pa) | |||
2684 | { | |||
2685 | struct pciide_channel *cp; | |||
2686 | int channel; | |||
2687 | u_int32_t idetim; | |||
2688 | bus_size_t cmdsize, ctlsize; | |||
2689 | ||||
2690 | pcireg_t interface = PCI_INTERFACE(pa->pa_class)(((pa->pa_class) >> 8) & 0xff); | |||
2691 | ||||
2692 | printf(": DMA"); | |||
2693 | pciide_mapreg_dma(sc, pa); | |||
2694 | sc->sc_wdcdev.cap |= WDC_CAPABILITY_DATA160x0001 | WDC_CAPABILITY_DATA320x0002 | | |||
2695 | WDC_CAPABILITY_MODE0x0004; | |||
2696 | if (sc->sc_dma_ok) { | |||
2697 | sc->sc_wdcdev.cap |= WDC_CAPABILITY_DMA0x0008 | WDC_CAPABILITY_IRQACK0x0400; | |||
2698 | sc->sc_wdcdev.irqack = pciide_irqack; | |||
2699 | switch (sc->sc_pp->ide_product) { | |||
2700 | case PCI_PRODUCT_INTEL_6300ESB_IDE0x25a2: | |||
2701 | case PCI_PRODUCT_INTEL_6321ESB_IDE0x269e: | |||
2702 | case PCI_PRODUCT_INTEL_82371AB_IDE0x7111: | |||
2703 | case PCI_PRODUCT_INTEL_82372FB_IDE0x7601: | |||
2704 | case PCI_PRODUCT_INTEL_82440MX_IDE0x7199: | |||
2705 | case PCI_PRODUCT_INTEL_82451NX0x84ca: | |||
2706 | case PCI_PRODUCT_INTEL_82801AA_IDE0x2411: | |||
2707 | case PCI_PRODUCT_INTEL_82801AB_IDE0x2421: | |||
2708 | case PCI_PRODUCT_INTEL_82801BAM_IDE0x244a: | |||
2709 | case PCI_PRODUCT_INTEL_82801BA_IDE0x244b: | |||
2710 | case PCI_PRODUCT_INTEL_82801CAM_IDE0x248a: | |||
2711 | case PCI_PRODUCT_INTEL_82801CA_IDE0x248b: | |||
2712 | case PCI_PRODUCT_INTEL_82801DB_IDE0x24cb: | |||
2713 | case PCI_PRODUCT_INTEL_82801DBL_IDE0x24c1: | |||
2714 | case PCI_PRODUCT_INTEL_82801DBM_IDE0x24ca: | |||
2715 | case PCI_PRODUCT_INTEL_82801EB_IDE0x24db: | |||
2716 | case PCI_PRODUCT_INTEL_82801FB_IDE0x266f: | |||
2717 | case PCI_PRODUCT_INTEL_82801GB_IDE0x27df: | |||
2718 | case PCI_PRODUCT_INTEL_82801HBM_IDE0x2850: | |||
2719 | sc->sc_wdcdev.cap |= WDC_CAPABILITY_UDMA0x0010; | |||
2720 | break; | |||
2721 | } | |||
2722 | } | |||
2723 | sc->sc_wdcdev.PIO_cap = 4; | |||
2724 | sc->sc_wdcdev.DMA_cap = 2; | |||
2725 | switch (sc->sc_pp->ide_product) { | |||
2726 | case PCI_PRODUCT_INTEL_82801AA_IDE0x2411: | |||
2727 | case PCI_PRODUCT_INTEL_82372FB_IDE0x7601: | |||
2728 | sc->sc_wdcdev.UDMA_cap = 4; | |||
2729 | break; | |||
2730 | case PCI_PRODUCT_INTEL_6300ESB_IDE0x25a2: | |||
2731 | case PCI_PRODUCT_INTEL_6321ESB_IDE0x269e: | |||
2732 | case PCI_PRODUCT_INTEL_82801BAM_IDE0x244a: | |||
2733 | case PCI_PRODUCT_INTEL_82801BA_IDE0x244b: | |||
2734 | case PCI_PRODUCT_INTEL_82801CAM_IDE0x248a: | |||
2735 | case PCI_PRODUCT_INTEL_82801CA_IDE0x248b: | |||
2736 | case PCI_PRODUCT_INTEL_82801DB_IDE0x24cb: | |||
2737 | case PCI_PRODUCT_INTEL_82801DBL_IDE0x24c1: | |||
2738 | case PCI_PRODUCT_INTEL_82801DBM_IDE0x24ca: | |||
2739 | case PCI_PRODUCT_INTEL_82801EB_IDE0x24db: | |||
2740 | case PCI_PRODUCT_INTEL_82801FB_IDE0x266f: | |||
2741 | case PCI_PRODUCT_INTEL_82801GB_IDE0x27df: | |||
2742 | case PCI_PRODUCT_INTEL_82801HBM_IDE0x2850: | |||
2743 | sc->sc_wdcdev.UDMA_cap = 5; | |||
2744 | break; | |||
2745 | default: | |||
2746 | sc->sc_wdcdev.UDMA_cap = 2; | |||
2747 | break; | |||
2748 | } | |||
2749 | ||||
2750 | if (sc->sc_pp->ide_product == PCI_PRODUCT_INTEL_82371FB_IDE0x1230 || | |||
2751 | sc->sc_pp->ide_product == PCI_PRODUCT_INTEL_82371FB_ISA0x122e) { | |||
2752 | sc->sc_wdcdev.set_modes = piix_setup_channel; | |||
2753 | } else { | |||
2754 | sc->sc_wdcdev.set_modes = piix3_4_setup_channel; | |||
2755 | } | |||
2756 | sc->sc_wdcdev.channels = sc->wdc_chanarray; | |||
2757 | sc->sc_wdcdev.nchannels = PCIIDE_NUM_CHANNELS2; | |||
2758 | ||||
2759 | pciide_print_channels(sc->sc_wdcdev.nchannels, interface); | |||
2760 | ||||
2761 | piix_timing_debug(sc); | |||
2762 | ||||
2763 | for (channel = 0; channel < sc->sc_wdcdev.nchannels; channel++) { | |||
2764 | cp = &sc->pciide_channels[channel]; | |||
2765 | ||||
2766 | if (pciide_chansetup(sc, channel, interface) == 0) | |||
2767 | continue; | |||
2768 | idetim = pci_conf_read(sc->sc_pc, sc->sc_tag, PIIX_IDETIM0x40); | |||
2769 | if ((PIIX_IDETIM_READ(idetim, channel)(((idetim) >> (16 * (channel))) & 0x0000FFFF) & | |||
2770 | PIIX_IDETIM_IDE0x8000) == 0) { | |||
2771 | printf("%s: %s ignored (disabled)\n", | |||
2772 | sc->sc_wdcdev.sc_dev.dv_xname, cp->name); | |||
2773 | cp->hw_ok = 0; | |||
2774 | continue; | |||
2775 | } | |||
2776 | pciide_map_compat_intr(pa, cp, channel, interface); | |||
2777 | if (cp->hw_ok == 0) | |||
2778 | continue; | |||
2779 | pciide_mapchan(pa, cp, interface, &cmdsize, &ctlsize, | |||
2780 | pciide_pci_intr); | |||
2781 | if (cp->hw_ok == 0) | |||
2782 | goto next; | |||
2783 | if (pciide_chan_candisable(cp)) { | |||
2784 | idetim = PIIX_IDETIM_CLEAR(idetim, PIIX_IDETIM_IDE,((idetim) & ~((0x8000) << (16 * (channel)))) | |||
2785 | channel)((idetim) & ~((0x8000) << (16 * (channel)))); | |||
2786 | pci_conf_write(sc->sc_pc, sc->sc_tag, PIIX_IDETIM0x40, | |||
2787 | idetim); | |||
2788 | } | |||
2789 | if (cp->hw_ok == 0) | |||
2790 | goto next; | |||
2791 | sc->sc_wdcdev.set_modes(&cp->wdc_channel); | |||
2792 | next: | |||
2793 | if (cp->hw_ok == 0) | |||
2794 | pciide_unmap_compat_intr(pa, cp, channel, interface); | |||
2795 | } | |||
2796 | ||||
2797 | piix_timing_debug(sc); | |||
2798 | } | |||
2799 | ||||
2800 | void | |||
2801 | piixsata_chip_map(struct pciide_softc *sc, struct pci_attach_args *pa) | |||
2802 | { | |||
2803 | struct pciide_channel *cp; | |||
2804 | pcireg_t interface = PCI_INTERFACE(pa->pa_class)(((pa->pa_class) >> 8) & 0xff); | |||
2805 | int channel; | |||
2806 | bus_size_t cmdsize, ctlsize; | |||
2807 | u_int8_t reg, ich = 0; | |||
2808 | ||||
2809 | printf(": DMA"); | |||
2810 | pciide_mapreg_dma(sc, pa); | |||
2811 | ||||
2812 | if (sc->sc_dma_ok) { | |||
2813 | sc->sc_wdcdev.cap |= WDC_CAPABILITY_UDMA0x0010 | | |||
2814 | WDC_CAPABILITY_DMA0x0008 | WDC_CAPABILITY_IRQACK0x0400; | |||
2815 | sc->sc_wdcdev.irqack = pciide_irqack; | |||
2816 | sc->sc_wdcdev.DMA_cap = 2; | |||
2817 | sc->sc_wdcdev.UDMA_cap = 6; | |||
2818 | } | |||
2819 | sc->sc_wdcdev.PIO_cap = 4; | |||
2820 | ||||
2821 | sc->sc_wdcdev.channels = sc->wdc_chanarray; | |||
2822 | sc->sc_wdcdev.nchannels = PCIIDE_NUM_CHANNELS2; | |||
2823 | sc->sc_wdcdev.cap |= WDC_CAPABILITY_DATA160x0001 | WDC_CAPABILITY_DATA320x0002 | | |||
2824 | WDC_CAPABILITY_MODE0x0004 | WDC_CAPABILITY_SATA0x2000; | |||
2825 | sc->sc_wdcdev.set_modes = sata_setup_channel; | |||
2826 | ||||
2827 | switch(sc->sc_pp->ide_product) { | |||
2828 | case PCI_PRODUCT_INTEL_6300ESB_SATA0x25a3: | |||
2829 | case PCI_PRODUCT_INTEL_6300ESB_SATA20x25b0: | |||
2830 | case PCI_PRODUCT_INTEL_82801EB_SATA0x24d1: | |||
2831 | case PCI_PRODUCT_INTEL_82801ER_SATA0x24df: | |||
2832 | ich = 5; | |||
2833 | break; | |||
2834 | case PCI_PRODUCT_INTEL_82801FB_SATA0x2651: | |||
2835 | case PCI_PRODUCT_INTEL_82801FR_SATA0x2652: | |||
2836 | case PCI_PRODUCT_INTEL_82801FBM_SATA0x2653: | |||
2837 | ich = 6; | |||
2838 | break; | |||
2839 | default: | |||
2840 | ich = 7; | |||
2841 | break; | |||
2842 | } | |||
2843 | ||||
2844 | /* | |||
2845 | * Put the SATA portion of controllers that don't operate in combined | |||
2846 | * mode into native PCI modes so the maximum number of devices can be | |||
2847 | * used. Intel calls this "enhanced mode" | |||
2848 | */ | |||
2849 | if (ich == 5) { | |||
2850 | reg = pciide_pci_read(sc->sc_pc, sc->sc_tag, ICH5_SATA_MAP0x90); | |||
2851 | if ((reg & ICH5_SATA_MAP_COMBINED0x04) == 0) { | |||
2852 | reg = pciide_pci_read(pa->pa_pc, pa->pa_tag, | |||
2853 | ICH5_SATA_PI0x09); | |||
2854 | reg |= ICH5_SATA_PI_PRI_NATIVE0x01 | | |||
2855 | ICH5_SATA_PI_SEC_NATIVE0x04; | |||
2856 | pciide_pci_write(pa->pa_pc, pa->pa_tag, | |||
2857 | ICH5_SATA_PI0x09, reg); | |||
2858 | interface |= PCIIDE_INTERFACE_PCI(0)(0x01 << (2 * (0))) | | |||
2859 | PCIIDE_INTERFACE_PCI(1)(0x01 << (2 * (1))); | |||
2860 | } | |||
2861 | } else { | |||
2862 | reg = pciide_pci_read(sc->sc_pc, sc->sc_tag, ICH5_SATA_MAP0x90) & | |||
2863 | ICH6_SATA_MAP_CMB_MASK0x03; | |||
2864 | if (reg != ICH6_SATA_MAP_CMB_PRI0x01 && | |||
2865 | reg != ICH6_SATA_MAP_CMB_SEC0x02) { | |||
2866 | reg = pciide_pci_read(pa->pa_pc, pa->pa_tag, | |||
2867 | ICH5_SATA_PI0x09); | |||
2868 | reg |= ICH5_SATA_PI_PRI_NATIVE0x01 | | |||
2869 | ICH5_SATA_PI_SEC_NATIVE0x04; | |||
2870 | ||||
2871 | pciide_pci_write(pa->pa_pc, pa->pa_tag, | |||
2872 | ICH5_SATA_PI0x09, reg); | |||
2873 | interface |= PCIIDE_INTERFACE_PCI(0)(0x01 << (2 * (0))) | | |||
2874 | PCIIDE_INTERFACE_PCI(1)(0x01 << (2 * (1))); | |||
2875 | ||||
2876 | /* | |||
2877 | * Ask for SATA IDE Mode, we don't need to do this | |||
2878 | * for the combined mode case as combined mode is | |||
2879 | * only allowed in IDE Mode | |||
2880 | */ | |||
2881 | if (ich >= 7) { | |||
2882 | reg = pciide_pci_read(sc->sc_pc, sc->sc_tag, | |||
2883 | ICH5_SATA_MAP0x90) & ~ICH7_SATA_MAP_SMS_MASK0xc0; | |||
2884 | pciide_pci_write(pa->pa_pc, pa->pa_tag, | |||
2885 | ICH5_SATA_MAP0x90, reg); | |||
2886 | } | |||
2887 | } | |||
2888 | } | |||
2889 | ||||
2890 | pciide_print_channels(sc->sc_wdcdev.nchannels, interface); | |||
2891 | ||||
2892 | for (channel = 0; channel < sc->sc_wdcdev.nchannels; channel++) { | |||
2893 | cp = &sc->pciide_channels[channel]; | |||
2894 | if (pciide_chansetup(sc, channel, interface) == 0) | |||
2895 | continue; | |||
2896 | ||||
2897 | pciide_map_compat_intr(pa, cp, channel, interface); | |||
2898 | if (cp->hw_ok == 0) | |||
2899 | continue; | |||
2900 | ||||
2901 | pciide_mapchan(pa, cp, interface, &cmdsize, &ctlsize, | |||
2902 | pciide_pci_intr); | |||
2903 | if (cp->hw_ok != 0) | |||
2904 | sc->sc_wdcdev.set_modes(&cp->wdc_channel); | |||
2905 | ||||
2906 | if (cp->hw_ok == 0) | |||
2907 | pciide_unmap_compat_intr(pa, cp, channel, interface); | |||
2908 | } | |||
2909 | } | |||
2910 | ||||
2911 | void | |||
2912 | piix_setup_channel(struct channel_softc *chp) | |||
2913 | { | |||
2914 | u_int8_t mode[2], drive; | |||
2915 | u_int32_t oidetim, idetim, idedma_ctl; | |||
2916 | struct pciide_channel *cp = (struct pciide_channel *)chp; | |||
2917 | struct pciide_softc *sc = (struct pciide_softc *)cp->wdc_channel.wdc; | |||
2918 | struct ata_drive_datas *drvp = cp->wdc_channel.ch_drive; | |||
2919 | ||||
2920 | oidetim = pci_conf_read(sc->sc_pc, sc->sc_tag, PIIX_IDETIM0x40); | |||
2921 | idetim = PIIX_IDETIM_CLEAR(oidetim, 0xffff, chp->channel)((oidetim) & ~((0xffff) << (16 * (chp->channel)) )); | |||
2922 | idedma_ctl = 0; | |||
2923 | ||||
2924 | /* set up new idetim: Enable IDE registers decode */ | |||
2925 | idetim = PIIX_IDETIM_SET(idetim, PIIX_IDETIM_IDE,((idetim) | ((0x8000) << (16 * (chp->channel)))) | |||
2926 | chp->channel)((idetim) | ((0x8000) << (16 * (chp->channel)))); | |||
2927 | ||||
2928 | /* setup DMA */ | |||
2929 | pciide_channel_dma_setup(cp); | |||
2930 | ||||
2931 | /* | |||
2932 | * Here we have to mess up with drives mode: PIIX can't have | |||
2933 | * different timings for master and slave drives. | |||
2934 | * We need to find the best combination. | |||
2935 | */ | |||
2936 | ||||
2937 | /* If both drives supports DMA, take the lower mode */ | |||
2938 | if ((drvp[0].drive_flags & DRIVE_DMA0x0010) && | |||
2939 | (drvp[1].drive_flags & DRIVE_DMA0x0010)) { | |||
2940 | mode[0] = mode[1] = | |||
2941 | min(drvp[0].DMA_mode, drvp[1].DMA_mode); | |||
2942 | drvp[0].DMA_mode = mode[0]; | |||
2943 | drvp[1].DMA_mode = mode[1]; | |||
2944 | goto ok; | |||
2945 | } | |||
2946 | /* | |||
2947 | * If only one drive supports DMA, use its mode, and | |||
2948 | * put the other one in PIO mode 0 if mode not compatible | |||
2949 | */ | |||
2950 | if (drvp[0].drive_flags & DRIVE_DMA0x0010) { | |||
2951 | mode[0] = drvp[0].DMA_mode; | |||
2952 | mode[1] = drvp[1].PIO_mode; | |||
2953 | if (piix_isp_pio[mode[1]] != piix_isp_dma[mode[0]] || | |||
2954 | piix_rtc_pio[mode[1]] != piix_rtc_dma[mode[0]]) | |||
2955 | mode[1] = drvp[1].PIO_mode = 0; | |||
2956 | goto ok; | |||
2957 | } | |||
2958 | if (drvp[1].drive_flags & DRIVE_DMA0x0010) { | |||
2959 | mode[1] = drvp[1].DMA_mode; | |||
2960 | mode[0] = drvp[0].PIO_mode; | |||
2961 | if (piix_isp_pio[mode[0]] != piix_isp_dma[mode[1]] || | |||
2962 | piix_rtc_pio[mode[0]] != piix_rtc_dma[mode[1]]) | |||
2963 | mode[0] = drvp[0].PIO_mode = 0; | |||
2964 | goto ok; | |||
2965 | } | |||
2966 | /* | |||
2967 | * If both drives are not DMA, takes the lower mode, unless | |||
2968 | * one of them is PIO mode < 2 | |||
2969 | */ | |||
2970 | if (drvp[0].PIO_mode < 2) { | |||
2971 | mode[0] = drvp[0].PIO_mode = 0; | |||
2972 | mode[1] = drvp[1].PIO_mode; | |||
2973 | } else if (drvp[1].PIO_mode < 2) { | |||
2974 | mode[1] = drvp[1].PIO_mode = 0; | |||
2975 | mode[0] = drvp[0].PIO_mode; | |||
2976 | } else { | |||
2977 | mode[0] = mode[1] = | |||
2978 | min(drvp[1].PIO_mode, drvp[0].PIO_mode); | |||
2979 | drvp[0].PIO_mode = mode[0]; | |||
2980 | drvp[1].PIO_mode = mode[1]; | |||
2981 | } | |||
2982 | ok: /* The modes are setup */ | |||
2983 | for (drive = 0; drive < 2; drive++) { | |||
2984 | if (drvp[drive].drive_flags & DRIVE_DMA0x0010) { | |||
2985 | idetim |= piix_setup_idetim_timings( | |||
2986 | mode[drive], 1, chp->channel); | |||
2987 | goto end; | |||
2988 | } | |||
2989 | } | |||
2990 | /* If we are there, none of the drives are DMA */ | |||
2991 | if (mode[0] >= 2) | |||
2992 | idetim |= piix_setup_idetim_timings( | |||
2993 | mode[0], 0, chp->channel); | |||
2994 | else | |||
2995 | idetim |= piix_setup_idetim_timings( | |||
2996 | mode[1], 0, chp->channel); | |||
2997 | end: /* | |||
2998 | * timing mode is now set up in the controller. Enable | |||
2999 | * it per-drive | |||
3000 | */ | |||
3001 | for (drive = 0; drive < 2; drive++) { | |||
3002 | /* If no drive, skip */ | |||
3003 | if ((drvp[drive].drive_flags & DRIVE(0x0001|0x0002|0x0004)) == 0) | |||
3004 | continue; | |||
3005 | idetim |= piix_setup_idetim_drvs(&drvp[drive]); | |||
3006 | if (drvp[drive].drive_flags & DRIVE_DMA0x0010) | |||
3007 | idedma_ctl |= IDEDMA_CTL_DRV_DMA(drive)(0x20 << (drive)); | |||
3008 | } | |||
3009 | if (idedma_ctl != 0) { | |||
3010 | /* Add software bits in status register */ | |||
3011 | bus_space_write_1(sc->sc_dma_iot, sc->sc_dma_ioh,((sc->sc_dma_iot)->write_1((sc->sc_dma_ioh), ((0x02 + 0x08 * (chp->channel))), (idedma_ctl))) | |||
3012 | IDEDMA_CTL(chp->channel),((sc->sc_dma_iot)->write_1((sc->sc_dma_ioh), ((0x02 + 0x08 * (chp->channel))), (idedma_ctl))) | |||
3013 | idedma_ctl)((sc->sc_dma_iot)->write_1((sc->sc_dma_ioh), ((0x02 + 0x08 * (chp->channel))), (idedma_ctl))); | |||
3014 | } | |||
3015 | pci_conf_write(sc->sc_pc, sc->sc_tag, PIIX_IDETIM0x40, idetim); | |||
3016 | pciide_print_modes(cp); | |||
3017 | } | |||
3018 | ||||
3019 | void | |||
3020 | piix3_4_setup_channel(struct channel_softc *chp) | |||
3021 | { | |||
3022 | struct ata_drive_datas *drvp; | |||
3023 | u_int32_t oidetim, idetim, sidetim, udmareg, ideconf, idedma_ctl; | |||
3024 | struct pciide_channel *cp = (struct pciide_channel *)chp; | |||
3025 | struct pciide_softc *sc = (struct pciide_softc *)cp->wdc_channel.wdc; | |||
3026 | int drive; | |||
3027 | int channel = chp->channel; | |||
3028 | ||||
3029 | oidetim = pci_conf_read(sc->sc_pc, sc->sc_tag, PIIX_IDETIM0x40); | |||
3030 | sidetim = pci_conf_read(sc->sc_pc, sc->sc_tag, PIIX_SIDETIM0x44); | |||
3031 | udmareg = pci_conf_read(sc->sc_pc, sc->sc_tag, PIIX_UDMAREG0x48); | |||
3032 | ideconf = pci_conf_read(sc->sc_pc, sc->sc_tag, PIIX_CONFIG0x54); | |||
3033 | idetim = PIIX_IDETIM_CLEAR(oidetim, 0xffff, channel)((oidetim) & ~((0xffff) << (16 * (channel)))); | |||
3034 | sidetim &= ~(PIIX_SIDETIM_ISP_MASK(channel)(0x0c << ((channel) * 4)) | | |||
3035 | PIIX_SIDETIM_RTC_MASK(channel)(0x03 << ((channel) * 4))); | |||
3036 | ||||
3037 | idedma_ctl = 0; | |||
3038 | /* If channel disabled, no need to go further */ | |||
3039 | if ((PIIX_IDETIM_READ(oidetim, channel)(((oidetim) >> (16 * (channel))) & 0x0000FFFF) & PIIX_IDETIM_IDE0x8000) == 0) | |||
3040 | return; | |||
3041 | /* set up new idetim: Enable IDE registers decode */ | |||
3042 | idetim = PIIX_IDETIM_SET(idetim, PIIX_IDETIM_IDE, channel)((idetim) | ((0x8000) << (16 * (channel)))); | |||
3043 | ||||
3044 | /* setup DMA if needed */ | |||
3045 | pciide_channel_dma_setup(cp); | |||
3046 | ||||
3047 | for (drive = 0; drive < 2; drive++) { | |||
3048 | udmareg &= ~(PIIX_UDMACTL_DRV_EN(channel, drive)(0x01 << ((channel) * 2 + (drive))) | | |||
3049 | PIIX_UDMATIM_SET(0x3, channel, drive)(((0x3) << ((channel * 8) + (drive * 4))) << 16)); | |||
3050 | drvp = &chp->ch_drive[drive]; | |||
3051 | /* If no drive, skip */ | |||
3052 | if ((drvp->drive_flags & DRIVE(0x0001|0x0002|0x0004)) == 0) | |||
3053 | continue; | |||
3054 | if (((drvp->drive_flags & DRIVE_DMA0x0010) == 0 && | |||
3055 | (drvp->drive_flags & DRIVE_UDMA0x0020) == 0)) | |||
3056 | goto pio; | |||
3057 | ||||
3058 | if (sc->sc_pp->ide_product == PCI_PRODUCT_INTEL_6300ESB_IDE0x25a2 || | |||
3059 | sc->sc_pp->ide_product == PCI_PRODUCT_INTEL_6321ESB_IDE0x269e || | |||
3060 | sc->sc_pp->ide_product == PCI_PRODUCT_INTEL_82801AA_IDE0x2411 || | |||
3061 | sc->sc_pp->ide_product == PCI_PRODUCT_INTEL_82801AB_IDE0x2421 || | |||
3062 | sc->sc_pp->ide_product == PCI_PRODUCT_INTEL_82801BAM_IDE0x244a || | |||
3063 | sc->sc_pp->ide_product == PCI_PRODUCT_INTEL_82801BA_IDE0x244b || | |||
3064 | sc->sc_pp->ide_product == PCI_PRODUCT_INTEL_82801CAM_IDE0x248a || | |||
3065 | sc->sc_pp->ide_product == PCI_PRODUCT_INTEL_82801CA_IDE0x248b || | |||
3066 | sc->sc_pp->ide_product == PCI_PRODUCT_INTEL_82801DB_IDE0x24cb || | |||
3067 | sc->sc_pp->ide_product == PCI_PRODUCT_INTEL_82801DBL_IDE0x24c1 || | |||
3068 | sc->sc_pp->ide_product == PCI_PRODUCT_INTEL_82801DBM_IDE0x24ca || | |||
3069 | sc->sc_pp->ide_product == PCI_PRODUCT_INTEL_82801EB_IDE0x24db || | |||
3070 | sc->sc_pp->ide_product == PCI_PRODUCT_INTEL_82801FB_IDE0x266f || | |||
3071 | sc->sc_pp->ide_product == PCI_PRODUCT_INTEL_82801GB_IDE0x27df || | |||
3072 | sc->sc_pp->ide_product == PCI_PRODUCT_INTEL_82801HBM_IDE0x2850 || | |||
3073 | sc->sc_pp->ide_product == PCI_PRODUCT_INTEL_82372FB_IDE0x7601) { | |||
3074 | ideconf |= PIIX_CONFIG_PINGPONG0x0400; | |||
3075 | } | |||
3076 | if (sc->sc_pp->ide_product == PCI_PRODUCT_INTEL_6300ESB_IDE0x25a2 || | |||
3077 | sc->sc_pp->ide_product == PCI_PRODUCT_INTEL_6321ESB_IDE0x269e || | |||
3078 | sc->sc_pp->ide_product == PCI_PRODUCT_INTEL_82801BAM_IDE0x244a || | |||
3079 | sc->sc_pp->ide_product == PCI_PRODUCT_INTEL_82801BA_IDE0x244b|| | |||
3080 | sc->sc_pp->ide_product == PCI_PRODUCT_INTEL_82801CAM_IDE0x248a|| | |||
3081 | sc->sc_pp->ide_product == PCI_PRODUCT_INTEL_82801CA_IDE0x248b || | |||
3082 | sc->sc_pp->ide_product == PCI_PRODUCT_INTEL_82801DB_IDE0x24cb || | |||
3083 | sc->sc_pp->ide_product == PCI_PRODUCT_INTEL_82801DBL_IDE0x24c1 || | |||
3084 | sc->sc_pp->ide_product == PCI_PRODUCT_INTEL_82801DBM_IDE0x24ca || | |||
3085 | sc->sc_pp->ide_product == PCI_PRODUCT_INTEL_82801EB_IDE0x24db || | |||
3086 | sc->sc_pp->ide_product == PCI_PRODUCT_INTEL_82801FB_IDE0x266f || | |||
3087 | sc->sc_pp->ide_product == PCI_PRODUCT_INTEL_82801GB_IDE0x27df || | |||
3088 | sc->sc_pp->ide_product == PCI_PRODUCT_INTEL_82801HBM_IDE0x2850) { | |||
3089 | /* setup Ultra/100 */ | |||
3090 | if (drvp->UDMA_mode > 2 && | |||
3091 | (ideconf & PIIX_CONFIG_CR(channel, drive)(0x0010 << ((channel) * 2 + (drive)))) == 0) | |||
3092 | drvp->UDMA_mode = 2; | |||
3093 | if (drvp->UDMA_mode > 4) { | |||
3094 | ideconf |= PIIX_CONFIG_UDMA100(channel, drive)(0x1000 << ((channel) * 2 + (drive))); | |||
3095 | } else { | |||
3096 | ideconf &= ~PIIX_CONFIG_UDMA100(channel, drive)(0x1000 << ((channel) * 2 + (drive))); | |||
3097 | if (drvp->UDMA_mode > 2) { | |||
3098 | ideconf |= PIIX_CONFIG_UDMA66(channel,(0x0001 << ((channel) * 2 + (drive))) | |||
3099 | drive)(0x0001 << ((channel) * 2 + (drive))); | |||
3100 | } else { | |||
3101 | ideconf &= ~PIIX_CONFIG_UDMA66(channel,(0x0001 << ((channel) * 2 + (drive))) | |||
3102 | drive)(0x0001 << ((channel) * 2 + (drive))); | |||
3103 | } | |||
3104 | } | |||
3105 | } | |||
3106 | if (sc->sc_pp->ide_product == PCI_PRODUCT_INTEL_82801AA_IDE0x2411 || | |||
3107 | sc->sc_pp->ide_product == PCI_PRODUCT_INTEL_82372FB_IDE0x7601) { | |||
3108 | /* setup Ultra/66 */ | |||
3109 | if (drvp->UDMA_mode > 2 && | |||
3110 | (ideconf & PIIX_CONFIG_CR(channel, drive)(0x0010 << ((channel) * 2 + (drive)))) == 0) | |||
3111 | drvp->UDMA_mode = 2; | |||
3112 | if (drvp->UDMA_mode > 2) | |||
3113 | ideconf |= PIIX_CONFIG_UDMA66(channel, drive)(0x0001 << ((channel) * 2 + (drive))); | |||
3114 | else | |||
3115 | ideconf &= ~PIIX_CONFIG_UDMA66(channel, drive)(0x0001 << ((channel) * 2 + (drive))); | |||
3116 | } | |||
3117 | ||||
3118 | if ((chp->wdc->cap & WDC_CAPABILITY_UDMA0x0010) && | |||
3119 | (drvp->drive_flags & DRIVE_UDMA0x0020)) { | |||
3120 | /* use Ultra/DMA */ | |||
3121 | drvp->drive_flags &= ~DRIVE_DMA0x0010; | |||
3122 | udmareg |= PIIX_UDMACTL_DRV_EN( channel, drive)(0x01 << ((channel) * 2 + (drive))); | |||
3123 | udmareg |= PIIX_UDMATIM_SET((((piix4_sct_udma[drvp->UDMA_mode]) << ((channel * 8 ) + (drive * 4))) << 16) | |||
3124 | piix4_sct_udma[drvp->UDMA_mode], channel, drive)(((piix4_sct_udma[drvp->UDMA_mode]) << ((channel * 8 ) + (drive * 4))) << 16); | |||
3125 | } else { | |||
3126 | /* use Multiword DMA */ | |||
3127 | drvp->drive_flags &= ~DRIVE_UDMA0x0020; | |||
3128 | if (drive == 0) { | |||
3129 | idetim |= piix_setup_idetim_timings( | |||
3130 | drvp->DMA_mode, 1, channel); | |||
3131 | } else { | |||
3132 | sidetim |= piix_setup_sidetim_timings( | |||
3133 | drvp->DMA_mode, 1, channel); | |||
3134 | idetim = PIIX_IDETIM_SET(idetim,((idetim) | ((0x4000) << (16 * (channel)))) | |||
3135 | PIIX_IDETIM_SITRE, channel)((idetim) | ((0x4000) << (16 * (channel)))); | |||
3136 | } | |||
3137 | } | |||
3138 | idedma_ctl |= IDEDMA_CTL_DRV_DMA(drive)(0x20 << (drive)); | |||
3139 | ||||
3140 | pio: /* use PIO mode */ | |||
3141 | idetim |= piix_setup_idetim_drvs(drvp); | |||
3142 | if (drive == 0) { | |||
3143 | idetim |= piix_setup_idetim_timings( | |||
3144 | drvp->PIO_mode, 0, channel); | |||
3145 | } else { | |||
3146 | sidetim |= piix_setup_sidetim_timings( | |||
3147 | drvp->PIO_mode, 0, channel); | |||
3148 | idetim = PIIX_IDETIM_SET(idetim,((idetim) | ((0x4000) << (16 * (channel)))) | |||
3149 | PIIX_IDETIM_SITRE, channel)((idetim) | ((0x4000) << (16 * (channel)))); | |||
3150 | } | |||
3151 | } | |||
3152 | if (idedma_ctl != 0) { | |||
3153 | /* Add software bits in status register */ | |||
3154 | bus_space_write_1(sc->sc_dma_iot, sc->sc_dma_ioh,((sc->sc_dma_iot)->write_1((sc->sc_dma_ioh), ((0x02 + 0x08 * (channel))), (idedma_ctl))) | |||
3155 | IDEDMA_CTL(channel),((sc->sc_dma_iot)->write_1((sc->sc_dma_ioh), ((0x02 + 0x08 * (channel))), (idedma_ctl))) | |||
3156 | idedma_ctl)((sc->sc_dma_iot)->write_1((sc->sc_dma_ioh), ((0x02 + 0x08 * (channel))), (idedma_ctl))); | |||
3157 | } | |||
3158 | pci_conf_write(sc->sc_pc, sc->sc_tag, PIIX_IDETIM0x40, idetim); | |||
3159 | pci_conf_write(sc->sc_pc, sc->sc_tag, PIIX_SIDETIM0x44, sidetim); | |||
3160 | pci_conf_write(sc->sc_pc, sc->sc_tag, PIIX_UDMAREG0x48, udmareg); | |||
3161 | pci_conf_write(sc->sc_pc, sc->sc_tag, PIIX_CONFIG0x54, ideconf); | |||
3162 | pciide_print_modes(cp); | |||
3163 | } | |||
3164 | ||||
3165 | ||||
3166 | /* setup ISP and RTC fields, based on mode */ | |||
3167 | u_int32_t | |||
3168 | piix_setup_idetim_timings(u_int8_t mode, u_int8_t dma, u_int8_t channel) | |||
3169 | { | |||
3170 | ||||
3171 | if (dma) | |||
3172 | return (PIIX_IDETIM_SET(0,((0) | ((((piix_isp_dma[mode]) << 12) | ((piix_rtc_dma[ mode]) << 8)) << (16 * (channel)))) | |||
3173 | PIIX_IDETIM_ISP_SET(piix_isp_dma[mode]) |((0) | ((((piix_isp_dma[mode]) << 12) | ((piix_rtc_dma[ mode]) << 8)) << (16 * (channel)))) | |||
3174 | PIIX_IDETIM_RTC_SET(piix_rtc_dma[mode]),((0) | ((((piix_isp_dma[mode]) << 12) | ((piix_rtc_dma[ mode]) << 8)) << (16 * (channel)))) | |||
3175 | channel)((0) | ((((piix_isp_dma[mode]) << 12) | ((piix_rtc_dma[ mode]) << 8)) << (16 * (channel))))); | |||
3176 | else | |||
3177 | return (PIIX_IDETIM_SET(0,((0) | ((((piix_isp_pio[mode]) << 12) | ((piix_rtc_pio[ mode]) << 8)) << (16 * (channel)))) | |||
3178 | PIIX_IDETIM_ISP_SET(piix_isp_pio[mode]) |((0) | ((((piix_isp_pio[mode]) << 12) | ((piix_rtc_pio[ mode]) << 8)) << (16 * (channel)))) | |||
3179 | PIIX_IDETIM_RTC_SET(piix_rtc_pio[mode]),((0) | ((((piix_isp_pio[mode]) << 12) | ((piix_rtc_pio[ mode]) << 8)) << (16 * (channel)))) | |||
3180 | channel)((0) | ((((piix_isp_pio[mode]) << 12) | ((piix_rtc_pio[ mode]) << 8)) << (16 * (channel))))); | |||
3181 | } | |||
3182 | ||||
3183 | /* setup DTE, PPE, IE and TIME field based on PIO mode */ | |||
3184 | u_int32_t | |||
3185 | piix_setup_idetim_drvs(struct ata_drive_datas *drvp) | |||
3186 | { | |||
3187 | u_int32_t ret = 0; | |||
3188 | struct channel_softc *chp = drvp->chnl_softc; | |||
3189 | u_int8_t channel = chp->channel; | |||
3190 | u_int8_t drive = drvp->drive; | |||
3191 | ||||
3192 | /* | |||
3193 | * If drive is using UDMA, timing setup is independent | |||
3194 | * so just check DMA and PIO here. | |||
3195 | */ | |||
3196 | if (drvp->drive_flags & DRIVE_DMA0x0010) { | |||
3197 | /* if mode = DMA mode 0, use compatible timings */ | |||
3198 | if ((drvp->drive_flags & DRIVE_DMA0x0010) && | |||
3199 | drvp->DMA_mode == 0) { | |||
3200 | drvp->PIO_mode = 0; | |||
3201 | return (ret); | |||
3202 | } | |||
3203 | ret = PIIX_IDETIM_SET(ret, PIIX_IDETIM_TIME(drive), channel)((ret) | (((0x0001 << (4 * (drive)))) << (16 * (channel )))); | |||
3204 | /* | |||
3205 | * PIO and DMA timings are the same, use fast timings for PIO | |||
3206 | * too, else use compat timings. | |||
3207 | */ | |||
3208 | if ((piix_isp_pio[drvp->PIO_mode] != | |||
3209 | piix_isp_dma[drvp->DMA_mode]) || | |||
3210 | (piix_rtc_pio[drvp->PIO_mode] != | |||
3211 | piix_rtc_dma[drvp->DMA_mode])) | |||
3212 | drvp->PIO_mode = 0; | |||
3213 | /* if PIO mode <= 2, use compat timings for PIO */ | |||
3214 | if (drvp->PIO_mode <= 2) { | |||
3215 | ret = PIIX_IDETIM_SET(ret, PIIX_IDETIM_DTE(drive),((ret) | (((0x0008 << (4 * (drive)))) << (16 * (channel )))) | |||
3216 | channel)((ret) | (((0x0008 << (4 * (drive)))) << (16 * (channel )))); | |||
3217 | return (ret); | |||
3218 | } | |||
3219 | } | |||
3220 | ||||
3221 | /* | |||
3222 | * Now setup PIO modes. If mode < 2, use compat timings. | |||
3223 | * Else enable fast timings. Enable IORDY and prefetch/post | |||
3224 | * if PIO mode >= 3. | |||
3225 | */ | |||
3226 | ||||
3227 | if (drvp->PIO_mode < 2) | |||
3228 | return (ret); | |||
3229 | ||||
3230 | ret = PIIX_IDETIM_SET(ret, PIIX_IDETIM_TIME(drive), channel)((ret) | (((0x0001 << (4 * (drive)))) << (16 * (channel )))); | |||
3231 | if (drvp->PIO_mode >= 3) { | |||
3232 | ret = PIIX_IDETIM_SET(ret, PIIX_IDETIM_IE(drive), channel)((ret) | (((0x0002 << (4 * (drive)))) << (16 * (channel )))); | |||
3233 | ret = PIIX_IDETIM_SET(ret, PIIX_IDETIM_PPE(drive), channel)((ret) | (((0x0004 << (4 * (drive)))) << (16 * (channel )))); | |||
3234 | } | |||
3235 | return (ret); | |||
3236 | } | |||
3237 | ||||
3238 | /* setup values in SIDETIM registers, based on mode */ | |||
3239 | u_int32_t | |||
3240 | piix_setup_sidetim_timings(u_int8_t mode, u_int8_t dma, u_int8_t channel) | |||
3241 | { | |||
3242 | if (dma) | |||
3243 | return (PIIX_SIDETIM_ISP_SET(piix_isp_dma[mode], channel)(piix_isp_dma[mode] << (2 + ((channel) * 4))) | | |||
3244 | PIIX_SIDETIM_RTC_SET(piix_rtc_dma[mode], channel)(piix_rtc_dma[mode] << (0 + ((channel) * 4)))); | |||
3245 | else | |||
3246 | return (PIIX_SIDETIM_ISP_SET(piix_isp_pio[mode], channel)(piix_isp_pio[mode] << (2 + ((channel) * 4))) | | |||
3247 | PIIX_SIDETIM_RTC_SET(piix_rtc_pio[mode], channel)(piix_rtc_pio[mode] << (0 + ((channel) * 4)))); | |||
3248 | } | |||
3249 | ||||
3250 | void | |||
3251 | amd756_chip_map(struct pciide_softc *sc, struct pci_attach_args *pa) | |||
3252 | { | |||
3253 | struct pciide_channel *cp; | |||
3254 | pcireg_t interface = PCI_INTERFACE(pa->pa_class)(((pa->pa_class) >> 8) & 0xff); | |||
3255 | int channel; | |||
3256 | pcireg_t chanenable; | |||
3257 | bus_size_t cmdsize, ctlsize; | |||
3258 | ||||
3259 | printf(": DMA"); | |||
3260 | pciide_mapreg_dma(sc, pa); | |||
3261 | sc->sc_wdcdev.cap = WDC_CAPABILITY_DATA160x0001 | WDC_CAPABILITY_DATA320x0002 | | |||
3262 | WDC_CAPABILITY_MODE0x0004; | |||
3263 | if (sc->sc_dma_ok) { | |||
3264 | sc->sc_wdcdev.cap |= WDC_CAPABILITY_DMA0x0008 | WDC_CAPABILITY_UDMA0x0010; | |||
3265 | sc->sc_wdcdev.cap |= WDC_CAPABILITY_IRQACK0x0400; | |||
3266 | sc->sc_wdcdev.irqack = pciide_irqack; | |||
3267 | } | |||
3268 | sc->sc_wdcdev.PIO_cap = 4; | |||
3269 | sc->sc_wdcdev.DMA_cap = 2; | |||
3270 | switch (sc->sc_pp->ide_product) { | |||
3271 | case PCI_PRODUCT_AMD_8111_IDE0x7469: | |||
3272 | sc->sc_wdcdev.UDMA_cap = 6; | |||
3273 | break; | |||
3274 | case PCI_PRODUCT_AMD_766_IDE0x7411: | |||
3275 | case PCI_PRODUCT_AMD_PBC768_IDE0x7441: | |||
3276 | sc->sc_wdcdev.UDMA_cap = 5; | |||
3277 | break; | |||
3278 | default: | |||
3279 | sc->sc_wdcdev.UDMA_cap = 4; | |||
3280 | break; | |||
3281 | } | |||
3282 | sc->sc_wdcdev.set_modes = amd756_setup_channel; | |||
3283 | sc->sc_wdcdev.channels = sc->wdc_chanarray; | |||
3284 | sc->sc_wdcdev.nchannels = PCIIDE_NUM_CHANNELS2; | |||
3285 | chanenable = pci_conf_read(sc->sc_pc, sc->sc_tag, AMD756_CHANSTATUS_EN0x40); | |||
3286 | ||||
3287 | pciide_print_channels(sc->sc_wdcdev.nchannels, interface); | |||
3288 | ||||
3289 | for (channel = 0; channel < sc->sc_wdcdev.nchannels; channel++) { | |||
3290 | cp = &sc->pciide_channels[channel]; | |||
3291 | if (pciide_chansetup(sc, channel, interface) == 0) | |||
3292 | continue; | |||
3293 | ||||
3294 | if ((chanenable & AMD756_CHAN_EN(channel)(0x01 << (1 - (channel)))) == 0) { | |||
3295 | printf("%s: %s ignored (disabled)\n", | |||
3296 | sc->sc_wdcdev.sc_dev.dv_xname, cp->name); | |||
3297 | cp->hw_ok = 0; | |||
3298 | continue; | |||
3299 | } | |||
3300 | pciide_map_compat_intr(pa, cp, channel, interface); | |||
3301 | if (cp->hw_ok == 0) | |||
3302 | continue; | |||
3303 | ||||
3304 | pciide_mapchan(pa, cp, interface, &cmdsize, &ctlsize, | |||
3305 | pciide_pci_intr); | |||
3306 | ||||
3307 | if (pciide_chan_candisable(cp)) { | |||
3308 | chanenable &= ~AMD756_CHAN_EN(channel)(0x01 << (1 - (channel))); | |||
3309 | } | |||
3310 | if (cp->hw_ok == 0) { | |||
3311 | pciide_unmap_compat_intr(pa, cp, channel, interface); | |||
3312 | continue; | |||
3313 | } | |||
3314 | ||||
3315 | amd756_setup_channel(&cp->wdc_channel); | |||
3316 | } | |||
3317 | pci_conf_write(sc->sc_pc, sc->sc_tag, AMD756_CHANSTATUS_EN0x40, | |||
3318 | chanenable); | |||
3319 | return; | |||
3320 | } | |||
3321 | ||||
3322 | void | |||
3323 | amd756_setup_channel(struct channel_softc *chp) | |||
3324 | { | |||
3325 | u_int32_t udmatim_reg, datatim_reg; | |||
3326 | u_int8_t idedma_ctl; | |||
3327 | int mode, drive; | |||
3328 | struct ata_drive_datas *drvp; | |||
3329 | struct pciide_channel *cp = (struct pciide_channel *)chp; | |||
3330 | struct pciide_softc *sc = (struct pciide_softc *)cp->wdc_channel.wdc; | |||
3331 | pcireg_t chanenable; | |||
3332 | #ifndef PCIIDE_AMD756_ENABLEDMA | |||
3333 | int product = sc->sc_pp->ide_product; | |||
3334 | int rev = sc->sc_rev; | |||
3335 | #endif | |||
3336 | ||||
3337 | idedma_ctl = 0; | |||
3338 | datatim_reg = pci_conf_read(sc->sc_pc, sc->sc_tag, AMD756_DATATIM0x48); | |||
3339 | udmatim_reg = pci_conf_read(sc->sc_pc, sc->sc_tag, AMD756_UDMA0x50); | |||
3340 | datatim_reg &= ~AMD756_DATATIM_MASK(chp->channel)(0xffff << ((1 - (chp->channel)) << 4)); | |||
3341 | udmatim_reg &= ~AMD756_UDMA_MASK(chp->channel)(0xffff << ((1 - (chp->channel)) << 4)); | |||
3342 | chanenable = pci_conf_read(sc->sc_pc, sc->sc_tag, | |||
3343 | AMD756_CHANSTATUS_EN0x40); | |||
3344 | ||||
3345 | /* setup DMA if needed */ | |||
3346 | pciide_channel_dma_setup(cp); | |||
3347 | ||||
3348 | for (drive = 0; drive < 2; drive++) { | |||
3349 | drvp = &chp->ch_drive[drive]; | |||
3350 | /* If no drive, skip */ | |||
3351 | if ((drvp->drive_flags & DRIVE(0x0001|0x0002|0x0004)) == 0) | |||
3352 | continue; | |||
3353 | /* add timing values, setup DMA if needed */ | |||
3354 | if (((drvp->drive_flags & DRIVE_DMA0x0010) == 0 && | |||
3355 | (drvp->drive_flags & DRIVE_UDMA0x0020) == 0)) { | |||
3356 | mode = drvp->PIO_mode; | |||
3357 | goto pio; | |||
3358 | } | |||
3359 | if ((chp->wdc->cap & WDC_CAPABILITY_UDMA0x0010) && | |||
3360 | (drvp->drive_flags & DRIVE_UDMA0x0020)) { | |||
3361 | /* use Ultra/DMA */ | |||
3362 | drvp->drive_flags &= ~DRIVE_DMA0x0010; | |||
3363 | ||||
3364 | /* Check cable */ | |||
3365 | if ((chanenable & AMD756_CABLE(chp->channel,(0x00010000 << ((chp->channel) * 2 + (drive))) | |||
3366 | drive)(0x00010000 << ((chp->channel) * 2 + (drive)))) == 0 && drvp->UDMA_mode > 2) { | |||
3367 | WDCDEBUG_PRINT(("%s(%s:%d:%d): 80-wire " | |||
3368 | "cable not detected\n", drvp->drive_name, | |||
3369 | sc->sc_wdcdev.sc_dev.dv_xname, | |||
3370 | chp->channel, drive), DEBUG_PROBE); | |||
3371 | drvp->UDMA_mode = 2; | |||
3372 | } | |||
3373 | ||||
3374 | udmatim_reg |= AMD756_UDMA_EN(chp->channel, drive)(0x40 << (((1 - (chp->channel)) << 4) + ((1 - ( drive)) << 3))) | | |||
3375 | AMD756_UDMA_EN_MTH(chp->channel, drive)(0x80 << (((1 - (chp->channel)) << 4) + ((1 - ( drive)) << 3))) | | |||
3376 | AMD756_UDMA_TIME(chp->channel, drive,(((amd756_udma_tim[drvp->UDMA_mode]) & 0x7) << ( ((1 - (chp->channel)) << 4) + ((1 - (drive)) << 3))) | |||
3377 | amd756_udma_tim[drvp->UDMA_mode])(((amd756_udma_tim[drvp->UDMA_mode]) & 0x7) << ( ((1 - (chp->channel)) << 4) + ((1 - (drive)) << 3))); | |||
3378 | /* can use PIO timings, MW DMA unused */ | |||
3379 | mode = drvp->PIO_mode; | |||
3380 | } else { | |||
3381 | /* use Multiword DMA, but only if revision is OK */ | |||
3382 | drvp->drive_flags &= ~DRIVE_UDMA0x0020; | |||
3383 | #ifndef PCIIDE_AMD756_ENABLEDMA | |||
3384 | /* | |||
3385 | * The workaround doesn't seem to be necessary | |||
3386 | * with all drives, so it can be disabled by | |||
3387 | * PCIIDE_AMD756_ENABLEDMA. It causes a hard hang if | |||
3388 | * triggered. | |||
3389 | */ | |||
3390 | if (AMD756_CHIPREV_DISABLEDMA(product, rev)((product) == 0x7409 && (rev) <= 3)) { | |||
3391 | printf("%s:%d:%d: multi-word DMA disabled due " | |||
3392 | "to chip revision\n", | |||
3393 | sc->sc_wdcdev.sc_dev.dv_xname, | |||
3394 | chp->channel, drive); | |||
3395 | mode = drvp->PIO_mode; | |||
3396 | drvp->drive_flags &= ~DRIVE_DMA0x0010; | |||
3397 | goto pio; | |||
3398 | } | |||
3399 | #endif | |||
3400 | /* mode = min(pio, dma+2) */ | |||
3401 | if (drvp->PIO_mode <= (drvp->DMA_mode +2)) | |||
3402 | mode = drvp->PIO_mode; | |||
3403 | else | |||
3404 | mode = drvp->DMA_mode + 2; | |||
3405 | } | |||
3406 | idedma_ctl |= IDEDMA_CTL_DRV_DMA(drive)(0x20 << (drive)); | |||
3407 | ||||
3408 | pio: /* setup PIO mode */ | |||
3409 | if (mode <= 2) { | |||
3410 | drvp->DMA_mode = 0; | |||
3411 | drvp->PIO_mode = 0; | |||
3412 | mode = 0; | |||
3413 | } else { | |||
3414 | drvp->PIO_mode = mode; | |||
3415 | drvp->DMA_mode = mode - 2; | |||
3416 | } | |||
3417 | datatim_reg |= | |||
3418 | AMD756_DATATIM_PULSE(chp->channel, drive,(((amd756_pio_set[mode]) & 0xf) << (((1 - (chp-> channel)) << 4) + ((1 - (drive)) << 3) + 4)) | |||
3419 | amd756_pio_set[mode])(((amd756_pio_set[mode]) & 0xf) << (((1 - (chp-> channel)) << 4) + ((1 - (drive)) << 3) + 4)) | | |||
3420 | AMD756_DATATIM_RECOV(chp->channel, drive,(((amd756_pio_rec[mode]) & 0xf) << (((1 - (chp-> channel)) << 4) + ((1 - (drive)) << 3))) | |||
3421 | amd756_pio_rec[mode])(((amd756_pio_rec[mode]) & 0xf) << (((1 - (chp-> channel)) << 4) + ((1 - (drive)) << 3))); | |||
3422 | } | |||
3423 | if (idedma_ctl != 0) { | |||
3424 | /* Add software bits in status register */ | |||
3425 | bus_space_write_1(sc->sc_dma_iot, sc->sc_dma_ioh,((sc->sc_dma_iot)->write_1((sc->sc_dma_ioh), ((0x02 + 0x08 * (chp->channel))), (idedma_ctl))) | |||
3426 | IDEDMA_CTL(chp->channel),((sc->sc_dma_iot)->write_1((sc->sc_dma_ioh), ((0x02 + 0x08 * (chp->channel))), (idedma_ctl))) | |||
3427 | idedma_ctl)((sc->sc_dma_iot)->write_1((sc->sc_dma_ioh), ((0x02 + 0x08 * (chp->channel))), (idedma_ctl))); | |||
3428 | } | |||
3429 | pciide_print_modes(cp); | |||
3430 | pci_conf_write(sc->sc_pc, sc->sc_tag, AMD756_DATATIM0x48, datatim_reg); | |||
3431 | pci_conf_write(sc->sc_pc, sc->sc_tag, AMD756_UDMA0x50, udmatim_reg); | |||
3432 | } | |||
3433 | ||||
3434 | void | |||
3435 | apollo_chip_map(struct pciide_softc *sc, struct pci_attach_args *pa) | |||
3436 | { | |||
3437 | struct pciide_channel *cp; | |||
3438 | pcireg_t interface; | |||
3439 | int no_ideconf = 0, channel; | |||
3440 | u_int32_t ideconf; | |||
3441 | bus_size_t cmdsize, ctlsize; | |||
3442 | pcitag_t tag; | |||
3443 | pcireg_t id, class; | |||
3444 | ||||
3445 | /* | |||
3446 | * Fake interface since VT6410 is claimed to be a ``RAID'' device. | |||
3447 | */ | |||
3448 | if (PCI_SUBCLASS(pa->pa_class)(((pa->pa_class) >> 16) & 0xff) == PCI_SUBCLASS_MASS_STORAGE_IDE0x01) { | |||
3449 | interface = PCI_INTERFACE(pa->pa_class)(((pa->pa_class) >> 8) & 0xff); | |||
3450 | } else { | |||
3451 | interface = PCIIDE_INTERFACE_BUS_MASTER_DMA0x80 | | |||
3452 | PCIIDE_INTERFACE_PCI(0)(0x01 << (2 * (0))) | PCIIDE_INTERFACE_PCI(1)(0x01 << (2 * (1))); | |||
3453 | } | |||
3454 | ||||
3455 | switch (PCI_PRODUCT(pa->pa_id)(((pa->pa_id) >> 16) & 0xffff)) { | |||
3456 | case PCI_PRODUCT_VIATECH_VT64100x3164: | |||
3457 | case PCI_PRODUCT_VIATECH_VT64150x0415: | |||
3458 | no_ideconf = 1; | |||
3459 | /* FALLTHROUGH */ | |||
3460 | case PCI_PRODUCT_VIATECH_CX700_IDE0x5324: | |||
3461 | case PCI_PRODUCT_VIATECH_VX700_IDE0x0581: | |||
3462 | case PCI_PRODUCT_VIATECH_VX855_IDE0xc409: | |||
3463 | case PCI_PRODUCT_VIATECH_VX900_IDE0x9001: | |||
3464 | printf(": ATA133"); | |||
3465 | sc->sc_wdcdev.UDMA_cap = 6; | |||
3466 | break; | |||
3467 | default: | |||
3468 | /* | |||
3469 | * Determine the DMA capabilities by looking at the | |||
3470 | * ISA bridge. | |||
3471 | */ | |||
3472 | tag = pci_make_tag(pa->pa_pc, pa->pa_bus, pa->pa_device, 0); | |||
3473 | id = pci_conf_read(sc->sc_pc, tag, PCI_ID_REG0x00); | |||
3474 | class = pci_conf_read(sc->sc_pc, tag, PCI_CLASS_REG0x08); | |||
3475 | ||||
3476 | /* | |||
3477 | * XXX On the VT8237, the ISA bridge is on a different | |||
3478 | * device. | |||
3479 | */ | |||
3480 | if (PCI_CLASS(class)(((class) >> 24) & 0xff) != PCI_CLASS_BRIDGE0x06 && | |||
3481 | pa->pa_device == 15) { | |||
3482 | tag = pci_make_tag(pa->pa_pc, pa->pa_bus, 17, 0); | |||
3483 | id = pci_conf_read(sc->sc_pc, tag, PCI_ID_REG0x00); | |||
3484 | class = pci_conf_read(sc->sc_pc, tag, PCI_CLASS_REG0x08); | |||
3485 | } | |||
3486 | ||||
3487 | switch (PCI_PRODUCT(id)(((id) >> 16) & 0xffff)) { | |||
3488 | case PCI_PRODUCT_VIATECH_VT82C586_ISA0x0586: | |||
3489 | if (PCI_REVISION(class)(((class) >> 0) & 0xff) >= 0x02) { | |||
3490 | printf(": ATA33"); | |||
3491 | sc->sc_wdcdev.UDMA_cap = 2; | |||
3492 | } else { | |||
3493 | printf(": DMA"); | |||
3494 | sc->sc_wdcdev.UDMA_cap = 0; | |||
3495 | } | |||
3496 | break; | |||
3497 | case PCI_PRODUCT_VIATECH_VT82C596A0x0596: | |||
3498 | if (PCI_REVISION(class)(((class) >> 0) & 0xff) >= 0x12) { | |||
3499 | printf(": ATA66"); | |||
3500 | sc->sc_wdcdev.UDMA_cap = 4; | |||
3501 | } else { | |||
3502 | printf(": ATA33"); | |||
3503 | sc->sc_wdcdev.UDMA_cap = 2; | |||
3504 | } | |||
3505 | break; | |||
3506 | ||||
3507 | case PCI_PRODUCT_VIATECH_VT82C686A_ISA0x0686: | |||
3508 | if (PCI_REVISION(class)(((class) >> 0) & 0xff) >= 0x40) { | |||
3509 | printf(": ATA100"); | |||
3510 | sc->sc_wdcdev.UDMA_cap = 5; | |||
3511 | } else { | |||
3512 | printf(": ATA66"); | |||
3513 | sc->sc_wdcdev.UDMA_cap = 4; | |||
3514 | } | |||
3515 | break; | |||
3516 | case PCI_PRODUCT_VIATECH_VT8231_ISA0x8231: | |||
3517 | case PCI_PRODUCT_VIATECH_VT8233_ISA0x3074: | |||
3518 | printf(": ATA100"); | |||
3519 | sc->sc_wdcdev.UDMA_cap = 5; | |||
3520 | break; | |||
3521 | case PCI_PRODUCT_VIATECH_VT8233A_ISA0x3147: | |||
3522 | case PCI_PRODUCT_VIATECH_VT8235_ISA0x3177: | |||
3523 | case PCI_PRODUCT_VIATECH_VT8237_ISA0x3227: | |||
3524 | printf(": ATA133"); | |||
3525 | sc->sc_wdcdev.UDMA_cap = 6; | |||
3526 | break; | |||
3527 | default: | |||
3528 | printf(": DMA"); | |||
3529 | sc->sc_wdcdev.UDMA_cap = 0; | |||
3530 | break; | |||
3531 | } | |||
3532 | break; | |||
3533 | } | |||
3534 | ||||
3535 | pciide_mapreg_dma(sc, pa); | |||
3536 | sc->sc_wdcdev.cap |= WDC_CAPABILITY_DATA160x0001 | WDC_CAPABILITY_DATA320x0002 | | |||
3537 | WDC_CAPABILITY_MODE0x0004; | |||
3538 | if (sc->sc_dma_ok) { | |||
3539 | sc->sc_wdcdev.cap |= WDC_CAPABILITY_DMA0x0008 | WDC_CAPABILITY_IRQACK0x0400; | |||
3540 | sc->sc_wdcdev.irqack = pciide_irqack; | |||
3541 | if (sc->sc_wdcdev.UDMA_cap > 0) | |||
3542 | sc->sc_wdcdev.cap |= WDC_CAPABILITY_UDMA0x0010; | |||
3543 | } | |||
3544 | sc->sc_wdcdev.PIO_cap = 4; | |||
3545 | sc->sc_wdcdev.DMA_cap = 2; | |||
3546 | sc->sc_wdcdev.set_modes = apollo_setup_channel; | |||
3547 | sc->sc_wdcdev.channels = sc->wdc_chanarray; | |||
3548 | sc->sc_wdcdev.nchannels = PCIIDE_NUM_CHANNELS2; | |||
3549 | ||||
3550 | pciide_print_channels(sc->sc_wdcdev.nchannels, interface); | |||
3551 | ||||
3552 | WDCDEBUG_PRINT(("apollo_chip_map: old APO_IDECONF=0x%x, " | |||
3553 | "APO_CTLMISC=0x%x, APO_DATATIM=0x%x, APO_UDMA=0x%x\n", | |||
3554 | pci_conf_read(sc->sc_pc, sc->sc_tag, APO_IDECONF), | |||
3555 | pci_conf_read(sc->sc_pc, sc->sc_tag, APO_CTLMISC), | |||
3556 | pci_conf_read(sc->sc_pc, sc->sc_tag, APO_DATATIM), | |||
3557 | pci_conf_read(sc->sc_pc, sc->sc_tag, APO_UDMA)), | |||
3558 | DEBUG_PROBE); | |||
3559 | ||||
3560 | for (channel = 0; channel < sc->sc_wdcdev.nchannels; channel++) { | |||
3561 | cp = &sc->pciide_channels[channel]; | |||
3562 | if (pciide_chansetup(sc, channel, interface) == 0) | |||
3563 | continue; | |||
3564 | ||||
3565 | if (no_ideconf == 0) { | |||
3566 | ideconf = pci_conf_read(sc->sc_pc, sc->sc_tag, | |||
3567 | APO_IDECONF0x40); | |||
3568 | if ((ideconf & APO_IDECONF_EN(channel)(0x00000001 << (1 - (channel)))) == 0) { | |||
3569 | printf("%s: %s ignored (disabled)\n", | |||
3570 | sc->sc_wdcdev.sc_dev.dv_xname, cp->name); | |||
3571 | cp->hw_ok = 0; | |||
3572 | continue; | |||
3573 | } | |||
3574 | } | |||
3575 | pciide_map_compat_intr(pa, cp, channel, interface); | |||
3576 | if (cp->hw_ok == 0) | |||
3577 | continue; | |||
3578 | ||||
3579 | pciide_mapchan(pa, cp, interface, &cmdsize, &ctlsize, | |||
3580 | pciide_pci_intr); | |||
3581 | if (cp->hw_ok == 0) { | |||
3582 | goto next; | |||
3583 | } | |||
3584 | if (pciide_chan_candisable(cp)) { | |||
3585 | if (no_ideconf == 0) { | |||
3586 | ideconf &= ~APO_IDECONF_EN(channel)(0x00000001 << (1 - (channel))); | |||
3587 | pci_conf_write(sc->sc_pc, sc->sc_tag, | |||
3588 | APO_IDECONF0x40, ideconf); | |||
3589 | } | |||
3590 | } | |||
3591 | ||||
3592 | if (cp->hw_ok == 0) | |||
3593 | goto next; | |||
3594 | apollo_setup_channel(&sc->pciide_channels[channel].wdc_channel); | |||
3595 | next: | |||
3596 | if (cp->hw_ok == 0) | |||
3597 | pciide_unmap_compat_intr(pa, cp, channel, interface); | |||
3598 | } | |||
3599 | WDCDEBUG_PRINT(("apollo_chip_map: APO_DATATIM=0x%x, APO_UDMA=0x%x\n", | |||
3600 | pci_conf_read(sc->sc_pc, sc->sc_tag, APO_DATATIM), | |||
3601 | pci_conf_read(sc->sc_pc, sc->sc_tag, APO_UDMA)), DEBUG_PROBE); | |||
3602 | } | |||
3603 | ||||
3604 | void | |||
3605 | apollo_setup_channel(struct channel_softc *chp) | |||
3606 | { | |||
3607 | u_int32_t udmatim_reg, datatim_reg; | |||
3608 | u_int8_t idedma_ctl; | |||
3609 | int mode, drive; | |||
3610 | struct ata_drive_datas *drvp; | |||
3611 | struct pciide_channel *cp = (struct pciide_channel *)chp; | |||
3612 | struct pciide_softc *sc = (struct pciide_softc *)cp->wdc_channel.wdc; | |||
3613 | ||||
3614 | idedma_ctl = 0; | |||
3615 | datatim_reg = pci_conf_read(sc->sc_pc, sc->sc_tag, APO_DATATIM0x48); | |||
3616 | udmatim_reg = pci_conf_read(sc->sc_pc, sc->sc_tag, APO_UDMA0x50); | |||
3617 | datatim_reg &= ~APO_DATATIM_MASK(chp->channel)(0xffff << ((1 - (chp->channel)) << 4)); | |||
3618 | udmatim_reg &= ~APO_UDMA_MASK(chp->channel)(0xffff << ((1 - (chp->channel)) << 4)); | |||
3619 | ||||
3620 | /* setup DMA if needed */ | |||
3621 | pciide_channel_dma_setup(cp); | |||
3622 | ||||
3623 | /* | |||
3624 | * We can't mix Ultra/33 and Ultra/66 on the same channel, so | |||
3625 | * downgrade to Ultra/33 if needed | |||
3626 | */ | |||
3627 | if ((chp->ch_drive[0].drive_flags & DRIVE_UDMA0x0020) && | |||
3628 | (chp->ch_drive[1].drive_flags & DRIVE_UDMA0x0020)) { | |||
3629 | /* both drives UDMA */ | |||
3630 | if (chp->ch_drive[0].UDMA_mode > 2 && | |||
3631 | chp->ch_drive[1].UDMA_mode <= 2) { | |||
3632 | /* drive 0 Ultra/66, drive 1 Ultra/33 */ | |||
3633 | chp->ch_drive[0].UDMA_mode = 2; | |||
3634 | } else if (chp->ch_drive[1].UDMA_mode > 2 && | |||
3635 | chp->ch_drive[0].UDMA_mode <= 2) { | |||
3636 | /* drive 1 Ultra/66, drive 0 Ultra/33 */ | |||
3637 | chp->ch_drive[1].UDMA_mode = 2; | |||
3638 | } | |||
3639 | } | |||
3640 | ||||
3641 | for (drive = 0; drive < 2; drive++) { | |||
3642 | drvp = &chp->ch_drive[drive]; | |||
3643 | /* If no drive, skip */ | |||
3644 | if ((drvp->drive_flags & DRIVE(0x0001|0x0002|0x0004)) == 0) | |||
3645 | continue; | |||
3646 | /* add timing values, setup DMA if needed */ | |||
3647 | if (((drvp->drive_flags & DRIVE_DMA0x0010) == 0 && | |||
3648 | (drvp->drive_flags & DRIVE_UDMA0x0020) == 0)) { | |||
3649 | mode = drvp->PIO_mode; | |||
3650 | goto pio; | |||
3651 | } | |||
3652 | if ((chp->wdc->cap & WDC_CAPABILITY_UDMA0x0010) && | |||
3653 | (drvp->drive_flags & DRIVE_UDMA0x0020)) { | |||
3654 | /* use Ultra/DMA */ | |||
3655 | drvp->drive_flags &= ~DRIVE_DMA0x0010; | |||
3656 | udmatim_reg |= APO_UDMA_EN(chp->channel, drive)(0x40 << (((1 - (chp->channel)) << 4) + ((1 - ( drive)) << 3))) | | |||
3657 | APO_UDMA_EN_MTH(chp->channel, drive)(0x80 << (((1 - (chp->channel)) << 4) + ((1 - ( drive)) << 3))); | |||
3658 | if (sc->sc_wdcdev.UDMA_cap == 6) { | |||
3659 | udmatim_reg |= APO_UDMA_TIME(chp->channel,(((apollo_udma133_tim[drvp->UDMA_mode]) & 0xf) << (((1 - (chp->channel)) << 4) + ((1 - (drive)) << 3))) | |||
3660 | drive, apollo_udma133_tim[drvp->UDMA_mode])(((apollo_udma133_tim[drvp->UDMA_mode]) & 0xf) << (((1 - (chp->channel)) << 4) + ((1 - (drive)) << 3))); | |||
3661 | } else if (sc->sc_wdcdev.UDMA_cap == 5) { | |||
3662 | /* 686b */ | |||
3663 | udmatim_reg |= APO_UDMA_TIME(chp->channel,(((apollo_udma100_tim[drvp->UDMA_mode]) & 0xf) << (((1 - (chp->channel)) << 4) + ((1 - (drive)) << 3))) | |||
3664 | drive, apollo_udma100_tim[drvp->UDMA_mode])(((apollo_udma100_tim[drvp->UDMA_mode]) & 0xf) << (((1 - (chp->channel)) << 4) + ((1 - (drive)) << 3))); | |||
3665 | } else if (sc->sc_wdcdev.UDMA_cap == 4) { | |||
3666 | /* 596b or 686a */ | |||
3667 | udmatim_reg |= APO_UDMA_CLK66(chp->channel)(0x08 << ((1 - (chp->channel)) << 4)); | |||
3668 | udmatim_reg |= APO_UDMA_TIME(chp->channel,(((apollo_udma66_tim[drvp->UDMA_mode]) & 0xf) << (((1 - (chp->channel)) << 4) + ((1 - (drive)) << 3))) | |||
3669 | drive, apollo_udma66_tim[drvp->UDMA_mode])(((apollo_udma66_tim[drvp->UDMA_mode]) & 0xf) << (((1 - (chp->channel)) << 4) + ((1 - (drive)) << 3))); | |||
3670 | } else { | |||
3671 | /* 596a or 586b */ | |||
3672 | udmatim_reg |= APO_UDMA_TIME(chp->channel,(((apollo_udma33_tim[drvp->UDMA_mode]) & 0xf) << (((1 - (chp->channel)) << 4) + ((1 - (drive)) << 3))) | |||
3673 | drive, apollo_udma33_tim[drvp->UDMA_mode])(((apollo_udma33_tim[drvp->UDMA_mode]) & 0xf) << (((1 - (chp->channel)) << 4) + ((1 - (drive)) << 3))); | |||
3674 | } | |||
3675 | /* can use PIO timings, MW DMA unused */ | |||
3676 | mode = drvp->PIO_mode; | |||
3677 | } else { | |||
3678 | /* use Multiword DMA */ | |||
3679 | drvp->drive_flags &= ~DRIVE_UDMA0x0020; | |||
3680 | /* mode = min(pio, dma+2) */ | |||
3681 | if (drvp->PIO_mode <= (drvp->DMA_mode +2)) | |||
3682 | mode = drvp->PIO_mode; | |||
3683 | else | |||
3684 | mode = drvp->DMA_mode + 2; | |||
3685 | } | |||
3686 | idedma_ctl |= IDEDMA_CTL_DRV_DMA(drive)(0x20 << (drive)); | |||
3687 | ||||
3688 | pio: /* setup PIO mode */ | |||
3689 | if (mode <= 2) { | |||
3690 | drvp->DMA_mode = 0; | |||
3691 | drvp->PIO_mode = 0; | |||
3692 | mode = 0; | |||
3693 | } else { | |||
3694 | drvp->PIO_mode = mode; | |||
3695 | drvp->DMA_mode = mode - 2; | |||
3696 | } | |||
3697 | datatim_reg |= | |||
3698 | APO_DATATIM_PULSE(chp->channel, drive,(((apollo_pio_set[mode]) & 0xf) << (((1 - (chp-> channel)) << 4) + ((1 - (drive)) << 3) + 4)) | |||
3699 | apollo_pio_set[mode])(((apollo_pio_set[mode]) & 0xf) << (((1 - (chp-> channel)) << 4) + ((1 - (drive)) << 3) + 4)) | | |||
3700 | APO_DATATIM_RECOV(chp->channel, drive,(((apollo_pio_rec[mode]) & 0xf) << (((1 - (chp-> channel)) << 4) + ((1 - (drive)) << 3))) | |||
3701 | apollo_pio_rec[mode])(((apollo_pio_rec[mode]) & 0xf) << (((1 - (chp-> channel)) << 4) + ((1 - (drive)) << 3))); | |||
3702 | } | |||
3703 | if (idedma_ctl != 0) { | |||
3704 | /* Add software bits in status register */ | |||
3705 | bus_space_write_1(sc->sc_dma_iot, sc->sc_dma_ioh,((sc->sc_dma_iot)->write_1((sc->sc_dma_ioh), ((0x02 + 0x08 * (chp->channel))), (idedma_ctl))) | |||
3706 | IDEDMA_CTL(chp->channel),((sc->sc_dma_iot)->write_1((sc->sc_dma_ioh), ((0x02 + 0x08 * (chp->channel))), (idedma_ctl))) | |||
3707 | idedma_ctl)((sc->sc_dma_iot)->write_1((sc->sc_dma_ioh), ((0x02 + 0x08 * (chp->channel))), (idedma_ctl))); | |||
3708 | } | |||
3709 | pciide_print_modes(cp); | |||
3710 | pci_conf_write(sc->sc_pc, sc->sc_tag, APO_DATATIM0x48, datatim_reg); | |||
3711 | pci_conf_write(sc->sc_pc, sc->sc_tag, APO_UDMA0x50, udmatim_reg); | |||
3712 | } | |||
3713 | ||||
3714 | void | |||
3715 | cmd_channel_map(struct pci_attach_args *pa, struct pciide_softc *sc, | |||
3716 | int channel) | |||
3717 | { | |||
3718 | struct pciide_channel *cp = &sc->pciide_channels[channel]; | |||
3719 | bus_size_t cmdsize, ctlsize; | |||
3720 | u_int8_t ctrl = pciide_pci_read(sc->sc_pc, sc->sc_tag, CMD_CTRL0x51); | |||
3721 | pcireg_t interface; | |||
3722 | int one_channel; | |||
3723 | ||||
3724 | /* | |||
3725 | * The 0648/0649 can be told to identify as a RAID controller. | |||
3726 | * In this case, we have to fake interface | |||
3727 | */ | |||
3728 | if (PCI_SUBCLASS(pa->pa_class)(((pa->pa_class) >> 16) & 0xff) != PCI_SUBCLASS_MASS_STORAGE_IDE0x01) { | |||
3729 | interface = PCIIDE_INTERFACE_SETTABLE(0)(0x02 << (2 * (0))) | | |||
3730 | PCIIDE_INTERFACE_SETTABLE(1)(0x02 << (2 * (1))); | |||
3731 | if (pciide_pci_read(pa->pa_pc, pa->pa_tag, CMD_CONF0x50) & | |||
3732 | CMD_CONF_DSA10x40) | |||
3733 | interface |= PCIIDE_INTERFACE_PCI(0)(0x01 << (2 * (0))) | | |||
3734 | PCIIDE_INTERFACE_PCI(1)(0x01 << (2 * (1))); | |||
3735 | } else { | |||
3736 | interface = PCI_INTERFACE(pa->pa_class)(((pa->pa_class) >> 8) & 0xff); | |||
3737 | } | |||
3738 | ||||
3739 | sc->wdc_chanarray[channel] = &cp->wdc_channel; | |||
3740 | cp->name = PCIIDE_CHANNEL_NAME(channel)((channel) == 0 ? "channel 0" : "channel 1"); | |||
3741 | cp->wdc_channel.channel = channel; | |||
3742 | cp->wdc_channel.wdc = &sc->sc_wdcdev; | |||
3743 | ||||
3744 | /* | |||
3745 | * Older CMD64X doesn't have independent channels | |||
3746 | */ | |||
3747 | switch (sc->sc_pp->ide_product) { | |||
3748 | case PCI_PRODUCT_CMDTECH_6490x0649: | |||
3749 | one_channel = 0; | |||
3750 | break; | |||
3751 | default: | |||
3752 | one_channel = 1; | |||
3753 | break; | |||
3754 | } | |||
3755 | ||||
3756 | if (channel > 0 && one_channel) { | |||
3757 | cp->wdc_channel.ch_queue = | |||
3758 | sc->pciide_channels[0].wdc_channel.ch_queue; | |||
3759 | } else { | |||
3760 | cp->wdc_channel.ch_queue = wdc_alloc_queue(); | |||
3761 | } | |||
3762 | if (cp->wdc_channel.ch_queue == NULL((void *)0)) { | |||
3763 | printf( | |||
3764 | "%s: %s cannot allocate channel queue", | |||
3765 | sc->sc_wdcdev.sc_dev.dv_xname, cp->name); | |||
3766 | return; | |||
3767 | } | |||
3768 | ||||
3769 | /* | |||
3770 | * with a CMD PCI64x, if we get here, the first channel is enabled: | |||
3771 | * there's no way to disable the first channel without disabling | |||
3772 | * the whole device | |||
3773 | */ | |||
3774 | if (channel != 0 && (ctrl & CMD_CTRL_2PORT0x08) == 0) { | |||
3775 | printf("%s: %s ignored (disabled)\n", | |||
3776 | sc->sc_wdcdev.sc_dev.dv_xname, cp->name); | |||
3777 | cp->hw_ok = 0; | |||
3778 | return; | |||
3779 | } | |||
3780 | cp->hw_ok = 1; | |||
3781 | pciide_map_compat_intr(pa, cp, channel, interface); | |||
3782 | if (cp->hw_ok == 0) | |||
3783 | return; | |||
3784 | pciide_mapchan(pa, cp, interface, &cmdsize, &ctlsize, cmd_pci_intr); | |||
3785 | if (cp->hw_ok == 0) { | |||
3786 | pciide_unmap_compat_intr(pa, cp, channel, interface); | |||
3787 | return; | |||
3788 | } | |||
3789 | if (pciide_chan_candisable(cp)) { | |||
3790 | if (channel == 1) { | |||
3791 | ctrl &= ~CMD_CTRL_2PORT0x08; | |||
3792 | pciide_pci_write(pa->pa_pc, pa->pa_tag, | |||
3793 | CMD_CTRL0x51, ctrl); | |||
3794 | pciide_unmap_compat_intr(pa, cp, channel, interface); | |||
3795 | } | |||
3796 | } | |||
3797 | } | |||
3798 | ||||
3799 | int | |||
3800 | cmd_pci_intr(void *arg) | |||
3801 | { | |||
3802 | struct pciide_softc *sc = arg; | |||
3803 | struct pciide_channel *cp; | |||
3804 | struct channel_softc *wdc_cp; | |||
3805 | int i, rv, crv; | |||
3806 | u_int32_t priirq, secirq; | |||
3807 | ||||
3808 | rv = 0; | |||
3809 | priirq = pciide_pci_read(sc->sc_pc, sc->sc_tag, CMD_CONF0x50); | |||
3810 | secirq = pciide_pci_read(sc->sc_pc, sc->sc_tag, CMD_ARTTIM230x57); | |||
3811 | for (i = 0; i < sc->sc_wdcdev.nchannels; i++) { | |||
3812 | cp = &sc->pciide_channels[i]; | |||
3813 | wdc_cp = &cp->wdc_channel; | |||
3814 | /* If a compat channel skip. */ | |||
3815 | if (cp->compat) | |||
3816 | continue; | |||
3817 | if ((i == 0 && (priirq & CMD_CONF_DRV0_INTR0x04)) || | |||
3818 | (i == 1 && (secirq & CMD_ARTTIM23_IRQ0x10))) { | |||
3819 | crv = wdcintr(wdc_cp); | |||
3820 | if (crv == 0) { | |||
3821 | #if 0 | |||
3822 | printf("%s:%d: bogus intr\n", | |||
3823 | sc->sc_wdcdev.sc_dev.dv_xname, i); | |||
3824 | #endif | |||
3825 | } else | |||
3826 | rv = 1; | |||
3827 | } | |||
3828 | } | |||
3829 | return (rv); | |||
3830 | } | |||
3831 | ||||
3832 | void | |||
3833 | cmd_chip_map(struct pciide_softc *sc, struct pci_attach_args *pa) | |||
3834 | { | |||
3835 | int channel; | |||
3836 | pcireg_t interface = PCI_INTERFACE(pa->pa_class)(((pa->pa_class) >> 8) & 0xff); | |||
3837 | ||||
3838 | printf(": no DMA"); | |||
3839 | sc->sc_dma_ok = 0; | |||
3840 | ||||
3841 | sc->sc_wdcdev.channels = sc->wdc_chanarray; | |||
3842 | sc->sc_wdcdev.nchannels = PCIIDE_NUM_CHANNELS2; | |||
3843 | sc->sc_wdcdev.cap = WDC_CAPABILITY_DATA160x0001; | |||
3844 | ||||
3845 | pciide_print_channels(sc->sc_wdcdev.nchannels, interface); | |||
3846 | ||||
3847 | for (channel = 0; channel < sc->sc_wdcdev.nchannels; channel++) { | |||
3848 | cmd_channel_map(pa, sc, channel); | |||
3849 | } | |||
3850 | } | |||
3851 | ||||
3852 | void | |||
3853 | cmd0643_9_chip_map(struct pciide_softc *sc, struct pci_attach_args *pa) | |||
3854 | { | |||
3855 | struct pciide_channel *cp; | |||
3856 | int channel; | |||
3857 | int rev = sc->sc_rev; | |||
3858 | pcireg_t interface; | |||
3859 | ||||
3860 | /* | |||
3861 | * The 0648/0649 can be told to identify as a RAID controller. | |||
3862 | * In this case, we have to fake interface | |||
3863 | */ | |||
3864 | if (PCI_SUBCLASS(pa->pa_class)(((pa->pa_class) >> 16) & 0xff) != PCI_SUBCLASS_MASS_STORAGE_IDE0x01) { | |||
3865 | interface = PCIIDE_INTERFACE_SETTABLE(0)(0x02 << (2 * (0))) | | |||
3866 | PCIIDE_INTERFACE_SETTABLE(1)(0x02 << (2 * (1))); | |||
3867 | if (pciide_pci_read(pa->pa_pc, pa->pa_tag, CMD_CONF0x50) & | |||
3868 | CMD_CONF_DSA10x40) | |||
3869 | interface |= PCIIDE_INTERFACE_PCI(0)(0x01 << (2 * (0))) | | |||
3870 | PCIIDE_INTERFACE_PCI(1)(0x01 << (2 * (1))); | |||
3871 | } else { | |||
3872 | interface = PCI_INTERFACE(pa->pa_class)(((pa->pa_class) >> 8) & 0xff); | |||
3873 | } | |||
3874 | ||||
3875 | printf(": DMA"); | |||
3876 | pciide_mapreg_dma(sc, pa); | |||
3877 | sc->sc_wdcdev.cap = WDC_CAPABILITY_DATA160x0001 | WDC_CAPABILITY_DATA320x0002 | | |||
3878 | WDC_CAPABILITY_MODE0x0004; | |||
3879 | if (sc->sc_dma_ok) { | |||
3880 | sc->sc_wdcdev.cap |= WDC_CAPABILITY_DMA0x0008 | WDC_CAPABILITY_IRQACK0x0400; | |||
3881 | switch (sc->sc_pp->ide_product) { | |||
3882 | case PCI_PRODUCT_CMDTECH_6490x0649: | |||
3883 | sc->sc_wdcdev.cap |= WDC_CAPABILITY_UDMA0x0010; | |||
3884 | sc->sc_wdcdev.UDMA_cap = 5; | |||
3885 | sc->sc_wdcdev.irqack = cmd646_9_irqack; | |||
3886 | break; | |||
3887 | case PCI_PRODUCT_CMDTECH_6480x0648: | |||
3888 | sc->sc_wdcdev.cap |= WDC_CAPABILITY_UDMA0x0010; | |||
3889 | sc->sc_wdcdev.UDMA_cap = 4; | |||
3890 | sc->sc_wdcdev.irqack = cmd646_9_irqack; | |||
3891 | break; | |||
3892 | case PCI_PRODUCT_CMDTECH_6460x0646: | |||
3893 | if (rev >= CMD0646U2_REV0x05) { | |||
3894 | sc->sc_wdcdev.cap |= WDC_CAPABILITY_UDMA0x0010; | |||
3895 | sc->sc_wdcdev.UDMA_cap = 2; | |||
3896 | } else if (rev >= CMD0646U_REV0x03) { | |||
3897 | /* | |||
3898 | * Linux's driver claims that the 646U is broken | |||
3899 | * with UDMA. Only enable it if we know what we're | |||
3900 | * doing | |||
3901 | */ | |||
3902 | #ifdef PCIIDE_CMD0646U_ENABLEUDMA | |||
3903 | sc->sc_wdcdev.cap |= WDC_CAPABILITY_UDMA0x0010; | |||
3904 | sc->sc_wdcdev.UDMA_cap = 2; | |||
3905 | #endif | |||
3906 | /* explicitly disable UDMA */ | |||
3907 | pciide_pci_write(sc->sc_pc, sc->sc_tag, | |||
3908 | CMD_UDMATIM(0)(0x73 + (8 * (0))), 0); | |||
3909 | pciide_pci_write(sc->sc_pc, sc->sc_tag, | |||
3910 | CMD_UDMATIM(1)(0x73 + (8 * (1))), 0); | |||
3911 | } | |||
3912 | sc->sc_wdcdev.irqack = cmd646_9_irqack; | |||
3913 | break; | |||
3914 | default: | |||
3915 | sc->sc_wdcdev.irqack = pciide_irqack; | |||
3916 | } | |||
3917 | } | |||
3918 | ||||
3919 | sc->sc_wdcdev.channels = sc->wdc_chanarray; | |||
3920 | sc->sc_wdcdev.nchannels = PCIIDE_NUM_CHANNELS2; | |||
3921 | sc->sc_wdcdev.PIO_cap = 4; | |||
3922 | sc->sc_wdcdev.DMA_cap = 2; | |||
3923 | sc->sc_wdcdev.set_modes = cmd0643_9_setup_channel; | |||
3924 | ||||
3925 | pciide_print_channels(sc->sc_wdcdev.nchannels, interface); | |||
3926 | ||||
3927 | WDCDEBUG_PRINT(("cmd0643_9_chip_map: old timings reg 0x%x 0x%x\n", | |||
3928 | pci_conf_read(sc->sc_pc, sc->sc_tag, 0x54), | |||
3929 | pci_conf_read(sc->sc_pc, sc->sc_tag, 0x58)), | |||
3930 | DEBUG_PROBE); | |||
3931 | for (channel = 0; channel < sc->sc_wdcdev.nchannels; channel++) { | |||
3932 | cp = &sc->pciide_channels[channel]; | |||
3933 | cmd_channel_map(pa, sc, channel); | |||
3934 | if (cp->hw_ok == 0) | |||
3935 | continue; | |||
3936 | cmd0643_9_setup_channel(&cp->wdc_channel); | |||
3937 | } | |||
3938 | /* | |||
3939 | * note - this also makes sure we clear the irq disable and reset | |||
3940 | * bits | |||
3941 | */ | |||
3942 | pciide_pci_write(sc->sc_pc, sc->sc_tag, CMD_DMA_MODE0x71, CMD_DMA_MULTIPLE0x01); | |||
3943 | WDCDEBUG_PRINT(("cmd0643_9_chip_map: timings reg now 0x%x 0x%x\n", | |||
3944 | pci_conf_read(sc->sc_pc, sc->sc_tag, 0x54), | |||
3945 | pci_conf_read(sc->sc_pc, sc->sc_tag, 0x58)), | |||
3946 | DEBUG_PROBE); | |||
3947 | } | |||
3948 | ||||
3949 | void | |||
3950 | cmd0643_9_setup_channel(struct channel_softc *chp) | |||
3951 | { | |||
3952 | struct ata_drive_datas *drvp; | |||
3953 | u_int8_t tim; | |||
3954 | u_int32_t idedma_ctl, udma_reg; | |||
3955 | int drive; | |||
3956 | struct pciide_channel *cp = (struct pciide_channel *)chp; | |||
3957 | struct pciide_softc *sc = (struct pciide_softc *)cp->wdc_channel.wdc; | |||
3958 | ||||
3959 | idedma_ctl = 0; | |||
3960 | /* setup DMA if needed */ | |||
3961 | pciide_channel_dma_setup(cp); | |||
3962 | ||||
3963 | for (drive = 0; drive < 2; drive++) { | |||
3964 | drvp = &chp->ch_drive[drive]; | |||
3965 | /* If no drive, skip */ | |||
3966 | if ((drvp->drive_flags & DRIVE(0x0001|0x0002|0x0004)) == 0) | |||
3967 | continue; | |||
3968 | /* add timing values, setup DMA if needed */ | |||
3969 | tim = cmd0643_9_data_tim_pio[drvp->PIO_mode]; | |||
3970 | if (drvp->drive_flags & (DRIVE_DMA0x0010 | DRIVE_UDMA0x0020)) { | |||
3971 | if (drvp->drive_flags & DRIVE_UDMA0x0020) { | |||
3972 | /* UltraDMA on a 646U2, 0648 or 0649 */ | |||
3973 | drvp->drive_flags &= ~DRIVE_DMA0x0010; | |||
3974 | udma_reg = pciide_pci_read(sc->sc_pc, | |||
3975 | sc->sc_tag, CMD_UDMATIM(chp->channel)(0x73 + (8 * (chp->channel)))); | |||
3976 | if (drvp->UDMA_mode > 2 && | |||
3977 | (pciide_pci_read(sc->sc_pc, sc->sc_tag, | |||
3978 | CMD_BICSR0x79) & | |||
3979 | CMD_BICSR_80(chp->channel)(0x01 << (chp->channel))) == 0) { | |||
3980 | WDCDEBUG_PRINT(("%s(%s:%d:%d): " | |||
3981 | "80-wire cable not detected\n", | |||
3982 | drvp->drive_name, | |||
3983 | sc->sc_wdcdev.sc_dev.dv_xname, | |||
3984 | chp->channel, drive), DEBUG_PROBE); | |||
3985 | drvp->UDMA_mode = 2; | |||
3986 | } | |||
3987 | if (drvp->UDMA_mode > 2) | |||
3988 | udma_reg &= ~CMD_UDMATIM_UDMA33(drive)(0x04 << (drive)); | |||
3989 | else if (sc->sc_wdcdev.UDMA_cap > 2) | |||
3990 | udma_reg |= CMD_UDMATIM_UDMA33(drive)(0x04 << (drive)); | |||
3991 | udma_reg |= CMD_UDMATIM_UDMA(drive)(0x01 << (drive)); | |||
3992 | udma_reg &= ~(CMD_UDMATIM_TIM_MASK0x3 << | |||
3993 | CMD_UDMATIM_TIM_OFF(drive)(4 + ((drive) * 2))); | |||
3994 | udma_reg |= | |||
3995 | (cmd0646_9_tim_udma[drvp->UDMA_mode] << | |||
3996 | CMD_UDMATIM_TIM_OFF(drive)(4 + ((drive) * 2))); | |||
3997 | pciide_pci_write(sc->sc_pc, sc->sc_tag, | |||
3998 | CMD_UDMATIM(chp->channel)(0x73 + (8 * (chp->channel))), udma_reg); | |||
3999 | } else { | |||
4000 | /* | |||
4001 | * use Multiword DMA. | |||
4002 | * Timings will be used for both PIO and DMA, | |||
4003 | * so adjust DMA mode if needed | |||
4004 | * if we have a 0646U2/8/9, turn off UDMA | |||
4005 | */ | |||
4006 | if (sc->sc_wdcdev.cap & WDC_CAPABILITY_UDMA0x0010) { | |||
4007 | udma_reg = pciide_pci_read(sc->sc_pc, | |||
4008 | sc->sc_tag, | |||
4009 | CMD_UDMATIM(chp->channel)(0x73 + (8 * (chp->channel)))); | |||
4010 | udma_reg &= ~CMD_UDMATIM_UDMA(drive)(0x01 << (drive)); | |||
4011 | pciide_pci_write(sc->sc_pc, sc->sc_tag, | |||
4012 | CMD_UDMATIM(chp->channel)(0x73 + (8 * (chp->channel))), | |||
4013 | udma_reg); | |||
4014 | } | |||
4015 | if (drvp->PIO_mode >= 3 && | |||
4016 | (drvp->DMA_mode + 2) > drvp->PIO_mode) { | |||
4017 | drvp->DMA_mode = drvp->PIO_mode - 2; | |||
4018 | } | |||
4019 | tim = cmd0643_9_data_tim_dma[drvp->DMA_mode]; | |||
4020 | } | |||
4021 | idedma_ctl |= IDEDMA_CTL_DRV_DMA(drive)(0x20 << (drive)); | |||
4022 | } | |||
4023 | pciide_pci_write(sc->sc_pc, sc->sc_tag, | |||
4024 | CMD_DATA_TIM(chp->channel, drive)(((chp->channel) == 0) ? ((drive) == 0) ? 0x54: 0x56 : ((drive ) == 0) ? 0x58 : 0x5b), tim); | |||
4025 | } | |||
4026 | if (idedma_ctl != 0) { | |||
4027 | /* Add software bits in status register */ | |||
4028 | bus_space_write_1(sc->sc_dma_iot, sc->sc_dma_ioh,((sc->sc_dma_iot)->write_1((sc->sc_dma_ioh), ((0x02 + 0x08 * (chp->channel))), (idedma_ctl))) | |||
4029 | IDEDMA_CTL(chp->channel),((sc->sc_dma_iot)->write_1((sc->sc_dma_ioh), ((0x02 + 0x08 * (chp->channel))), (idedma_ctl))) | |||
4030 | idedma_ctl)((sc->sc_dma_iot)->write_1((sc->sc_dma_ioh), ((0x02 + 0x08 * (chp->channel))), (idedma_ctl))); | |||
4031 | } | |||
4032 | pciide_print_modes(cp); | |||
4033 | #ifdef __sparc64__ | |||
4034 | /* | |||
4035 | * The Ultra 5 has a tendency to hang during reboot. This is due | |||
4036 | * to the PCI0646U asserting a PCI interrupt line when the chip | |||
4037 | * registers claim that it is not. Performing a reset at this | |||
4038 | * point appears to eliminate the symptoms. It is likely the | |||
4039 | * real cause is still lurking somewhere in the code. | |||
4040 | */ | |||
4041 | wdcreset(chp, SILENT0x00); | |||
4042 | #endif /* __sparc64__ */ | |||
4043 | } | |||
4044 | ||||
4045 | void | |||
4046 | cmd646_9_irqack(struct channel_softc *chp) | |||
4047 | { | |||
4048 | u_int32_t priirq, secirq; | |||
4049 | struct pciide_channel *cp = (struct pciide_channel *)chp; | |||
4050 | struct pciide_softc *sc = (struct pciide_softc *)cp->wdc_channel.wdc; | |||
4051 | ||||
4052 | if (chp->channel == 0) { | |||
4053 | priirq = pciide_pci_read(sc->sc_pc, sc->sc_tag, CMD_CONF0x50); | |||
4054 | pciide_pci_write(sc->sc_pc, sc->sc_tag, CMD_CONF0x50, priirq); | |||
4055 | } else { | |||
4056 | secirq = pciide_pci_read(sc->sc_pc, sc->sc_tag, CMD_ARTTIM230x57); | |||
4057 | pciide_pci_write(sc->sc_pc, sc->sc_tag, CMD_ARTTIM230x57, secirq); | |||
4058 | } | |||
4059 | pciide_irqack(chp); | |||
4060 | } | |||
4061 | ||||
4062 | void | |||
4063 | cmd680_chip_map(struct pciide_softc *sc, struct pci_attach_args *pa) | |||
4064 | { | |||
4065 | struct pciide_channel *cp; | |||
4066 | int channel; | |||
4067 | ||||
4068 | printf("\n%s: bus-master DMA support present", | |||
4069 | sc->sc_wdcdev.sc_dev.dv_xname); | |||
4070 | pciide_mapreg_dma(sc, pa); | |||
4071 | printf("\n"); | |||
4072 | sc->sc_wdcdev.cap = WDC_CAPABILITY_DATA160x0001 | WDC_CAPABILITY_DATA320x0002 | | |||
4073 | WDC_CAPABILITY_MODE0x0004; | |||
4074 | if (sc->sc_dma_ok) { | |||
4075 | sc->sc_wdcdev.cap |= WDC_CAPABILITY_DMA0x0008 | WDC_CAPABILITY_IRQACK0x0400; | |||
4076 | sc->sc_wdcdev.cap |= WDC_CAPABILITY_UDMA0x0010; | |||
4077 | sc->sc_wdcdev.UDMA_cap = 6; | |||
4078 | sc->sc_wdcdev.irqack = pciide_irqack; | |||
4079 | } | |||
4080 | ||||
4081 | sc->sc_wdcdev.channels = sc->wdc_chanarray; | |||
4082 | sc->sc_wdcdev.nchannels = PCIIDE_NUM_CHANNELS2; | |||
4083 | sc->sc_wdcdev.PIO_cap = 4; | |||
4084 | sc->sc_wdcdev.DMA_cap = 2; | |||
4085 | sc->sc_wdcdev.set_modes = cmd680_setup_channel; | |||
4086 | ||||
4087 | pciide_pci_write(sc->sc_pc, sc->sc_tag, 0x80, 0x00); | |||
4088 | pciide_pci_write(sc->sc_pc, sc->sc_tag, 0x84, 0x00); | |||
4089 | pciide_pci_write(sc->sc_pc, sc->sc_tag, 0x8a, | |||
4090 | pciide_pci_read(sc->sc_pc, sc->sc_tag, 0x8a) | 0x01); | |||
4091 | for (channel = 0; channel < sc->sc_wdcdev.nchannels; channel++) { | |||
4092 | cp = &sc->pciide_channels[channel]; | |||
4093 | cmd680_channel_map(pa, sc, channel); | |||
4094 | if (cp->hw_ok == 0) | |||
4095 | continue; | |||
4096 | cmd680_setup_channel(&cp->wdc_channel); | |||
4097 | } | |||
4098 | } | |||
4099 | ||||
4100 | void | |||
4101 | cmd680_channel_map(struct pci_attach_args *pa, struct pciide_softc *sc, | |||
4102 | int channel) | |||
4103 | { | |||
4104 | struct pciide_channel *cp = &sc->pciide_channels[channel]; | |||
4105 | bus_size_t cmdsize, ctlsize; | |||
4106 | int interface, i, reg; | |||
4107 | static const u_int8_t init_val[] = | |||
4108 | { 0x8a, 0x32, 0x8a, 0x32, 0x8a, 0x32, | |||
4109 | 0x92, 0x43, 0x92, 0x43, 0x09, 0x40, 0x09, 0x40 }; | |||
4110 | ||||
4111 | if (PCI_SUBCLASS(pa->pa_class)(((pa->pa_class) >> 16) & 0xff) != PCI_SUBCLASS_MASS_STORAGE_IDE0x01) { | |||
4112 | interface = PCIIDE_INTERFACE_SETTABLE(0)(0x02 << (2 * (0))) | | |||
4113 | PCIIDE_INTERFACE_SETTABLE(1)(0x02 << (2 * (1))); | |||
4114 | interface |= PCIIDE_INTERFACE_PCI(0)(0x01 << (2 * (0))) | | |||
4115 | PCIIDE_INTERFACE_PCI(1)(0x01 << (2 * (1))); | |||
4116 | } else { | |||
4117 | interface = PCI_INTERFACE(pa->pa_class)(((pa->pa_class) >> 8) & 0xff); | |||
4118 | } | |||
4119 | ||||
4120 | sc->wdc_chanarray[channel] = &cp->wdc_channel; | |||
4121 | cp->name = PCIIDE_CHANNEL_NAME(channel)((channel) == 0 ? "channel 0" : "channel 1"); | |||
4122 | cp->wdc_channel.channel = channel; | |||
4123 | cp->wdc_channel.wdc = &sc->sc_wdcdev; | |||
4124 | ||||
4125 | cp->wdc_channel.ch_queue = wdc_alloc_queue(); | |||
4126 | if (cp->wdc_channel.ch_queue == NULL((void *)0)) { | |||
4127 | printf("%s %s: " | |||
4128 | "cannot allocate channel queue", | |||
4129 | sc->sc_wdcdev.sc_dev.dv_xname, cp->name); | |||
4130 | return; | |||
4131 | } | |||
4132 | ||||
4133 | /* XXX */ | |||
4134 | reg = 0xa2 + channel * 16; | |||
4135 | for (i = 0; i < sizeof(init_val); i++) | |||
4136 | pciide_pci_write(sc->sc_pc, sc->sc_tag, reg + i, init_val[i]); | |||
4137 | ||||
4138 | printf("%s: %s %s to %s mode\n", | |||
4139 | sc->sc_wdcdev.sc_dev.dv_xname, cp->name, | |||
4140 | (interface & PCIIDE_INTERFACE_SETTABLE(channel)(0x02 << (2 * (channel)))) ? | |||
4141 | "configured" : "wired", | |||
4142 | (interface & PCIIDE_INTERFACE_PCI(channel)(0x01 << (2 * (channel)))) ? | |||
4143 | "native-PCI" : "compatibility"); | |||
4144 | ||||
4145 | pciide_mapchan(pa, cp, interface, &cmdsize, &ctlsize, pciide_pci_intr); | |||
4146 | if (cp->hw_ok == 0) | |||
4147 | return; | |||
4148 | pciide_map_compat_intr(pa, cp, channel, interface); | |||
4149 | } | |||
4150 | ||||
4151 | void | |||
4152 | cmd680_setup_channel(struct channel_softc *chp) | |||
4153 | { | |||
4154 | struct ata_drive_datas *drvp; | |||
4155 | u_int8_t mode, off, scsc; | |||
4156 | u_int16_t val; | |||
4157 | u_int32_t idedma_ctl; | |||
4158 | int drive; | |||
4159 | struct pciide_channel *cp = (struct pciide_channel *)chp; | |||
4160 | struct pciide_softc *sc = (struct pciide_softc *)cp->wdc_channel.wdc; | |||
4161 | pci_chipset_tag_t pc = sc->sc_pc; | |||
4162 | pcitag_t pa = sc->sc_tag; | |||
4163 | static const u_int8_t udma2_tbl[] = | |||
4164 | { 0x0f, 0x0b, 0x07, 0x06, 0x03, 0x02, 0x01 }; | |||
4165 | static const u_int8_t udma_tbl[] = | |||
4166 | { 0x0c, 0x07, 0x05, 0x04, 0x02, 0x01, 0x00 }; | |||
4167 | static const u_int16_t dma_tbl[] = | |||
4168 | { 0x2208, 0x10c2, 0x10c1 }; | |||
4169 | static const u_int16_t pio_tbl[] = | |||
4170 | { 0x328a, 0x2283, 0x1104, 0x10c3, 0x10c1 }; | |||
4171 | ||||
4172 | idedma_ctl = 0; | |||
4173 | pciide_channel_dma_setup(cp); | |||
4174 | mode = pciide_pci_read(pc, pa, 0x80 + chp->channel * 4); | |||
4175 | ||||
4176 | for (drive = 0; drive < 2; drive++) { | |||
4177 | drvp = &chp->ch_drive[drive]; | |||
4178 | /* If no drive, skip */ | |||
4179 | if ((drvp->drive_flags & DRIVE(0x0001|0x0002|0x0004)) == 0) | |||
4180 | continue; | |||
4181 | mode &= ~(0x03 << (drive * 4)); | |||
4182 | if (drvp->drive_flags & DRIVE_UDMA0x0020) { | |||
4183 | drvp->drive_flags &= ~DRIVE_DMA0x0010; | |||
4184 | off = 0xa0 + chp->channel * 16; | |||
4185 | if (drvp->UDMA_mode > 2 && | |||
4186 | (pciide_pci_read(pc, pa, off) & 0x01) == 0) | |||
4187 | drvp->UDMA_mode = 2; | |||
4188 | scsc = pciide_pci_read(pc, pa, 0x8a); | |||
4189 | if (drvp->UDMA_mode == 6 && (scsc & 0x30) == 0) { | |||
4190 | pciide_pci_write(pc, pa, 0x8a, scsc | 0x01); | |||
4191 | scsc = pciide_pci_read(pc, pa, 0x8a); | |||
4192 | if ((scsc & 0x30) == 0) | |||
4193 | drvp->UDMA_mode = 5; | |||
4194 | } | |||
4195 | mode |= 0x03 << (drive * 4); | |||
4196 | off = 0xac + chp->channel * 16 + drive * 2; | |||
4197 | val = pciide_pci_read(pc, pa, off) & ~0x3f; | |||
4198 | if (scsc & 0x30) | |||
4199 | val |= udma2_tbl[drvp->UDMA_mode]; | |||
4200 | else | |||
4201 | val |= udma_tbl[drvp->UDMA_mode]; | |||
4202 | pciide_pci_write(pc, pa, off, val); | |||
4203 | idedma_ctl |= IDEDMA_CTL_DRV_DMA(drive)(0x20 << (drive)); | |||
4204 | } else if (drvp->drive_flags & DRIVE_DMA0x0010) { | |||
4205 | mode |= 0x02 << (drive * 4); | |||
4206 | off = 0xa8 + chp->channel * 16 + drive * 2; | |||
4207 | val = dma_tbl[drvp->DMA_mode]; | |||
4208 | pciide_pci_write(pc, pa, off, val & 0xff); | |||
4209 | pciide_pci_write(pc, pa, off, val >> 8); | |||
4210 | idedma_ctl |= IDEDMA_CTL_DRV_DMA(drive)(0x20 << (drive)); | |||
4211 | } else { | |||
4212 | mode |= 0x01 << (drive * 4); | |||
4213 | off = 0xa4 + chp->channel * 16 + drive * 2; | |||
4214 | val = pio_tbl[drvp->PIO_mode]; | |||
4215 | pciide_pci_write(pc, pa, off, val & 0xff); | |||
4216 | pciide_pci_write(pc, pa, off, val >> 8); | |||
4217 | } | |||
4218 | } | |||
4219 | ||||
4220 | pciide_pci_write(pc, pa, 0x80 + chp->channel * 4, mode); | |||
4221 | if (idedma_ctl != 0) { | |||
4222 | /* Add software bits in status register */ | |||
4223 | bus_space_write_1(sc->sc_dma_iot, sc->sc_dma_ioh,((sc->sc_dma_iot)->write_1((sc->sc_dma_ioh), ((0x02 + 0x08 * (chp->channel))), (idedma_ctl))) | |||
4224 | IDEDMA_CTL(chp->channel),((sc->sc_dma_iot)->write_1((sc->sc_dma_ioh), ((0x02 + 0x08 * (chp->channel))), (idedma_ctl))) | |||
4225 | idedma_ctl)((sc->sc_dma_iot)->write_1((sc->sc_dma_ioh), ((0x02 + 0x08 * (chp->channel))), (idedma_ctl))); | |||
4226 | } | |||
4227 | pciide_print_modes(cp); | |||
4228 | } | |||
4229 | ||||
4230 | /* | |||
4231 | * When the Silicon Image 3112 retries a PCI memory read command, | |||
4232 | * it may retry it as a memory read multiple command under some | |||
4233 | * circumstances. This can totally confuse some PCI controllers, | |||
4234 | * so ensure that it will never do this by making sure that the | |||
4235 | * Read Threshold (FIFO Read Request Control) field of the FIFO | |||
4236 | * Valid Byte Count and Control registers for both channels (BA5 | |||
4237 | * offset 0x40 and 0x44) are set to be at least as large as the | |||
4238 | * cacheline size register. | |||
4239 | */ | |||
4240 | void | |||
4241 | sii_fixup_cacheline(struct pciide_softc *sc, struct pci_attach_args *pa) | |||
4242 | { | |||
4243 | pcireg_t cls, reg40, reg44; | |||
4244 | ||||
4245 | cls = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_BHLC_REG0x0c); | |||
4246 | cls = (cls >> PCI_CACHELINE_SHIFT0) & PCI_CACHELINE_MASK0xff; | |||
4247 | cls *= 4; | |||
4248 | if (cls > 224) { | |||
4249 | cls = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_BHLC_REG0x0c); | |||
4250 | cls &= ~(PCI_CACHELINE_MASK0xff << PCI_CACHELINE_SHIFT0); | |||
4251 | cls |= ((224/4) << PCI_CACHELINE_SHIFT0); | |||
4252 | pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_BHLC_REG0x0c, cls); | |||
4253 | cls = 224; | |||
4254 | } | |||
4255 | if (cls < 32) | |||
4256 | cls = 32; | |||
4257 | cls = (cls + 31) / 32; | |||
4258 | reg40 = ba5_read_4(sc, 0x40); | |||
4259 | reg44 = ba5_read_4(sc, 0x44); | |||
4260 | if ((reg40 & 0x7) < cls) | |||
4261 | ba5_write_4(sc, 0x40, (reg40 & ~0x07) | cls); | |||
4262 | if ((reg44 & 0x7) < cls) | |||
4263 | ba5_write_4(sc, 0x44, (reg44 & ~0x07) | cls); | |||
4264 | } | |||
4265 | ||||
4266 | void | |||
4267 | sii3112_chip_map(struct pciide_softc *sc, struct pci_attach_args *pa) | |||
4268 | { | |||
4269 | struct pciide_channel *cp; | |||
4270 | bus_size_t cmdsize, ctlsize; | |||
4271 | pcireg_t interface, scs_cmd, cfgctl; | |||
4272 | int channel; | |||
4273 | struct pciide_satalink *sl; | |||
4274 | ||||
4275 | /* Allocate memory for private data */ | |||
4276 | sc->sc_cookielen = sizeof(*sl); | |||
4277 | sc->sc_cookie = malloc(sc->sc_cookielen, M_DEVBUF2, M_NOWAIT0x0002 | M_ZERO0x0008); | |||
4278 | sl = sc->sc_cookie; | |||
4279 | ||||
4280 | sc->chip_unmap = default_chip_unmap; | |||
4281 | ||||
4282 | #define SII3112_RESET_BITS((1U << 0) | (1U << 1) | (1U << 4) | (1U << 5) | (1U << 6) | (1U << 7)) \ | |||
4283 | (SCS_CMD_PBM_RESET(1U << 0) | SCS_CMD_ARB_RESET(1U << 1) | \ | |||
4284 | SCS_CMD_FF1_RESET(1U << 4) | SCS_CMD_FF0_RESET(1U << 5) | \ | |||
4285 | SCS_CMD_IDE1_RESET(1U << 6) | SCS_CMD_IDE0_RESET(1U << 7)) | |||
4286 | ||||
4287 | /* | |||
4288 | * Reset everything and then unblock all of the interrupts. | |||
4289 | */ | |||
4290 | scs_cmd = pci_conf_read(pa->pa_pc, pa->pa_tag, SII3112_SCS_CMD0x88); | |||
4291 | pci_conf_write(pa->pa_pc, pa->pa_tag, SII3112_SCS_CMD0x88, | |||
4292 | scs_cmd | SII3112_RESET_BITS((1U << 0) | (1U << 1) | (1U << 4) | (1U << 5) | (1U << 6) | (1U << 7))); | |||
4293 | delay(50 * 1000)(*delay_func)(50 * 1000); | |||
4294 | pci_conf_write(pa->pa_pc, pa->pa_tag, SII3112_SCS_CMD0x88, | |||
4295 | scs_cmd & SCS_CMD_BA5_EN(1U << 16)); | |||
4296 | delay(50 * 1000)(*delay_func)(50 * 1000); | |||
4297 | ||||
4298 | if (scs_cmd & SCS_CMD_BA5_EN(1U << 16)) { | |||
4299 | if (pci_mapreg_map(pa, PCI_MAPREG_START0x10 + 0x14, | |||
4300 | PCI_MAPREG_TYPE_MEM0x00000000 | | |||
4301 | PCI_MAPREG_MEM_TYPE_32BIT0x00000000, 0, | |||
4302 | &sl->ba5_st, &sl->ba5_sh, | |||
4303 | NULL((void *)0), NULL((void *)0), 0) != 0) | |||
4304 | printf(": unable to map BA5 register space\n"); | |||
4305 | else | |||
4306 | sl->ba5_en = 1; | |||
4307 | } else { | |||
4308 | cfgctl = pci_conf_read(pa->pa_pc, pa->pa_tag, | |||
4309 | SII3112_PCI_CFGCTL0x40); | |||
4310 | pci_conf_write(pa->pa_pc, pa->pa_tag, SII3112_PCI_CFGCTL0x40, | |||
4311 | cfgctl | CFGCTL_BA5INDEN(1U << 1)); | |||
4312 | } | |||
4313 | ||||
4314 | printf(": DMA"); | |||
4315 | pciide_mapreg_dma(sc, pa); | |||
4316 | printf("\n"); | |||
4317 | ||||
4318 | /* | |||
4319 | * Rev. <= 0x01 of the 3112 have a bug that can cause data | |||
4320 | * corruption if DMA transfers cross an 8K boundary. This is | |||
4321 | * apparently hard to tickle, but we'll go ahead and play it | |||
4322 | * safe. | |||
4323 | */ | |||
4324 | if (sc->sc_rev <= 0x01) { | |||
4325 | sc->sc_dma_maxsegsz = 8192; | |||
4326 | sc->sc_dma_boundary = 8192; | |||
4327 | } | |||
4328 | ||||
4329 | sii_fixup_cacheline(sc, pa); | |||
4330 | ||||
4331 | sc->sc_wdcdev.cap |= WDC_CAPABILITY_DATA160x0001 | WDC_CAPABILITY_DATA320x0002; | |||
4332 | sc->sc_wdcdev.PIO_cap = 4; | |||
4333 | if (sc->sc_dma_ok) { | |||
4334 | sc->sc_wdcdev.cap |= WDC_CAPABILITY_DMA0x0008 | WDC_CAPABILITY_UDMA0x0010; | |||
4335 | sc->sc_wdcdev.cap |= WDC_CAPABILITY_IRQACK0x0400; | |||
4336 | sc->sc_wdcdev.irqack = pciide_irqack; | |||
4337 | sc->sc_wdcdev.DMA_cap = 2; | |||
4338 | sc->sc_wdcdev.UDMA_cap = 6; | |||
4339 | } | |||
4340 | sc->sc_wdcdev.set_modes = sii3112_setup_channel; | |||
4341 | ||||
4342 | /* We can use SControl and SStatus to probe for drives. */ | |||
4343 | sc->sc_wdcdev.drv_probe = sii3112_drv_probe; | |||
4344 | ||||
4345 | sc->sc_wdcdev.channels = sc->wdc_chanarray; | |||
4346 | sc->sc_wdcdev.nchannels = PCIIDE_NUM_CHANNELS2; | |||
4347 | ||||
4348 | /* | |||
4349 | * The 3112 either identifies itself as a RAID storage device | |||
4350 | * or a Misc storage device. Fake up the interface bits for | |||
4351 | * what our driver expects. | |||
4352 | */ | |||
4353 | if (PCI_SUBCLASS(pa->pa_class)(((pa->pa_class) >> 16) & 0xff) == PCI_SUBCLASS_MASS_STORAGE_IDE0x01) { | |||
4354 | interface = PCI_INTERFACE(pa->pa_class)(((pa->pa_class) >> 8) & 0xff); | |||
4355 | } else { | |||
4356 | interface = PCIIDE_INTERFACE_BUS_MASTER_DMA0x80 | | |||
4357 | PCIIDE_INTERFACE_PCI(0)(0x01 << (2 * (0))) | PCIIDE_INTERFACE_PCI(1)(0x01 << (2 * (1))); | |||
4358 | } | |||
4359 | ||||
4360 | for (channel = 0; channel < sc->sc_wdcdev.nchannels; channel++) { | |||
4361 | cp = &sc->pciide_channels[channel]; | |||
4362 | if (pciide_chansetup(sc, channel, interface) == 0) | |||
4363 | continue; | |||
4364 | pciide_mapchan(pa, cp, interface, &cmdsize, &ctlsize, | |||
4365 | pciide_pci_intr); | |||
4366 | if (cp->hw_ok == 0) | |||
4367 | continue; | |||
4368 | sc->sc_wdcdev.set_modes(&cp->wdc_channel); | |||
4369 | } | |||
4370 | } | |||
4371 | ||||
4372 | void | |||
4373 | sii3112_setup_channel(struct channel_softc *chp) | |||
4374 | { | |||
4375 | struct ata_drive_datas *drvp; | |||
4376 | int drive; | |||
4377 | u_int32_t idedma_ctl, dtm; | |||
4378 | struct pciide_channel *cp = (struct pciide_channel *)chp; | |||
4379 | struct pciide_softc *sc = (struct pciide_softc *)cp->wdc_channel.wdc; | |||
4380 | ||||
4381 | /* setup DMA if needed */ | |||
4382 | pciide_channel_dma_setup(cp); | |||
4383 | ||||
4384 | idedma_ctl = 0; | |||
4385 | dtm = 0; | |||
4386 | ||||
4387 | for (drive = 0; drive < 2; drive++) { | |||
4388 | drvp = &chp->ch_drive[drive]; | |||
4389 | /* If no drive, skip */ | |||
4390 | if ((drvp->drive_flags & DRIVE(0x0001|0x0002|0x0004)) == 0) | |||
4391 | continue; | |||
4392 | if (drvp->drive_flags & DRIVE_UDMA0x0020) { | |||
4393 | /* use Ultra/DMA */ | |||
4394 | drvp->drive_flags &= ~DRIVE_DMA0x0010; | |||
4395 | idedma_ctl |= IDEDMA_CTL_DRV_DMA(drive)(0x20 << (drive)); | |||
4396 | dtm |= DTM_IDEx_DMA0x00000002; | |||
4397 | } else if (drvp->drive_flags & DRIVE_DMA0x0010) { | |||
4398 | idedma_ctl |= IDEDMA_CTL_DRV_DMA(drive)(0x20 << (drive)); | |||
4399 | dtm |= DTM_IDEx_DMA0x00000002; | |||
4400 | } else { | |||
4401 | dtm |= DTM_IDEx_PIO0x00000000; | |||
4402 | } | |||
4403 | } | |||
4404 | ||||
4405 | /* | |||
4406 | * Nothing to do to setup modes; it is meaningless in S-ATA | |||
4407 | * (but many S-ATA drives still want to get the SET_FEATURE | |||
4408 | * command). | |||
4409 | */ | |||
4410 | if (idedma_ctl != 0) { | |||
4411 | /* Add software bits in status register */ | |||
4412 | PCIIDE_DMACTL_WRITE(sc, chp->channel, idedma_ctl)(sc)->sc_dmactl_write((sc), (chp->channel), (idedma_ctl )); | |||
4413 | } | |||
4414 | BA5_WRITE_4(sc, chp->channel, ba5_IDE_DTM, dtm)ba5_write_4((sc), satalink_ba5_regmap[(chp->channel)].ba5_IDE_DTM , (dtm)); | |||
4415 | pciide_print_modes(cp); | |||
4416 | } | |||
4417 | ||||
4418 | void | |||
4419 | sii3112_drv_probe(struct channel_softc *chp) | |||
4420 | { | |||
4421 | struct pciide_channel *cp = (struct pciide_channel *)chp; | |||
4422 | struct pciide_softc *sc = (struct pciide_softc *)cp->wdc_channel.wdc; | |||
4423 | uint32_t scontrol, sstatus; | |||
4424 | uint8_t scnt, sn, cl, ch; | |||
4425 | int s; | |||
4426 | ||||
4427 | /* | |||
4428 | * The 3112 is a 2-port part, and only has one drive per channel | |||
4429 | * (each port emulates a master drive). | |||
4430 | * | |||
4431 | * The 3114 is similar, but has 4 channels. | |||
4432 | */ | |||
4433 | ||||
4434 | /* | |||
4435 | * Request communication initialization sequence, any speed. | |||
4436 | * Performing this is the equivalent of an ATA Reset. | |||
4437 | */ | |||
4438 | scontrol = SControl_DET_INIT(0x1 << 0) | SControl_SPD_ANY(0x0 << 4); | |||
4439 | ||||
4440 | /* | |||
4441 | * XXX We don't yet support SATA power management; disable all | |||
4442 | * power management state transitions. | |||
4443 | */ | |||
4444 | scontrol |= SControl_IPM_NONE(0x3 << 8); | |||
4445 | ||||
4446 | BA5_WRITE_4(sc, chp->channel, ba5_SControl, scontrol)ba5_write_4((sc), satalink_ba5_regmap[(chp->channel)].ba5_SControl , (scontrol)); | |||
4447 | delay(50 * 1000)(*delay_func)(50 * 1000); | |||
4448 | scontrol &= ~SControl_DET_INIT(0x1 << 0); | |||
4449 | BA5_WRITE_4(sc, chp->channel, ba5_SControl, scontrol)ba5_write_4((sc), satalink_ba5_regmap[(chp->channel)].ba5_SControl , (scontrol)); | |||
4450 | delay(50 * 1000)(*delay_func)(50 * 1000); | |||
4451 | ||||
4452 | sstatus = BA5_READ_4(sc, chp->channel, ba5_SStatus)ba5_read_4((sc), satalink_ba5_regmap[(chp->channel)].ba5_SStatus ); | |||
4453 | #if 0 | |||
4454 | printf("%s: port %d: SStatus=0x%08x, SControl=0x%08x\n", | |||
4455 | sc->sc_wdcdev.sc_dev.dv_xname, chp->channel, sstatus, | |||
4456 | BA5_READ_4(sc, chp->channel, ba5_SControl)ba5_read_4((sc), satalink_ba5_regmap[(chp->channel)].ba5_SControl )); | |||
4457 | #endif | |||
4458 | switch (sstatus & SStatus_DET_mask(0xf << 0)) { | |||
4459 | case SStatus_DET_NODEV(0x0 << 0): | |||
4460 | /* No device; be silent. */ | |||
4461 | break; | |||
4462 | ||||
4463 | case SStatus_DET_DEV_NE(0x1 << 0): | |||
4464 | printf("%s: port %d: device connected, but " | |||
4465 | "communication not established\n", | |||
4466 | sc->sc_wdcdev.sc_dev.dv_xname, chp->channel); | |||
4467 | break; | |||
4468 | ||||
4469 | case SStatus_DET_OFFLINE(0x4 << 0): | |||
4470 | printf("%s: port %d: PHY offline\n", | |||
4471 | sc->sc_wdcdev.sc_dev.dv_xname, chp->channel); | |||
4472 | break; | |||
4473 | ||||
4474 | case SStatus_DET_DEV(0x3 << 0): | |||
4475 | /* | |||
4476 | * XXX ATAPI detection doesn't currently work. Don't | |||
4477 | * XXX know why. But, it's not like the standard method | |||
4478 | * XXX can detect an ATAPI device connected via a SATA/PATA | |||
4479 | * XXX bridge, so at least this is no worse. --thorpej | |||
4480 | */ | |||
4481 | if (chp->_vtbl != NULL((void *)0)) | |||
4482 | CHP_WRITE_REG(chp, wdr_sdh, WDSD_IBM | (0 << 4))((chp)->_vtbl->write_reg)(chp, wdr_sdh, 0xa0 | (0 << 4)); | |||
4483 | else | |||
4484 | bus_space_write_1(chp->cmd_iot, chp->cmd_ioh,((chp->cmd_iot)->write_1((chp->cmd_ioh), (wdr_sdh & 7), (0xa0 | (0 << 4)))) | |||
4485 | wdr_sdh & _WDC_REGMASK, WDSD_IBM | (0 << 4))((chp->cmd_iot)->write_1((chp->cmd_ioh), (wdr_sdh & 7), (0xa0 | (0 << 4)))); | |||
4486 | delay(10)(*delay_func)(10); /* 400ns delay */ | |||
4487 | /* Save register contents. */ | |||
4488 | if (chp->_vtbl != NULL((void *)0)) { | |||
4489 | scnt = CHP_READ_REG(chp, wdr_seccnt)((chp)->_vtbl->read_reg)(chp, wdr_seccnt); | |||
4490 | sn = CHP_READ_REG(chp, wdr_sector)((chp)->_vtbl->read_reg)(chp, wdr_sector); | |||
4491 | cl = CHP_READ_REG(chp, wdr_cyl_lo)((chp)->_vtbl->read_reg)(chp, wdr_cyl_lo); | |||
4492 | ch = CHP_READ_REG(chp, wdr_cyl_hi)((chp)->_vtbl->read_reg)(chp, wdr_cyl_hi); | |||
4493 | } else { | |||
4494 | scnt = bus_space_read_1(chp->cmd_iot,((chp->cmd_iot)->read_1((chp->cmd_ioh), (wdr_seccnt & 7))) | |||
4495 | chp->cmd_ioh, wdr_seccnt & _WDC_REGMASK)((chp->cmd_iot)->read_1((chp->cmd_ioh), (wdr_seccnt & 7))); | |||
4496 | sn = bus_space_read_1(chp->cmd_iot,((chp->cmd_iot)->read_1((chp->cmd_ioh), (wdr_sector & 7))) | |||
4497 | chp->cmd_ioh, wdr_sector & _WDC_REGMASK)((chp->cmd_iot)->read_1((chp->cmd_ioh), (wdr_sector & 7))); | |||
4498 | cl = bus_space_read_1(chp->cmd_iot,((chp->cmd_iot)->read_1((chp->cmd_ioh), (wdr_cyl_lo & 7))) | |||
4499 | chp->cmd_ioh, wdr_cyl_lo & _WDC_REGMASK)((chp->cmd_iot)->read_1((chp->cmd_ioh), (wdr_cyl_lo & 7))); | |||
4500 | ch = bus_space_read_1(chp->cmd_iot,((chp->cmd_iot)->read_1((chp->cmd_ioh), (wdr_cyl_hi & 7))) | |||
4501 | chp->cmd_ioh, wdr_cyl_hi & _WDC_REGMASK)((chp->cmd_iot)->read_1((chp->cmd_ioh), (wdr_cyl_hi & 7))); | |||
4502 | } | |||
4503 | #if 0 | |||
4504 | printf("%s: port %d: scnt=0x%x sn=0x%x cl=0x%x ch=0x%x\n", | |||
4505 | sc->sc_wdcdev.sc_dev.dv_xname, chp->channel, | |||
4506 | scnt, sn, cl, ch); | |||
4507 | #endif | |||
4508 | /* | |||
4509 | * scnt and sn are supposed to be 0x1 for ATAPI, but in some | |||
4510 | * cases we get wrong values here, so ignore it. | |||
4511 | */ | |||
4512 | s = splbio()splraise(0x3); | |||
4513 | if (cl == 0x14 && ch == 0xeb) | |||
4514 | chp->ch_drive[0].drive_flags |= DRIVE_ATAPI0x0002; | |||
4515 | else | |||
4516 | chp->ch_drive[0].drive_flags |= DRIVE_ATA0x0001; | |||
4517 | splx(s)spllower(s); | |||
4518 | ||||
4519 | printf("%s: port %d", | |||
4520 | sc->sc_wdcdev.sc_dev.dv_xname, chp->channel); | |||
4521 | switch ((sstatus & SStatus_SPD_mask(0xf << 4)) >> SStatus_SPD_shift4) { | |||
4522 | case 1: | |||
4523 | printf(": 1.5Gb/s"); | |||
4524 | break; | |||
4525 | case 2: | |||
4526 | printf(": 3.0Gb/s"); | |||
4527 | break; | |||
4528 | } | |||
4529 | printf("\n"); | |||
4530 | break; | |||
4531 | ||||
4532 | default: | |||
4533 | printf("%s: port %d: unknown SStatus: 0x%08x\n", | |||
4534 | sc->sc_wdcdev.sc_dev.dv_xname, chp->channel, sstatus); | |||
4535 | } | |||
4536 | } | |||
4537 | ||||
4538 | void | |||
4539 | sii3114_chip_map(struct pciide_softc *sc, struct pci_attach_args *pa) | |||
4540 | { | |||
4541 | struct pciide_channel *cp; | |||
4542 | pcireg_t scs_cmd; | |||
4543 | pci_intr_handle_t intrhandle; | |||
4544 | const char *intrstr; | |||
4545 | int channel; | |||
4546 | struct pciide_satalink *sl; | |||
4547 | ||||
4548 | /* Allocate memory for private data */ | |||
4549 | sc->sc_cookielen = sizeof(*sl); | |||
4550 | sc->sc_cookie = malloc(sc->sc_cookielen, M_DEVBUF2, M_NOWAIT0x0002 | M_ZERO0x0008); | |||
4551 | sl = sc->sc_cookie; | |||
4552 | ||||
4553 | #define SII3114_RESET_BITS((1U << 0) | (1U << 1) | (1U << 4) | (1U << 5) | (1U << 8) | (1U << 9) | (1U << 6) | ( 1U << 7) | (1U << 10) | (1U << 11)) \ | |||
4554 | (SCS_CMD_PBM_RESET(1U << 0) | SCS_CMD_ARB_RESET(1U << 1) | \ | |||
4555 | SCS_CMD_FF1_RESET(1U << 4) | SCS_CMD_FF0_RESET(1U << 5) | \ | |||
4556 | SCS_CMD_FF3_RESET(1U << 8) | SCS_CMD_FF2_RESET(1U << 9) | \ | |||
4557 | SCS_CMD_IDE1_RESET(1U << 6) | SCS_CMD_IDE0_RESET(1U << 7) | \ | |||
4558 | SCS_CMD_IDE3_RESET(1U << 10) | SCS_CMD_IDE2_RESET(1U << 11)) | |||
4559 | ||||
4560 | /* | |||
4561 | * Reset everything and then unblock all of the interrupts. | |||
4562 | */ | |||
4563 | scs_cmd = pci_conf_read(pa->pa_pc, pa->pa_tag, SII3112_SCS_CMD0x88); | |||
4564 | pci_conf_write(pa->pa_pc, pa->pa_tag, SII3112_SCS_CMD0x88, | |||
4565 | scs_cmd | SII3114_RESET_BITS((1U << 0) | (1U << 1) | (1U << 4) | (1U << 5) | (1U << 8) | (1U << 9) | (1U << 6) | ( 1U << 7) | (1U << 10) | (1U << 11))); | |||
4566 | delay(50 * 1000)(*delay_func)(50 * 1000); | |||
4567 | pci_conf_write(pa->pa_pc, pa->pa_tag, SII3112_SCS_CMD0x88, | |||
4568 | scs_cmd & SCS_CMD_M66EN(1U << 16)); | |||
4569 | delay(50 * 1000)(*delay_func)(50 * 1000); | |||
4570 | ||||
4571 | /* | |||
4572 | * On the 3114, the BA5 register space is always enabled. In | |||
4573 | * order to use the 3114 in any sane way, we must use this BA5 | |||
4574 | * register space, and so we consider it an error if we cannot | |||
4575 | * map it. | |||
4576 | * | |||
4577 | * As a consequence of using BA5, our register mapping is different | |||
4578 | * from a normal PCI IDE controller's, and so we are unable to use | |||
4579 | * most of the common PCI IDE register mapping functions. | |||
4580 | */ | |||
4581 | if (pci_mapreg_map(pa, PCI_MAPREG_START0x10 + 0x14, | |||
4582 | PCI_MAPREG_TYPE_MEM0x00000000 | | |||
4583 | PCI_MAPREG_MEM_TYPE_32BIT0x00000000, 0, | |||
4584 | &sl->ba5_st, &sl->ba5_sh, | |||
4585 | NULL((void *)0), NULL((void *)0), 0) != 0) { | |||
4586 | printf(": unable to map BA5 register space\n"); | |||
4587 | return; | |||
4588 | } | |||
4589 | sl->ba5_en = 1; | |||
4590 | ||||
4591 | /* | |||
4592 | * Set the Interrupt Steering bit in the IDEDMA_CMD register of | |||
4593 | * channel 2. This is required at all times for proper operation | |||
4594 | * when using the BA5 register space (otherwise interrupts from | |||
4595 | * all 4 channels won't work). | |||
4596 | */ | |||
4597 | BA5_WRITE_4(sc, 2, ba5_IDEDMA_CMD, IDEDMA_CMD_INT_STEER)ba5_write_4((sc), satalink_ba5_regmap[(2)].ba5_IDEDMA_CMD, (( 1U << 1))); | |||
4598 | ||||
4599 | printf(": DMA"); | |||
4600 | sii3114_mapreg_dma(sc, pa); | |||
4601 | printf("\n"); | |||
4602 | ||||
4603 | sii_fixup_cacheline(sc, pa); | |||
4604 | ||||
4605 | sc->sc_wdcdev.cap |= WDC_CAPABILITY_DATA160x0001 | WDC_CAPABILITY_DATA320x0002; | |||
4606 | sc->sc_wdcdev.PIO_cap = 4; | |||
4607 | if (sc->sc_dma_ok) { | |||
4608 | sc->sc_wdcdev.cap |= WDC_CAPABILITY_DMA0x0008 | WDC_CAPABILITY_UDMA0x0010; | |||
4609 | sc->sc_wdcdev.cap |= WDC_CAPABILITY_IRQACK0x0400; | |||
4610 | sc->sc_wdcdev.irqack = pciide_irqack; | |||
4611 | sc->sc_wdcdev.DMA_cap = 2; | |||
4612 | sc->sc_wdcdev.UDMA_cap = 6; | |||
4613 | } | |||
4614 | sc->sc_wdcdev.set_modes = sii3112_setup_channel; | |||
4615 | ||||
4616 | /* We can use SControl and SStatus to probe for drives. */ | |||
4617 | sc->sc_wdcdev.drv_probe = sii3112_drv_probe; | |||
4618 | ||||
4619 | sc->sc_wdcdev.channels = sc->wdc_chanarray; | |||
4620 | sc->sc_wdcdev.nchannels = 4; | |||
4621 | ||||
4622 | /* Map and establish the interrupt handler. */ | |||
4623 | if (pci_intr_map(pa, &intrhandle) != 0) { | |||
4624 | printf("%s: couldn't map native-PCI interrupt\n", | |||
4625 | sc->sc_wdcdev.sc_dev.dv_xname); | |||
4626 | return; | |||
4627 | } | |||
4628 | intrstr = pci_intr_string(pa->pa_pc, intrhandle); | |||
4629 | sc->sc_pci_ih = pci_intr_establish(pa->pa_pc, intrhandle, IPL_BIO0x3, | |||
4630 | /* XXX */ | |||
4631 | pciide_pci_intr, sc, | |||
4632 | sc->sc_wdcdev.sc_dev.dv_xname); | |||
4633 | if (sc->sc_pci_ih != NULL((void *)0)) { | |||
4634 | printf("%s: using %s for native-PCI interrupt\n", | |||
4635 | sc->sc_wdcdev.sc_dev.dv_xname, | |||
4636 | intrstr ? intrstr : "unknown interrupt"); | |||
4637 | } else { | |||
4638 | printf("%s: couldn't establish native-PCI interrupt", | |||
4639 | sc->sc_wdcdev.sc_dev.dv_xname); | |||
4640 | if (intrstr != NULL((void *)0)) | |||
4641 | printf(" at %s", intrstr); | |||
4642 | printf("\n"); | |||
4643 | return; | |||
4644 | } | |||
4645 | ||||
4646 | for (channel = 0; channel < sc->sc_wdcdev.nchannels; channel++) { | |||
4647 | cp = &sc->pciide_channels[channel]; | |||
4648 | if (sii3114_chansetup(sc, channel) == 0) | |||
4649 | continue; | |||
4650 | sii3114_mapchan(cp); | |||
4651 | if (cp->hw_ok == 0) | |||
4652 | continue; | |||
4653 | sc->sc_wdcdev.set_modes(&cp->wdc_channel); | |||
4654 | } | |||
4655 | } | |||
4656 | ||||
4657 | void | |||
4658 | sii3114_mapreg_dma(struct pciide_softc *sc, struct pci_attach_args *pa) | |||
4659 | { | |||
4660 | int chan, reg; | |||
4661 | bus_size_t size; | |||
4662 | struct pciide_satalink *sl = sc->sc_cookie; | |||
4663 | ||||
4664 | sc->sc_wdcdev.dma_arg = sc; | |||
4665 | sc->sc_wdcdev.dma_init = pciide_dma_init; | |||
4666 | sc->sc_wdcdev.dma_start = pciide_dma_start; | |||
4667 | sc->sc_wdcdev.dma_finish = pciide_dma_finish; | |||
4668 | ||||
4669 | /* | |||
4670 | * Slice off a subregion of BA5 for each of the channel's DMA | |||
4671 | * registers. | |||
4672 | */ | |||
4673 | ||||
4674 | sc->sc_dma_iot = sl->ba5_st; | |||
4675 | for (chan = 0; chan < 4; chan++) { | |||
4676 | for (reg = 0; reg < IDEDMA_NREGS8; reg++) { | |||
4677 | size = 4; | |||
4678 | if (size > (IDEDMA_SCH_OFFSET0x08 - reg)) | |||
4679 | size = IDEDMA_SCH_OFFSET0x08 - reg; | |||
4680 | if (bus_space_subregion(sl->ba5_st, | |||
4681 | sl->ba5_sh, | |||
4682 | satalink_ba5_regmap[chan].ba5_IDEDMA_CMD + reg, | |||
4683 | size, &sl->regs[chan].dma_iohs[reg]) != 0) { | |||
4684 | sc->sc_dma_ok = 0; | |||
4685 | printf(": can't subregion offset " | |||
4686 | "%lu size %lu", | |||
4687 | (u_long) satalink_ba5_regmap[ | |||
4688 | chan].ba5_IDEDMA_CMD + reg, | |||
4689 | (u_long) size); | |||
4690 | return; | |||
4691 | } | |||
4692 | } | |||
4693 | } | |||
4694 | ||||
4695 | sc->sc_dmacmd_read = sii3114_dmacmd_read; | |||
4696 | sc->sc_dmacmd_write = sii3114_dmacmd_write; | |||
4697 | sc->sc_dmactl_read = sii3114_dmactl_read; | |||
4698 | sc->sc_dmactl_write = sii3114_dmactl_write; | |||
4699 | sc->sc_dmatbl_write = sii3114_dmatbl_write; | |||
4700 | ||||
4701 | /* DMA registers all set up! */ | |||
4702 | sc->sc_dmat = pa->pa_dmat; | |||
4703 | sc->sc_dma_ok = 1; | |||
4704 | } | |||
4705 | ||||
4706 | int | |||
4707 | sii3114_chansetup(struct pciide_softc *sc, int channel) | |||
4708 | { | |||
4709 | static const char *channel_names[] = { | |||
4710 | "port 0", | |||
4711 | "port 1", | |||
4712 | "port 2", | |||
4713 | "port 3", | |||
4714 | }; | |||
4715 | struct pciide_channel *cp = &sc->pciide_channels[channel]; | |||
4716 | ||||
4717 | sc->wdc_chanarray[channel] = &cp->wdc_channel; | |||
4718 | ||||
4719 | /* | |||
4720 | * We must always keep the Interrupt Steering bit set in channel 2's | |||
4721 | * IDEDMA_CMD register. | |||
4722 | */ | |||
4723 | if (channel == 2) | |||
4724 | cp->idedma_cmd = IDEDMA_CMD_INT_STEER(1U << 1); | |||
4725 | ||||
4726 | cp->name = channel_names[channel]; | |||
4727 | cp->wdc_channel.channel = channel; | |||
4728 | cp->wdc_channel.wdc = &sc->sc_wdcdev; | |||
4729 | cp->wdc_channel.ch_queue = wdc_alloc_queue(); | |||
4730 | if (cp->wdc_channel.ch_queue == NULL((void *)0)) { | |||
4731 | printf("%s %s channel: " | |||
4732 | "cannot allocate channel queue", | |||
4733 | sc->sc_wdcdev.sc_dev.dv_xname, cp->name); | |||
4734 | return (0); | |||
4735 | } | |||
4736 | return (1); | |||
4737 | } | |||
4738 | ||||
4739 | void | |||
4740 | sii3114_mapchan(struct pciide_channel *cp) | |||
4741 | { | |||
4742 | struct channel_softc *wdc_cp = &cp->wdc_channel; | |||
4743 | struct pciide_softc *sc = (struct pciide_softc *)cp->wdc_channel.wdc; | |||
4744 | struct pciide_satalink *sl = sc->sc_cookie; | |||
4745 | int chan = wdc_cp->channel; | |||
4746 | int i; | |||
4747 | ||||
4748 | cp->hw_ok = 0; | |||
4749 | cp->compat = 0; | |||
4750 | cp->ih = sc->sc_pci_ih; | |||
4751 | ||||
4752 | sl->regs[chan].cmd_iot = sl->ba5_st; | |||
4753 | if (bus_space_subregion(sl->ba5_st, sl->ba5_sh, | |||
4754 | satalink_ba5_regmap[chan].ba5_IDE_TF0, | |||
4755 | 9, &sl->regs[chan].cmd_baseioh) != 0) { | |||
4756 | printf("%s: couldn't subregion %s cmd base\n", | |||
4757 | sc->sc_wdcdev.sc_dev.dv_xname, cp->name); | |||
4758 | return; | |||
4759 | } | |||
4760 | ||||
4761 | sl->regs[chan].ctl_iot = sl->ba5_st; | |||
4762 | if (bus_space_subregion(sl->ba5_st, sl->ba5_sh, | |||
4763 | satalink_ba5_regmap[chan].ba5_IDE_TF8, | |||
4764 | 1, &cp->ctl_baseioh) != 0) { | |||
4765 | printf("%s: couldn't subregion %s ctl base\n", | |||
4766 | sc->sc_wdcdev.sc_dev.dv_xname, cp->name); | |||
4767 | return; | |||
4768 | } | |||
4769 | sl->regs[chan].ctl_ioh = cp->ctl_baseioh; | |||
4770 | ||||
4771 | for (i = 0; i < WDC_NREG8; i++) { | |||
4772 | if (bus_space_subregion(sl->regs[chan].cmd_iot, | |||
4773 | sl->regs[chan].cmd_baseioh, | |||
4774 | i, i == 0 ? 4 : 1, | |||
4775 | &sl->regs[chan].cmd_iohs[i]) != 0) { | |||
4776 | printf("%s: couldn't subregion %s channel " | |||
4777 | "cmd regs\n", | |||
4778 | sc->sc_wdcdev.sc_dev.dv_xname, cp->name); | |||
4779 | return; | |||
4780 | } | |||
4781 | } | |||
4782 | sl->regs[chan].cmd_iohs[wdr_status & _WDC_REGMASK7] = | |||
4783 | sl->regs[chan].cmd_iohs[wdr_command & _WDC_REGMASK7]; | |||
4784 | sl->regs[chan].cmd_iohs[wdr_features & _WDC_REGMASK7] = | |||
4785 | sl->regs[chan].cmd_iohs[wdr_error & _WDC_REGMASK7]; | |||
4786 | wdc_cp->data32iot = wdc_cp->cmd_iot = sl->regs[chan].cmd_iot; | |||
4787 | wdc_cp->data32ioh = wdc_cp->cmd_ioh = sl->regs[chan].cmd_iohs[0]; | |||
4788 | wdc_cp->_vtbl = &wdc_sii3114_vtbl; | |||
4789 | wdcattach(wdc_cp); | |||
4790 | cp->hw_ok = 1; | |||
4791 | } | |||
4792 | ||||
4793 | u_int8_t | |||
4794 | sii3114_read_reg(struct channel_softc *chp, enum wdc_regs reg) | |||
4795 | { | |||
4796 | struct pciide_channel *cp = (struct pciide_channel *)chp; | |||
4797 | struct pciide_softc *sc = (struct pciide_softc *)cp->wdc_channel.wdc; | |||
4798 | struct pciide_satalink *sl = sc->sc_cookie; | |||
4799 | ||||
4800 | if (reg & _WDC_AUX8) | |||
4801 | return (bus_space_read_1(sl->regs[chp->channel].ctl_iot,((sl->regs[chp->channel].ctl_iot)->read_1((sl->regs [chp->channel].ctl_ioh), (reg & 7))) | |||
4802 | sl->regs[chp->channel].ctl_ioh, reg & _WDC_REGMASK)((sl->regs[chp->channel].ctl_iot)->read_1((sl->regs [chp->channel].ctl_ioh), (reg & 7)))); | |||
4803 | else | |||
4804 | return (bus_space_read_1(sl->regs[chp->channel].cmd_iot,((sl->regs[chp->channel].cmd_iot)->read_1((sl->regs [chp->channel].cmd_iohs[reg & 7]), (0))) | |||
4805 | sl->regs[chp->channel].cmd_iohs[reg & _WDC_REGMASK], 0)((sl->regs[chp->channel].cmd_iot)->read_1((sl->regs [chp->channel].cmd_iohs[reg & 7]), (0)))); | |||
4806 | } | |||
4807 | ||||
4808 | void | |||
4809 | sii3114_write_reg(struct channel_softc *chp, enum wdc_regs reg, u_int8_t val) | |||
4810 | { | |||
4811 | struct pciide_channel *cp = (struct pciide_channel *)chp; | |||
4812 | struct pciide_softc *sc = (struct pciide_softc *)cp->wdc_channel.wdc; | |||
4813 | struct pciide_satalink *sl = sc->sc_cookie; | |||
4814 | ||||
4815 | if (reg & _WDC_AUX8) | |||
4816 | bus_space_write_1(sl->regs[chp->channel].ctl_iot,((sl->regs[chp->channel].ctl_iot)->write_1((sl->regs [chp->channel].ctl_ioh), (reg & 7), (val))) | |||
4817 | sl->regs[chp->channel].ctl_ioh, reg & _WDC_REGMASK, val)((sl->regs[chp->channel].ctl_iot)->write_1((sl->regs [chp->channel].ctl_ioh), (reg & 7), (val))); | |||
4818 | else | |||
4819 | bus_space_write_1(sl->regs[chp->channel].cmd_iot,((sl->regs[chp->channel].cmd_iot)->write_1((sl->regs [chp->channel].cmd_iohs[reg & 7]), (0), (val))) | |||
4820 | sl->regs[chp->channel].cmd_iohs[reg & _WDC_REGMASK],((sl->regs[chp->channel].cmd_iot)->write_1((sl->regs [chp->channel].cmd_iohs[reg & 7]), (0), (val))) | |||
4821 | 0, val)((sl->regs[chp->channel].cmd_iot)->write_1((sl->regs [chp->channel].cmd_iohs[reg & 7]), (0), (val))); | |||
4822 | } | |||
4823 | ||||
4824 | u_int8_t | |||
4825 | sii3114_dmacmd_read(struct pciide_softc *sc, int chan) | |||
4826 | { | |||
4827 | struct pciide_satalink *sl = sc->sc_cookie; | |||
4828 | ||||
4829 | return (bus_space_read_1(sc->sc_dma_iot,((sc->sc_dma_iot)->read_1((sl->regs[chan].dma_iohs[( 0x00 + 0x08 * (0))]), (0))) | |||
4830 | sl->regs[chan].dma_iohs[IDEDMA_CMD(0)], 0)((sc->sc_dma_iot)->read_1((sl->regs[chan].dma_iohs[( 0x00 + 0x08 * (0))]), (0)))); | |||
4831 | } | |||
4832 | ||||
4833 | void | |||
4834 | sii3114_dmacmd_write(struct pciide_softc *sc, int chan, u_int8_t val) | |||
4835 | { | |||
4836 | struct pciide_satalink *sl = sc->sc_cookie; | |||
4837 | ||||
4838 | bus_space_write_1(sc->sc_dma_iot,((sc->sc_dma_iot)->write_1((sl->regs[chan].dma_iohs[ (0x00 + 0x08 * (0))]), (0), (val))) | |||
4839 | sl->regs[chan].dma_iohs[IDEDMA_CMD(0)], 0, val)((sc->sc_dma_iot)->write_1((sl->regs[chan].dma_iohs[ (0x00 + 0x08 * (0))]), (0), (val))); | |||
4840 | } | |||
4841 | ||||
4842 | u_int8_t | |||
4843 | sii3114_dmactl_read(struct pciide_softc *sc, int chan) | |||
4844 | { | |||
4845 | struct pciide_satalink *sl = sc->sc_cookie; | |||
4846 | ||||
4847 | return (bus_space_read_1(sc->sc_dma_iot,((sc->sc_dma_iot)->read_1((sl->regs[chan].dma_iohs[( 0x02 + 0x08 * (0))]), (0))) | |||
4848 | sl->regs[chan].dma_iohs[IDEDMA_CTL(0)], 0)((sc->sc_dma_iot)->read_1((sl->regs[chan].dma_iohs[( 0x02 + 0x08 * (0))]), (0)))); | |||
4849 | } | |||
4850 | ||||
4851 | void | |||
4852 | sii3114_dmactl_write(struct pciide_softc *sc, int chan, u_int8_t val) | |||
4853 | { | |||
4854 | struct pciide_satalink *sl = sc->sc_cookie; | |||
4855 | ||||
4856 | bus_space_write_1(sc->sc_dma_iot,((sc->sc_dma_iot)->write_1((sl->regs[chan].dma_iohs[ (0x02 + 0x08 * (0))]), (0), (val))) | |||
4857 | sl->regs[chan].dma_iohs[IDEDMA_CTL(0)], 0, val)((sc->sc_dma_iot)->write_1((sl->regs[chan].dma_iohs[ (0x02 + 0x08 * (0))]), (0), (val))); | |||
4858 | } | |||
4859 | ||||
4860 | void | |||
4861 | sii3114_dmatbl_write(struct pciide_softc *sc, int chan, u_int32_t val) | |||
4862 | { | |||
4863 | struct pciide_satalink *sl = sc->sc_cookie; | |||
4864 | ||||
4865 | bus_space_write_4(sc->sc_dma_iot,((sc->sc_dma_iot)->write_4((sl->regs[chan].dma_iohs[ (0x04 + 0x08 * (0))]), (0), (val))) | |||
4866 | sl->regs[chan].dma_iohs[IDEDMA_TBL(0)], 0, val)((sc->sc_dma_iot)->write_4((sl->regs[chan].dma_iohs[ (0x04 + 0x08 * (0))]), (0), (val))); | |||
4867 | } | |||
4868 | ||||
4869 | void | |||
4870 | cy693_chip_map(struct pciide_softc *sc, struct pci_attach_args *pa) | |||
4871 | { | |||
4872 | struct pciide_channel *cp; | |||
4873 | pcireg_t interface = PCI_INTERFACE(pa->pa_class)(((pa->pa_class) >> 8) & 0xff); | |||
4874 | bus_size_t cmdsize, ctlsize; | |||
4875 | struct pciide_cy *cy; | |||
4876 | ||||
4877 | /* Allocate memory for private data */ | |||
4878 | sc->sc_cookielen = sizeof(*cy); | |||
4879 | sc->sc_cookie = malloc(sc->sc_cookielen, M_DEVBUF2, M_NOWAIT0x0002 | M_ZERO0x0008); | |||
4880 | cy = sc->sc_cookie; | |||
4881 | ||||
4882 | /* | |||
4883 | * this chip has 2 PCI IDE functions, one for primary and one for | |||
4884 | * secondary. So we need to call pciide_mapregs_compat() with | |||
4885 | * the real channel | |||
4886 | */ | |||
4887 | if (pa->pa_function == 1) { | |||
4888 | cy->cy_compatchan = 0; | |||
4889 | } else if (pa->pa_function == 2) { | |||
4890 | cy->cy_compatchan = 1; | |||
4891 | } else { | |||
4892 | printf(": unexpected PCI function %d\n", pa->pa_function); | |||
4893 | return; | |||
4894 | } | |||
4895 | ||||
4896 | if (interface & PCIIDE_INTERFACE_BUS_MASTER_DMA0x80) { | |||
4897 | printf(": DMA"); | |||
4898 | pciide_mapreg_dma(sc, pa); | |||
4899 | } else { | |||
4900 | printf(": no DMA"); | |||
4901 | sc->sc_dma_ok = 0; | |||
4902 | } | |||
4903 | ||||
4904 | cy->cy_handle = cy82c693_init(pa->pa_iot); | |||
4905 | if (cy->cy_handle == NULL((void *)0)) { | |||
4906 | printf(", (unable to map ctl registers)"); | |||
4907 | sc->sc_dma_ok = 0; | |||
4908 | } | |||
4909 | ||||
4910 | sc->sc_wdcdev.cap = WDC_CAPABILITY_DATA160x0001 | WDC_CAPABILITY_DATA320x0002 | | |||
4911 | WDC_CAPABILITY_MODE0x0004; | |||
4912 | if (sc->sc_dma_ok) { | |||
4913 | sc->sc_wdcdev.cap |= WDC_CAPABILITY_DMA0x0008 | WDC_CAPABILITY_IRQACK0x0400; | |||
4914 | sc->sc_wdcdev.irqack = pciide_irqack; | |||
4915 | } | |||
4916 | sc->sc_wdcdev.PIO_cap = 4; | |||
4917 | sc->sc_wdcdev.DMA_cap = 2; | |||
4918 | sc->sc_wdcdev.set_modes = cy693_setup_channel; | |||
4919 | ||||
4920 | sc->sc_wdcdev.channels = sc->wdc_chanarray; | |||
4921 | sc->sc_wdcdev.nchannels = 1; | |||
4922 | ||||
4923 | /* Only one channel for this chip; if we are here it's enabled */ | |||
4924 | cp = &sc->pciide_channels[0]; | |||
4925 | sc->wdc_chanarray[0] = &cp->wdc_channel; | |||
4926 | cp->name = PCIIDE_CHANNEL_NAME(0)((0) == 0 ? "channel 0" : "channel 1"); | |||
4927 | cp->wdc_channel.channel = 0; | |||
4928 | cp->wdc_channel.wdc = &sc->sc_wdcdev; | |||
4929 | cp->wdc_channel.ch_queue = wdc_alloc_queue(); | |||
4930 | if (cp->wdc_channel.ch_queue == NULL((void *)0)) { | |||
4931 | printf(": cannot allocate channel queue\n"); | |||
4932 | return; | |||
4933 | } | |||
4934 | printf(", %s %s to ", PCIIDE_CHANNEL_NAME(0)((0) == 0 ? "channel 0" : "channel 1"), | |||
4935 | (interface & PCIIDE_INTERFACE_SETTABLE(0)(0x02 << (2 * (0)))) ? | |||
4936 | "configured" : "wired"); | |||
4937 | if (interface & PCIIDE_INTERFACE_PCI(0)(0x01 << (2 * (0)))) { | |||
4938 | printf("native-PCI\n"); | |||
4939 | cp->hw_ok = pciide_mapregs_native(pa, cp, &cmdsize, &ctlsize, | |||
4940 | pciide_pci_intr); | |||
4941 | } else { | |||
4942 | printf("compatibility\n"); | |||
4943 | cp->hw_ok = pciide_mapregs_compat(pa, cp, cy->cy_compatchan, | |||
4944 | &cmdsize, &ctlsize); | |||
4945 | } | |||
4946 | ||||
4947 | cp->wdc_channel.data32iot = cp->wdc_channel.cmd_iot; | |||
4948 | cp->wdc_channel.data32ioh = cp->wdc_channel.cmd_ioh; | |||
4949 | pciide_map_compat_intr(pa, cp, cy->cy_compatchan, interface); | |||
4950 | if (cp->hw_ok == 0) | |||
4951 | return; | |||
4952 | wdcattach(&cp->wdc_channel); | |||
4953 | if (pciide_chan_candisable(cp)) { | |||
4954 | pci_conf_write(sc->sc_pc, sc->sc_tag, | |||
4955 | PCI_COMMAND_STATUS_REG0x04, 0); | |||
4956 | } | |||
4957 | if (cp->hw_ok == 0) { | |||
4958 | pciide_unmap_compat_intr(pa, cp, cy->cy_compatchan, | |||
4959 | interface); | |||
4960 | return; | |||
4961 | } | |||
4962 | ||||
4963 | WDCDEBUG_PRINT(("cy693_chip_map: old timings reg 0x%x\n", | |||
4964 | pci_conf_read(sc->sc_pc, sc->sc_tag, CY_CMD_CTRL)), DEBUG_PROBE); | |||
4965 | cy693_setup_channel(&cp->wdc_channel); | |||
4966 | WDCDEBUG_PRINT(("cy693_chip_map: new timings reg 0x%x\n", | |||
4967 | pci_conf_read(sc->sc_pc, sc->sc_tag, CY_CMD_CTRL)), DEBUG_PROBE); | |||
4968 | } | |||
4969 | ||||
4970 | void | |||
4971 | cy693_setup_channel(struct channel_softc *chp) | |||
4972 | { | |||
4973 | struct ata_drive_datas *drvp; | |||
4974 | int drive; | |||
4975 | u_int32_t cy_cmd_ctrl; | |||
4976 | u_int32_t idedma_ctl; | |||
4977 | struct pciide_channel *cp = (struct pciide_channel *)chp; | |||
4978 | struct pciide_softc *sc = (struct pciide_softc *)cp->wdc_channel.wdc; | |||
4979 | int dma_mode = -1; | |||
4980 | struct pciide_cy *cy = sc->sc_cookie; | |||
4981 | ||||
4982 | cy_cmd_ctrl = idedma_ctl = 0; | |||
4983 | ||||
4984 | /* setup DMA if needed */ | |||
4985 | pciide_channel_dma_setup(cp); | |||
4986 | ||||
4987 | for (drive = 0; drive < 2; drive++) { | |||
4988 | drvp = &chp->ch_drive[drive]; | |||
4989 | /* If no drive, skip */ | |||
4990 | if ((drvp->drive_flags & DRIVE(0x0001|0x0002|0x0004)) == 0) | |||
4991 | continue; | |||
4992 | /* add timing values, setup DMA if needed */ | |||
4993 | if (drvp->drive_flags & DRIVE_DMA0x0010) { | |||
4994 | idedma_ctl |= IDEDMA_CTL_DRV_DMA(drive)(0x20 << (drive)); | |||
4995 | /* use Multiword DMA */ | |||
4996 | if (dma_mode == -1 || dma_mode > drvp->DMA_mode) | |||
4997 | dma_mode = drvp->DMA_mode; | |||
4998 | } | |||
4999 | cy_cmd_ctrl |= (cy_pio_pulse[drvp->PIO_mode] << | |||
5000 | CY_CMD_CTRL_IOW_PULSE_OFF(drive)(12 + 16 * (drive))); | |||
5001 | cy_cmd_ctrl |= (cy_pio_rec[drvp->PIO_mode] << | |||
5002 | CY_CMD_CTRL_IOW_REC_OFF(drive)(8 + 16 * (drive))); | |||
5003 | cy_cmd_ctrl |= (cy_pio_pulse[drvp->PIO_mode] << | |||
5004 | CY_CMD_CTRL_IOR_PULSE_OFF(drive)(4 + 16 * (drive))); | |||
5005 | cy_cmd_ctrl |= (cy_pio_rec[drvp->PIO_mode] << | |||
5006 | CY_CMD_CTRL_IOR_REC_OFF(drive)(0 + 16 * (drive))); | |||
5007 | } | |||
5008 | pci_conf_write(sc->sc_pc, sc->sc_tag, CY_CMD_CTRL0x4c, cy_cmd_ctrl); | |||
5009 | chp->ch_drive[0].DMA_mode = dma_mode; | |||
5010 | chp->ch_drive[1].DMA_mode = dma_mode; | |||
5011 | ||||
5012 | if (dma_mode == -1) | |||
5013 | dma_mode = 0; | |||
5014 | ||||
5015 | if (cy->cy_handle != NULL((void *)0)) { | |||
5016 | /* Note: `multiple' is implied. */ | |||
5017 | cy82c693_write(cy->cy_handle, | |||
5018 | (cy->cy_compatchan == 0) ? | |||
5019 | CY_DMA_IDX_PRIMARY0x30 : CY_DMA_IDX_SECONDARY0x31, dma_mode); | |||
5020 | } | |||
5021 | ||||
5022 | pciide_print_modes(cp); | |||
5023 | ||||
5024 | if (idedma_ctl != 0) { | |||
5025 | /* Add software bits in status register */ | |||
5026 | bus_space_write_1(sc->sc_dma_iot, sc->sc_dma_ioh,((sc->sc_dma_iot)->write_1((sc->sc_dma_ioh), ((0x02 + 0x08 * (chp->channel))), (idedma_ctl))) | |||
5027 | IDEDMA_CTL(chp->channel), idedma_ctl)((sc->sc_dma_iot)->write_1((sc->sc_dma_ioh), ((0x02 + 0x08 * (chp->channel))), (idedma_ctl))); | |||
5028 | } | |||
5029 | } | |||
5030 | ||||
5031 | static struct sis_hostbr_type { | |||
5032 | u_int16_t id; | |||
5033 | u_int8_t rev; | |||
5034 | u_int8_t udma_mode; | |||
5035 | char *name; | |||
5036 | u_int8_t type; | |||
5037 | #define SIS_TYPE_NOUDMA0 0 | |||
5038 | #define SIS_TYPE_661 1 | |||
5039 | #define SIS_TYPE_100OLD2 2 | |||
5040 | #define SIS_TYPE_100NEW3 3 | |||
5041 | #define SIS_TYPE_133OLD4 4 | |||
5042 | #define SIS_TYPE_133NEW5 5 | |||
5043 | #define SIS_TYPE_SOUTH6 6 | |||
5044 | } sis_hostbr_type[] = { | |||
5045 | /* Most infos here are from sos@freebsd.org */ | |||
5046 | {PCI_PRODUCT_SIS_5300x0530, 0x00, 4, "530", SIS_TYPE_661}, | |||
5047 | #if 0 | |||
5048 | /* | |||
5049 | * controllers associated to a rev 0x2 530 Host to PCI Bridge | |||
5050 | * have problems with UDMA (info provided by Christos) | |||
5051 | */ | |||
5052 | {PCI_PRODUCT_SIS_5300x0530, 0x02, 0, "530 (buggy)", SIS_TYPE_NOUDMA0}, | |||
5053 | #endif | |||
5054 | {PCI_PRODUCT_SIS_5400x0540, 0x00, 4, "540", SIS_TYPE_661}, | |||
5055 | {PCI_PRODUCT_SIS_5500x0550, 0x00, 4, "550", SIS_TYPE_661}, | |||
5056 | {PCI_PRODUCT_SIS_6200x0620, 0x00, 4, "620", SIS_TYPE_661}, | |||
5057 | {PCI_PRODUCT_SIS_6300x0630, 0x00, 4, "630", SIS_TYPE_661}, | |||
5058 | {PCI_PRODUCT_SIS_6300x0630, 0x30, 5, "630S", SIS_TYPE_100NEW3}, | |||
5059 | {PCI_PRODUCT_SIS_6330x0633, 0x00, 5, "633", SIS_TYPE_100NEW3}, | |||
5060 | {PCI_PRODUCT_SIS_6350x0635, 0x00, 5, "635", SIS_TYPE_100NEW3}, | |||
5061 | {PCI_PRODUCT_SIS_6400x0640, 0x00, 4, "640", SIS_TYPE_SOUTH6}, | |||
5062 | {PCI_PRODUCT_SIS_6450x0645, 0x00, 6, "645", SIS_TYPE_SOUTH6}, | |||
5063 | {PCI_PRODUCT_SIS_6460x0646, 0x00, 6, "645DX", SIS_TYPE_SOUTH6}, | |||
5064 | {PCI_PRODUCT_SIS_6480x0648, 0x00, 6, "648", SIS_TYPE_SOUTH6}, | |||
5065 | {PCI_PRODUCT_SIS_6500x0650, 0x00, 6, "650", SIS_TYPE_SOUTH6}, | |||
5066 | {PCI_PRODUCT_SIS_6510x0651, 0x00, 6, "651", SIS_TYPE_SOUTH6}, | |||
5067 | {PCI_PRODUCT_SIS_6520x0652, 0x00, 6, "652", SIS_TYPE_SOUTH6}, | |||
5068 | {PCI_PRODUCT_SIS_6550x0655, 0x00, 6, "655", SIS_TYPE_SOUTH6}, | |||
5069 | {PCI_PRODUCT_SIS_6580x0658, 0x00, 6, "658", SIS_TYPE_SOUTH6}, | |||
5070 | {PCI_PRODUCT_SIS_6610x0661, 0x00, 6, "661", SIS_TYPE_SOUTH6}, | |||
5071 | {PCI_PRODUCT_SIS_7300x0730, 0x00, 5, "730", SIS_TYPE_100OLD2}, | |||
5072 | {PCI_PRODUCT_SIS_7330x0733, 0x00, 5, "733", SIS_TYPE_100NEW3}, | |||
5073 | {PCI_PRODUCT_SIS_7350x0735, 0x00, 5, "735", SIS_TYPE_100NEW3}, | |||
5074 | {PCI_PRODUCT_SIS_7400x0740, 0x00, 5, "740", SIS_TYPE_SOUTH6}, | |||
5075 | {PCI_PRODUCT_SIS_7410x0741, 0x00, 6, "741", SIS_TYPE_SOUTH6}, | |||
5076 | {PCI_PRODUCT_SIS_7450x0745, 0x00, 5, "745", SIS_TYPE_100NEW3}, | |||
5077 | {PCI_PRODUCT_SIS_7460x0746, 0x00, 6, "746", SIS_TYPE_SOUTH6}, | |||
5078 | {PCI_PRODUCT_SIS_7480x0748, 0x00, 6, "748", SIS_TYPE_SOUTH6}, | |||
5079 | {PCI_PRODUCT_SIS_7500x0750, 0x00, 6, "750", SIS_TYPE_SOUTH6}, | |||
5080 | {PCI_PRODUCT_SIS_7510x0751, 0x00, 6, "751", SIS_TYPE_SOUTH6}, | |||
5081 | {PCI_PRODUCT_SIS_7520x0752, 0x00, 6, "752", SIS_TYPE_SOUTH6}, | |||
5082 | {PCI_PRODUCT_SIS_7550x0755, 0x00, 6, "755", SIS_TYPE_SOUTH6}, | |||
5083 | {PCI_PRODUCT_SIS_7600x0760, 0x00, 6, "760", SIS_TYPE_SOUTH6}, | |||
5084 | /* | |||
5085 | * From sos@freebsd.org: the 0x961 ID will never be found in real world | |||
5086 | * {PCI_PRODUCT_SIS_961, 0x00, 6, "961", SIS_TYPE_133NEW}, | |||
5087 | */ | |||
5088 | {PCI_PRODUCT_SIS_9620x0962, 0x00, 6, "962", SIS_TYPE_133NEW5}, | |||
5089 | {PCI_PRODUCT_SIS_9630x0963, 0x00, 6, "963", SIS_TYPE_133NEW5}, | |||
5090 | {PCI_PRODUCT_SIS_9640x0964, 0x00, 6, "964", SIS_TYPE_133NEW5}, | |||
5091 | {PCI_PRODUCT_SIS_9650x0965, 0x00, 6, "965", SIS_TYPE_133NEW5}, | |||
5092 | {PCI_PRODUCT_SIS_9660x0966, 0x00, 6, "966", SIS_TYPE_133NEW5}, | |||
5093 | {PCI_PRODUCT_SIS_9680x0968, 0x00, 6, "968", SIS_TYPE_133NEW5} | |||
5094 | }; | |||
5095 | ||||
5096 | static struct sis_hostbr_type *sis_hostbr_type_match; | |||
5097 | ||||
5098 | int | |||
5099 | sis_hostbr_match(struct pci_attach_args *pa) | |||
5100 | { | |||
5101 | int i; | |||
5102 | ||||
5103 | if (PCI_VENDOR(pa->pa_id)(((pa->pa_id) >> 0) & 0xffff) != PCI_VENDOR_SIS0x1039) | |||
5104 | return (0); | |||
5105 | sis_hostbr_type_match = NULL((void *)0); | |||
5106 | for (i = 0; | |||
5107 | i < sizeof(sis_hostbr_type) / sizeof(sis_hostbr_type[0]); | |||
5108 | i++) { | |||
5109 | if (PCI_PRODUCT(pa->pa_id)(((pa->pa_id) >> 16) & 0xffff) == sis_hostbr_type[i].id && | |||
5110 | PCI_REVISION(pa->pa_class)(((pa->pa_class) >> 0) & 0xff) >= sis_hostbr_type[i].rev) | |||
5111 | sis_hostbr_type_match = &sis_hostbr_type[i]; | |||
5112 | } | |||
5113 | return (sis_hostbr_type_match != NULL((void *)0)); | |||
5114 | } | |||
5115 | ||||
5116 | int | |||
5117 | sis_south_match(struct pci_attach_args *pa) | |||
5118 | { | |||
5119 | return(PCI_VENDOR(pa->pa_id)(((pa->pa_id) >> 0) & 0xffff) == PCI_VENDOR_SIS0x1039 && | |||
5120 | PCI_PRODUCT(pa->pa_id)(((pa->pa_id) >> 16) & 0xffff) == PCI_PRODUCT_SIS_85C5030x0008 && | |||
5121 | PCI_REVISION(pa->pa_class)(((pa->pa_class) >> 0) & 0xff) >= 0x10); | |||
5122 | } | |||
5123 | ||||
5124 | void | |||
5125 | sis_chip_map(struct pciide_softc *sc, struct pci_attach_args *pa) | |||
5126 | { | |||
5127 | struct pciide_channel *cp; | |||
5128 | int channel; | |||
5129 | u_int8_t sis_ctr0 = pciide_pci_read(sc->sc_pc, sc->sc_tag, SIS_CTRL00x4a); | |||
5130 | pcireg_t interface = PCI_INTERFACE(pa->pa_class)(((pa->pa_class) >> 8) & 0xff); | |||
5131 | int rev = sc->sc_rev; | |||
5132 | bus_size_t cmdsize, ctlsize; | |||
5133 | struct pciide_sis *sis; | |||
5134 | ||||
5135 | /* Allocate memory for private data */ | |||
5136 | sc->sc_cookielen = sizeof(*sis); | |||
5137 | sc->sc_cookie = malloc(sc->sc_cookielen, M_DEVBUF2, M_NOWAIT0x0002 | M_ZERO0x0008); | |||
5138 | sis = sc->sc_cookie; | |||
5139 | ||||
5140 | pci_find_device(NULL((void *)0), sis_hostbr_match); | |||
5141 | ||||
5142 | if (sis_hostbr_type_match) { | |||
5143 | if (sis_hostbr_type_match->type == SIS_TYPE_SOUTH6) { | |||
5144 | pciide_pci_write(sc->sc_pc, sc->sc_tag, SIS_REG_570x57, | |||
5145 | pciide_pci_read(sc->sc_pc, sc->sc_tag, | |||
5146 | SIS_REG_570x57) & 0x7f); | |||
5147 | if (sc->sc_pp->ide_product == SIS_PRODUCT_55180x5518) { | |||
5148 | sis->sis_type = SIS_TYPE_133NEW5; | |||
5149 | sc->sc_wdcdev.UDMA_cap = | |||
5150 | sis_hostbr_type_match->udma_mode; | |||
5151 | } else { | |||
5152 | if (pci_find_device(NULL((void *)0), sis_south_match)) { | |||
5153 | sis->sis_type = SIS_TYPE_133OLD4; | |||
5154 | sc->sc_wdcdev.UDMA_cap = | |||
5155 | sis_hostbr_type_match->udma_mode; | |||
5156 | } else { | |||
5157 | sis->sis_type = SIS_TYPE_100NEW3; | |||
5158 | sc->sc_wdcdev.UDMA_cap = | |||
5159 | sis_hostbr_type_match->udma_mode; | |||
5160 | } | |||
5161 | } | |||
5162 | } else { | |||
5163 | sis->sis_type = sis_hostbr_type_match->type; | |||
5164 | sc->sc_wdcdev.UDMA_cap = | |||
5165 | sis_hostbr_type_match->udma_mode; | |||
5166 | } | |||
5167 | printf(": %s", sis_hostbr_type_match->name); | |||
5168 | } else { | |||
5169 | printf(": 5597/5598"); | |||
5170 | if (rev >= 0xd0) { | |||
5171 | sc->sc_wdcdev.UDMA_cap = 2; | |||
5172 | sis->sis_type = SIS_TYPE_661; | |||
5173 | } else { | |||
5174 | sc->sc_wdcdev.UDMA_cap = 0; | |||
5175 | sis->sis_type = SIS_TYPE_NOUDMA0; | |||
5176 | } | |||
5177 | } | |||
5178 | ||||
5179 | printf(": DMA"); | |||
5180 | pciide_mapreg_dma(sc, pa); | |||
5181 | ||||
5182 | sc->sc_wdcdev.cap = WDC_CAPABILITY_DATA160x0001 | WDC_CAPABILITY_DATA320x0002 | | |||
5183 | WDC_CAPABILITY_MODE0x0004; | |||
5184 | if (sc->sc_dma_ok) { | |||
5185 | sc->sc_wdcdev.cap |= WDC_CAPABILITY_DMA0x0008 | WDC_CAPABILITY_IRQACK0x0400; | |||
5186 | sc->sc_wdcdev.irqack = pciide_irqack; | |||
5187 | if (sis->sis_type >= SIS_TYPE_661) | |||
5188 | sc->sc_wdcdev.cap |= WDC_CAPABILITY_UDMA0x0010; | |||
5189 | } | |||
5190 | ||||
5191 | sc->sc_wdcdev.PIO_cap = 4; | |||
5192 | sc->sc_wdcdev.DMA_cap = 2; | |||
5193 | ||||
5194 | sc->sc_wdcdev.channels = sc->wdc_chanarray; | |||
5195 | sc->sc_wdcdev.nchannels = PCIIDE_NUM_CHANNELS2; | |||
5196 | switch (sis->sis_type) { | |||
5197 | case SIS_TYPE_NOUDMA0: | |||
5198 | case SIS_TYPE_661: | |||
5199 | case SIS_TYPE_100OLD2: | |||
5200 | sc->sc_wdcdev.set_modes = sis_setup_channel; | |||
5201 | pciide_pci_write(sc->sc_pc, sc->sc_tag, SIS_MISC0x52, | |||
5202 | pciide_pci_read(sc->sc_pc, sc->sc_tag, SIS_MISC0x52) | | |||
5203 | SIS_MISC_TIM_SEL0x08 | SIS_MISC_FIFO_SIZE0x01 | SIS_MISC_GTC0x04); | |||
5204 | break; | |||
5205 | case SIS_TYPE_100NEW3: | |||
5206 | case SIS_TYPE_133OLD4: | |||
5207 | sc->sc_wdcdev.set_modes = sis_setup_channel; | |||
5208 | pciide_pci_write(sc->sc_pc, sc->sc_tag, SIS_REG_490x49, | |||
5209 | pciide_pci_read(sc->sc_pc, sc->sc_tag, SIS_REG_490x49) | 0x01); | |||
5210 | break; | |||
5211 | case SIS_TYPE_133NEW5: | |||
5212 | sc->sc_wdcdev.set_modes = sis96x_setup_channel; | |||
5213 | pciide_pci_write(sc->sc_pc, sc->sc_tag, SIS_REG_500x50, | |||
5214 | pciide_pci_read(sc->sc_pc, sc->sc_tag, SIS_REG_500x50) & 0xf7); | |||
5215 | pciide_pci_write(sc->sc_pc, sc->sc_tag, SIS_REG_520x52, | |||
5216 | pciide_pci_read(sc->sc_pc, sc->sc_tag, SIS_REG_520x52) & 0xf7); | |||
5217 | break; | |||
5218 | } | |||
5219 | ||||
5220 | pciide_print_channels(sc->sc_wdcdev.nchannels, interface); | |||
5221 | ||||
5222 | for (channel = 0; channel < sc->sc_wdcdev.nchannels; channel++) { | |||
5223 | cp = &sc->pciide_channels[channel]; | |||
5224 | if (pciide_chansetup(sc, channel, interface) == 0) | |||
5225 | continue; | |||
5226 | if ((channel == 0 && (sis_ctr0 & SIS_CTRL0_CHAN0_EN0x02) == 0) || | |||
5227 | (channel == 1 && (sis_ctr0 & SIS_CTRL0_CHAN1_EN0x04) == 0)) { | |||
5228 | printf("%s: %s ignored (disabled)\n", | |||
5229 | sc->sc_wdcdev.sc_dev.dv_xname, cp->name); | |||
5230 | cp->hw_ok = 0; | |||
5231 | continue; | |||
5232 | } | |||
5233 | pciide_map_compat_intr(pa, cp, channel, interface); | |||
5234 | if (cp->hw_ok == 0) | |||
5235 | continue; | |||
5236 | pciide_mapchan(pa, cp, interface, &cmdsize, &ctlsize, | |||
5237 | pciide_pci_intr); | |||
5238 | if (cp->hw_ok == 0) { | |||
5239 | pciide_unmap_compat_intr(pa, cp, channel, interface); | |||
5240 | continue; | |||
5241 | } | |||
5242 | if (pciide_chan_candisable(cp)) { | |||
5243 | if (channel == 0) | |||
5244 | sis_ctr0 &= ~SIS_CTRL0_CHAN0_EN0x02; | |||
5245 | else | |||
5246 | sis_ctr0 &= ~SIS_CTRL0_CHAN1_EN0x04; | |||
5247 | pciide_pci_write(sc->sc_pc, sc->sc_tag, SIS_CTRL00x4a, | |||
5248 | sis_ctr0); | |||
5249 | } | |||
5250 | if (cp->hw_ok == 0) { | |||
5251 | pciide_unmap_compat_intr(pa, cp, channel, interface); | |||
5252 | continue; | |||
5253 | } | |||
5254 | sc->sc_wdcdev.set_modes(&cp->wdc_channel); | |||
5255 | } | |||
5256 | } | |||
5257 | ||||
5258 | void | |||
5259 | sis96x_setup_channel(struct channel_softc *chp) | |||
5260 | { | |||
5261 | struct ata_drive_datas *drvp; | |||
5262 | int drive; | |||
5263 | u_int32_t sis_tim; | |||
5264 | u_int32_t idedma_ctl; | |||
5265 | int regtim; | |||
5266 | struct pciide_channel *cp = (struct pciide_channel *)chp; | |||
5267 | struct pciide_softc *sc = (struct pciide_softc *)cp->wdc_channel.wdc; | |||
5268 | ||||
5269 | sis_tim = 0; | |||
5270 | idedma_ctl = 0; | |||
5271 | /* setup DMA if needed */ | |||
5272 | pciide_channel_dma_setup(cp); | |||
5273 | ||||
5274 | for (drive = 0; drive < 2; drive++) { | |||
5275 | regtim = SIS_TIM133(((((pciide_pci_read(sc->sc_pc, sc->sc_tag, 0x57)) & 0x40) ? 0x70 : 0x40) + ((chp->channel) << 3) + ((drive ) << 2)) | |||
5276 | pciide_pci_read(sc->sc_pc, sc->sc_tag, SIS_REG_57),((((pciide_pci_read(sc->sc_pc, sc->sc_tag, 0x57)) & 0x40) ? 0x70 : 0x40) + ((chp->channel) << 3) + ((drive ) << 2)) | |||
5277 | chp->channel, drive)((((pciide_pci_read(sc->sc_pc, sc->sc_tag, 0x57)) & 0x40) ? 0x70 : 0x40) + ((chp->channel) << 3) + ((drive ) << 2)); | |||
5278 | drvp = &chp->ch_drive[drive]; | |||
5279 | /* If no drive, skip */ | |||
5280 | if ((drvp->drive_flags & DRIVE(0x0001|0x0002|0x0004)) == 0) | |||
5281 | continue; | |||
5282 | /* add timing values, setup DMA if needed */ | |||
5283 | if (drvp->drive_flags & DRIVE_UDMA0x0020) { | |||
5284 | /* use Ultra/DMA */ | |||
5285 | drvp->drive_flags &= ~DRIVE_DMA0x0010; | |||
5286 | if (pciide_pci_read(sc->sc_pc, sc->sc_tag, | |||
5287 | SIS96x_REG_CBL(chp->channel)(0x51 + (chp->channel) * 2)) & SIS96x_REG_CBL_330x80) { | |||
5288 | if (drvp->UDMA_mode > 2) | |||
5289 | drvp->UDMA_mode = 2; | |||
5290 | } | |||
5291 | sis_tim |= sis_udma133new_tim[drvp->UDMA_mode]; | |||
5292 | sis_tim |= sis_pio133new_tim[drvp->PIO_mode]; | |||
5293 | idedma_ctl |= IDEDMA_CTL_DRV_DMA(drive)(0x20 << (drive)); | |||
5294 | } else if (drvp->drive_flags & DRIVE_DMA0x0010) { | |||
5295 | /* | |||
5296 | * use Multiword DMA | |||
5297 | * Timings will be used for both PIO and DMA, | |||
5298 | * so adjust DMA mode if needed | |||
5299 | */ | |||
5300 | if (drvp->PIO_mode > (drvp->DMA_mode + 2)) | |||
5301 | drvp->PIO_mode = drvp->DMA_mode + 2; | |||
5302 | if (drvp->DMA_mode + 2 > (drvp->PIO_mode)) | |||
5303 | drvp->DMA_mode = (drvp->PIO_mode > 2) ? | |||
5304 | drvp->PIO_mode - 2 : 0; | |||
5305 | sis_tim |= sis_dma133new_tim[drvp->DMA_mode]; | |||
5306 | idedma_ctl |= IDEDMA_CTL_DRV_DMA(drive)(0x20 << (drive)); | |||
5307 | } else { | |||
5308 | sis_tim |= sis_pio133new_tim[drvp->PIO_mode]; | |||
5309 | } | |||
5310 | WDCDEBUG_PRINT(("sis96x_setup_channel: new timings reg for " | |||
5311 | "channel %d drive %d: 0x%x (reg 0x%x)\n", | |||
5312 | chp->channel, drive, sis_tim, regtim), DEBUG_PROBE); | |||
5313 | pci_conf_write(sc->sc_pc, sc->sc_tag, regtim, sis_tim); | |||
5314 | } | |||
5315 | if (idedma_ctl != 0) { | |||
5316 | /* Add software bits in status register */ | |||
5317 | bus_space_write_1(sc->sc_dma_iot, sc->sc_dma_ioh,((sc->sc_dma_iot)->write_1((sc->sc_dma_ioh), ((0x02 + 0x08 * (chp->channel))), (idedma_ctl))) | |||
5318 | IDEDMA_CTL(chp->channel), idedma_ctl)((sc->sc_dma_iot)->write_1((sc->sc_dma_ioh), ((0x02 + 0x08 * (chp->channel))), (idedma_ctl))); | |||
5319 | } | |||
5320 | pciide_print_modes(cp); | |||
5321 | } | |||
5322 | ||||
5323 | void | |||
5324 | sis_setup_channel(struct channel_softc *chp) | |||
5325 | { | |||
5326 | struct ata_drive_datas *drvp; | |||
5327 | int drive; | |||
5328 | u_int32_t sis_tim; | |||
5329 | u_int32_t idedma_ctl; | |||
5330 | struct pciide_channel *cp = (struct pciide_channel *)chp; | |||
5331 | struct pciide_softc *sc = (struct pciide_softc *)cp->wdc_channel.wdc; | |||
5332 | struct pciide_sis *sis = sc->sc_cookie; | |||
5333 | ||||
5334 | WDCDEBUG_PRINT(("sis_setup_channel: old timings reg for " | |||
5335 | "channel %d 0x%x\n", chp->channel, | |||
5336 | pci_conf_read(sc->sc_pc, sc->sc_tag, SIS_TIM(chp->channel))), | |||
5337 | DEBUG_PROBE); | |||
5338 | sis_tim = 0; | |||
5339 | idedma_ctl = 0; | |||
5340 | /* setup DMA if needed */ | |||
5341 | pciide_channel_dma_setup(cp); | |||
5342 | ||||
5343 | for (drive = 0; drive < 2; drive++) { | |||
5344 | drvp = &chp->ch_drive[drive]; | |||
5345 | /* If no drive, skip */ | |||
5346 | if ((drvp->drive_flags & DRIVE(0x0001|0x0002|0x0004)) == 0) | |||
5347 | continue; | |||
5348 | /* add timing values, setup DMA if needed */ | |||
5349 | if ((drvp->drive_flags & DRIVE_DMA0x0010) == 0 && | |||
5350 | (drvp->drive_flags & DRIVE_UDMA0x0020) == 0) | |||
5351 | goto pio; | |||
5352 | ||||
5353 | if (drvp->drive_flags & DRIVE_UDMA0x0020) { | |||
5354 | /* use Ultra/DMA */ | |||
5355 | drvp->drive_flags &= ~DRIVE_DMA0x0010; | |||
5356 | if (pciide_pci_read(sc->sc_pc, sc->sc_tag, | |||
5357 | SIS_REG_CBL0x48) & SIS_REG_CBL_33(chp->channel)(0x10 << (chp->channel))) { | |||
5358 | if (drvp->UDMA_mode > 2) | |||
5359 | drvp->UDMA_mode = 2; | |||
5360 | } | |||
5361 | switch (sis->sis_type) { | |||
5362 | case SIS_TYPE_661: | |||
5363 | case SIS_TYPE_100OLD2: | |||
5364 | sis_tim |= sis_udma66_tim[drvp->UDMA_mode] << | |||
5365 | SIS_TIM66_UDMA_TIME_OFF(drive)(12 + 16 * (drive)); | |||
5366 | break; | |||
5367 | case SIS_TYPE_100NEW3: | |||
5368 | sis_tim |= | |||
5369 | sis_udma100new_tim[drvp->UDMA_mode] << | |||
5370 | SIS_TIM100_UDMA_TIME_OFF(drive)(8 + 16 * (drive)); | |||
5371 | break; | |||
5372 | case SIS_TYPE_133OLD4: | |||
5373 | sis_tim |= | |||
5374 | sis_udma133old_tim[drvp->UDMA_mode] << | |||
5375 | SIS_TIM100_UDMA_TIME_OFF(drive)(8 + 16 * (drive)); | |||
5376 | break; | |||
5377 | default: | |||
5378 | printf("unknown SiS IDE type %d\n", | |||
5379 | sis->sis_type); | |||
5380 | } | |||
5381 | } else { | |||
5382 | /* | |||
5383 | * use Multiword DMA | |||
5384 | * Timings will be used for both PIO and DMA, | |||
5385 | * so adjust DMA mode if needed | |||
5386 | */ | |||
5387 | if (drvp->PIO_mode > (drvp->DMA_mode + 2)) | |||
5388 | drvp->PIO_mode = drvp->DMA_mode + 2; | |||
5389 | if (drvp->DMA_mode + 2 > (drvp->PIO_mode)) | |||
5390 | drvp->DMA_mode = (drvp->PIO_mode > 2) ? | |||
5391 | drvp->PIO_mode - 2 : 0; | |||
5392 | if (drvp->DMA_mode == 0) | |||
5393 | drvp->PIO_mode = 0; | |||
5394 | } | |||
5395 | idedma_ctl |= IDEDMA_CTL_DRV_DMA(drive)(0x20 << (drive)); | |||
5396 | pio: switch (sis->sis_type) { | |||
5397 | case SIS_TYPE_NOUDMA0: | |||
5398 | case SIS_TYPE_661: | |||
5399 | case SIS_TYPE_100OLD2: | |||
5400 | sis_tim |= sis_pio_act[drvp->PIO_mode] << | |||
5401 | SIS_TIM66_ACT_OFF(drive)(8 + 16 * (drive)); | |||
5402 | sis_tim |= sis_pio_rec[drvp->PIO_mode] << | |||
5403 | SIS_TIM66_REC_OFF(drive)(16 * (drive)); | |||
5404 | break; | |||
5405 | case SIS_TYPE_100NEW3: | |||
5406 | case SIS_TYPE_133OLD4: | |||
5407 | sis_tim |= sis_pio_act[drvp->PIO_mode] << | |||
5408 | SIS_TIM100_ACT_OFF(drive)(4 + 16 * (drive)); | |||
5409 | sis_tim |= sis_pio_rec[drvp->PIO_mode] << | |||
5410 | SIS_TIM100_REC_OFF(drive)(16 * (drive)); | |||
5411 | break; | |||
5412 | default: | |||
5413 | printf("unknown SiS IDE type %d\n", | |||
5414 | sis->sis_type); | |||
5415 | } | |||
5416 | } | |||
5417 | WDCDEBUG_PRINT(("sis_setup_channel: new timings reg for " | |||
5418 | "channel %d 0x%x\n", chp->channel, sis_tim), DEBUG_PROBE); | |||
5419 | pci_conf_write(sc->sc_pc, sc->sc_tag, SIS_TIM(chp->channel)(0x40 + (chp->channel * 4)), sis_tim); | |||
5420 | if (idedma_ctl != 0) { | |||
5421 | /* Add software bits in status register */ | |||
5422 | bus_space_write_1(sc->sc_dma_iot, sc->sc_dma_ioh,((sc->sc_dma_iot)->write_1((sc->sc_dma_ioh), ((0x02 + 0x08 * (chp->channel))), (idedma_ctl))) | |||
5423 | IDEDMA_CTL(chp->channel), idedma_ctl)((sc->sc_dma_iot)->write_1((sc->sc_dma_ioh), ((0x02 + 0x08 * (chp->channel))), (idedma_ctl))); | |||
5424 | } | |||
5425 | pciide_print_modes(cp); | |||
5426 | } | |||
5427 | ||||
5428 | void | |||
5429 | natsemi_chip_map(struct pciide_softc *sc, struct pci_attach_args *pa) | |||
5430 | { | |||
5431 | struct pciide_channel *cp; | |||
5432 | int channel; | |||
5433 | pcireg_t interface, ctl; | |||
5434 | bus_size_t cmdsize, ctlsize; | |||
5435 | ||||
5436 | printf(": DMA"); | |||
5437 | pciide_mapreg_dma(sc, pa); | |||
5438 | sc->sc_wdcdev.cap = WDC_CAPABILITY_DATA160x0001; | |||
5439 | ||||
5440 | if (sc->sc_dma_ok) { | |||
5441 | sc->sc_wdcdev.cap |= WDC_CAPABILITY_DMA0x0008 | WDC_CAPABILITY_IRQACK0x0400; | |||
5442 | sc->sc_wdcdev.irqack = natsemi_irqack; | |||
5443 | } | |||
5444 | ||||
5445 | pciide_pci_write(sc->sc_pc, sc->sc_tag, NATSEMI_CCBT0x54, 0xb7); | |||
5446 | ||||
5447 | /* | |||
5448 | * Mask off interrupts from both channels, appropriate channel(s) | |||
5449 | * will be unmasked later. | |||
5450 | */ | |||
5451 | pciide_pci_write(sc->sc_pc, sc->sc_tag, NATSEMI_CTRL20x41, | |||
5452 | pciide_pci_read(sc->sc_pc, sc->sc_tag, NATSEMI_CTRL20x41) | | |||
5453 | NATSEMI_CHMASK(0)(0x01 << (0)) | NATSEMI_CHMASK(1)(0x01 << (1))); | |||
5454 | ||||
5455 | sc->sc_wdcdev.PIO_cap = 4; | |||
5456 | sc->sc_wdcdev.DMA_cap = 2; | |||
5457 | sc->sc_wdcdev.set_modes = natsemi_setup_channel; | |||
5458 | sc->sc_wdcdev.channels = sc->wdc_chanarray; | |||
5459 | sc->sc_wdcdev.nchannels = PCIIDE_NUM_CHANNELS2; | |||
5460 | ||||
5461 | interface = PCI_INTERFACE(pci_conf_read(sc->sc_pc, sc->sc_tag,(((pci_conf_read(sc->sc_pc, sc->sc_tag, 0x08)) >> 8) & 0xff) | |||
5462 | PCI_CLASS_REG))(((pci_conf_read(sc->sc_pc, sc->sc_tag, 0x08)) >> 8) & 0xff); | |||
5463 | interface &= ~PCIIDE_CHANSTATUS_EN0x40; /* Reserved on PC87415 */ | |||
5464 | pciide_print_channels(sc->sc_wdcdev.nchannels, interface); | |||
5465 | ||||
5466 | /* If we're in PCIIDE mode, unmask INTA, otherwise mask it. */ | |||
5467 | ctl = pciide_pci_read(sc->sc_pc, sc->sc_tag, NATSEMI_CTRL10x40); | |||
5468 | if (interface & (PCIIDE_INTERFACE_PCI(0)(0x01 << (2 * (0))) | PCIIDE_INTERFACE_PCI(1)(0x01 << (2 * (1))))) | |||
5469 | ctl &= ~NATSEMI_CTRL1_INTAMASK0x40; | |||
5470 | else | |||
5471 | ctl |= NATSEMI_CTRL1_INTAMASK0x40; | |||
5472 | pciide_pci_write(sc->sc_pc, sc->sc_tag, NATSEMI_CTRL10x40, ctl); | |||
5473 | ||||
5474 | for (channel = 0; channel < sc->sc_wdcdev.nchannels; channel++) { | |||
5475 | cp = &sc->pciide_channels[channel]; | |||
5476 | if (pciide_chansetup(sc, channel, interface) == 0) | |||
5477 | continue; | |||
5478 | ||||
5479 | pciide_map_compat_intr(pa, cp, channel, interface); | |||
5480 | if (cp->hw_ok == 0) | |||
5481 | continue; | |||
5482 | ||||
5483 | pciide_mapchan(pa, cp, interface, &cmdsize, &ctlsize, | |||
5484 | natsemi_pci_intr); | |||
5485 | if (cp->hw_ok == 0) { | |||
5486 | pciide_unmap_compat_intr(pa, cp, channel, interface); | |||
5487 | continue; | |||
5488 | } | |||
5489 | natsemi_setup_channel(&cp->wdc_channel); | |||
5490 | } | |||
5491 | } | |||
5492 | ||||
5493 | void | |||
5494 | natsemi_setup_channel(struct channel_softc *chp) | |||
5495 | { | |||
5496 | struct ata_drive_datas *drvp; | |||
5497 | int drive, ndrives = 0; | |||
5498 | u_int32_t idedma_ctl = 0; | |||
5499 | struct pciide_channel *cp = (struct pciide_channel *)chp; | |||
5500 | struct pciide_softc *sc = (struct pciide_softc *)cp->wdc_channel.wdc; | |||
5501 | u_int8_t tim; | |||
5502 | ||||
5503 | /* setup DMA if needed */ | |||
5504 | pciide_channel_dma_setup(cp); | |||
5505 | ||||
5506 | for (drive = 0; drive < 2; drive++) { | |||
5507 | drvp = &chp->ch_drive[drive]; | |||
5508 | /* If no drive, skip */ | |||
5509 | if ((drvp->drive_flags & DRIVE(0x0001|0x0002|0x0004)) == 0) | |||
5510 | continue; | |||
5511 | ||||
5512 | ndrives++; | |||
5513 | /* add timing values, setup DMA if needed */ | |||
5514 | if ((drvp->drive_flags & DRIVE_DMA0x0010) == 0) { | |||
5515 | tim = natsemi_pio_pulse[drvp->PIO_mode] | | |||
5516 | (natsemi_pio_recover[drvp->PIO_mode] << 4); | |||
5517 | } else { | |||
5518 | /* | |||
5519 | * use Multiword DMA | |||
5520 | * Timings will be used for both PIO and DMA, | |||
5521 | * so adjust DMA mode if needed | |||
5522 | */ | |||
5523 | if (drvp->PIO_mode >= 3 && | |||
5524 | (drvp->DMA_mode + 2) > drvp->PIO_mode) { | |||
5525 | drvp->DMA_mode = drvp->PIO_mode - 2; | |||
5526 | } | |||
5527 | idedma_ctl |= IDEDMA_CTL_DRV_DMA(drive)(0x20 << (drive)); | |||
5528 | tim = natsemi_dma_pulse[drvp->DMA_mode] | | |||
5529 | (natsemi_dma_recover[drvp->DMA_mode] << 4); | |||
5530 | } | |||
5531 | ||||
5532 | pciide_pci_write(sc->sc_pc, sc->sc_tag, | |||
5533 | NATSEMI_RTREG(chp->channel, drive)(0x44 + (chp->channel * 8) + (drive * 4) + 0), tim); | |||
5534 | pciide_pci_write(sc->sc_pc, sc->sc_tag, | |||
5535 | NATSEMI_WTREG(chp->channel, drive)(0x44 + (chp->channel * 8) + (drive * 4) + 1), tim); | |||
5536 | } | |||
5537 | if (idedma_ctl != 0) { | |||
5538 | /* Add software bits in status register */ | |||
5539 | bus_space_write_1(sc->sc_dma_iot, sc->sc_dma_ioh,((sc->sc_dma_iot)->write_1((sc->sc_dma_ioh), ((0x02 + 0x08 * (chp->channel))), (idedma_ctl))) | |||
5540 | IDEDMA_CTL(chp->channel), idedma_ctl)((sc->sc_dma_iot)->write_1((sc->sc_dma_ioh), ((0x02 + 0x08 * (chp->channel))), (idedma_ctl))); | |||
5541 | } | |||
5542 | if (ndrives > 0) { | |||
5543 | /* Unmask the channel if at least one drive is found */ | |||
5544 | pciide_pci_write(sc->sc_pc, sc->sc_tag, NATSEMI_CTRL20x41, | |||
5545 | pciide_pci_read(sc->sc_pc, sc->sc_tag, NATSEMI_CTRL20x41) & | |||
5546 | ~(NATSEMI_CHMASK(chp->channel)(0x01 << (chp->channel)))); | |||
5547 | } | |||
5548 | ||||
5549 | pciide_print_modes(cp); | |||
5550 | ||||
5551 | /* Go ahead and ack interrupts generated during probe. */ | |||
5552 | bus_space_write_1(sc->sc_dma_iot, sc->sc_dma_ioh,((sc->sc_dma_iot)->write_1((sc->sc_dma_ioh), ((0x02 + 0x08 * (chp->channel))), (((sc->sc_dma_iot)->read_1 ((sc->sc_dma_ioh), ((0x02 + 0x08 * (chp->channel))))))) ) | |||
5553 | IDEDMA_CTL(chp->channel),((sc->sc_dma_iot)->write_1((sc->sc_dma_ioh), ((0x02 + 0x08 * (chp->channel))), (((sc->sc_dma_iot)->read_1 ((sc->sc_dma_ioh), ((0x02 + 0x08 * (chp->channel))))))) ) | |||
5554 | bus_space_read_1(sc->sc_dma_iot, sc->sc_dma_ioh,((sc->sc_dma_iot)->write_1((sc->sc_dma_ioh), ((0x02 + 0x08 * (chp->channel))), (((sc->sc_dma_iot)->read_1 ((sc->sc_dma_ioh), ((0x02 + 0x08 * (chp->channel))))))) ) | |||
5555 | IDEDMA_CTL(chp->channel)))((sc->sc_dma_iot)->write_1((sc->sc_dma_ioh), ((0x02 + 0x08 * (chp->channel))), (((sc->sc_dma_iot)->read_1 ((sc->sc_dma_ioh), ((0x02 + 0x08 * (chp->channel))))))) ); | |||
5556 | } | |||
5557 | ||||
5558 | void | |||
5559 | natsemi_irqack(struct channel_softc *chp) | |||
5560 | { | |||
5561 | struct pciide_channel *cp = (struct pciide_channel *)chp; | |||
5562 | struct pciide_softc *sc = (struct pciide_softc *)cp->wdc_channel.wdc; | |||
5563 | u_int8_t clr; | |||
5564 | ||||
5565 | /* The "clear" bits are in the wrong register *sigh* */ | |||
5566 | clr = bus_space_read_1(sc->sc_dma_iot, sc->sc_dma_ioh,((sc->sc_dma_iot)->read_1((sc->sc_dma_ioh), ((0x00 + 0x08 * (chp->channel))))) | |||
5567 | IDEDMA_CMD(chp->channel))((sc->sc_dma_iot)->read_1((sc->sc_dma_ioh), ((0x00 + 0x08 * (chp->channel))))); | |||
5568 | clr |= bus_space_read_1(sc->sc_dma_iot, sc->sc_dma_ioh,((sc->sc_dma_iot)->read_1((sc->sc_dma_ioh), ((0x02 + 0x08 * (chp->channel))))) | |||
5569 | IDEDMA_CTL(chp->channel))((sc->sc_dma_iot)->read_1((sc->sc_dma_ioh), ((0x02 + 0x08 * (chp->channel))))) & | |||
5570 | (IDEDMA_CTL_ERR0x02 | IDEDMA_CTL_INTR0x04); | |||
5571 | bus_space_write_1(sc->sc_dma_iot, sc->sc_dma_ioh,((sc->sc_dma_iot)->write_1((sc->sc_dma_ioh), ((0x00 + 0x08 * (chp->channel))), (clr))) | |||
5572 | IDEDMA_CMD(chp->channel), clr)((sc->sc_dma_iot)->write_1((sc->sc_dma_ioh), ((0x00 + 0x08 * (chp->channel))), (clr))); | |||
5573 | } | |||
5574 | ||||
5575 | int | |||
5576 | natsemi_pci_intr(void *arg) | |||
5577 | { | |||
5578 | struct pciide_softc *sc = arg; | |||
5579 | struct pciide_channel *cp; | |||
5580 | struct channel_softc *wdc_cp; | |||
5581 | int i, rv, crv; | |||
5582 | u_int8_t msk; | |||
5583 | ||||
5584 | rv = 0; | |||
5585 | msk = pciide_pci_read(sc->sc_pc, sc->sc_tag, NATSEMI_CTRL20x41); | |||
5586 | for (i = 0; i < sc->sc_wdcdev.nchannels; i++) { | |||
5587 | cp = &sc->pciide_channels[i]; | |||
5588 | wdc_cp = &cp->wdc_channel; | |||
5589 | ||||
5590 | /* If a compat channel skip. */ | |||
5591 | if (cp->compat) | |||
5592 | continue; | |||
5593 | ||||
5594 | /* If this channel is masked, skip it. */ | |||
5595 | if (msk & NATSEMI_CHMASK(i)(0x01 << (i))) | |||
5596 | continue; | |||
5597 | ||||
5598 | if (pciide_intr_flag(cp) == 0) | |||
5599 | continue; | |||
5600 | ||||
5601 | crv = wdcintr(wdc_cp); | |||
5602 | if (crv == 0) | |||
5603 | ; /* leave rv alone */ | |||
5604 | else if (crv == 1) | |||
5605 | rv = 1; /* claim the intr */ | |||
5606 | else if (rv == 0) /* crv should be -1 in this case */ | |||
5607 | rv = crv; /* if we've done no better, take it */ | |||
5608 | } | |||
5609 | return (rv); | |||
5610 | } | |||
5611 | ||||
5612 | void | |||
5613 | ns_scx200_chip_map(struct pciide_softc *sc, struct pci_attach_args *pa) | |||
5614 | { | |||
5615 | struct pciide_channel *cp; | |||
5616 | int channel; | |||
5617 | pcireg_t interface = PCI_INTERFACE(pa->pa_class)(((pa->pa_class) >> 8) & 0xff); | |||
5618 | bus_size_t cmdsize, ctlsize; | |||
5619 | ||||
5620 | printf(": DMA"); | |||
5621 | pciide_mapreg_dma(sc, pa); | |||
5622 | ||||
5623 | sc->sc_wdcdev.cap = WDC_CAPABILITY_DATA160x0001 | WDC_CAPABILITY_DATA320x0002 | | |||
5624 | WDC_CAPABILITY_MODE0x0004; | |||
5625 | if (sc->sc_dma_ok) { | |||
5626 | sc->sc_wdcdev.cap |= WDC_CAPABILITY_DMA0x0008 | WDC_CAPABILITY_UDMA0x0010; | |||
5627 | sc->sc_wdcdev.cap |= WDC_CAPABILITY_IRQACK0x0400; | |||
5628 | sc->sc_wdcdev.irqack = pciide_irqack; | |||
5629 | } | |||
5630 | sc->sc_wdcdev.PIO_cap = 4; | |||
5631 | sc->sc_wdcdev.DMA_cap = 2; | |||
5632 | sc->sc_wdcdev.UDMA_cap = 2; | |||
5633 | ||||
5634 | sc->sc_wdcdev.set_modes = ns_scx200_setup_channel; | |||
5635 | sc->sc_wdcdev.channels = sc->wdc_chanarray; | |||
5636 | sc->sc_wdcdev.nchannels = PCIIDE_NUM_CHANNELS2; | |||
5637 | ||||
5638 | /* | |||
5639 | * Soekris net4801 errata 0003: | |||
5640 | * | |||
5641 | * The SC1100 built in busmaster IDE controller is pretty standard, | |||
5642 | * but have two bugs: data transfers need to be dword aligned and | |||
5643 | * it cannot do an exact 64Kbyte data transfer. | |||
5644 | * | |||
5645 | * Assume that reducing maximum segment size by one page | |||
5646 | * will be enough, and restrict boundary too for extra certainty. | |||
5647 | */ | |||
5648 | if (sc->sc_pp->ide_product == PCI_PRODUCT_NS_SCX200_IDE0x0502) { | |||
5649 | sc->sc_dma_maxsegsz = IDEDMA_BYTE_COUNT_MAX0x00010000 - PAGE_SIZE(1 << 12); | |||
5650 | sc->sc_dma_boundary = IDEDMA_BYTE_COUNT_MAX0x00010000 - PAGE_SIZE(1 << 12); | |||
5651 | } | |||
5652 | ||||
5653 | /* | |||
5654 | * This chip seems to be unable to do one-sector transfers | |||
5655 | * using DMA. | |||
5656 | */ | |||
5657 | sc->sc_wdcdev.quirks = WDC_QUIRK_NOSHORTDMA0x0001; | |||
5658 | ||||
5659 | pciide_print_channels(sc->sc_wdcdev.nchannels, interface); | |||
5660 | ||||
5661 | for (channel = 0; channel < sc->sc_wdcdev.nchannels; channel++) { | |||
5662 | cp = &sc->pciide_channels[channel]; | |||
5663 | if (pciide_chansetup(sc, channel, interface) == 0) | |||
5664 | continue; | |||
5665 | pciide_map_compat_intr(pa, cp, channel, interface); | |||
5666 | if (cp->hw_ok == 0) | |||
5667 | continue; | |||
5668 | pciide_mapchan(pa, cp, interface, &cmdsize, &ctlsize, | |||
5669 | pciide_pci_intr); | |||
5670 | if (cp->hw_ok == 0) { | |||
5671 | pciide_unmap_compat_intr(pa, cp, channel, interface); | |||
5672 | continue; | |||
5673 | } | |||
5674 | sc->sc_wdcdev.set_modes(&cp->wdc_channel); | |||
5675 | } | |||
5676 | } | |||
5677 | ||||
5678 | void | |||
5679 | ns_scx200_setup_channel(struct channel_softc *chp) | |||
5680 | { | |||
5681 | struct ata_drive_datas *drvp; | |||
5682 | int drive, mode; | |||
5683 | u_int32_t idedma_ctl; | |||
5684 | struct pciide_channel *cp = (struct pciide_channel*)chp; | |||
5685 | struct pciide_softc *sc = (struct pciide_softc *)cp->wdc_channel.wdc; | |||
5686 | int channel = chp->channel; | |||
5687 | int pioformat; | |||
5688 | pcireg_t piotim, dmatim; | |||
5689 | ||||
5690 | /* Setup DMA if needed */ | |||
5691 | pciide_channel_dma_setup(cp); | |||
5692 | ||||
5693 | idedma_ctl = 0; | |||
5694 | ||||
5695 | pioformat = (pci_conf_read(sc->sc_pc, sc->sc_tag, | |||
5696 | SCx200_TIM_DMA(0, 0)(0x44 + 16 * (0) + 8 * (0))) >> SCx200_PIOFORMAT_SHIFT31) & 0x01; | |||
5697 | WDCDEBUG_PRINT(("%s: pio format %d\n", __func__, pioformat), | |||
5698 | DEBUG_PROBE); | |||
5699 | ||||
5700 | /* Per channel settings */ | |||
5701 | for (drive = 0; drive < 2; drive++) { | |||
5702 | drvp = &chp->ch_drive[drive]; | |||
5703 | ||||
5704 | /* If no drive, skip */ | |||
5705 | if ((drvp->drive_flags & DRIVE(0x0001|0x0002|0x0004)) == 0) | |||
5706 | continue; | |||
5707 | ||||
5708 | piotim = pci_conf_read(sc->sc_pc, sc->sc_tag, | |||
5709 | SCx200_TIM_PIO(channel, drive)(0x40 + 16 * (channel) + 8 * (drive))); | |||
5710 | dmatim = pci_conf_read(sc->sc_pc, sc->sc_tag, | |||
5711 | SCx200_TIM_DMA(channel, drive)(0x44 + 16 * (channel) + 8 * (drive))); | |||
5712 | WDCDEBUG_PRINT(("%s:%d:%d: piotim=0x%x, dmatim=0x%x\n", | |||
5713 | sc->sc_wdcdev.sc_dev.dv_xname, channel, drive, | |||
5714 | piotim, dmatim), DEBUG_PROBE); | |||
5715 | ||||
5716 | if ((chp->wdc->cap & WDC_CAPABILITY_UDMA0x0010) != 0 && | |||
5717 | (drvp->drive_flags & DRIVE_UDMA0x0020) != 0) { | |||
5718 | /* Setup UltraDMA mode */ | |||
5719 | drvp->drive_flags &= ~DRIVE_DMA0x0010; | |||
5720 | idedma_ctl |= IDEDMA_CTL_DRV_DMA(drive)(0x20 << (drive)); | |||
5721 | dmatim = scx200_udma33[drvp->UDMA_mode]; | |||
5722 | mode = drvp->PIO_mode; | |||
5723 | } else if ((chp->wdc->cap & WDC_CAPABILITY_DMA0x0008) != 0 && | |||
5724 | (drvp->drive_flags & DRIVE_DMA0x0010) != 0) { | |||
5725 | /* Setup multiword DMA mode */ | |||
5726 | drvp->drive_flags &= ~DRIVE_UDMA0x0020; | |||
5727 | idedma_ctl |= IDEDMA_CTL_DRV_DMA(drive)(0x20 << (drive)); | |||
5728 | dmatim = scx200_dma33[drvp->DMA_mode]; | |||
5729 | ||||
5730 | /* mode = min(pio, dma + 2) */ | |||
5731 | if (drvp->PIO_mode <= (drvp->DMA_mode + 2)) | |||
5732 | mode = drvp->PIO_mode; | |||
5733 | else | |||
5734 | mode = drvp->DMA_mode + 2; | |||
5735 | } else { | |||
5736 | mode = drvp->PIO_mode; | |||
5737 | } | |||
5738 | ||||
5739 | /* Setup PIO mode */ | |||
5740 | drvp->PIO_mode = mode; | |||
5741 | if (mode < 2) | |||
5742 | drvp->DMA_mode = 0; | |||
5743 | else | |||
5744 | drvp->DMA_mode = mode - 2; | |||
5745 | ||||
5746 | piotim = scx200_pio33[pioformat][drvp->PIO_mode]; | |||
5747 | ||||
5748 | WDCDEBUG_PRINT(("%s:%d:%d: new piotim=0x%x, dmatim=0x%x\n", | |||
5749 | sc->sc_wdcdev.sc_dev.dv_xname, channel, drive, | |||
5750 | piotim, dmatim), DEBUG_PROBE); | |||
5751 | ||||
5752 | pci_conf_write(sc->sc_pc, sc->sc_tag, | |||
5753 | SCx200_TIM_PIO(channel, drive)(0x40 + 16 * (channel) + 8 * (drive)), piotim); | |||
5754 | pci_conf_write(sc->sc_pc, sc->sc_tag, | |||
5755 | SCx200_TIM_DMA(channel, drive)(0x44 + 16 * (channel) + 8 * (drive)), dmatim); | |||
5756 | } | |||
5757 | ||||
5758 | if (idedma_ctl != 0) { | |||
5759 | /* Add software bits in status register */ | |||
5760 | bus_space_write_1(sc->sc_dma_iot, sc->sc_dma_ioh,((sc->sc_dma_iot)->write_1((sc->sc_dma_ioh), ((0x02 + 0x08 * (channel))), (idedma_ctl))) | |||
5761 | IDEDMA_CTL(channel), idedma_ctl)((sc->sc_dma_iot)->write_1((sc->sc_dma_ioh), ((0x02 + 0x08 * (channel))), (idedma_ctl))); | |||
5762 | } | |||
5763 | ||||
5764 | pciide_print_modes(cp); | |||
5765 | } | |||
5766 | ||||
5767 | void | |||
5768 | acer_chip_map(struct pciide_softc *sc, struct pci_attach_args *pa) | |||
5769 | { | |||
5770 | struct pciide_channel *cp; | |||
5771 | int channel; | |||
5772 | pcireg_t cr, interface; | |||
5773 | bus_size_t cmdsize, ctlsize; | |||
5774 | int rev = sc->sc_rev; | |||
5775 | ||||
5776 | printf(": DMA"); | |||
5777 | pciide_mapreg_dma(sc, pa); | |||
5778 | sc->sc_wdcdev.cap = WDC_CAPABILITY_DATA160x0001 | WDC_CAPABILITY_DATA320x0002 | | |||
5779 | WDC_CAPABILITY_MODE0x0004; | |||
5780 | ||||
5781 | if (sc->sc_dma_ok) { | |||
5782 | sc->sc_wdcdev.cap |= WDC_CAPABILITY_DMA0x0008; | |||
5783 | if (rev >= 0x20) { | |||
5784 | sc->sc_wdcdev.cap |= WDC_CAPABILITY_UDMA0x0010; | |||
5785 | if (rev >= 0xC4) | |||
5786 | sc->sc_wdcdev.UDMA_cap = 5; | |||
5787 | else if (rev >= 0xC2) | |||
5788 | sc->sc_wdcdev.UDMA_cap = 4; | |||
5789 | else | |||
5790 | sc->sc_wdcdev.UDMA_cap = 2; | |||
5791 | } | |||
5792 | sc->sc_wdcdev.cap |= WDC_CAPABILITY_IRQACK0x0400; | |||
5793 | sc->sc_wdcdev.irqack = pciide_irqack; | |||
5794 | if (rev <= 0xC4) | |||
5795 | sc->sc_wdcdev.dma_init = acer_dma_init; | |||
5796 | } | |||
5797 | ||||
5798 | sc->sc_wdcdev.PIO_cap = 4; | |||
5799 | sc->sc_wdcdev.DMA_cap = 2; | |||
5800 | sc->sc_wdcdev.set_modes = acer_setup_channel; | |||
5801 | sc->sc_wdcdev.channels = sc->wdc_chanarray; | |||
5802 | sc->sc_wdcdev.nchannels = PCIIDE_NUM_CHANNELS2; | |||
5803 | ||||
5804 | pciide_pci_write(sc->sc_pc, sc->sc_tag, ACER_CDRC0x53, | |||
5805 | (pciide_pci_read(sc->sc_pc, sc->sc_tag, ACER_CDRC0x53) | | |||
5806 | ACER_CDRC_DMA_EN0x01) & ~ACER_CDRC_FIFO_DISABLE0x02); | |||
5807 | ||||
5808 | /* Enable "microsoft register bits" R/W. */ | |||
5809 | pciide_pci_write(sc->sc_pc, sc->sc_tag, ACER_CCAR30x50, | |||
5810 | pciide_pci_read(sc->sc_pc, sc->sc_tag, ACER_CCAR30x50) | ACER_CCAR3_PI0x02); | |||
5811 | pciide_pci_write(sc->sc_pc, sc->sc_tag, ACER_CCAR10x43, | |||
5812 | pciide_pci_read(sc->sc_pc, sc->sc_tag, ACER_CCAR10x43) & | |||
5813 | ~(ACER_CHANSTATUS_RO0x40|PCIIDE_CHAN_RO(0)(0x20 >> (0))|PCIIDE_CHAN_RO(1)(0x20 >> (1)))); | |||
5814 | pciide_pci_write(sc->sc_pc, sc->sc_tag, ACER_CCAR20x4d, | |||
5815 | pciide_pci_read(sc->sc_pc, sc->sc_tag, ACER_CCAR20x4d) & | |||
5816 | ~ACER_CHANSTATUSREGS_RO0x80); | |||
5817 | cr = pci_conf_read(sc->sc_pc, sc->sc_tag, PCI_CLASS_REG0x08); | |||
5818 | cr |= (PCIIDE_CHANSTATUS_EN0x40 << PCI_INTERFACE_SHIFT8); | |||
5819 | pci_conf_write(sc->sc_pc, sc->sc_tag, PCI_CLASS_REG0x08, cr); | |||
5820 | /* Don't use cr, re-read the real register content instead */ | |||
5821 | interface = PCI_INTERFACE(pci_conf_read(sc->sc_pc, sc->sc_tag,(((pci_conf_read(sc->sc_pc, sc->sc_tag, 0x08)) >> 8) & 0xff) | |||
5822 | PCI_CLASS_REG))(((pci_conf_read(sc->sc_pc, sc->sc_tag, 0x08)) >> 8) & 0xff); | |||
5823 | ||||
5824 | pciide_print_channels(sc->sc_wdcdev.nchannels, interface); | |||
5825 | ||||
5826 | /* From linux: enable "Cable Detection" */ | |||
5827 | if (rev >= 0xC2) | |||
5828 | pciide_pci_write(sc->sc_pc, sc->sc_tag, ACER_0x4B0x4b, | |||
5829 | pciide_pci_read(sc->sc_pc, sc->sc_tag, ACER_0x4B0x4b) | |||
5830 | | ACER_0x4B_CDETECT0x08); | |||
5831 | ||||
5832 | for (channel = 0; channel < sc->sc_wdcdev.nchannels; channel++) { | |||
5833 | cp = &sc->pciide_channels[channel]; | |||
5834 | if (pciide_chansetup(sc, channel, interface) == 0) | |||
5835 | continue; | |||
5836 | if ((interface & PCIIDE_CHAN_EN(channel)(0x20 >> (channel))) == 0) { | |||
5837 | printf("%s: %s ignored (disabled)\n", | |||
5838 | sc->sc_wdcdev.sc_dev.dv_xname, cp->name); | |||
5839 | cp->hw_ok = 0; | |||
5840 | continue; | |||
5841 | } | |||
5842 | pciide_map_compat_intr(pa, cp, channel, interface); | |||
5843 | if (cp->hw_ok == 0) | |||
5844 | continue; | |||
5845 | pciide_mapchan(pa, cp, interface, &cmdsize, &ctlsize, | |||
5846 | (rev >= 0xC2) ? pciide_pci_intr : acer_pci_intr); | |||
5847 | if (cp->hw_ok == 0) { | |||
5848 | pciide_unmap_compat_intr(pa, cp, channel, interface); | |||
5849 | continue; | |||
5850 | } | |||
5851 | if (pciide_chan_candisable(cp)) { | |||
5852 | cr &= ~(PCIIDE_CHAN_EN(channel)(0x20 >> (channel)) << PCI_INTERFACE_SHIFT8); | |||
5853 | pci_conf_write(sc->sc_pc, sc->sc_tag, | |||
5854 | PCI_CLASS_REG0x08, cr); | |||
5855 | } | |||
5856 | if (cp->hw_ok == 0) { | |||
5857 | pciide_unmap_compat_intr(pa, cp, channel, interface); | |||
5858 | continue; | |||
5859 | } | |||
5860 | acer_setup_channel(&cp->wdc_channel); | |||
5861 | } | |||
5862 | } | |||
5863 | ||||
5864 | void | |||
5865 | acer_setup_channel(struct channel_softc *chp) | |||
5866 | { | |||
5867 | struct ata_drive_datas *drvp; | |||
5868 | int drive; | |||
5869 | u_int32_t acer_fifo_udma; | |||
5870 | u_int32_t idedma_ctl; | |||
5871 | struct pciide_channel *cp = (struct pciide_channel *)chp; | |||
5872 | struct pciide_softc *sc = (struct pciide_softc *)cp->wdc_channel.wdc; | |||
5873 | ||||
5874 | idedma_ctl = 0; | |||
5875 | acer_fifo_udma = pci_conf_read(sc->sc_pc, sc->sc_tag, ACER_FTH_UDMA0x54); | |||
5876 | WDCDEBUG_PRINT(("acer_setup_channel: old fifo/udma reg 0x%x\n", | |||
5877 | acer_fifo_udma), DEBUG_PROBE); | |||
5878 | /* setup DMA if needed */ | |||
5879 | pciide_channel_dma_setup(cp); | |||
5880 | ||||
5881 | if ((chp->ch_drive[0].drive_flags | chp->ch_drive[1].drive_flags) & | |||
5882 | DRIVE_UDMA0x0020) { /* check 80 pins cable */ | |||
5883 | if (pciide_pci_read(sc->sc_pc, sc->sc_tag, ACER_0x4A0x4a) & | |||
5884 | ACER_0x4A_80PIN(chp->channel)(0x1 << (chp->channel))) { | |||
5885 | WDCDEBUG_PRINT(("%s:%d: 80-wire cable not detected\n", | |||
5886 | sc->sc_wdcdev.sc_dev.dv_xname, chp->channel), | |||
5887 | DEBUG_PROBE); | |||
5888 | if (chp->ch_drive[0].UDMA_mode > 2) | |||
5889 | chp->ch_drive[0].UDMA_mode = 2; | |||
5890 | if (chp->ch_drive[1].UDMA_mode > 2) | |||
5891 | chp->ch_drive[1].UDMA_mode = 2; | |||
5892 | } | |||
5893 | } | |||
5894 | ||||
5895 | for (drive = 0; drive < 2; drive++) { | |||
5896 | drvp = &chp->ch_drive[drive]; | |||
5897 | /* If no drive, skip */ | |||
5898 | if ((drvp->drive_flags & DRIVE(0x0001|0x0002|0x0004)) == 0) | |||
5899 | continue; | |||
5900 | WDCDEBUG_PRINT(("acer_setup_channel: old timings reg for " | |||
5901 | "channel %d drive %d 0x%x\n", chp->channel, drive, | |||
5902 | pciide_pci_read(sc->sc_pc, sc->sc_tag, | |||
5903 | ACER_IDETIM(chp->channel, drive))), DEBUG_PROBE); | |||
5904 | /* clear FIFO/DMA mode */ | |||
5905 | acer_fifo_udma &= ~(ACER_FTH_OPL(chp->channel, drive, 0x3)(((0x3) & 0x3) << (2 + (drive) * 4 + (chp->channel ) * 8)) | | |||
5906 | ACER_UDMA_EN(chp->channel, drive)(0x8 << (16 + (drive) * 4 + (chp->channel) * 8)) | | |||
5907 | ACER_UDMA_TIM(chp->channel, drive, 0x7)(((0x7) & 0x7) << (16 + (drive) * 4 + (chp->channel ) * 8))); | |||
5908 | ||||
5909 | /* add timing values, setup DMA if needed */ | |||
5910 | if ((drvp->drive_flags & DRIVE_DMA0x0010) == 0 && | |||
5911 | (drvp->drive_flags & DRIVE_UDMA0x0020) == 0) { | |||
5912 | acer_fifo_udma |= | |||
5913 | ACER_FTH_OPL(chp->channel, drive, 0x1)(((0x1) & 0x3) << (2 + (drive) * 4 + (chp->channel ) * 8)); | |||
5914 | goto pio; | |||
5915 | } | |||
5916 | ||||
5917 | acer_fifo_udma |= ACER_FTH_OPL(chp->channel, drive, 0x2)(((0x2) & 0x3) << (2 + (drive) * 4 + (chp->channel ) * 8)); | |||
5918 | if (drvp->drive_flags & DRIVE_UDMA0x0020) { | |||
5919 | /* use Ultra/DMA */ | |||
5920 | drvp->drive_flags &= ~DRIVE_DMA0x0010; | |||
5921 | acer_fifo_udma |= ACER_UDMA_EN(chp->channel, drive)(0x8 << (16 + (drive) * 4 + (chp->channel) * 8)); | |||
5922 | acer_fifo_udma |= | |||
5923 | ACER_UDMA_TIM(chp->channel, drive,(((acer_udma[drvp->UDMA_mode]) & 0x7) << (16 + ( drive) * 4 + (chp->channel) * 8)) | |||
5924 | acer_udma[drvp->UDMA_mode])(((acer_udma[drvp->UDMA_mode]) & 0x7) << (16 + ( drive) * 4 + (chp->channel) * 8)); | |||
5925 | /* XXX disable if one drive < UDMA3 ? */ | |||
5926 | if (drvp->UDMA_mode >= 3) { | |||
5927 | pciide_pci_write(sc->sc_pc, sc->sc_tag, | |||
5928 | ACER_0x4B0x4b, | |||
5929 | pciide_pci_read(sc->sc_pc, sc->sc_tag, | |||
5930 | ACER_0x4B0x4b) | ACER_0x4B_UDMA660x01); | |||
5931 | } | |||
5932 | } else { | |||
5933 | /* | |||
5934 | * use Multiword DMA | |||
5935 | * Timings will be used for both PIO and DMA, | |||
5936 | * so adjust DMA mode if needed | |||
5937 | */ | |||
5938 | if (drvp->PIO_mode > (drvp->DMA_mode + 2)) | |||
5939 | drvp->PIO_mode = drvp->DMA_mode + 2; | |||
5940 | if (drvp->DMA_mode + 2 > (drvp->PIO_mode)) | |||
5941 | drvp->DMA_mode = (drvp->PIO_mode > 2) ? | |||
5942 | drvp->PIO_mode - 2 : 0; | |||
5943 | if (drvp->DMA_mode == 0) | |||
5944 | drvp->PIO_mode = 0; | |||
5945 | } | |||
5946 | idedma_ctl |= IDEDMA_CTL_DRV_DMA(drive)(0x20 << (drive)); | |||
5947 | pio: pciide_pci_write(sc->sc_pc, sc->sc_tag, | |||
5948 | ACER_IDETIM(chp->channel, drive)(0x5a + (drive) + (chp->channel) * 4), | |||
5949 | acer_pio[drvp->PIO_mode]); | |||
5950 | } | |||
5951 | WDCDEBUG_PRINT(("acer_setup_channel: new fifo/udma reg 0x%x\n", | |||
5952 | acer_fifo_udma), DEBUG_PROBE); | |||
5953 | pci_conf_write(sc->sc_pc, sc->sc_tag, ACER_FTH_UDMA0x54, acer_fifo_udma); | |||
5954 | if (idedma_ctl != 0) { | |||
5955 | /* Add software bits in status register */ | |||
5956 | bus_space_write_1(sc->sc_dma_iot, sc->sc_dma_ioh,((sc->sc_dma_iot)->write_1((sc->sc_dma_ioh), ((0x02 + 0x08 * (chp->channel))), (idedma_ctl))) | |||
5957 | IDEDMA_CTL(chp->channel), idedma_ctl)((sc->sc_dma_iot)->write_1((sc->sc_dma_ioh), ((0x02 + 0x08 * (chp->channel))), (idedma_ctl))); | |||
5958 | } | |||
5959 | pciide_print_modes(cp); | |||
5960 | } | |||
5961 | ||||
5962 | int | |||
5963 | acer_pci_intr(void *arg) | |||
5964 | { | |||
5965 | struct pciide_softc *sc = arg; | |||
5966 | struct pciide_channel *cp; | |||
5967 | struct channel_softc *wdc_cp; | |||
5968 | int i, rv, crv; | |||
5969 | u_int32_t chids; | |||
5970 | ||||
5971 | rv = 0; | |||
5972 | chids = pciide_pci_read(sc->sc_pc, sc->sc_tag, ACER_CHIDS0x75); | |||
5973 | for (i = 0; i < sc->sc_wdcdev.nchannels; i++) { | |||
5974 | cp = &sc->pciide_channels[i]; | |||
5975 | wdc_cp = &cp->wdc_channel; | |||
5976 | /* If a compat channel skip. */ | |||
5977 | if (cp->compat) | |||
5978 | continue; | |||
5979 | if (chids & ACER_CHIDS_INT(i)((0x1) << (i))) { | |||
5980 | crv = wdcintr(wdc_cp); | |||
5981 | if (crv == 0) | |||
5982 | printf("%s:%d: bogus intr\n", | |||
5983 | sc->sc_wdcdev.sc_dev.dv_xname, i); | |||
5984 | else | |||
5985 | rv = 1; | |||
5986 | } | |||
5987 | } | |||
5988 | return (rv); | |||
5989 | } | |||
5990 | ||||
5991 | int | |||
5992 | acer_dma_init(void *v, int channel, int drive, void *databuf, | |||
5993 | size_t datalen, int flags) | |||
5994 | { | |||
5995 | /* Use PIO for LBA48 transfers. */ | |||
5996 | if (flags & WDC_DMA_LBA480x04) | |||
5997 | return (EINVAL22); | |||
5998 | ||||
5999 | return (pciide_dma_init(v, channel, drive, databuf, datalen, flags)); | |||
6000 | } | |||
6001 | ||||
6002 | void | |||
6003 | hpt_chip_map(struct pciide_softc *sc, struct pci_attach_args *pa) | |||
6004 | { | |||
6005 | struct pciide_channel *cp; | |||
6006 | int i, compatchan, revision; | |||
6007 | pcireg_t interface; | |||
6008 | bus_size_t cmdsize, ctlsize; | |||
6009 | ||||
6010 | revision = sc->sc_rev; | |||
6011 | ||||
6012 | /* | |||
6013 | * when the chip is in native mode it identifies itself as a | |||
6014 | * 'misc mass storage'. Fake interface in this case. | |||
6015 | */ | |||
6016 | if (PCI_SUBCLASS(pa->pa_class)(((pa->pa_class) >> 16) & 0xff) == PCI_SUBCLASS_MASS_STORAGE_IDE0x01) { | |||
6017 | interface = PCI_INTERFACE(pa->pa_class)(((pa->pa_class) >> 8) & 0xff); | |||
6018 | } else { | |||
6019 | interface = PCIIDE_INTERFACE_BUS_MASTER_DMA0x80 | | |||
6020 | PCIIDE_INTERFACE_PCI(0)(0x01 << (2 * (0))); | |||
6021 | if ((sc->sc_pp->ide_product == PCI_PRODUCT_TRIONES_HPT3660x0004 && | |||
6022 | (revision == HPT370_REV0x03 || revision == HPT370A_REV0x04 || | |||
6023 | revision == HPT372_REV0x05)) || | |||
6024 | sc->sc_pp->ide_product == PCI_PRODUCT_TRIONES_HPT372A0x0005 || | |||
6025 | sc->sc_pp->ide_product == PCI_PRODUCT_TRIONES_HPT3020x0006 || | |||
6026 | sc->sc_pp->ide_product == PCI_PRODUCT_TRIONES_HPT3710x0007 || | |||
6027 | sc->sc_pp->ide_product == PCI_PRODUCT_TRIONES_HPT3740x0008) | |||
6028 | interface |= PCIIDE_INTERFACE_PCI(1)(0x01 << (2 * (1))); | |||
6029 | } | |||
6030 | ||||
6031 | printf(": DMA"); | |||
6032 | pciide_mapreg_dma(sc, pa); | |||
6033 | printf("\n"); | |||
6034 | sc->sc_wdcdev.cap = WDC_CAPABILITY_DATA160x0001 | WDC_CAPABILITY_DATA320x0002 | | |||
6035 | WDC_CAPABILITY_MODE0x0004; | |||
6036 | if (sc->sc_dma_ok) { | |||
6037 | sc->sc_wdcdev.cap |= WDC_CAPABILITY_DMA0x0008 | WDC_CAPABILITY_UDMA0x0010; | |||
6038 | sc->sc_wdcdev.cap |= WDC_CAPABILITY_IRQACK0x0400; | |||
6039 | sc->sc_wdcdev.irqack = pciide_irqack; | |||
6040 | } | |||
6041 | sc->sc_wdcdev.PIO_cap = 4; | |||
6042 | sc->sc_wdcdev.DMA_cap = 2; | |||
6043 | ||||
6044 | sc->sc_wdcdev.set_modes = hpt_setup_channel; | |||
6045 | sc->sc_wdcdev.channels = sc->wdc_chanarray; | |||
6046 | if (sc->sc_pp->ide_product == PCI_PRODUCT_TRIONES_HPT3660x0004 && | |||
6047 | revision == HPT366_REV0x01) { | |||
6048 | sc->sc_wdcdev.UDMA_cap = 4; | |||
6049 | /* | |||
6050 | * The 366 has 2 PCI IDE functions, one for primary and one | |||
6051 | * for secondary. So we need to call pciide_mapregs_compat() | |||
6052 | * with the real channel | |||
6053 | */ | |||
6054 | if (pa->pa_function == 0) { | |||
6055 | compatchan = 0; | |||
6056 | } else if (pa->pa_function == 1) { | |||
6057 | compatchan = 1; | |||
6058 | } else { | |||
6059 | printf("%s: unexpected PCI function %d\n", | |||
6060 | sc->sc_wdcdev.sc_dev.dv_xname, pa->pa_function); | |||
6061 | return; | |||
6062 | } | |||
6063 | sc->sc_wdcdev.nchannels = 1; | |||
6064 | } else { | |||
6065 | sc->sc_wdcdev.nchannels = 2; | |||
6066 | if (sc->sc_pp->ide_product == PCI_PRODUCT_TRIONES_HPT372A0x0005 || | |||
6067 | sc->sc_pp->ide_product == PCI_PRODUCT_TRIONES_HPT3020x0006 || | |||
6068 | sc->sc_pp->ide_product == PCI_PRODUCT_TRIONES_HPT3710x0007 || | |||
6069 | sc->sc_pp->ide_product == PCI_PRODUCT_TRIONES_HPT3740x0008) | |||
6070 | sc->sc_wdcdev.UDMA_cap = 6; | |||
6071 | else if (sc->sc_pp->ide_product == PCI_PRODUCT_TRIONES_HPT3660x0004) { | |||
6072 | if (revision == HPT372_REV0x05) | |||
6073 | sc->sc_wdcdev.UDMA_cap = 6; | |||
6074 | else | |||
6075 | sc->sc_wdcdev.UDMA_cap = 5; | |||
6076 | } | |||
6077 | } | |||
6078 | for (i = 0; i < sc->sc_wdcdev.nchannels; i++) { | |||
6079 | cp = &sc->pciide_channels[i]; | |||
6080 | compatchan = 0; | |||
6081 | if (sc->sc_wdcdev.nchannels > 1) { | |||
6082 | compatchan = i; | |||
6083 | if((pciide_pci_read(sc->sc_pc, sc->sc_tag, | |||
6084 | HPT370_CTRL1(i)(0x50 + ((i) * 4))) & HPT370_CTRL1_EN0x04) == 0) { | |||
6085 | printf("%s: %s ignored (disabled)\n", | |||
6086 | sc->sc_wdcdev.sc_dev.dv_xname, cp->name); | |||
6087 | cp->hw_ok = 0; | |||
6088 | continue; | |||
6089 | } | |||
6090 | } | |||
6091 | if (pciide_chansetup(sc, i, interface) == 0) | |||
6092 | continue; | |||
6093 | if (interface & PCIIDE_INTERFACE_PCI(i)(0x01 << (2 * (i)))) { | |||
6094 | cp->hw_ok = pciide_mapregs_native(pa, cp, &cmdsize, | |||
6095 | &ctlsize, hpt_pci_intr); | |||
6096 | } else { | |||
6097 | cp->hw_ok = pciide_mapregs_compat(pa, cp, compatchan, | |||
6098 | &cmdsize, &ctlsize); | |||
6099 | } | |||
6100 | if (cp->hw_ok == 0) | |||
6101 | return; | |||
6102 | cp->wdc_channel.data32iot = cp->wdc_channel.cmd_iot; | |||
6103 | cp->wdc_channel.data32ioh = cp->wdc_channel.cmd_ioh; | |||
6104 | wdcattach(&cp->wdc_channel); | |||
6105 | hpt_setup_channel(&cp->wdc_channel); | |||
6106 | } | |||
6107 | if ((sc->sc_pp->ide_product == PCI_PRODUCT_TRIONES_HPT3660x0004 && | |||
6108 | (revision == HPT370_REV0x03 || revision == HPT370A_REV0x04 || | |||
6109 | revision == HPT372_REV0x05)) || | |||
6110 | sc->sc_pp->ide_product == PCI_PRODUCT_TRIONES_HPT372A0x0005 || | |||
6111 | sc->sc_pp->ide_product == PCI_PRODUCT_TRIONES_HPT3020x0006 || | |||
6112 | sc->sc_pp->ide_product == PCI_PRODUCT_TRIONES_HPT3710x0007 || | |||
6113 | sc->sc_pp->ide_product == PCI_PRODUCT_TRIONES_HPT3740x0008) { | |||
6114 | /* | |||
6115 | * Turn off fast interrupts | |||
6116 | */ | |||
6117 | pciide_pci_write(sc->sc_pc, sc->sc_tag, HPT370_CTRL2(0)(0x51 + ((0) * 4)), | |||
6118 | pciide_pci_read(sc->sc_pc, sc->sc_tag, HPT370_CTRL2(0)(0x51 + ((0) * 4))) & | |||
6119 | ~(HPT370_CTRL2_FASTIRQ0x02 | HPT370_CTRL2_HIRQ0x01)); | |||
6120 | pciide_pci_write(sc->sc_pc, sc->sc_tag, HPT370_CTRL2(1)(0x51 + ((1) * 4)), | |||
6121 | pciide_pci_read(sc->sc_pc, sc->sc_tag, HPT370_CTRL2(1)(0x51 + ((1) * 4))) & | |||
6122 | ~(HPT370_CTRL2_FASTIRQ0x02 | HPT370_CTRL2_HIRQ0x01)); | |||
6123 | ||||
6124 | /* | |||
6125 | * HPT370 and higher has a bit to disable interrupts, | |||
6126 | * make sure to clear it | |||
6127 | */ | |||
6128 | pciide_pci_write(sc->sc_pc, sc->sc_tag, HPT_CSEL0x5a, | |||
6129 | pciide_pci_read(sc->sc_pc, sc->sc_tag, HPT_CSEL0x5a) & | |||
6130 | ~HPT_CSEL_IRQDIS0x10); | |||
6131 | } | |||
6132 | /* set clocks, etc (mandatory on 372/4, optional otherwise) */ | |||
6133 | if (sc->sc_pp->ide_product == PCI_PRODUCT_TRIONES_HPT372A0x0005 || | |||
6134 | sc->sc_pp->ide_product == PCI_PRODUCT_TRIONES_HPT3020x0006 || | |||
6135 | sc->sc_pp->ide_product == PCI_PRODUCT_TRIONES_HPT3710x0007 || | |||
6136 | sc->sc_pp->ide_product == PCI_PRODUCT_TRIONES_HPT3740x0008 || | |||
6137 | (sc->sc_pp->ide_product == PCI_PRODUCT_TRIONES_HPT3660x0004 && | |||
6138 | revision == HPT372_REV0x05)) | |||
6139 | pciide_pci_write(sc->sc_pc, sc->sc_tag, HPT_SC20x5b, | |||
6140 | (pciide_pci_read(sc->sc_pc, sc->sc_tag, HPT_SC20x5b) & | |||
6141 | HPT_SC2_MAEN0x01) | HPT_SC2_OSC_EN0x20); | |||
6142 | ||||
6143 | return; | |||
6144 | } | |||
6145 | ||||
6146 | void | |||
6147 | hpt_setup_channel(struct channel_softc *chp) | |||
6148 | { | |||
6149 | struct ata_drive_datas *drvp; | |||
6150 | int drive; | |||
6151 | int cable; | |||
6152 | u_int32_t before, after; | |||
6153 | u_int32_t idedma_ctl; | |||
6154 | struct pciide_channel *cp = (struct pciide_channel *)chp; | |||
6155 | struct pciide_softc *sc = (struct pciide_softc *)cp->wdc_channel.wdc; | |||
6156 | int revision = sc->sc_rev; | |||
6157 | u_int32_t *tim_pio, *tim_dma, *tim_udma; | |||
6158 | ||||
6159 | cable = pciide_pci_read(sc->sc_pc, sc->sc_tag, HPT_CSEL0x5a); | |||
6160 | ||||
6161 | /* setup DMA if needed */ | |||
6162 | pciide_channel_dma_setup(cp); | |||
6163 | ||||
6164 | idedma_ctl = 0; | |||
6165 | ||||
6166 | switch (sc->sc_pp->ide_product) { | |||
6167 | case PCI_PRODUCT_TRIONES_HPT3660x0004: | |||
6168 | if (revision == HPT370_REV0x03 || | |||
6169 | revision == HPT370A_REV0x04) { | |||
6170 | tim_pio = hpt370_pio; | |||
6171 | tim_dma = hpt370_dma; | |||
6172 | tim_udma = hpt370_udma; | |||
6173 | } else if (revision == HPT372_REV0x05) { | |||
6174 | tim_pio = hpt372_pio; | |||
6175 | tim_dma = hpt372_dma; | |||
6176 | tim_udma = hpt372_udma; | |||
6177 | } else { | |||
6178 | tim_pio = hpt366_pio; | |||
6179 | tim_dma = hpt366_dma; | |||
6180 | tim_udma = hpt366_udma; | |||
6181 | } | |||
6182 | break; | |||
6183 | case PCI_PRODUCT_TRIONES_HPT372A0x0005: | |||
6184 | case PCI_PRODUCT_TRIONES_HPT3020x0006: | |||
6185 | case PCI_PRODUCT_TRIONES_HPT3710x0007: | |||
6186 | tim_pio = hpt372_pio; | |||
6187 | tim_dma = hpt372_dma; | |||
6188 | tim_udma = hpt372_udma; | |||
6189 | break; | |||
6190 | case PCI_PRODUCT_TRIONES_HPT3740x0008: | |||
6191 | tim_pio = hpt374_pio; | |||
6192 | tim_dma = hpt374_dma; | |||
6193 | tim_udma = hpt374_udma; | |||
6194 | break; | |||
6195 | default: | |||
6196 | printf("%s: no known timing values\n", | |||
6197 | sc->sc_wdcdev.sc_dev.dv_xname); | |||
6198 | goto end; | |||
6199 | } | |||
6200 | ||||
6201 | /* Per drive settings */ | |||
6202 | for (drive = 0; drive < 2; drive++) { | |||
6203 | drvp = &chp->ch_drive[drive]; | |||
6204 | /* If no drive, skip */ | |||
6205 | if ((drvp->drive_flags & DRIVE(0x0001|0x0002|0x0004)) == 0) | |||
6206 | continue; | |||
6207 | before = pci_conf_read(sc->sc_pc, sc->sc_tag, | |||
6208 | HPT_IDETIM(chp->channel, drive)(0x40 + ((drive) * 4) + ((chp->channel) * 8))); | |||
6209 | ||||
6210 | /* add timing values, setup DMA if needed */ | |||
6211 | if (drvp->drive_flags & DRIVE_UDMA0x0020) { | |||
6212 | /* use Ultra/DMA */ | |||
6213 | drvp->drive_flags &= ~DRIVE_DMA0x0010; | |||
6214 | if ((cable & HPT_CSEL_CBLID(chp->channel)(0x01 << (1 - (chp->channel)))) != 0 && | |||
6215 | drvp->UDMA_mode > 2) { | |||
6216 | WDCDEBUG_PRINT(("%s(%s:%d:%d): 80-wire " | |||
6217 | "cable not detected\n", drvp->drive_name, | |||
6218 | sc->sc_wdcdev.sc_dev.dv_xname, | |||
6219 | chp->channel, drive), DEBUG_PROBE); | |||
6220 | drvp->UDMA_mode = 2; | |||
6221 | } | |||
6222 | after = tim_udma[drvp->UDMA_mode]; | |||
6223 | idedma_ctl |= IDEDMA_CTL_DRV_DMA(drive)(0x20 << (drive)); | |||
6224 | } else if (drvp->drive_flags & DRIVE_DMA0x0010) { | |||
6225 | /* | |||
6226 | * use Multiword DMA. | |||
6227 | * Timings will be used for both PIO and DMA, so adjust | |||
6228 | * DMA mode if needed | |||
6229 | */ | |||
6230 | if (drvp->PIO_mode >= 3 && | |||
6231 | (drvp->DMA_mode + 2) > drvp->PIO_mode) { | |||
6232 | drvp->DMA_mode = drvp->PIO_mode - 2; | |||
6233 | } | |||
6234 | after = tim_dma[drvp->DMA_mode]; | |||
6235 | idedma_ctl |= IDEDMA_CTL_DRV_DMA(drive)(0x20 << (drive)); | |||
6236 | } else { | |||
6237 | /* PIO only */ | |||
6238 | after = tim_pio[drvp->PIO_mode]; | |||
6239 | } | |||
6240 | pci_conf_write(sc->sc_pc, sc->sc_tag, | |||
6241 | HPT_IDETIM(chp->channel, drive)(0x40 + ((drive) * 4) + ((chp->channel) * 8)), after); | |||
6242 | WDCDEBUG_PRINT(("%s: bus speed register set to 0x%08x " | |||
6243 | "(BIOS 0x%08x)\n", sc->sc_wdcdev.sc_dev.dv_xname, | |||
6244 | after, before), DEBUG_PROBE); | |||
6245 | } | |||
6246 | end: | |||
6247 | if (idedma_ctl != 0) { | |||
6248 | /* Add software bits in status register */ | |||
6249 | bus_space_write_1(sc->sc_dma_iot, sc->sc_dma_ioh,((sc->sc_dma_iot)->write_1((sc->sc_dma_ioh), ((0x02 + 0x08 * (chp->channel))), (idedma_ctl))) | |||
6250 | IDEDMA_CTL(chp->channel), idedma_ctl)((sc->sc_dma_iot)->write_1((sc->sc_dma_ioh), ((0x02 + 0x08 * (chp->channel))), (idedma_ctl))); | |||
6251 | } | |||
6252 | pciide_print_modes(cp); | |||
6253 | } | |||
6254 | ||||
6255 | int | |||
6256 | hpt_pci_intr(void *arg) | |||
6257 | { | |||
6258 | struct pciide_softc *sc = arg; | |||
6259 | struct pciide_channel *cp; | |||
6260 | struct channel_softc *wdc_cp; | |||
6261 | int rv = 0; | |||
6262 | int dmastat, i, crv; | |||
6263 | ||||
6264 | for (i = 0; i < sc->sc_wdcdev.nchannels; i++) { | |||
6265 | dmastat = bus_space_read_1(sc->sc_dma_iot, sc->sc_dma_ioh,((sc->sc_dma_iot)->read_1((sc->sc_dma_ioh), ((0x02 + 0x08 * (i))))) | |||
6266 | IDEDMA_CTL(i))((sc->sc_dma_iot)->read_1((sc->sc_dma_ioh), ((0x02 + 0x08 * (i))))); | |||
6267 | if((dmastat & (IDEDMA_CTL_ACT0x01 | IDEDMA_CTL_INTR0x04)) != | |||
6268 | IDEDMA_CTL_INTR0x04) | |||
6269 | continue; | |||
6270 | cp = &sc->pciide_channels[i]; | |||
6271 | wdc_cp = &cp->wdc_channel; | |||
6272 | crv = wdcintr(wdc_cp); | |||
6273 | if (crv == 0) { | |||
6274 | printf("%s:%d: bogus intr\n", | |||
6275 | sc->sc_wdcdev.sc_dev.dv_xname, i); | |||
6276 | bus_space_write_1(sc->sc_dma_iot, sc->sc_dma_ioh,((sc->sc_dma_iot)->write_1((sc->sc_dma_ioh), ((0x02 + 0x08 * (i))), (dmastat))) | |||
6277 | IDEDMA_CTL(i), dmastat)((sc->sc_dma_iot)->write_1((sc->sc_dma_ioh), ((0x02 + 0x08 * (i))), (dmastat))); | |||
6278 | } else | |||
6279 | rv = 1; | |||
6280 | } | |||
6281 | return (rv); | |||
6282 | } | |||
6283 | ||||
6284 | /* Macros to test product */ | |||
6285 | #define PDC_IS_262(sc)((sc)->sc_pp->ide_product == 0x4d38 || (sc)->sc_pp-> ide_product == 0x0d30 || (sc)->sc_pp->ide_product == 0x4d30 ) \ | |||
6286 | ((sc)->sc_pp->ide_product == PCI_PRODUCT_PROMISE_PDC202620x4d38 || \ | |||
6287 | (sc)->sc_pp->ide_product == PCI_PRODUCT_PROMISE_PDC202650x0d30 || \ | |||
6288 | (sc)->sc_pp->ide_product == PCI_PRODUCT_PROMISE_PDC202670x4d30) | |||
6289 | #define PDC_IS_265(sc)((sc)->sc_pp->ide_product == 0x0d30 || (sc)->sc_pp-> ide_product == 0x4d30 || (sc)->sc_pp->ide_product == 0x4d68 || (sc)->sc_pp->ide_product == 0x6268 || (sc)->sc_pp ->ide_product == 0x4d69 || (sc)->sc_pp->ide_product == 0x6269 || (sc)->sc_pp->ide_product == 0x1275 || (sc)-> sc_pp->ide_product == 0x5275 || (sc)->sc_pp->ide_product == 0x7275) \ | |||
6290 | ((sc)->sc_pp->ide_product == PCI_PRODUCT_PROMISE_PDC202650x0d30 || \ | |||
6291 | (sc)->sc_pp->ide_product == PCI_PRODUCT_PROMISE_PDC202670x4d30 || \ | |||
6292 | (sc)->sc_pp->ide_product == PCI_PRODUCT_PROMISE_PDC202680x4d68 || \ | |||
6293 | (sc)->sc_pp->ide_product == PCI_PRODUCT_PROMISE_PDC20268R0x6268 || \ | |||
6294 | (sc)->sc_pp->ide_product == PCI_PRODUCT_PROMISE_PDC202690x4d69 || \ | |||
6295 | (sc)->sc_pp->ide_product == PCI_PRODUCT_PROMISE_PDC202710x6269 || \ | |||
6296 | (sc)->sc_pp->ide_product == PCI_PRODUCT_PROMISE_PDC202750x1275 || \ | |||
6297 | (sc)->sc_pp->ide_product == PCI_PRODUCT_PROMISE_PDC202760x5275 || \ | |||
6298 | (sc)->sc_pp->ide_product == PCI_PRODUCT_PROMISE_PDC202770x7275) | |||
6299 | #define PDC_IS_268(sc)((sc)->sc_pp->ide_product == 0x4d68 || (sc)->sc_pp-> ide_product == 0x6268 || (sc)->sc_pp->ide_product == 0x4d69 || (sc)->sc_pp->ide_product == 0x6269 || (sc)->sc_pp ->ide_product == 0x1275 || (sc)->sc_pp->ide_product == 0x5275 || (sc)->sc_pp->ide_product == 0x7275) \ | |||
6300 | ((sc)->sc_pp->ide_product == PCI_PRODUCT_PROMISE_PDC202680x4d68 || \ | |||
6301 | (sc)->sc_pp->ide_product == PCI_PRODUCT_PROMISE_PDC20268R0x6268 || \ | |||
6302 | (sc)->sc_pp->ide_product == PCI_PRODUCT_PROMISE_PDC202690x4d69 || \ | |||
6303 | (sc)->sc_pp->ide_product == PCI_PRODUCT_PROMISE_PDC202710x6269 || \ | |||
6304 | (sc)->sc_pp->ide_product == PCI_PRODUCT_PROMISE_PDC202750x1275 || \ | |||
6305 | (sc)->sc_pp->ide_product == PCI_PRODUCT_PROMISE_PDC202760x5275 || \ | |||
6306 | (sc)->sc_pp->ide_product == PCI_PRODUCT_PROMISE_PDC202770x7275) | |||
6307 | #define PDC_IS_269(sc)((sc)->sc_pp->ide_product == 0x4d69 || (sc)->sc_pp-> ide_product == 0x6269 || (sc)->sc_pp->ide_product == 0x1275 || (sc)->sc_pp->ide_product == 0x5275 || (sc)->sc_pp ->ide_product == 0x7275) \ | |||
6308 | ((sc)->sc_pp->ide_product == PCI_PRODUCT_PROMISE_PDC202690x4d69 || \ | |||
6309 | (sc)->sc_pp->ide_product == PCI_PRODUCT_PROMISE_PDC202710x6269 || \ | |||
6310 | (sc)->sc_pp->ide_product == PCI_PRODUCT_PROMISE_PDC202750x1275 || \ | |||
6311 | (sc)->sc_pp->ide_product == PCI_PRODUCT_PROMISE_PDC202760x5275 || \ | |||
6312 | (sc)->sc_pp->ide_product == PCI_PRODUCT_PROMISE_PDC202770x7275) | |||
6313 | ||||
6314 | u_int8_t | |||
6315 | pdc268_config_read(struct channel_softc *chp, int index) | |||
6316 | { | |||
6317 | struct pciide_channel *cp = (struct pciide_channel *)chp; | |||
6318 | struct pciide_softc *sc = (struct pciide_softc *)cp->wdc_channel.wdc; | |||
6319 | int channel = chp->channel; | |||
6320 | ||||
6321 | bus_space_write_1(sc->sc_dma_iot, sc->sc_dma_ioh,((sc->sc_dma_iot)->write_1((sc->sc_dma_ioh), ((0x01 + 0x08 * (channel))), (index))) | |||
6322 | PDC268_INDEX(channel), index)((sc->sc_dma_iot)->write_1((sc->sc_dma_ioh), ((0x01 + 0x08 * (channel))), (index))); | |||
6323 | return (bus_space_read_1(sc->sc_dma_iot, sc->sc_dma_ioh,((sc->sc_dma_iot)->read_1((sc->sc_dma_ioh), ((0x03 + 0x08 * (channel))))) | |||
6324 | PDC268_DATA(channel))((sc->sc_dma_iot)->read_1((sc->sc_dma_ioh), ((0x03 + 0x08 * (channel)))))); | |||
6325 | } | |||
6326 | ||||
6327 | void | |||
6328 | pdc202xx_chip_map(struct pciide_softc *sc, struct pci_attach_args *pa) | |||
6329 | { | |||
6330 | struct pciide_channel *cp; | |||
6331 | int channel; | |||
6332 | pcireg_t interface, st, mode; | |||
6333 | bus_size_t cmdsize, ctlsize; | |||
6334 | ||||
6335 | if (!PDC_IS_268(sc)((sc)->sc_pp->ide_product == 0x4d68 || (sc)->sc_pp-> ide_product == 0x6268 || (sc)->sc_pp->ide_product == 0x4d69 || (sc)->sc_pp->ide_product == 0x6269 || (sc)->sc_pp ->ide_product == 0x1275 || (sc)->sc_pp->ide_product == 0x5275 || (sc)->sc_pp->ide_product == 0x7275)) { | |||
6336 | st = pci_conf_read(sc->sc_pc, sc->sc_tag, PDC2xx_STATE0x50); | |||
6337 | WDCDEBUG_PRINT(("pdc202xx_setup_chip: controller state 0x%x\n", | |||
6338 | st), DEBUG_PROBE); | |||
6339 | } | |||
6340 | ||||
6341 | /* turn off RAID mode */ | |||
6342 | if (!PDC_IS_268(sc)((sc)->sc_pp->ide_product == 0x4d68 || (sc)->sc_pp-> ide_product == 0x6268 || (sc)->sc_pp->ide_product == 0x4d69 || (sc)->sc_pp->ide_product == 0x6269 || (sc)->sc_pp ->ide_product == 0x1275 || (sc)->sc_pp->ide_product == 0x5275 || (sc)->sc_pp->ide_product == 0x7275)) | |||
6343 | st &= ~PDC2xx_STATE_IDERAID0x0001; | |||
6344 | ||||
6345 | /* | |||
6346 | * can't rely on the PCI_CLASS_REG content if the chip was in raid | |||
6347 | * mode. We have to fake interface | |||
6348 | */ | |||
6349 | interface = PCIIDE_INTERFACE_SETTABLE(0)(0x02 << (2 * (0))) | PCIIDE_INTERFACE_SETTABLE(1)(0x02 << (2 * (1))); | |||
6350 | if (PDC_IS_268(sc)((sc)->sc_pp->ide_product == 0x4d68 || (sc)->sc_pp-> ide_product == 0x6268 || (sc)->sc_pp->ide_product == 0x4d69 || (sc)->sc_pp->ide_product == 0x6269 || (sc)->sc_pp ->ide_product == 0x1275 || (sc)->sc_pp->ide_product == 0x5275 || (sc)->sc_pp->ide_product == 0x7275) || (st & PDC2xx_STATE_NATIVE0x0080)) | |||
6351 | interface |= PCIIDE_INTERFACE_PCI(0)(0x01 << (2 * (0))) | PCIIDE_INTERFACE_PCI(1)(0x01 << (2 * (1))); | |||
6352 | ||||
6353 | printf(": DMA"); | |||
6354 | pciide_mapreg_dma(sc, pa); | |||
6355 | ||||
6356 | sc->sc_wdcdev.cap = WDC_CAPABILITY_DATA160x0001 | WDC_CAPABILITY_DATA320x0002 | | |||
6357 | WDC_CAPABILITY_MODE0x0004; | |||
6358 | if (sc->sc_pp->ide_product == PCI_PRODUCT_PROMISE_PDC202460x4d33 || | |||
6359 | PDC_IS_262(sc)((sc)->sc_pp->ide_product == 0x4d38 || (sc)->sc_pp-> ide_product == 0x0d30 || (sc)->sc_pp->ide_product == 0x4d30 )) | |||
6360 | sc->sc_wdcdev.cap |= WDC_CAPABILITY_NO_ATAPI_DMA0x1000; | |||
6361 | if (sc->sc_dma_ok) { | |||
6362 | sc->sc_wdcdev.cap |= WDC_CAPABILITY_DMA0x0008 | WDC_CAPABILITY_UDMA0x0010; | |||
6363 | sc->sc_wdcdev.cap |= WDC_CAPABILITY_IRQACK0x0400; | |||
6364 | sc->sc_wdcdev.irqack = pciide_irqack; | |||
6365 | } | |||
6366 | sc->sc_wdcdev.PIO_cap = 4; | |||
6367 | sc->sc_wdcdev.DMA_cap = 2; | |||
6368 | if (PDC_IS_269(sc)((sc)->sc_pp->ide_product == 0x4d69 || (sc)->sc_pp-> ide_product == 0x6269 || (sc)->sc_pp->ide_product == 0x1275 || (sc)->sc_pp->ide_product == 0x5275 || (sc)->sc_pp ->ide_product == 0x7275)) | |||
6369 | sc->sc_wdcdev.UDMA_cap = 6; | |||
6370 | else if (PDC_IS_265(sc)((sc)->sc_pp->ide_product == 0x0d30 || (sc)->sc_pp-> ide_product == 0x4d30 || (sc)->sc_pp->ide_product == 0x4d68 || (sc)->sc_pp->ide_product == 0x6268 || (sc)->sc_pp ->ide_product == 0x4d69 || (sc)->sc_pp->ide_product == 0x6269 || (sc)->sc_pp->ide_product == 0x1275 || (sc)-> sc_pp->ide_product == 0x5275 || (sc)->sc_pp->ide_product == 0x7275)) | |||
6371 | sc->sc_wdcdev.UDMA_cap = 5; | |||
6372 | else if (PDC_IS_262(sc)((sc)->sc_pp->ide_product == 0x4d38 || (sc)->sc_pp-> ide_product == 0x0d30 || (sc)->sc_pp->ide_product == 0x4d30 )) | |||
6373 | sc->sc_wdcdev.UDMA_cap = 4; | |||
6374 | else | |||
6375 | sc->sc_wdcdev.UDMA_cap = 2; | |||
6376 | sc->sc_wdcdev.set_modes = PDC_IS_268(sc)((sc)->sc_pp->ide_product == 0x4d68 || (sc)->sc_pp-> ide_product == 0x6268 || (sc)->sc_pp->ide_product == 0x4d69 || (sc)->sc_pp->ide_product == 0x6269 || (sc)->sc_pp ->ide_product == 0x1275 || (sc)->sc_pp->ide_product == 0x5275 || (sc)->sc_pp->ide_product == 0x7275) ? | |||
6377 | pdc20268_setup_channel : pdc202xx_setup_channel; | |||
6378 | sc->sc_wdcdev.channels = sc->wdc_chanarray; | |||
6379 | sc->sc_wdcdev.nchannels = PCIIDE_NUM_CHANNELS2; | |||
6380 | ||||
6381 | if (PDC_IS_262(sc)((sc)->sc_pp->ide_product == 0x4d38 || (sc)->sc_pp-> ide_product == 0x0d30 || (sc)->sc_pp->ide_product == 0x4d30 )) { | |||
6382 | sc->sc_wdcdev.dma_start = pdc20262_dma_start; | |||
6383 | sc->sc_wdcdev.dma_finish = pdc20262_dma_finish; | |||
6384 | } | |||
6385 | ||||
6386 | pciide_print_channels(sc->sc_wdcdev.nchannels, interface); | |||
6387 | if (!PDC_IS_268(sc)((sc)->sc_pp->ide_product == 0x4d68 || (sc)->sc_pp-> ide_product == 0x6268 || (sc)->sc_pp->ide_product == 0x4d69 || (sc)->sc_pp->ide_product == 0x6269 || (sc)->sc_pp ->ide_product == 0x1275 || (sc)->sc_pp->ide_product == 0x5275 || (sc)->sc_pp->ide_product == 0x7275)) { | |||
6388 | /* setup failsafe defaults */ | |||
6389 | mode = 0; | |||
6390 | mode = PDC2xx_TIM_SET_PA(mode, pdc2xx_pa[0])(((mode) & 0xfffffff0) | ((pdc2xx_pa[0]) & 0xf)); | |||
6391 | mode = PDC2xx_TIM_SET_PB(mode, pdc2xx_pb[0])(((mode) & 0xffffe0ff) | (((pdc2xx_pb[0]) & 0x1f) << 8)); | |||
6392 | mode = PDC2xx_TIM_SET_MB(mode, pdc2xx_dma_mb[0])(((mode) & 0xffff1fff) | (((pdc2xx_dma_mb[0]) & 0x7) << 13)); | |||
6393 | mode = PDC2xx_TIM_SET_MC(mode, pdc2xx_dma_mc[0])(((mode) & 0xfff0ffff) | (((pdc2xx_dma_mc[0]) & 0xf) << 16)); | |||
6394 | for (channel = 0; | |||
6395 | channel < sc->sc_wdcdev.nchannels; | |||
6396 | channel++) { | |||
6397 | WDCDEBUG_PRINT(("pdc202xx_setup_chip: channel %d " | |||
6398 | "drive 0 initial timings 0x%x, now 0x%x\n", | |||
6399 | channel, pci_conf_read(sc->sc_pc, sc->sc_tag, | |||
6400 | PDC2xx_TIM(channel, 0)), mode | PDC2xx_TIM_IORDYp), | |||
6401 | DEBUG_PROBE); | |||
6402 | pci_conf_write(sc->sc_pc, sc->sc_tag, | |||
6403 | PDC2xx_TIM(channel, 0)(0x60 + 4 * (0) + 8 * (channel)), mode | PDC2xx_TIM_IORDYp0x00400000); | |||
6404 | WDCDEBUG_PRINT(("pdc202xx_setup_chip: channel %d " | |||
6405 | "drive 1 initial timings 0x%x, now 0x%x\n", | |||
6406 | channel, pci_conf_read(sc->sc_pc, sc->sc_tag, | |||
6407 | PDC2xx_TIM(channel, 1)), mode), DEBUG_PROBE); | |||
6408 | pci_conf_write(sc->sc_pc, sc->sc_tag, | |||
6409 | PDC2xx_TIM(channel, 1)(0x60 + 4 * (1) + 8 * (channel)), mode); | |||
6410 | } | |||
6411 | ||||
6412 | mode = PDC2xx_SCR_DMA0x01000000; | |||
6413 | if (PDC_IS_262(sc)((sc)->sc_pp->ide_product == 0x4d38 || (sc)->sc_pp-> ide_product == 0x0d30 || (sc)->sc_pp->ide_product == 0x4d30 )) { | |||
6414 | mode = PDC2xx_SCR_SET_GEN(mode, PDC262_SCR_GEN_LAT)(((mode) & 0xffffff00) | ((0x20) & 0xff)); | |||
6415 | } else { | |||
6416 | /* the BIOS set it up this way */ | |||
6417 | mode = PDC2xx_SCR_SET_GEN(mode, 0x1)(((mode) & 0xffffff00) | ((0x1) & 0xff)); | |||
6418 | } | |||
6419 | mode = PDC2xx_SCR_SET_I2C(mode, 0x3)(((mode) & 0xfff0ffff) | (((0x3) & 0xf) << 16)); /* ditto */ | |||
6420 | mode = PDC2xx_SCR_SET_POLL(mode, 0x1)(((mode) & 0xff0fffff) | (((0x1) & 0xf) << 20)); /* ditto */ | |||
6421 | WDCDEBUG_PRINT(("pdc202xx_setup_chip: initial SCR 0x%x, " | |||
6422 | "now 0x%x\n", | |||
6423 | bus_space_read_4(sc->sc_dma_iot, sc->sc_dma_ioh, | |||
6424 | PDC2xx_SCR), | |||
6425 | mode), DEBUG_PROBE); | |||
6426 | bus_space_write_4(sc->sc_dma_iot, sc->sc_dma_ioh,((sc->sc_dma_iot)->write_4((sc->sc_dma_ioh), (0x1c), (mode))) | |||
6427 | PDC2xx_SCR, mode)((sc->sc_dma_iot)->write_4((sc->sc_dma_ioh), (0x1c), (mode))); | |||
6428 | ||||
6429 | /* controller initial state register is OK even without BIOS */ | |||
6430 | /* Set DMA mode to IDE DMA compatibility */ | |||
6431 | mode = | |||
6432 | bus_space_read_1(sc->sc_dma_iot, sc->sc_dma_ioh, PDC2xx_PM)((sc->sc_dma_iot)->read_1((sc->sc_dma_ioh), (0x1a))); | |||
6433 | WDCDEBUG_PRINT(("pdc202xx_setup_chip: primary mode 0x%x", mode), | |||
6434 | DEBUG_PROBE); | |||
6435 | bus_space_write_1(sc->sc_dma_iot, sc->sc_dma_ioh, PDC2xx_PM,((sc->sc_dma_iot)->write_1((sc->sc_dma_ioh), (0x1a), (mode | 0x1))) | |||
6436 | mode | 0x1)((sc->sc_dma_iot)->write_1((sc->sc_dma_ioh), (0x1a), (mode | 0x1))); | |||
6437 | mode = | |||
6438 | bus_space_read_1(sc->sc_dma_iot, sc->sc_dma_ioh, PDC2xx_SM)((sc->sc_dma_iot)->read_1((sc->sc_dma_ioh), (0x1b))); | |||
6439 | WDCDEBUG_PRINT((", secondary mode 0x%x\n", mode ), DEBUG_PROBE); | |||
6440 | bus_space_write_1(sc->sc_dma_iot, sc->sc_dma_ioh, PDC2xx_SM,((sc->sc_dma_iot)->write_1((sc->sc_dma_ioh), (0x1b), (mode | 0x1))) | |||
6441 | mode | 0x1)((sc->sc_dma_iot)->write_1((sc->sc_dma_ioh), (0x1b), (mode | 0x1))); | |||
6442 | } | |||
6443 | ||||
6444 | for (channel = 0; channel < sc->sc_wdcdev.nchannels; channel++) { | |||
6445 | cp = &sc->pciide_channels[channel]; | |||
6446 | if (pciide_chansetup(sc, channel, interface) == 0) | |||
6447 | continue; | |||
6448 | if (!PDC_IS_268(sc)((sc)->sc_pp->ide_product == 0x4d68 || (sc)->sc_pp-> ide_product == 0x6268 || (sc)->sc_pp->ide_product == 0x4d69 || (sc)->sc_pp->ide_product == 0x6269 || (sc)->sc_pp ->ide_product == 0x1275 || (sc)->sc_pp->ide_product == 0x5275 || (sc)->sc_pp->ide_product == 0x7275) && (st & (PDC_IS_262(sc)((sc)->sc_pp->ide_product == 0x4d38 || (sc)->sc_pp-> ide_product == 0x0d30 || (sc)->sc_pp->ide_product == 0x4d30 ) ? | |||
6449 | PDC262_STATE_EN(channel)(0x1000 << (channel)):PDC246_STATE_EN(channel)(0x0002 << (channel)))) == 0) { | |||
6450 | printf("%s: %s ignored (disabled)\n", | |||
6451 | sc->sc_wdcdev.sc_dev.dv_xname, cp->name); | |||
6452 | cp->hw_ok = 0; | |||
6453 | continue; | |||
6454 | } | |||
6455 | pciide_map_compat_intr(pa, cp, channel, interface); | |||
6456 | if (cp->hw_ok == 0) | |||
6457 | continue; | |||
6458 | if (PDC_IS_265(sc)((sc)->sc_pp->ide_product == 0x0d30 || (sc)->sc_pp-> ide_product == 0x4d30 || (sc)->sc_pp->ide_product == 0x4d68 || (sc)->sc_pp->ide_product == 0x6268 || (sc)->sc_pp ->ide_product == 0x4d69 || (sc)->sc_pp->ide_product == 0x6269 || (sc)->sc_pp->ide_product == 0x1275 || (sc)-> sc_pp->ide_product == 0x5275 || (sc)->sc_pp->ide_product == 0x7275)) | |||
6459 | pciide_mapchan(pa, cp, interface, &cmdsize, &ctlsize, | |||
6460 | pdc20265_pci_intr); | |||
6461 | else | |||
6462 | pciide_mapchan(pa, cp, interface, &cmdsize, &ctlsize, | |||
6463 | pdc202xx_pci_intr); | |||
6464 | if (cp->hw_ok == 0) { | |||
6465 | pciide_unmap_compat_intr(pa, cp, channel, interface); | |||
6466 | continue; | |||
6467 | } | |||
6468 | if (!PDC_IS_268(sc)((sc)->sc_pp->ide_product == 0x4d68 || (sc)->sc_pp-> ide_product == 0x6268 || (sc)->sc_pp->ide_product == 0x4d69 || (sc)->sc_pp->ide_product == 0x6269 || (sc)->sc_pp ->ide_product == 0x1275 || (sc)->sc_pp->ide_product == 0x5275 || (sc)->sc_pp->ide_product == 0x7275) && pciide_chan_candisable(cp)) { | |||
6469 | st &= ~(PDC_IS_262(sc)((sc)->sc_pp->ide_product == 0x4d38 || (sc)->sc_pp-> ide_product == 0x0d30 || (sc)->sc_pp->ide_product == 0x4d30 ) ? | |||
6470 | PDC262_STATE_EN(channel)(0x1000 << (channel)):PDC246_STATE_EN(channel)(0x0002 << (channel))); | |||
6471 | pciide_unmap_compat_intr(pa, cp, channel, interface); | |||
6472 | } | |||
6473 | if (PDC_IS_268(sc)((sc)->sc_pp->ide_product == 0x4d68 || (sc)->sc_pp-> ide_product == 0x6268 || (sc)->sc_pp->ide_product == 0x4d69 || (sc)->sc_pp->ide_product == 0x6269 || (sc)->sc_pp ->ide_product == 0x1275 || (sc)->sc_pp->ide_product == 0x5275 || (sc)->sc_pp->ide_product == 0x7275)) | |||
6474 | pdc20268_setup_channel(&cp->wdc_channel); | |||
6475 | else | |||
6476 | pdc202xx_setup_channel(&cp->wdc_channel); | |||
6477 | } | |||
6478 | if (!PDC_IS_268(sc)((sc)->sc_pp->ide_product == 0x4d68 || (sc)->sc_pp-> ide_product == 0x6268 || (sc)->sc_pp->ide_product == 0x4d69 || (sc)->sc_pp->ide_product == 0x6269 || (sc)->sc_pp ->ide_product == 0x1275 || (sc)->sc_pp->ide_product == 0x5275 || (sc)->sc_pp->ide_product == 0x7275)) { | |||
6479 | WDCDEBUG_PRINT(("pdc202xx_setup_chip: new controller state " | |||
6480 | "0x%x\n", st), DEBUG_PROBE); | |||
6481 | pci_conf_write(sc->sc_pc, sc->sc_tag, PDC2xx_STATE0x50, st); | |||
6482 | } | |||
6483 | return; | |||
6484 | } | |||
6485 | ||||
6486 | void | |||
6487 | pdc202xx_setup_channel(struct channel_softc *chp) | |||
6488 | { | |||
6489 | struct ata_drive_datas *drvp; | |||
6490 | int drive; | |||
6491 | pcireg_t mode, st; | |||
6492 | u_int32_t idedma_ctl, scr, atapi; | |||
6493 | struct pciide_channel *cp = (struct pciide_channel *)chp; | |||
6494 | struct pciide_softc *sc = (struct pciide_softc *)cp->wdc_channel.wdc; | |||
6495 | int channel = chp->channel; | |||
6496 | ||||
6497 | /* setup DMA if needed */ | |||
6498 | pciide_channel_dma_setup(cp); | |||
6499 | ||||
6500 | idedma_ctl = 0; | |||
6501 | WDCDEBUG_PRINT(("pdc202xx_setup_channel %s: scr 0x%x\n", | |||
6502 | sc->sc_wdcdev.sc_dev.dv_xname, | |||
6503 | bus_space_read_1(sc->sc_dma_iot, sc->sc_dma_ioh, PDC262_U66)), | |||
6504 | DEBUG_PROBE); | |||
6505 | ||||
6506 | /* Per channel settings */ | |||
6507 | if (PDC_IS_262(sc)((sc)->sc_pp->ide_product == 0x4d38 || (sc)->sc_pp-> ide_product == 0x0d30 || (sc)->sc_pp->ide_product == 0x4d30 )) { | |||
6508 | scr = bus_space_read_1(sc->sc_dma_iot, sc->sc_dma_ioh,((sc->sc_dma_iot)->read_1((sc->sc_dma_ioh), (0x11))) | |||
6509 | PDC262_U66)((sc->sc_dma_iot)->read_1((sc->sc_dma_ioh), (0x11))); | |||
6510 | st = pci_conf_read(sc->sc_pc, sc->sc_tag, PDC2xx_STATE0x50); | |||
6511 | /* Check cable */ | |||
6512 | if ((st & PDC262_STATE_80P(channel)(0x0400 << (channel))) != 0 && | |||
6513 | ((chp->ch_drive[0].drive_flags & DRIVE_UDMA0x0020 && | |||
6514 | chp->ch_drive[0].UDMA_mode > 2) || | |||
6515 | (chp->ch_drive[1].drive_flags & DRIVE_UDMA0x0020 && | |||
6516 | chp->ch_drive[1].UDMA_mode > 2))) { | |||
6517 | WDCDEBUG_PRINT(("%s:%d: 80-wire cable not detected\n", | |||
6518 | sc->sc_wdcdev.sc_dev.dv_xname, channel), | |||
6519 | DEBUG_PROBE); | |||
6520 | if (chp->ch_drive[0].UDMA_mode > 2) | |||
6521 | chp->ch_drive[0].UDMA_mode = 2; | |||
6522 | if (chp->ch_drive[1].UDMA_mode > 2) | |||
6523 | chp->ch_drive[1].UDMA_mode = 2; | |||
6524 | } | |||
6525 | /* Trim UDMA mode */ | |||
6526 | if ((chp->ch_drive[0].drive_flags & DRIVE_UDMA0x0020 && | |||
6527 | chp->ch_drive[0].UDMA_mode <= 2) || | |||
6528 | (chp->ch_drive[1].drive_flags & DRIVE_UDMA0x0020 && | |||
6529 | chp->ch_drive[1].UDMA_mode <= 2)) { | |||
6530 | if (chp->ch_drive[0].UDMA_mode > 2) | |||
6531 | chp->ch_drive[0].UDMA_mode = 2; | |||
6532 | if (chp->ch_drive[1].UDMA_mode > 2) | |||
6533 | chp->ch_drive[1].UDMA_mode = 2; | |||
6534 | } | |||
6535 | /* Set U66 if needed */ | |||
6536 | if ((chp->ch_drive[0].drive_flags & DRIVE_UDMA0x0020 && | |||
6537 | chp->ch_drive[0].UDMA_mode > 2) || | |||
6538 | (chp->ch_drive[1].drive_flags & DRIVE_UDMA0x0020 && | |||
6539 | chp->ch_drive[1].UDMA_mode > 2)) | |||
6540 | scr |= PDC262_U66_EN(channel)(0x2 << ((channel) *2)); | |||
6541 | else | |||
6542 | scr &= ~PDC262_U66_EN(channel)(0x2 << ((channel) *2)); | |||
6543 | bus_space_write_1(sc->sc_dma_iot, sc->sc_dma_ioh,((sc->sc_dma_iot)->write_1((sc->sc_dma_ioh), (0x11), (scr))) | |||
6544 | PDC262_U66, scr)((sc->sc_dma_iot)->write_1((sc->sc_dma_ioh), (0x11), (scr))); | |||
6545 | WDCDEBUG_PRINT(("pdc202xx_setup_channel %s:%d: ATAPI 0x%x\n", | |||
6546 | sc->sc_wdcdev.sc_dev.dv_xname, channel, | |||
6547 | bus_space_read_4(sc->sc_dma_iot, sc->sc_dma_ioh, | |||
6548 | PDC262_ATAPI(channel))), DEBUG_PROBE); | |||
6549 | if (chp->ch_drive[0].drive_flags & DRIVE_ATAPI0x0002 || | |||
6550 | chp->ch_drive[1].drive_flags & DRIVE_ATAPI0x0002) { | |||
6551 | if (((chp->ch_drive[0].drive_flags & DRIVE_UDMA0x0020) && | |||
6552 | !(chp->ch_drive[1].drive_flags & DRIVE_UDMA0x0020) && | |||
6553 | (chp->ch_drive[1].drive_flags & DRIVE_DMA0x0010)) || | |||
6554 | ((chp->ch_drive[1].drive_flags & DRIVE_UDMA0x0020) && | |||
6555 | !(chp->ch_drive[0].drive_flags & DRIVE_UDMA0x0020) && | |||
6556 | (chp->ch_drive[0].drive_flags & DRIVE_DMA0x0010))) | |||
6557 | atapi = 0; | |||
6558 | else | |||
6559 | atapi = PDC262_ATAPI_UDMA0x00004000; | |||
6560 | bus_space_write_4(sc->sc_dma_iot, sc->sc_dma_ioh,((sc->sc_dma_iot)->write_4((sc->sc_dma_ioh), ((0x20 + (4 * (channel)))), (atapi))) | |||
6561 | PDC262_ATAPI(channel), atapi)((sc->sc_dma_iot)->write_4((sc->sc_dma_ioh), ((0x20 + (4 * (channel)))), (atapi))); | |||
6562 | } | |||
6563 | } | |||
6564 | for (drive = 0; drive < 2; drive++) { | |||
6565 | drvp = &chp->ch_drive[drive]; | |||
6566 | /* If no drive, skip */ | |||
6567 | if ((drvp->drive_flags & DRIVE(0x0001|0x0002|0x0004)) == 0) | |||
6568 | continue; | |||
6569 | mode = 0; | |||
6570 | if (drvp->drive_flags & DRIVE_UDMA0x0020) { | |||
6571 | /* use Ultra/DMA */ | |||
6572 | drvp->drive_flags &= ~DRIVE_DMA0x0010; | |||
6573 | mode = PDC2xx_TIM_SET_MB(mode,(((mode) & 0xffff1fff) | (((pdc2xx_udma_mb[drvp->UDMA_mode ]) & 0x7) << 13)) | |||
6574 | pdc2xx_udma_mb[drvp->UDMA_mode])(((mode) & 0xffff1fff) | (((pdc2xx_udma_mb[drvp->UDMA_mode ]) & 0x7) << 13)); | |||
6575 | mode = PDC2xx_TIM_SET_MC(mode,(((mode) & 0xfff0ffff) | (((pdc2xx_udma_mc[drvp->UDMA_mode ]) & 0xf) << 16)) | |||
6576 | pdc2xx_udma_mc[drvp->UDMA_mode])(((mode) & 0xfff0ffff) | (((pdc2xx_udma_mc[drvp->UDMA_mode ]) & 0xf) << 16)); | |||
6577 | idedma_ctl |= IDEDMA_CTL_DRV_DMA(drive)(0x20 << (drive)); | |||
6578 | } else if (drvp->drive_flags & DRIVE_DMA0x0010) { | |||
6579 | mode = PDC2xx_TIM_SET_MB(mode,(((mode) & 0xffff1fff) | (((pdc2xx_dma_mb[drvp->DMA_mode ]) & 0x7) << 13)) | |||
6580 | pdc2xx_dma_mb[drvp->DMA_mode])(((mode) & 0xffff1fff) | (((pdc2xx_dma_mb[drvp->DMA_mode ]) & 0x7) << 13)); | |||
6581 | mode = PDC2xx_TIM_SET_MC(mode,(((mode) & 0xfff0ffff) | (((pdc2xx_dma_mc[drvp->DMA_mode ]) & 0xf) << 16)) | |||
6582 | pdc2xx_dma_mc[drvp->DMA_mode])(((mode) & 0xfff0ffff) | (((pdc2xx_dma_mc[drvp->DMA_mode ]) & 0xf) << 16)); | |||
6583 | idedma_ctl |= IDEDMA_CTL_DRV_DMA(drive)(0x20 << (drive)); | |||
6584 | } else { | |||
6585 | mode = PDC2xx_TIM_SET_MB(mode,(((mode) & 0xffff1fff) | (((pdc2xx_dma_mb[0]) & 0x7) << 13)) | |||
6586 | pdc2xx_dma_mb[0])(((mode) & 0xffff1fff) | (((pdc2xx_dma_mb[0]) & 0x7) << 13)); | |||
6587 | mode = PDC2xx_TIM_SET_MC(mode,(((mode) & 0xfff0ffff) | (((pdc2xx_dma_mc[0]) & 0xf) << 16)) | |||
6588 | pdc2xx_dma_mc[0])(((mode) & 0xfff0ffff) | (((pdc2xx_dma_mc[0]) & 0xf) << 16)); | |||
6589 | } | |||
6590 | mode = PDC2xx_TIM_SET_PA(mode, pdc2xx_pa[drvp->PIO_mode])(((mode) & 0xfffffff0) | ((pdc2xx_pa[drvp->PIO_mode]) & 0xf)); | |||
6591 | mode = PDC2xx_TIM_SET_PB(mode, pdc2xx_pb[drvp->PIO_mode])(((mode) & 0xffffe0ff) | (((pdc2xx_pb[drvp->PIO_mode]) & 0x1f) << 8)); | |||
6592 | if (drvp->drive_flags & DRIVE_ATA0x0001) | |||
6593 | mode |= PDC2xx_TIM_PRE0x00000010; | |||
6594 | mode |= PDC2xx_TIM_SYNC0x00000080 | PDC2xx_TIM_ERRDY0x00000040; | |||
6595 | if (drvp->PIO_mode >= 3) { | |||
6596 | mode |= PDC2xx_TIM_IORDY0x00000020; | |||
6597 | if (drive == 0) | |||
6598 | mode |= PDC2xx_TIM_IORDYp0x00400000; | |||
6599 | } | |||
6600 | WDCDEBUG_PRINT(("pdc202xx_setup_channel: %s:%d:%d " | |||
6601 | "timings 0x%x\n", | |||
6602 | sc->sc_wdcdev.sc_dev.dv_xname, | |||
6603 | chp->channel, drive, mode), DEBUG_PROBE); | |||
6604 | pci_conf_write(sc->sc_pc, sc->sc_tag, | |||
6605 | PDC2xx_TIM(chp->channel, drive)(0x60 + 4 * (drive) + 8 * (chp->channel)), mode); | |||
6606 | } | |||
6607 | if (idedma_ctl != 0) { | |||
6608 | /* Add software bits in status register */ | |||
6609 | bus_space_write_1(sc->sc_dma_iot, sc->sc_dma_ioh,((sc->sc_dma_iot)->write_1((sc->sc_dma_ioh), ((0x02 + 0x08 * (channel))), (idedma_ctl))) | |||
6610 | IDEDMA_CTL(channel), idedma_ctl)((sc->sc_dma_iot)->write_1((sc->sc_dma_ioh), ((0x02 + 0x08 * (channel))), (idedma_ctl))); | |||
6611 | } | |||
6612 | pciide_print_modes(cp); | |||
6613 | } | |||
6614 | ||||
6615 | void | |||
6616 | pdc20268_setup_channel(struct channel_softc *chp) | |||
6617 | { | |||
6618 | struct ata_drive_datas *drvp; | |||
6619 | int drive, cable; | |||
6620 | u_int32_t idedma_ctl; | |||
6621 | struct pciide_channel *cp = (struct pciide_channel *)chp; | |||
6622 | struct pciide_softc *sc = (struct pciide_softc *)cp->wdc_channel.wdc; | |||
6623 | int channel = chp->channel; | |||
6624 | ||||
6625 | /* check 80 pins cable */ | |||
6626 | cable = pdc268_config_read(chp, 0x0b) & PDC268_CABLE0x04; | |||
6627 | ||||
6628 | /* setup DMA if needed */ | |||
6629 | pciide_channel_dma_setup(cp); | |||
6630 | ||||
6631 | idedma_ctl = 0; | |||
6632 | ||||
6633 | for (drive = 0; drive < 2; drive++) { | |||
6634 | drvp = &chp->ch_drive[drive]; | |||
6635 | /* If no drive, skip */ | |||
6636 | if ((drvp->drive_flags & DRIVE(0x0001|0x0002|0x0004)) == 0) | |||
6637 | continue; | |||
6638 | if (drvp->drive_flags & DRIVE_UDMA0x0020) { | |||
6639 | /* use Ultra/DMA */ | |||
6640 | drvp->drive_flags &= ~DRIVE_DMA0x0010; | |||
6641 | idedma_ctl |= IDEDMA_CTL_DRV_DMA(drive)(0x20 << (drive)); | |||
6642 | if (cable && drvp->UDMA_mode > 2) { | |||
6643 | WDCDEBUG_PRINT(("%s(%s:%d:%d): 80-wire " | |||
6644 | "cable not detected\n", drvp->drive_name, | |||
6645 | sc->sc_wdcdev.sc_dev.dv_xname, | |||
6646 | channel, drive), DEBUG_PROBE); | |||
6647 | drvp->UDMA_mode = 2; | |||
6648 | } | |||
6649 | } else if (drvp->drive_flags & DRIVE_DMA0x0010) { | |||
6650 | idedma_ctl |= IDEDMA_CTL_DRV_DMA(drive)(0x20 << (drive)); | |||
6651 | } | |||
6652 | } | |||
6653 | /* nothing to do to setup modes, the controller snoop SET_FEATURE cmd */ | |||
6654 | if (idedma_ctl != 0) { | |||
6655 | /* Add software bits in status register */ | |||
6656 | bus_space_write_1(sc->sc_dma_iot, sc->sc_dma_ioh,((sc->sc_dma_iot)->write_1((sc->sc_dma_ioh), ((0x02 + 0x08 * (channel))), (idedma_ctl))) | |||
6657 | IDEDMA_CTL(channel), idedma_ctl)((sc->sc_dma_iot)->write_1((sc->sc_dma_ioh), ((0x02 + 0x08 * (channel))), (idedma_ctl))); | |||
6658 | } | |||
6659 | pciide_print_modes(cp); | |||
6660 | } | |||
6661 | ||||
6662 | int | |||
6663 | pdc202xx_pci_intr(void *arg) | |||
6664 | { | |||
6665 | struct pciide_softc *sc = arg; | |||
6666 | struct pciide_channel *cp; | |||
6667 | struct channel_softc *wdc_cp; | |||
6668 | int i, rv, crv; | |||
6669 | u_int32_t scr; | |||
6670 | ||||
6671 | rv = 0; | |||
6672 | scr = bus_space_read_4(sc->sc_dma_iot, sc->sc_dma_ioh, PDC2xx_SCR)((sc->sc_dma_iot)->read_4((sc->sc_dma_ioh), (0x1c))); | |||
6673 | for (i = 0; i < sc->sc_wdcdev.nchannels; i++) { | |||
6674 | cp = &sc->pciide_channels[i]; | |||
6675 | wdc_cp = &cp->wdc_channel; | |||
6676 | /* If a compat channel skip. */ | |||
6677 | if (cp->compat) | |||
6678 | continue; | |||
6679 | if (scr & PDC2xx_SCR_INT(i)(0x00000400 << (4 * i))) { | |||
6680 | crv = wdcintr(wdc_cp); | |||
6681 | if (crv == 0) | |||
6682 | printf("%s:%d: bogus intr (reg 0x%x)\n", | |||
6683 | sc->sc_wdcdev.sc_dev.dv_xname, i, scr); | |||
6684 | else | |||
6685 | rv = 1; | |||
6686 | } | |||
6687 | } | |||
6688 | return (rv); | |||
6689 | } | |||
6690 | ||||
6691 | int | |||
6692 | pdc20265_pci_intr(void *arg) | |||
6693 | { | |||
6694 | struct pciide_softc *sc = arg; | |||
6695 | struct pciide_channel *cp; | |||
6696 | struct channel_softc *wdc_cp; | |||
6697 | int i, rv, crv; | |||
6698 | u_int32_t dmastat; | |||
6699 | ||||
6700 | rv = 0; | |||
6701 | for (i = 0; i < sc->sc_wdcdev.nchannels; i++) { | |||
6702 | cp = &sc->pciide_channels[i]; | |||
6703 | wdc_cp = &cp->wdc_channel; | |||
6704 | /* If a compat channel skip. */ | |||
6705 | if (cp->compat) | |||
6706 | continue; | |||
6707 | ||||
6708 | /* | |||
6709 | * In case of shared IRQ check that the interrupt | |||
6710 | * was actually generated by this channel. | |||
6711 | * Only check the channel that is enabled. | |||
6712 | */ | |||
6713 | if (cp->hw_ok && PDC_IS_268(sc)((sc)->sc_pp->ide_product == 0x4d68 || (sc)->sc_pp-> ide_product == 0x6268 || (sc)->sc_pp->ide_product == 0x4d69 || (sc)->sc_pp->ide_product == 0x6269 || (sc)->sc_pp ->ide_product == 0x1275 || (sc)->sc_pp->ide_product == 0x5275 || (sc)->sc_pp->ide_product == 0x7275)) { | |||
6714 | if ((pdc268_config_read(wdc_cp, | |||
6715 | 0x0b) & PDC268_INTR0x20) == 0) | |||
6716 | continue; | |||
6717 | } | |||
6718 | ||||
6719 | /* | |||
6720 | * The Ultra/100 seems to assert PDC2xx_SCR_INT * spuriously, | |||
6721 | * however it asserts INT in IDEDMA_CTL even for non-DMA ops. | |||
6722 | * So use it instead (requires 2 reg reads instead of 1, | |||
6723 | * but we can't do it another way). | |||
6724 | */ | |||
6725 | dmastat = bus_space_read_1(sc->sc_dma_iot,((sc->sc_dma_iot)->read_1((sc->sc_dma_ioh), ((0x02 + 0x08 * (i))))) | |||
6726 | sc->sc_dma_ioh, IDEDMA_CTL(i))((sc->sc_dma_iot)->read_1((sc->sc_dma_ioh), ((0x02 + 0x08 * (i))))); | |||
6727 | if ((dmastat & IDEDMA_CTL_INTR0x04) == 0) | |||
6728 | continue; | |||
6729 | ||||
6730 | crv = wdcintr(wdc_cp); | |||
6731 | if (crv == 0) | |||
6732 | printf("%s:%d: bogus intr\n", | |||
6733 | sc->sc_wdcdev.sc_dev.dv_xname, i); | |||
6734 | else | |||
6735 | rv = 1; | |||
6736 | } | |||
6737 | return (rv); | |||
6738 | } | |||
6739 | ||||
6740 | void | |||
6741 | pdc20262_dma_start(void *v, int channel, int drive) | |||
6742 | { | |||
6743 | struct pciide_softc *sc = v; | |||
6744 | struct pciide_dma_maps *dma_maps = | |||
6745 | &sc->pciide_channels[channel].dma_maps[drive]; | |||
6746 | u_int8_t clock; | |||
6747 | u_int32_t count; | |||
6748 | ||||
6749 | if (dma_maps->dma_flags & WDC_DMA_LBA480x04) { | |||
6750 | clock = bus_space_read_1(sc->sc_dma_iot, sc->sc_dma_ioh,((sc->sc_dma_iot)->read_1((sc->sc_dma_ioh), (0x11))) | |||
6751 | PDC262_U66)((sc->sc_dma_iot)->read_1((sc->sc_dma_ioh), (0x11))); | |||
6752 | bus_space_write_1(sc->sc_dma_iot, sc->sc_dma_ioh,((sc->sc_dma_iot)->write_1((sc->sc_dma_ioh), (0x11), (clock | (0x2 << ((channel) *2))))) | |||
6753 | PDC262_U66, clock | PDC262_U66_EN(channel))((sc->sc_dma_iot)->write_1((sc->sc_dma_ioh), (0x11), (clock | (0x2 << ((channel) *2))))); | |||
6754 | count = dma_maps->dmamap_xfer->dm_mapsize >> 1; | |||
6755 | count |= dma_maps->dma_flags & WDC_DMA_READ0x01 ? | |||
6756 | PDC262_ATAPI_LBA48_READ0x05000000 : PDC262_ATAPI_LBA48_WRITE0x06000000; | |||
6757 | bus_space_write_4(sc->sc_dma_iot, sc->sc_dma_ioh,((sc->sc_dma_iot)->write_4((sc->sc_dma_ioh), ((0x20 + (4 * (channel)))), (count))) | |||
6758 | PDC262_ATAPI(channel), count)((sc->sc_dma_iot)->write_4((sc->sc_dma_ioh), ((0x20 + (4 * (channel)))), (count))); | |||
6759 | } | |||
6760 | ||||
6761 | pciide_dma_start(v, channel, drive); | |||
6762 | } | |||
6763 | ||||
6764 | int | |||
6765 | pdc20262_dma_finish(void *v, int channel, int drive, int force) | |||
6766 | { | |||
6767 | struct pciide_softc *sc = v; | |||
6768 | struct pciide_dma_maps *dma_maps = | |||
6769 | &sc->pciide_channels[channel].dma_maps[drive]; | |||
6770 | u_int8_t clock; | |||
6771 | ||||
6772 | if (dma_maps->dma_flags & WDC_DMA_LBA480x04) { | |||
6773 | clock = bus_space_read_1(sc->sc_dma_iot, sc->sc_dma_ioh,((sc->sc_dma_iot)->read_1((sc->sc_dma_ioh), (0x11))) | |||
6774 | PDC262_U66)((sc->sc_dma_iot)->read_1((sc->sc_dma_ioh), (0x11))); | |||
6775 | bus_space_write_1(sc->sc_dma_iot, sc->sc_dma_ioh,((sc->sc_dma_iot)->write_1((sc->sc_dma_ioh), (0x11), (clock & ~(0x2 << ((channel) *2))))) | |||
6776 | PDC262_U66, clock & ~PDC262_U66_EN(channel))((sc->sc_dma_iot)->write_1((sc->sc_dma_ioh), (0x11), (clock & ~(0x2 << ((channel) *2))))); | |||
6777 | bus_space_write_4(sc->sc_dma_iot, sc->sc_dma_ioh,((sc->sc_dma_iot)->write_4((sc->sc_dma_ioh), ((0x20 + (4 * (channel)))), (0))) | |||
6778 | PDC262_ATAPI(channel), 0)((sc->sc_dma_iot)->write_4((sc->sc_dma_ioh), ((0x20 + (4 * (channel)))), (0))); | |||
6779 | } | |||
6780 | ||||
6781 | return (pciide_dma_finish(v, channel, drive, force)); | |||
6782 | } | |||
6783 | ||||
6784 | void | |||
6785 | pdcsata_chip_map(struct pciide_softc *sc, struct pci_attach_args *pa) | |||
6786 | { | |||
6787 | struct pciide_channel *cp; | |||
6788 | struct channel_softc *wdc_cp; | |||
6789 | struct pciide_pdcsata *ps; | |||
6790 | int channel, i; | |||
6791 | bus_size_t dmasize; | |||
6792 | pci_intr_handle_t intrhandle; | |||
6793 | const char *intrstr; | |||
6794 | ||||
6795 | /* Allocate memory for private data */ | |||
6796 | sc->sc_cookielen = sizeof(*ps); | |||
6797 | sc->sc_cookie = malloc(sc->sc_cookielen, M_DEVBUF2, M_NOWAIT0x0002 | M_ZERO0x0008); | |||
6798 | ps = sc->sc_cookie; | |||
6799 | ||||
6800 | /* | |||
6801 | * Promise SATA controllers have 3 or 4 channels, | |||
6802 | * the usual IDE registers are mapped in I/O space, with offsets. | |||
6803 | */ | |||
6804 | if (pci_intr_map(pa, &intrhandle) != 0) { | |||
6805 | printf(": couldn't map interrupt\n"); | |||
6806 | return; | |||
6807 | } | |||
6808 | intrstr = pci_intr_string(pa->pa_pc, intrhandle); | |||
6809 | ||||
6810 | switch (sc->sc_pp->ide_product) { | |||
6811 | case PCI_PRODUCT_PROMISE_PDC203180x3318: | |||
6812 | case PCI_PRODUCT_PROMISE_PDC203190x3319: | |||
6813 | case PCI_PRODUCT_PROMISE_PDC203710x3371: | |||
6814 | case PCI_PRODUCT_PROMISE_PDC203750x3375: | |||
6815 | case PCI_PRODUCT_PROMISE_PDC203760x3376: | |||
6816 | case PCI_PRODUCT_PROMISE_PDC203770x3377: | |||
6817 | case PCI_PRODUCT_PROMISE_PDC203780x3373: | |||
6818 | case PCI_PRODUCT_PROMISE_PDC203790x3372: | |||
6819 | default: | |||
6820 | sc->sc_pci_ih = pci_intr_establish(pa->pa_pc, | |||
6821 | intrhandle, IPL_BIO0x3, pdc203xx_pci_intr, sc, | |||
6822 | sc->sc_wdcdev.sc_dev.dv_xname); | |||
6823 | break; | |||
6824 | ||||
6825 | case PCI_PRODUCT_PROMISE_PDC405180x3d18: | |||
6826 | case PCI_PRODUCT_PROMISE_PDC405190x3519: | |||
6827 | case PCI_PRODUCT_PROMISE_PDC407180x3d17: | |||
6828 | case PCI_PRODUCT_PROMISE_PDC407190x3515: | |||
6829 | case PCI_PRODUCT_PROMISE_PDC407790x3577: | |||
6830 | case PCI_PRODUCT_PROMISE_PDC205710x3571: | |||
6831 | case PCI_PRODUCT_PROMISE_PDC205750x3d75: | |||
6832 | case PCI_PRODUCT_PROMISE_PDC205790x3574: | |||
6833 | case PCI_PRODUCT_PROMISE_PDC207710x3570: | |||
6834 | case PCI_PRODUCT_PROMISE_PDC207750x3d73: | |||
6835 | sc->sc_pci_ih = pci_intr_establish(pa->pa_pc, | |||
6836 | intrhandle, IPL_BIO0x3, pdc205xx_pci_intr, sc, | |||
6837 | sc->sc_wdcdev.sc_dev.dv_xname); | |||
6838 | break; | |||
6839 | } | |||
6840 | ||||
6841 | if (sc->sc_pci_ih == NULL((void *)0)) { | |||
6842 | printf(": couldn't establish native-PCI interrupt"); | |||
6843 | if (intrstr != NULL((void *)0)) | |||
6844 | printf(" at %s", intrstr); | |||
6845 | printf("\n"); | |||
6846 | return; | |||
6847 | } | |||
6848 | ||||
6849 | sc->sc_dma_ok = (pci_mapreg_map(pa, PCIIDE_REG_BUS_MASTER_DMA0x20, | |||
6850 | PCI_MAPREG_MEM_TYPE_32BIT0x00000000, 0, &sc->sc_dma_iot, | |||
6851 | &sc->sc_dma_ioh, NULL((void *)0), &dmasize, 0) == 0); | |||
6852 | if (!sc->sc_dma_ok) { | |||
6853 | printf(": couldn't map bus-master DMA registers\n"); | |||
6854 | pci_intr_disestablish(pa->pa_pc, sc->sc_pci_ih); | |||
6855 | return; | |||
6856 | } | |||
6857 | ||||
6858 | sc->sc_dmat = pa->pa_dmat; | |||
6859 | ||||
6860 | if (pci_mapreg_map(pa, PDC203xx_BAR_IDEREGS0x1c, | |||
6861 | PCI_MAPREG_MEM_TYPE_32BIT0x00000000, 0, &ps->ba5_st, | |||
6862 | &ps->ba5_sh, NULL((void *)0), NULL((void *)0), 0) != 0) { | |||
6863 | printf(": couldn't map IDE registers\n"); | |||
6864 | bus_space_unmap(sc->sc_dma_iot, sc->sc_dma_ioh, dmasize); | |||
6865 | pci_intr_disestablish(pa->pa_pc, sc->sc_pci_ih); | |||
6866 | return; | |||
6867 | } | |||
6868 | ||||
6869 | printf(": DMA\n"); | |||
6870 | ||||
6871 | sc->sc_wdcdev.cap = WDC_CAPABILITY_DATA160x0001; | |||
6872 | sc->sc_wdcdev.cap |= WDC_CAPABILITY_DMA0x0008 | WDC_CAPABILITY_UDMA0x0010; | |||
6873 | sc->sc_wdcdev.cap |= WDC_CAPABILITY_IRQACK0x0400; | |||
6874 | sc->sc_wdcdev.irqack = pdc203xx_irqack; | |||
6875 | sc->sc_wdcdev.PIO_cap = 4; | |||
6876 | sc->sc_wdcdev.DMA_cap = 2; | |||
6877 | sc->sc_wdcdev.UDMA_cap = 6; | |||
6878 | sc->sc_wdcdev.set_modes = pdc203xx_setup_channel; | |||
6879 | sc->sc_wdcdev.channels = sc->wdc_chanarray; | |||
6880 | ||||
6881 | switch (sc->sc_pp->ide_product) { | |||
6882 | case PCI_PRODUCT_PROMISE_PDC203180x3318: | |||
6883 | case PCI_PRODUCT_PROMISE_PDC203190x3319: | |||
6884 | case PCI_PRODUCT_PROMISE_PDC203710x3371: | |||
6885 | case PCI_PRODUCT_PROMISE_PDC203750x3375: | |||
6886 | case PCI_PRODUCT_PROMISE_PDC203760x3376: | |||
6887 | case PCI_PRODUCT_PROMISE_PDC203770x3377: | |||
6888 | case PCI_PRODUCT_PROMISE_PDC203780x3373: | |||
6889 | case PCI_PRODUCT_PROMISE_PDC203790x3372: | |||
6890 | default: | |||
6891 | bus_space_write_4(ps->ba5_st, ps->ba5_sh, 0x06c, 0x00ff0033)((ps->ba5_st)->write_4((ps->ba5_sh), (0x06c), (0x00ff0033 ))); | |||
6892 | sc->sc_wdcdev.nchannels = | |||
6893 | (bus_space_read_4(ps->ba5_st, ps->ba5_sh, 0x48)((ps->ba5_st)->read_4((ps->ba5_sh), (0x48))) & 0x02) ? | |||
6894 | PDC203xx_NCHANNELS4 : 3; | |||
6895 | break; | |||
6896 | ||||
6897 | case PCI_PRODUCT_PROMISE_PDC405180x3d18: | |||
6898 | case PCI_PRODUCT_PROMISE_PDC405190x3519: | |||
6899 | case PCI_PRODUCT_PROMISE_PDC407180x3d17: | |||
6900 | case PCI_PRODUCT_PROMISE_PDC407190x3515: | |||
6901 | case PCI_PRODUCT_PROMISE_PDC407790x3577: | |||
6902 | case PCI_PRODUCT_PROMISE_PDC205710x3571: | |||
6903 | bus_space_write_4(ps->ba5_st, ps->ba5_sh, 0x60, 0x00ff00ff)((ps->ba5_st)->write_4((ps->ba5_sh), (0x60), (0x00ff00ff ))); | |||
6904 | sc->sc_wdcdev.nchannels = PDC40718_NCHANNELS4; | |||
6905 | ||||
6906 | sc->sc_wdcdev.reset = pdc205xx_do_reset; | |||
6907 | sc->sc_wdcdev.drv_probe = pdc205xx_drv_probe; | |||
6908 | ||||
6909 | break; | |||
6910 | case PCI_PRODUCT_PROMISE_PDC205750x3d75: | |||
6911 | case PCI_PRODUCT_PROMISE_PDC205790x3574: | |||
6912 | case PCI_PRODUCT_PROMISE_PDC207710x3570: | |||
6913 | case PCI_PRODUCT_PROMISE_PDC207750x3d73: | |||
6914 | bus_space_write_4(ps->ba5_st, ps->ba5_sh, 0x60, 0x00ff00ff)((ps->ba5_st)->write_4((ps->ba5_sh), (0x60), (0x00ff00ff ))); | |||
6915 | sc->sc_wdcdev.nchannels = PDC20575_NCHANNELS3; | |||
6916 | ||||
6917 | sc->sc_wdcdev.reset = pdc205xx_do_reset; | |||
6918 | sc->sc_wdcdev.drv_probe = pdc205xx_drv_probe; | |||
6919 | ||||
6920 | break; | |||
6921 | } | |||
6922 | ||||
6923 | sc->sc_wdcdev.dma_arg = sc; | |||
6924 | sc->sc_wdcdev.dma_init = pciide_dma_init; | |||
6925 | sc->sc_wdcdev.dma_start = pdc203xx_dma_start; | |||
6926 | sc->sc_wdcdev.dma_finish = pdc203xx_dma_finish; | |||
6927 | ||||
6928 | for (channel = 0; channel < sc->sc_wdcdev.nchannels; | |||
6929 | channel++) { | |||
6930 | cp = &sc->pciide_channels[channel]; | |||
6931 | sc->wdc_chanarray[channel] = &cp->wdc_channel; | |||
6932 | ||||
6933 | cp->ih = sc->sc_pci_ih; | |||
6934 | cp->name = NULL((void *)0); | |||
6935 | cp->wdc_channel.channel = channel; | |||
6936 | cp->wdc_channel.wdc = &sc->sc_wdcdev; | |||
6937 | cp->wdc_channel.ch_queue = wdc_alloc_queue(); | |||
6938 | if (cp->wdc_channel.ch_queue == NULL((void *)0)) { | |||
6939 | printf("%s: channel %d: " | |||
6940 | "cannot allocate channel queue\n", | |||
6941 | sc->sc_wdcdev.sc_dev.dv_xname, channel); | |||
6942 | continue; | |||
6943 | } | |||
6944 | wdc_cp = &cp->wdc_channel; | |||
6945 | ||||
6946 | ps->regs[channel].ctl_iot = ps->ba5_st; | |||
6947 | ps->regs[channel].cmd_iot = ps->ba5_st; | |||
6948 | ||||
6949 | if (bus_space_subregion(ps->ba5_st, ps->ba5_sh, | |||
6950 | 0x0238 + (channel << 7), 1, | |||
6951 | &ps->regs[channel].ctl_ioh) != 0) { | |||
6952 | printf("%s: couldn't map channel %d ctl regs\n", | |||
6953 | sc->sc_wdcdev.sc_dev.dv_xname, | |||
6954 | channel); | |||
6955 | continue; | |||
6956 | } | |||
6957 | for (i = 0; i < WDC_NREG8; i++) { | |||
6958 | if (bus_space_subregion(ps->ba5_st, ps->ba5_sh, | |||
6959 | 0x0200 + (i << 2) + (channel << 7), i == 0 ? 4 : 1, | |||
6960 | &ps->regs[channel].cmd_iohs[i]) != 0) { | |||
6961 | printf("%s: couldn't map channel %d cmd " | |||
6962 | "regs\n", | |||
6963 | sc->sc_wdcdev.sc_dev.dv_xname, | |||
6964 | channel); | |||
6965 | goto loop_end; | |||
6966 | } | |||
6967 | } | |||
6968 | ps->regs[channel].cmd_iohs[wdr_status & _WDC_REGMASK7] = | |||
6969 | ps->regs[channel].cmd_iohs[wdr_command & _WDC_REGMASK7]; | |||
6970 | ps->regs[channel].cmd_iohs[wdr_features & _WDC_REGMASK7] = | |||
6971 | ps->regs[channel].cmd_iohs[wdr_error & _WDC_REGMASK7]; | |||
6972 | wdc_cp->data32iot = wdc_cp->cmd_iot = | |||
6973 | ps->regs[channel].cmd_iot; | |||
6974 | wdc_cp->data32ioh = wdc_cp->cmd_ioh = | |||
6975 | ps->regs[channel].cmd_iohs[0]; | |||
6976 | wdc_cp->_vtbl = &wdc_pdc203xx_vtbl; | |||
6977 | ||||
6978 | /* | |||
6979 | * Subregion de busmaster registers. They're spread all over | |||
6980 | * the controller's register space :(. They are also 4 bytes | |||
6981 | * sized, with some specific extensions in the extra bits. | |||
6982 | * It also seems that the IDEDMA_CTL register isn't available. | |||
6983 | */ | |||
6984 | if (bus_space_subregion(ps->ba5_st, ps->ba5_sh, | |||
6985 | 0x260 + (channel << 7), 1, | |||
6986 | &ps->regs[channel].dma_iohs[IDEDMA_CMD(0)(0x00 + 0x08 * (0))]) != 0) { | |||
6987 | printf("%s channel %d: can't subregion DMA " | |||
6988 | "registers\n", | |||
6989 | sc->sc_wdcdev.sc_dev.dv_xname, channel); | |||
6990 | continue; | |||
6991 | } | |||
6992 | if (bus_space_subregion(ps->ba5_st, ps->ba5_sh, | |||
6993 | 0x244 + (channel << 7), 4, | |||
6994 | &ps->regs[channel].dma_iohs[IDEDMA_TBL(0)(0x04 + 0x08 * (0))]) != 0) { | |||
6995 | printf("%s channel %d: can't subregion DMA " | |||
6996 | "registers\n", | |||
6997 | sc->sc_wdcdev.sc_dev.dv_xname, channel); | |||
6998 | continue; | |||
6999 | } | |||
7000 | ||||
7001 | wdcattach(wdc_cp); | |||
7002 | bus_space_write_4(sc->sc_dma_iot,((sc->sc_dma_iot)->write_4((ps->regs[channel].dma_iohs [(0x00 + 0x08 * (0))]), (0), ((((sc->sc_dma_iot)->read_4 ((ps->regs[channel].dma_iohs[(0x00 + 0x08 * (0))]), (0))) & ~0x00003f9f) | (channel + 1)))) | |||
7003 | ps->regs[channel].dma_iohs[IDEDMA_CMD(0)], 0,((sc->sc_dma_iot)->write_4((ps->regs[channel].dma_iohs [(0x00 + 0x08 * (0))]), (0), ((((sc->sc_dma_iot)->read_4 ((ps->regs[channel].dma_iohs[(0x00 + 0x08 * (0))]), (0))) & ~0x00003f9f) | (channel + 1)))) | |||
7004 | (bus_space_read_4(sc->sc_dma_iot,((sc->sc_dma_iot)->write_4((ps->regs[channel].dma_iohs [(0x00 + 0x08 * (0))]), (0), ((((sc->sc_dma_iot)->read_4 ((ps->regs[channel].dma_iohs[(0x00 + 0x08 * (0))]), (0))) & ~0x00003f9f) | (channel + 1)))) | |||
7005 | ps->regs[channel].dma_iohs[IDEDMA_CMD(0)],((sc->sc_dma_iot)->write_4((ps->regs[channel].dma_iohs [(0x00 + 0x08 * (0))]), (0), ((((sc->sc_dma_iot)->read_4 ((ps->regs[channel].dma_iohs[(0x00 + 0x08 * (0))]), (0))) & ~0x00003f9f) | (channel + 1)))) | |||
7006 | 0) & ~0x00003f9f) | (channel + 1))((sc->sc_dma_iot)->write_4((ps->regs[channel].dma_iohs [(0x00 + 0x08 * (0))]), (0), ((((sc->sc_dma_iot)->read_4 ((ps->regs[channel].dma_iohs[(0x00 + 0x08 * (0))]), (0))) & ~0x00003f9f) | (channel + 1)))); | |||
7007 | bus_space_write_4(ps->ba5_st, ps->ba5_sh,((ps->ba5_st)->write_4((ps->ba5_sh), ((channel + 1) << 2), (0x00000001))) | |||
7008 | (channel + 1) << 2, 0x00000001)((ps->ba5_st)->write_4((ps->ba5_sh), ((channel + 1) << 2), (0x00000001))); | |||
7009 | ||||
7010 | pdc203xx_setup_channel(&cp->wdc_channel); | |||
7011 | ||||
7012 | loop_end: ; | |||
7013 | } | |||
7014 | ||||
7015 | printf("%s: using %s for native-PCI interrupt\n", | |||
7016 | sc->sc_wdcdev.sc_dev.dv_xname, | |||
7017 | intrstr ? intrstr : "unknown interrupt"); | |||
7018 | } | |||
7019 | ||||
7020 | void | |||
7021 | pdc203xx_setup_channel(struct channel_softc *chp) | |||
7022 | { | |||
7023 | struct ata_drive_datas *drvp; | |||
7024 | struct pciide_channel *cp = (struct pciide_channel *)chp; | |||
7025 | int drive, s; | |||
7026 | ||||
7027 | pciide_channel_dma_setup(cp); | |||
7028 | ||||
7029 | for (drive = 0; drive < 2; drive++) { | |||
7030 | drvp = &chp->ch_drive[drive]; | |||
7031 | if ((drvp->drive_flags & DRIVE(0x0001|0x0002|0x0004)) == 0) | |||
7032 | continue; | |||
7033 | if (drvp->drive_flags & DRIVE_UDMA0x0020) { | |||
7034 | s = splbio()splraise(0x3); | |||
7035 | drvp->drive_flags &= ~DRIVE_DMA0x0010; | |||
7036 | splx(s)spllower(s); | |||
7037 | } | |||
7038 | } | |||
7039 | pciide_print_modes(cp); | |||
7040 | } | |||
7041 | ||||
7042 | int | |||
7043 | pdc203xx_pci_intr(void *arg) | |||
7044 | { | |||
7045 | struct pciide_softc *sc = arg; | |||
7046 | struct pciide_channel *cp; | |||
7047 | struct channel_softc *wdc_cp; | |||
7048 | struct pciide_pdcsata *ps = sc->sc_cookie; | |||
7049 | int i, rv, crv; | |||
7050 | u_int32_t scr; | |||
7051 | ||||
7052 | rv = 0; | |||
7053 | scr = bus_space_read_4(ps->ba5_st, ps->ba5_sh, 0x00040)((ps->ba5_st)->read_4((ps->ba5_sh), (0x00040))); | |||
7054 | ||||
7055 | for (i = 0; i < sc->sc_wdcdev.nchannels; i++) { | |||
7056 | cp = &sc->pciide_channels[i]; | |||
7057 | wdc_cp = &cp->wdc_channel; | |||
7058 | if (scr & (1 << (i + 1))) { | |||
7059 | crv = wdcintr(wdc_cp); | |||
7060 | if (crv == 0) { | |||
7061 | printf("%s:%d: bogus intr (reg 0x%x)\n", | |||
7062 | sc->sc_wdcdev.sc_dev.dv_xname, | |||
7063 | i, scr); | |||
7064 | } else | |||
7065 | rv = 1; | |||
7066 | } | |||
7067 | } | |||
7068 | ||||
7069 | return (rv); | |||
7070 | } | |||
7071 | ||||
7072 | int | |||
7073 | pdc205xx_pci_intr(void *arg) | |||
7074 | { | |||
7075 | struct pciide_softc *sc = arg; | |||
7076 | struct pciide_channel *cp; | |||
7077 | struct channel_softc *wdc_cp; | |||
7078 | struct pciide_pdcsata *ps = sc->sc_cookie; | |||
7079 | int i, rv, crv; | |||
7080 | u_int32_t scr, status; | |||
7081 | ||||
7082 | rv = 0; | |||
7083 | scr = bus_space_read_4(ps->ba5_st, ps->ba5_sh, 0x40)((ps->ba5_st)->read_4((ps->ba5_sh), (0x40))); | |||
7084 | bus_space_write_4(ps->ba5_st, ps->ba5_sh, 0x40, scr & 0x0000ffff)((ps->ba5_st)->write_4((ps->ba5_sh), (0x40), (scr & 0x0000ffff))); | |||
7085 | ||||
7086 | status = bus_space_read_4(ps->ba5_st, ps->ba5_sh, 0x60)((ps->ba5_st)->read_4((ps->ba5_sh), (0x60))); | |||
7087 | bus_space_write_4(ps->ba5_st, ps->ba5_sh, 0x60, status & 0x000000ff)((ps->ba5_st)->write_4((ps->ba5_sh), (0x60), (status & 0x000000ff))); | |||
7088 | ||||
7089 | for (i = 0; i < sc->sc_wdcdev.nchannels; i++) { | |||
7090 | cp = &sc->pciide_channels[i]; | |||
7091 | wdc_cp = &cp->wdc_channel; | |||
7092 | if (scr & (1 << (i + 1))) { | |||
7093 | crv = wdcintr(wdc_cp); | |||
7094 | if (crv == 0) { | |||
7095 | printf("%s:%d: bogus intr (reg 0x%x)\n", | |||
7096 | sc->sc_wdcdev.sc_dev.dv_xname, | |||
7097 | i, scr); | |||
7098 | } else | |||
7099 | rv = 1; | |||
7100 | } | |||
7101 | } | |||
7102 | return rv; | |||
7103 | } | |||
7104 | ||||
7105 | void | |||
7106 | pdc203xx_irqack(struct channel_softc *chp) | |||
7107 | { | |||
7108 | struct pciide_channel *cp = (struct pciide_channel *)chp; | |||
7109 | struct pciide_softc *sc = (struct pciide_softc *)cp->wdc_channel.wdc; | |||
7110 | struct pciide_pdcsata *ps = sc->sc_cookie; | |||
7111 | int chan = chp->channel; | |||
7112 | ||||
7113 | bus_space_write_4(sc->sc_dma_iot,((sc->sc_dma_iot)->write_4((ps->regs[chan].dma_iohs[ (0x00 + 0x08 * (0))]), (0), ((((sc->sc_dma_iot)->read_4 ((ps->regs[chan].dma_iohs[(0x00 + 0x08 * (0))]), (0))) & ~0x00003f9f) | (chan + 1)))) | |||
7114 | ps->regs[chan].dma_iohs[IDEDMA_CMD(0)], 0,((sc->sc_dma_iot)->write_4((ps->regs[chan].dma_iohs[ (0x00 + 0x08 * (0))]), (0), ((((sc->sc_dma_iot)->read_4 ((ps->regs[chan].dma_iohs[(0x00 + 0x08 * (0))]), (0))) & ~0x00003f9f) | (chan + 1)))) | |||
7115 | (bus_space_read_4(sc->sc_dma_iot,((sc->sc_dma_iot)->write_4((ps->regs[chan].dma_iohs[ (0x00 + 0x08 * (0))]), (0), ((((sc->sc_dma_iot)->read_4 ((ps->regs[chan].dma_iohs[(0x00 + 0x08 * (0))]), (0))) & ~0x00003f9f) | (chan + 1)))) | |||
7116 | ps->regs[chan].dma_iohs[IDEDMA_CMD(0)],((sc->sc_dma_iot)->write_4((ps->regs[chan].dma_iohs[ (0x00 + 0x08 * (0))]), (0), ((((sc->sc_dma_iot)->read_4 ((ps->regs[chan].dma_iohs[(0x00 + 0x08 * (0))]), (0))) & ~0x00003f9f) | (chan + 1)))) | |||
7117 | 0) & ~0x00003f9f) | (chan + 1))((sc->sc_dma_iot)->write_4((ps->regs[chan].dma_iohs[ (0x00 + 0x08 * (0))]), (0), ((((sc->sc_dma_iot)->read_4 ((ps->regs[chan].dma_iohs[(0x00 + 0x08 * (0))]), (0))) & ~0x00003f9f) | (chan + 1)))); | |||
7118 | bus_space_write_4(ps->ba5_st, ps->ba5_sh,((ps->ba5_st)->write_4((ps->ba5_sh), ((chan + 1) << 2), (0x00000001))) | |||
7119 | (chan + 1) << 2, 0x00000001)((ps->ba5_st)->write_4((ps->ba5_sh), ((chan + 1) << 2), (0x00000001))); | |||
7120 | } | |||
7121 | ||||
7122 | void | |||
7123 | pdc203xx_dma_start(void *v, int channel, int drive) | |||
7124 | { | |||
7125 | struct pciide_softc *sc = v; | |||
7126 | struct pciide_channel *cp = &sc->pciide_channels[channel]; | |||
7127 | struct pciide_dma_maps *dma_maps = &cp->dma_maps[drive]; | |||
7128 | struct pciide_pdcsata *ps = sc->sc_cookie; | |||
7129 | ||||
7130 | /* Write table address */ | |||
7131 | bus_space_write_4(sc->sc_dma_iot,((sc->sc_dma_iot)->write_4((ps->regs[channel].dma_iohs [(0x04 + 0x08 * (0))]), (0), (dma_maps->dmamap_table->dm_segs [0].ds_addr))) | |||
7132 | ps->regs[channel].dma_iohs[IDEDMA_TBL(0)], 0,((sc->sc_dma_iot)->write_4((ps->regs[channel].dma_iohs [(0x04 + 0x08 * (0))]), (0), (dma_maps->dmamap_table->dm_segs [0].ds_addr))) | |||
7133 | dma_maps->dmamap_table->dm_segs[0].ds_addr)((sc->sc_dma_iot)->write_4((ps->regs[channel].dma_iohs [(0x04 + 0x08 * (0))]), (0), (dma_maps->dmamap_table->dm_segs [0].ds_addr))); | |||
7134 | ||||
7135 | /* Start DMA engine */ | |||
7136 | bus_space_write_4(sc->sc_dma_iot,((sc->sc_dma_iot)->write_4((ps->regs[channel].dma_iohs [(0x00 + 0x08 * (0))]), (0), ((((sc->sc_dma_iot)->read_4 ((ps->regs[channel].dma_iohs[(0x00 + 0x08 * (0))]), (0))) & ~0xc0) | ((dma_maps->dma_flags & 0x01) ? 0x80 : 0xc0) ))) | |||
7137 | ps->regs[channel].dma_iohs[IDEDMA_CMD(0)], 0,((sc->sc_dma_iot)->write_4((ps->regs[channel].dma_iohs [(0x00 + 0x08 * (0))]), (0), ((((sc->sc_dma_iot)->read_4 ((ps->regs[channel].dma_iohs[(0x00 + 0x08 * (0))]), (0))) & ~0xc0) | ((dma_maps->dma_flags & 0x01) ? 0x80 : 0xc0) ))) | |||
7138 | (bus_space_read_4(sc->sc_dma_iot,((sc->sc_dma_iot)->write_4((ps->regs[channel].dma_iohs [(0x00 + 0x08 * (0))]), (0), ((((sc->sc_dma_iot)->read_4 ((ps->regs[channel].dma_iohs[(0x00 + 0x08 * (0))]), (0))) & ~0xc0) | ((dma_maps->dma_flags & 0x01) ? 0x80 : 0xc0) ))) | |||
7139 | ps->regs[channel].dma_iohs[IDEDMA_CMD(0)],((sc->sc_dma_iot)->write_4((ps->regs[channel].dma_iohs [(0x00 + 0x08 * (0))]), (0), ((((sc->sc_dma_iot)->read_4 ((ps->regs[channel].dma_iohs[(0x00 + 0x08 * (0))]), (0))) & ~0xc0) | ((dma_maps->dma_flags & 0x01) ? 0x80 : 0xc0) ))) | |||
7140 | 0) & ~0xc0) | ((dma_maps->dma_flags & WDC_DMA_READ) ? 0x80 : 0xc0))((sc->sc_dma_iot)->write_4((ps->regs[channel].dma_iohs [(0x00 + 0x08 * (0))]), (0), ((((sc->sc_dma_iot)->read_4 ((ps->regs[channel].dma_iohs[(0x00 + 0x08 * (0))]), (0))) & ~0xc0) | ((dma_maps->dma_flags & 0x01) ? 0x80 : 0xc0) ))); | |||
7141 | } | |||
7142 | ||||
7143 | int | |||
7144 | pdc203xx_dma_finish(void *v, int channel, int drive, int force) | |||
7145 | { | |||
7146 | struct pciide_softc *sc = v; | |||
7147 | struct pciide_channel *cp = &sc->pciide_channels[channel]; | |||
7148 | struct pciide_dma_maps *dma_maps = &cp->dma_maps[drive]; | |||
7149 | struct pciide_pdcsata *ps = sc->sc_cookie; | |||
7150 | ||||
7151 | /* Stop DMA channel */ | |||
7152 | bus_space_write_4(sc->sc_dma_iot,((sc->sc_dma_iot)->write_4((ps->regs[channel].dma_iohs [(0x00 + 0x08 * (0))]), (0), ((((sc->sc_dma_iot)->read_4 ((ps->regs[channel].dma_iohs[(0x00 + 0x08 * (0))]), (0))) & ~0x80)))) | |||
7153 | ps->regs[channel].dma_iohs[IDEDMA_CMD(0)], 0,((sc->sc_dma_iot)->write_4((ps->regs[channel].dma_iohs [(0x00 + 0x08 * (0))]), (0), ((((sc->sc_dma_iot)->read_4 ((ps->regs[channel].dma_iohs[(0x00 + 0x08 * (0))]), (0))) & ~0x80)))) | |||
7154 | (bus_space_read_4(sc->sc_dma_iot,((sc->sc_dma_iot)->write_4((ps->regs[channel].dma_iohs [(0x00 + 0x08 * (0))]), (0), ((((sc->sc_dma_iot)->read_4 ((ps->regs[channel].dma_iohs[(0x00 + 0x08 * (0))]), (0))) & ~0x80)))) | |||
7155 | ps->regs[channel].dma_iohs[IDEDMA_CMD(0)],((sc->sc_dma_iot)->write_4((ps->regs[channel].dma_iohs [(0x00 + 0x08 * (0))]), (0), ((((sc->sc_dma_iot)->read_4 ((ps->regs[channel].dma_iohs[(0x00 + 0x08 * (0))]), (0))) & ~0x80)))) | |||
7156 | 0) & ~0x80))((sc->sc_dma_iot)->write_4((ps->regs[channel].dma_iohs [(0x00 + 0x08 * (0))]), (0), ((((sc->sc_dma_iot)->read_4 ((ps->regs[channel].dma_iohs[(0x00 + 0x08 * (0))]), (0))) & ~0x80)))); | |||
7157 | ||||
7158 | /* Unload the map of the data buffer */ | |||
7159 | bus_dmamap_sync(sc->sc_dmat, dma_maps->dmamap_xfer, 0,(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (dma_maps ->dmamap_xfer), (0), (dma_maps->dmamap_xfer->dm_mapsize ), ((dma_maps->dma_flags & 0x01) ? 0x02 : 0x08)) | |||
7160 | dma_maps->dmamap_xfer->dm_mapsize,(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (dma_maps ->dmamap_xfer), (0), (dma_maps->dmamap_xfer->dm_mapsize ), ((dma_maps->dma_flags & 0x01) ? 0x02 : 0x08)) | |||
7161 | (dma_maps->dma_flags & WDC_DMA_READ) ?(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (dma_maps ->dmamap_xfer), (0), (dma_maps->dmamap_xfer->dm_mapsize ), ((dma_maps->dma_flags & 0x01) ? 0x02 : 0x08)) | |||
7162 | BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE)(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (dma_maps ->dmamap_xfer), (0), (dma_maps->dmamap_xfer->dm_mapsize ), ((dma_maps->dma_flags & 0x01) ? 0x02 : 0x08)); | |||
7163 | bus_dmamap_unload(sc->sc_dmat, dma_maps->dmamap_xfer)(*(sc->sc_dmat)->_dmamap_unload)((sc->sc_dmat), (dma_maps ->dmamap_xfer)); | |||
7164 | ||||
7165 | return (0); | |||
7166 | } | |||
7167 | ||||
7168 | u_int8_t | |||
7169 | pdc203xx_read_reg(struct channel_softc *chp, enum wdc_regs reg) | |||
7170 | { | |||
7171 | struct pciide_channel *cp = (struct pciide_channel *)chp; | |||
7172 | struct pciide_softc *sc = (struct pciide_softc *)cp->wdc_channel.wdc; | |||
7173 | struct pciide_pdcsata *ps = sc->sc_cookie; | |||
7174 | u_int8_t val; | |||
7175 | ||||
7176 | if (reg & _WDC_AUX8) { | |||
7177 | return (bus_space_read_1(ps->regs[chp->channel].ctl_iot,((ps->regs[chp->channel].ctl_iot)->read_1((ps->regs [chp->channel].ctl_ioh), (reg & 7))) | |||
7178 | ps->regs[chp->channel].ctl_ioh, reg & _WDC_REGMASK)((ps->regs[chp->channel].ctl_iot)->read_1((ps->regs [chp->channel].ctl_ioh), (reg & 7)))); | |||
7179 | } else { | |||
7180 | val = bus_space_read_1(ps->regs[chp->channel].cmd_iot,((ps->regs[chp->channel].cmd_iot)->read_1((ps->regs [chp->channel].cmd_iohs[reg & 7]), (0))) | |||
7181 | ps->regs[chp->channel].cmd_iohs[reg & _WDC_REGMASK], 0)((ps->regs[chp->channel].cmd_iot)->read_1((ps->regs [chp->channel].cmd_iohs[reg & 7]), (0))); | |||
7182 | return (val); | |||
7183 | } | |||
7184 | } | |||
7185 | ||||
7186 | void | |||
7187 | pdc203xx_write_reg(struct channel_softc *chp, enum wdc_regs reg, u_int8_t val) | |||
7188 | { | |||
7189 | struct pciide_channel *cp = (struct pciide_channel *)chp; | |||
7190 | struct pciide_softc *sc = (struct pciide_softc *)cp->wdc_channel.wdc; | |||
7191 | struct pciide_pdcsata *ps = sc->sc_cookie; | |||
7192 | ||||
7193 | if (reg & _WDC_AUX8) | |||
7194 | bus_space_write_1(ps->regs[chp->channel].ctl_iot,((ps->regs[chp->channel].ctl_iot)->write_1((ps->regs [chp->channel].ctl_ioh), (reg & 7), (val))) | |||
7195 | ps->regs[chp->channel].ctl_ioh, reg & _WDC_REGMASK, val)((ps->regs[chp->channel].ctl_iot)->write_1((ps->regs [chp->channel].ctl_ioh), (reg & 7), (val))); | |||
7196 | else | |||
7197 | bus_space_write_1(ps->regs[chp->channel].cmd_iot,((ps->regs[chp->channel].cmd_iot)->write_1((ps->regs [chp->channel].cmd_iohs[reg & 7]), (0), (val))) | |||
7198 | ps->regs[chp->channel].cmd_iohs[reg & _WDC_REGMASK],((ps->regs[chp->channel].cmd_iot)->write_1((ps->regs [chp->channel].cmd_iohs[reg & 7]), (0), (val))) | |||
7199 | 0, val)((ps->regs[chp->channel].cmd_iot)->write_1((ps->regs [chp->channel].cmd_iohs[reg & 7]), (0), (val))); | |||
7200 | } | |||
7201 | ||||
7202 | void | |||
7203 | pdc205xx_do_reset(struct channel_softc *chp) | |||
7204 | { | |||
7205 | struct pciide_channel *cp = (struct pciide_channel *)chp; | |||
7206 | struct pciide_softc *sc = (struct pciide_softc *)cp->wdc_channel.wdc; | |||
7207 | struct pciide_pdcsata *ps = sc->sc_cookie; | |||
7208 | u_int32_t scontrol; | |||
7209 | ||||
7210 | wdc_do_reset(chp); | |||
7211 | ||||
7212 | /* reset SATA */ | |||
7213 | scontrol = SControl_DET_INIT(0x1 << 0) | SControl_SPD_ANY(0x0 << 4) | SControl_IPM_NONE(0x3 << 8); | |||
7214 | SCONTROL_WRITE(ps, chp->channel, scontrol)(((ps)->ba5_st)->write_4(((ps)->ba5_sh), (((0x408)+( (chp->channel)<<8))), (scontrol))); | |||
7215 | delay(50*1000)(*delay_func)(50*1000); | |||
7216 | ||||
7217 | scontrol &= ~SControl_DET_INIT(0x1 << 0); | |||
7218 | SCONTROL_WRITE(ps, chp->channel, scontrol)(((ps)->ba5_st)->write_4(((ps)->ba5_sh), (((0x408)+( (chp->channel)<<8))), (scontrol))); | |||
7219 | delay(50*1000)(*delay_func)(50*1000); | |||
7220 | } | |||
7221 | ||||
7222 | void | |||
7223 | pdc205xx_drv_probe(struct channel_softc *chp) | |||
7224 | { | |||
7225 | struct pciide_channel *cp = (struct pciide_channel *)chp; | |||
7226 | struct pciide_softc *sc = (struct pciide_softc *)cp->wdc_channel.wdc; | |||
7227 | struct pciide_pdcsata *ps = sc->sc_cookie; | |||
7228 | bus_space_handle_t *iohs; | |||
7229 | u_int32_t scontrol, sstatus; | |||
7230 | u_int16_t scnt, sn, cl, ch; | |||
7231 | int s; | |||
7232 | ||||
7233 | SCONTROL_WRITE(ps, chp->channel, 0)(((ps)->ba5_st)->write_4(((ps)->ba5_sh), (((0x408)+( (chp->channel)<<8))), (0))); | |||
7234 | delay(50*1000)(*delay_func)(50*1000); | |||
7235 | ||||
7236 | scontrol = SControl_DET_INIT(0x1 << 0) | SControl_SPD_ANY(0x0 << 4) | SControl_IPM_NONE(0x3 << 8); | |||
7237 | SCONTROL_WRITE(ps,chp->channel,scontrol)(((ps)->ba5_st)->write_4(((ps)->ba5_sh), (((0x408)+( (chp->channel)<<8))), (scontrol))); | |||
7238 | delay(50*1000)(*delay_func)(50*1000); | |||
7239 | ||||
7240 | scontrol &= ~SControl_DET_INIT(0x1 << 0); | |||
7241 | SCONTROL_WRITE(ps,chp->channel,scontrol)(((ps)->ba5_st)->write_4(((ps)->ba5_sh), (((0x408)+( (chp->channel)<<8))), (scontrol))); | |||
7242 | delay(50*1000)(*delay_func)(50*1000); | |||
7243 | ||||
7244 | sstatus = SSTATUS_READ(ps,chp->channel)(((ps)->ba5_st)->read_4(((ps)->ba5_sh), (((0x400)+(( chp->channel)<<8))))); | |||
7245 | ||||
7246 | switch (sstatus & SStatus_DET_mask(0xf << 0)) { | |||
7247 | case SStatus_DET_NODEV(0x0 << 0): | |||
7248 | /* No Device; be silent. */ | |||
7249 | break; | |||
7250 | ||||
7251 | case SStatus_DET_DEV_NE(0x1 << 0): | |||
7252 | printf("%s: port %d: device connected, but " | |||
7253 | "communication not established\n", | |||
7254 | sc->sc_wdcdev.sc_dev.dv_xname, chp->channel); | |||
7255 | break; | |||
7256 | ||||
7257 | case SStatus_DET_OFFLINE(0x4 << 0): | |||
7258 | printf("%s: port %d: PHY offline\n", | |||
7259 | sc->sc_wdcdev.sc_dev.dv_xname, chp->channel); | |||
7260 | break; | |||
7261 | ||||
7262 | case SStatus_DET_DEV(0x3 << 0): | |||
7263 | iohs = ps->regs[chp->channel].cmd_iohs; | |||
7264 | bus_space_write_1(chp->cmd_iot, iohs[wdr_sdh], 0,((chp->cmd_iot)->write_1((iohs[wdr_sdh]), (0), (0xa0))) | |||
7265 | WDSD_IBM)((chp->cmd_iot)->write_1((iohs[wdr_sdh]), (0), (0xa0))); | |||
7266 | delay(10)(*delay_func)(10); /* 400ns delay */ | |||
7267 | scnt = bus_space_read_2(chp->cmd_iot, iohs[wdr_seccnt], 0)((chp->cmd_iot)->read_2((iohs[wdr_seccnt]), (0))); | |||
7268 | sn = bus_space_read_2(chp->cmd_iot, iohs[wdr_sector], 0)((chp->cmd_iot)->read_2((iohs[wdr_sector]), (0))); | |||
7269 | cl = bus_space_read_2(chp->cmd_iot, iohs[wdr_cyl_lo], 0)((chp->cmd_iot)->read_2((iohs[wdr_cyl_lo]), (0))); | |||
7270 | ch = bus_space_read_2(chp->cmd_iot, iohs[wdr_cyl_hi], 0)((chp->cmd_iot)->read_2((iohs[wdr_cyl_hi]), (0))); | |||
7271 | #if 0 | |||
7272 | printf("%s: port %d: scnt=0x%x sn=0x%x cl=0x%x ch=0x%x\n", | |||
7273 | sc->sc_wdcdev.sc_dev.dv_xname, chp->channel, | |||
7274 | scnt, sn, cl, ch); | |||
7275 | #endif | |||
7276 | /* | |||
7277 | * scnt and sn are supposed to be 0x1 for ATAPI, but in some | |||
7278 | * cases we get wrong values here, so ignore it. | |||
7279 | */ | |||
7280 | s = splbio()splraise(0x3); | |||
7281 | if (cl == 0x14 && ch == 0xeb) | |||
7282 | chp->ch_drive[0].drive_flags |= DRIVE_ATAPI0x0002; | |||
7283 | else | |||
7284 | chp->ch_drive[0].drive_flags |= DRIVE_ATA0x0001; | |||
7285 | splx(s)spllower(s); | |||
7286 | #if 0 | |||
7287 | printf("%s: port %d", | |||
7288 | sc->sc_wdcdev.sc_dev.dv_xname, chp->channel); | |||
7289 | switch ((sstatus & SStatus_SPD_mask(0xf << 4)) >> SStatus_SPD_shift4) { | |||
7290 | case 1: | |||
7291 | printf(": 1.5Gb/s"); | |||
7292 | break; | |||
7293 | case 2: | |||
7294 | printf(": 3.0Gb/s"); | |||
7295 | break; | |||
7296 | } | |||
7297 | printf("\n"); | |||
7298 | #endif | |||
7299 | break; | |||
7300 | ||||
7301 | default: | |||
7302 | printf("%s: port %d: unknown SStatus: 0x%08x\n", | |||
7303 | sc->sc_wdcdev.sc_dev.dv_xname, chp->channel, sstatus); | |||
7304 | } | |||
7305 | } | |||
7306 | ||||
7307 | void | |||
7308 | serverworks_chip_map(struct pciide_softc *sc, struct pci_attach_args *pa) | |||
7309 | { | |||
7310 | struct pciide_channel *cp; | |||
7311 | pcireg_t interface = PCI_INTERFACE(pa->pa_class)(((pa->pa_class) >> 8) & 0xff); | |||
7312 | pcitag_t pcib_tag; | |||
7313 | int channel; | |||
7314 | bus_size_t cmdsize, ctlsize; | |||
7315 | ||||
7316 | printf(": DMA"); | |||
7317 | pciide_mapreg_dma(sc, pa); | |||
7318 | printf("\n"); | |||
7319 | sc->sc_wdcdev.cap = WDC_CAPABILITY_DATA160x0001 | WDC_CAPABILITY_DATA320x0002 | | |||
7320 | WDC_CAPABILITY_MODE0x0004; | |||
7321 | ||||
7322 | if (sc->sc_dma_ok) { | |||
7323 | sc->sc_wdcdev.cap |= WDC_CAPABILITY_DMA0x0008 | WDC_CAPABILITY_UDMA0x0010; | |||
7324 | sc->sc_wdcdev.cap |= WDC_CAPABILITY_IRQACK0x0400; | |||
7325 | sc->sc_wdcdev.irqack = pciide_irqack; | |||
7326 | } | |||
7327 | sc->sc_wdcdev.PIO_cap = 4; | |||
7328 | sc->sc_wdcdev.DMA_cap = 2; | |||
7329 | switch (sc->sc_pp->ide_product) { | |||
7330 | case PCI_PRODUCT_RCC_OSB4_IDE0x0211: | |||
7331 | sc->sc_wdcdev.UDMA_cap = 2; | |||
7332 | break; | |||
7333 | case PCI_PRODUCT_RCC_CSB5_IDE0x0212: | |||
7334 | if (sc->sc_rev < 0x92) | |||
7335 | sc->sc_wdcdev.UDMA_cap = 4; | |||
7336 | else | |||
7337 | sc->sc_wdcdev.UDMA_cap = 5; | |||
7338 | break; | |||
7339 | case PCI_PRODUCT_RCC_CSB6_IDE0x0217: | |||
7340 | sc->sc_wdcdev.UDMA_cap = 4; | |||
7341 | break; | |||
7342 | case PCI_PRODUCT_RCC_CSB6_RAID_IDE0x0213: | |||
7343 | case PCI_PRODUCT_RCC_HT_1000_IDE0x0214: | |||
7344 | sc->sc_wdcdev.UDMA_cap = 5; | |||
7345 | break; | |||
7346 | } | |||
7347 | ||||
7348 | sc->sc_wdcdev.set_modes = serverworks_setup_channel; | |||
7349 | sc->sc_wdcdev.channels = sc->wdc_chanarray; | |||
7350 | sc->sc_wdcdev.nchannels = | |||
7351 | (sc->sc_pp->ide_product == PCI_PRODUCT_RCC_CSB6_IDE0x0217 ? 1 : 2); | |||
7352 | ||||
7353 | for (channel = 0; channel < sc->sc_wdcdev.nchannels; channel++) { | |||
7354 | cp = &sc->pciide_channels[channel]; | |||
7355 | if (pciide_chansetup(sc, channel, interface) == 0) | |||
7356 | continue; | |||
7357 | pciide_mapchan(pa, cp, interface, &cmdsize, &ctlsize, | |||
7358 | serverworks_pci_intr); | |||
7359 | if (cp->hw_ok == 0) | |||
7360 | return; | |||
7361 | pciide_map_compat_intr(pa, cp, channel, interface); | |||
7362 | if (cp->hw_ok == 0) | |||
7363 | return; | |||
7364 | serverworks_setup_channel(&cp->wdc_channel); | |||
7365 | } | |||
7366 | ||||
7367 | pcib_tag = pci_make_tag(pa->pa_pc, pa->pa_bus, pa->pa_device, 0); | |||
7368 | pci_conf_write(pa->pa_pc, pcib_tag, 0x64, | |||
7369 | (pci_conf_read(pa->pa_pc, pcib_tag, 0x64) & ~0x2000) | 0x4000); | |||
7370 | } | |||
7371 | ||||
7372 | void | |||
7373 | serverworks_setup_channel(struct channel_softc *chp) | |||
7374 | { | |||
7375 | struct ata_drive_datas *drvp; | |||
7376 | struct pciide_channel *cp = (struct pciide_channel *)chp; | |||
7377 | struct pciide_softc *sc = (struct pciide_softc *)cp->wdc_channel.wdc; | |||
7378 | int channel = chp->channel; | |||
7379 | int drive, unit; | |||
7380 | u_int32_t pio_time, dma_time, pio_mode, udma_mode; | |||
7381 | u_int32_t idedma_ctl; | |||
7382 | static const u_int8_t pio_modes[5] = {0x5d, 0x47, 0x34, 0x22, 0x20}; | |||
7383 | static const u_int8_t dma_modes[3] = {0x77, 0x21, 0x20}; | |||
7384 | ||||
7385 | /* setup DMA if needed */ | |||
7386 | pciide_channel_dma_setup(cp); | |||
7387 | ||||
7388 | pio_time = pci_conf_read(sc->sc_pc, sc->sc_tag, 0x40); | |||
7389 | dma_time = pci_conf_read(sc->sc_pc, sc->sc_tag, 0x44); | |||
7390 | pio_mode = pci_conf_read(sc->sc_pc, sc->sc_tag, 0x48); | |||
7391 | udma_mode = pci_conf_read(sc->sc_pc, sc->sc_tag, 0x54); | |||
7392 | ||||
7393 | pio_time &= ~(0xffff << (16 * channel)); | |||
7394 | dma_time &= ~(0xffff << (16 * channel)); | |||
7395 | pio_mode &= ~(0xff << (8 * channel + 16)); | |||
7396 | udma_mode &= ~(0xff << (8 * channel + 16)); | |||
7397 | udma_mode &= ~(3 << (2 * channel)); | |||
7398 | ||||
7399 | idedma_ctl = 0; | |||
7400 | ||||
7401 | /* Per drive settings */ | |||
7402 | for (drive = 0; drive < 2; drive++) { | |||
7403 | drvp = &chp->ch_drive[drive]; | |||
7404 | /* If no drive, skip */ | |||
7405 | if ((drvp->drive_flags & DRIVE(0x0001|0x0002|0x0004)) == 0) | |||
7406 | continue; | |||
7407 | unit = drive + 2 * channel; | |||
7408 | /* add timing values, setup DMA if needed */ | |||
7409 | pio_time |= pio_modes[drvp->PIO_mode] << (8 * (unit^1)); | |||
7410 | pio_mode |= drvp->PIO_mode << (4 * unit + 16); | |||
7411 | if ((chp->wdc->cap & WDC_CAPABILITY_UDMA0x0010) && | |||
7412 | (drvp->drive_flags & DRIVE_UDMA0x0020)) { | |||
7413 | /* use Ultra/DMA, check for 80-pin cable */ | |||
7414 | if (sc->sc_rev <= 0x92 && drvp->UDMA_mode > 2 && | |||
7415 | (PCI_PRODUCT(pci_conf_read(sc->sc_pc, sc->sc_tag,(((pci_conf_read(sc->sc_pc, sc->sc_tag, 0x2c)) >> 16) & 0xffff) | |||
7416 | PCI_SUBSYS_ID_REG))(((pci_conf_read(sc->sc_pc, sc->sc_tag, 0x2c)) >> 16) & 0xffff) & | |||
7417 | (1 << (14 + channel))) == 0) { | |||
7418 | WDCDEBUG_PRINT(("%s(%s:%d:%d): 80-wire " | |||
7419 | "cable not detected\n", drvp->drive_name, | |||
7420 | sc->sc_wdcdev.sc_dev.dv_xname, | |||
7421 | channel, drive), DEBUG_PROBE); | |||
7422 | drvp->UDMA_mode = 2; | |||
7423 | } | |||
7424 | dma_time |= dma_modes[drvp->DMA_mode] << (8 * (unit^1)); | |||
7425 | udma_mode |= drvp->UDMA_mode << (4 * unit + 16); | |||
7426 | udma_mode |= 1 << unit; | |||
7427 | idedma_ctl |= IDEDMA_CTL_DRV_DMA(drive)(0x20 << (drive)); | |||
7428 | } else if ((chp->wdc->cap & WDC_CAPABILITY_DMA0x0008) && | |||
7429 | (drvp->drive_flags & DRIVE_DMA0x0010)) { | |||
7430 | /* use Multiword DMA */ | |||
7431 | drvp->drive_flags &= ~DRIVE_UDMA0x0020; | |||
7432 | dma_time |= dma_modes[drvp->DMA_mode] << (8 * (unit^1)); | |||
7433 | idedma_ctl |= IDEDMA_CTL_DRV_DMA(drive)(0x20 << (drive)); | |||
7434 | } else { | |||
7435 | /* PIO only */ | |||
7436 | drvp->drive_flags &= ~(DRIVE_UDMA0x0020 | DRIVE_DMA0x0010); | |||
7437 | } | |||
7438 | } | |||
7439 | ||||
7440 | pci_conf_write(sc->sc_pc, sc->sc_tag, 0x40, pio_time); | |||
7441 | pci_conf_write(sc->sc_pc, sc->sc_tag, 0x44, dma_time); | |||
7442 | if (sc->sc_pp->ide_product != PCI_PRODUCT_RCC_OSB4_IDE0x0211) | |||
7443 | pci_conf_write(sc->sc_pc, sc->sc_tag, 0x48, pio_mode); | |||
7444 | pci_conf_write(sc->sc_pc, sc->sc_tag, 0x54, udma_mode); | |||
7445 | ||||
7446 | if (idedma_ctl != 0) { | |||
7447 | /* Add software bits in status register */ | |||
7448 | bus_space_write_1(sc->sc_dma_iot, sc->sc_dma_ioh,((sc->sc_dma_iot)->write_1((sc->sc_dma_ioh), ((0x02 + 0x08 * (channel))), (idedma_ctl))) | |||
7449 | IDEDMA_CTL(channel), idedma_ctl)((sc->sc_dma_iot)->write_1((sc->sc_dma_ioh), ((0x02 + 0x08 * (channel))), (idedma_ctl))); | |||
7450 | } | |||
7451 | pciide_print_modes(cp); | |||
7452 | } | |||
7453 | ||||
7454 | int | |||
7455 | serverworks_pci_intr(void *arg) | |||
7456 | { | |||
7457 | struct pciide_softc *sc = arg; | |||
7458 | struct pciide_channel *cp; | |||
7459 | struct channel_softc *wdc_cp; | |||
7460 | int rv = 0; | |||
7461 | int dmastat, i, crv; | |||
7462 | ||||
7463 | for (i = 0; i < sc->sc_wdcdev.nchannels; i++) { | |||
7464 | dmastat = bus_space_read_1(sc->sc_dma_iot, sc->sc_dma_ioh,((sc->sc_dma_iot)->read_1((sc->sc_dma_ioh), ((0x02 + 0x08 * (i))))) | |||
7465 | IDEDMA_CTL(i))((sc->sc_dma_iot)->read_1((sc->sc_dma_ioh), ((0x02 + 0x08 * (i))))); | |||
7466 | if ((dmastat & (IDEDMA_CTL_ACT0x01 | IDEDMA_CTL_INTR0x04)) != | |||
7467 | IDEDMA_CTL_INTR0x04) | |||
7468 | continue; | |||
7469 | cp = &sc->pciide_channels[i]; | |||
7470 | wdc_cp = &cp->wdc_channel; | |||
7471 | crv = wdcintr(wdc_cp); | |||
7472 | if (crv == 0) { | |||
7473 | printf("%s:%d: bogus intr\n", | |||
7474 | sc->sc_wdcdev.sc_dev.dv_xname, i); | |||
7475 | bus_space_write_1(sc->sc_dma_iot, sc->sc_dma_ioh,((sc->sc_dma_iot)->write_1((sc->sc_dma_ioh), ((0x02 + 0x08 * (i))), (dmastat))) | |||
7476 | IDEDMA_CTL(i), dmastat)((sc->sc_dma_iot)->write_1((sc->sc_dma_ioh), ((0x02 + 0x08 * (i))), (dmastat))); | |||
7477 | } else | |||
7478 | rv = 1; | |||
7479 | } | |||
7480 | return (rv); | |||
7481 | } | |||
7482 | ||||
7483 | void | |||
7484 | svwsata_chip_map(struct pciide_softc *sc, struct pci_attach_args *pa) | |||
7485 | { | |||
7486 | struct pciide_channel *cp; | |||
7487 | pci_intr_handle_t intrhandle; | |||
7488 | const char *intrstr; | |||
7489 | int channel; | |||
7490 | struct pciide_svwsata *ss; | |||
7491 | ||||
7492 | /* Allocate memory for private data */ | |||
7493 | sc->sc_cookielen = sizeof(*ss); | |||
7494 | sc->sc_cookie = malloc(sc->sc_cookielen, M_DEVBUF2, M_NOWAIT0x0002 | M_ZERO0x0008); | |||
7495 | ss = sc->sc_cookie; | |||
7496 | ||||
7497 | /* The 4-port version has a dummy second function. */ | |||
7498 | if (pci_conf_read(sc->sc_pc, sc->sc_tag, | |||
7499 | PCI_MAPREG_START0x10 + 0x14) == 0) { | |||
7500 | printf("\n"); | |||
7501 | return; | |||
7502 | } | |||
7503 | ||||
7504 | if (pci_mapreg_map(pa, PCI_MAPREG_START0x10 + 0x14, | |||
7505 | PCI_MAPREG_TYPE_MEM0x00000000 | PCI_MAPREG_MEM_TYPE_32BIT0x00000000, 0, | |||
7506 | &ss->ba5_st, &ss->ba5_sh, NULL((void *)0), NULL((void *)0), 0) != 0) { | |||
7507 | printf(": unable to map BA5 register space\n"); | |||
7508 | return; | |||
7509 | } | |||
7510 | ||||
7511 | printf(": DMA"); | |||
7512 | svwsata_mapreg_dma(sc, pa); | |||
7513 | printf("\n"); | |||
7514 | ||||
7515 | if (sc->sc_dma_ok) { | |||
7516 | sc->sc_wdcdev.cap |= WDC_CAPABILITY_UDMA0x0010 | | |||
7517 | WDC_CAPABILITY_DMA0x0008 | WDC_CAPABILITY_IRQACK0x0400; | |||
7518 | sc->sc_wdcdev.irqack = pciide_irqack; | |||
7519 | } | |||
7520 | sc->sc_wdcdev.PIO_cap = 4; | |||
7521 | sc->sc_wdcdev.DMA_cap = 2; | |||
7522 | sc->sc_wdcdev.UDMA_cap = 6; | |||
7523 | ||||
7524 | sc->sc_wdcdev.channels = sc->wdc_chanarray; | |||
7525 | sc->sc_wdcdev.nchannels = 4; | |||
7526 | sc->sc_wdcdev.cap |= WDC_CAPABILITY_DATA160x0001 | WDC_CAPABILITY_DATA320x0002 | | |||
7527 | WDC_CAPABILITY_MODE0x0004 | WDC_CAPABILITY_SATA0x2000; | |||
7528 | sc->sc_wdcdev.set_modes = sata_setup_channel; | |||
7529 | ||||
7530 | /* We can use SControl and SStatus to probe for drives. */ | |||
7531 | sc->sc_wdcdev.drv_probe = svwsata_drv_probe; | |||
7532 | ||||
7533 | /* Map and establish the interrupt handler. */ | |||
7534 | if(pci_intr_map(pa, &intrhandle) != 0) { | |||
7535 | printf("%s: couldn't map native-PCI interrupt\n", | |||
7536 | sc->sc_wdcdev.sc_dev.dv_xname); | |||
7537 | return; | |||
7538 | } | |||
7539 | intrstr = pci_intr_string(pa->pa_pc, intrhandle); | |||
7540 | sc->sc_pci_ih = pci_intr_establish(pa->pa_pc, intrhandle, IPL_BIO0x3, | |||
7541 | pciide_pci_intr, sc, sc->sc_wdcdev.sc_dev.dv_xname); | |||
7542 | if (sc->sc_pci_ih != NULL((void *)0)) { | |||
7543 | printf("%s: using %s for native-PCI interrupt\n", | |||
7544 | sc->sc_wdcdev.sc_dev.dv_xname, | |||
7545 | intrstr ? intrstr : "unknown interrupt"); | |||
7546 | } else { | |||
7547 | printf("%s: couldn't establish native-PCI interrupt", | |||
7548 | sc->sc_wdcdev.sc_dev.dv_xname); | |||
7549 | if (intrstr != NULL((void *)0)) | |||
7550 | printf(" at %s", intrstr); | |||
7551 | printf("\n"); | |||
7552 | return; | |||
7553 | } | |||
7554 | ||||
7555 | switch (sc->sc_pp->ide_product) { | |||
7556 | case PCI_PRODUCT_RCC_K2_SATA0x0240: | |||
7557 | bus_space_write_4(ss->ba5_st, ss->ba5_sh, SVWSATA_SICR1,((ss->ba5_st)->write_4((ss->ba5_sh), (0x80), (((ss-> ba5_st)->read_4((ss->ba5_sh), (0x80))) & ~0x00040000 ))) | |||
7558 | bus_space_read_4(ss->ba5_st, ss->ba5_sh, SVWSATA_SICR1)((ss->ba5_st)->write_4((ss->ba5_sh), (0x80), (((ss-> ba5_st)->read_4((ss->ba5_sh), (0x80))) & ~0x00040000 ))) | |||
7559 | & ~0x00040000)((ss->ba5_st)->write_4((ss->ba5_sh), (0x80), (((ss-> ba5_st)->read_4((ss->ba5_sh), (0x80))) & ~0x00040000 ))); | |||
7560 | bus_space_write_4(ss->ba5_st, ss->ba5_sh,((ss->ba5_st)->write_4((ss->ba5_sh), (0x88), (0))) | |||
7561 | SVWSATA_SIM, 0)((ss->ba5_st)->write_4((ss->ba5_sh), (0x88), (0))); | |||
7562 | break; | |||
7563 | } | |||
7564 | ||||
7565 | for (channel = 0; channel < sc->sc_wdcdev.nchannels; channel++) { | |||
7566 | cp = &sc->pciide_channels[channel]; | |||
7567 | if (pciide_chansetup(sc, channel, 0) == 0) | |||
7568 | continue; | |||
7569 | svwsata_mapchan(cp); | |||
7570 | sata_setup_channel(&cp->wdc_channel); | |||
7571 | } | |||
7572 | } | |||
7573 | ||||
7574 | void | |||
7575 | svwsata_mapreg_dma(struct pciide_softc *sc, struct pci_attach_args *pa) | |||
7576 | { | |||
7577 | struct pciide_svwsata *ss = sc->sc_cookie; | |||
7578 | ||||
7579 | sc->sc_wdcdev.dma_arg = sc; | |||
7580 | sc->sc_wdcdev.dma_init = pciide_dma_init; | |||
7581 | sc->sc_wdcdev.dma_start = pciide_dma_start; | |||
7582 | sc->sc_wdcdev.dma_finish = pciide_dma_finish; | |||
7583 | ||||
7584 | /* XXX */ | |||
7585 | sc->sc_dma_iot = ss->ba5_st; | |||
7586 | sc->sc_dma_ioh = ss->ba5_sh; | |||
7587 | ||||
7588 | sc->sc_dmacmd_read = svwsata_dmacmd_read; | |||
7589 | sc->sc_dmacmd_write = svwsata_dmacmd_write; | |||
7590 | sc->sc_dmactl_read = svwsata_dmactl_read; | |||
7591 | sc->sc_dmactl_write = svwsata_dmactl_write; | |||
7592 | sc->sc_dmatbl_write = svwsata_dmatbl_write; | |||
7593 | ||||
7594 | /* DMA registers all set up! */ | |||
7595 | sc->sc_dmat = pa->pa_dmat; | |||
7596 | sc->sc_dma_ok = 1; | |||
7597 | } | |||
7598 | ||||
7599 | u_int8_t | |||
7600 | svwsata_dmacmd_read(struct pciide_softc *sc, int chan) | |||
7601 | { | |||
7602 | return (bus_space_read_1(sc->sc_dma_iot, sc->sc_dma_ioh,((sc->sc_dma_iot)->read_1((sc->sc_dma_ioh), ((chan << 8) + 0x30 + (0x00 + 0x08 * (0))))) | |||
7603 | (chan << 8) + SVWSATA_DMA + IDEDMA_CMD(0))((sc->sc_dma_iot)->read_1((sc->sc_dma_ioh), ((chan << 8) + 0x30 + (0x00 + 0x08 * (0)))))); | |||
7604 | } | |||
7605 | ||||
7606 | void | |||
7607 | svwsata_dmacmd_write(struct pciide_softc *sc, int chan, u_int8_t val) | |||
7608 | { | |||
7609 | bus_space_write_1(sc->sc_dma_iot, sc->sc_dma_ioh,((sc->sc_dma_iot)->write_1((sc->sc_dma_ioh), ((chan << 8) + 0x30 + (0x00 + 0x08 * (0))), (val))) | |||
7610 | (chan << 8) + SVWSATA_DMA + IDEDMA_CMD(0), val)((sc->sc_dma_iot)->write_1((sc->sc_dma_ioh), ((chan << 8) + 0x30 + (0x00 + 0x08 * (0))), (val))); | |||
7611 | } | |||
7612 | ||||
7613 | u_int8_t | |||
7614 | svwsata_dmactl_read(struct pciide_softc *sc, int chan) | |||
7615 | { | |||
7616 | return (bus_space_read_1(sc->sc_dma_iot, sc->sc_dma_ioh,((sc->sc_dma_iot)->read_1((sc->sc_dma_ioh), ((chan << 8) + 0x30 + (0x02 + 0x08 * (0))))) | |||
7617 | (chan << 8) + SVWSATA_DMA + IDEDMA_CTL(0))((sc->sc_dma_iot)->read_1((sc->sc_dma_ioh), ((chan << 8) + 0x30 + (0x02 + 0x08 * (0)))))); | |||
7618 | } | |||
7619 | ||||
7620 | void | |||
7621 | svwsata_dmactl_write(struct pciide_softc *sc, int chan, u_int8_t val) | |||
7622 | { | |||
7623 | bus_space_write_1(sc->sc_dma_iot, sc->sc_dma_ioh,((sc->sc_dma_iot)->write_1((sc->sc_dma_ioh), ((chan << 8) + 0x30 + (0x02 + 0x08 * (0))), (val))) | |||
7624 | (chan << 8) + SVWSATA_DMA + IDEDMA_CTL(0), val)((sc->sc_dma_iot)->write_1((sc->sc_dma_ioh), ((chan << 8) + 0x30 + (0x02 + 0x08 * (0))), (val))); | |||
7625 | } | |||
7626 | ||||
7627 | void | |||
7628 | svwsata_dmatbl_write(struct pciide_softc *sc, int chan, u_int32_t val) | |||
7629 | { | |||
7630 | bus_space_write_4(sc->sc_dma_iot, sc->sc_dma_ioh,((sc->sc_dma_iot)->write_4((sc->sc_dma_ioh), ((chan << 8) + 0x30 + (0x04 + 0x08 * (0))), (val))) | |||
7631 | (chan << 8) + SVWSATA_DMA + IDEDMA_TBL(0), val)((sc->sc_dma_iot)->write_4((sc->sc_dma_ioh), ((chan << 8) + 0x30 + (0x04 + 0x08 * (0))), (val))); | |||
7632 | } | |||
7633 | ||||
7634 | void | |||
7635 | svwsata_mapchan(struct pciide_channel *cp) | |||
7636 | { | |||
7637 | struct pciide_softc *sc = (struct pciide_softc *)cp->wdc_channel.wdc; | |||
7638 | struct channel_softc *wdc_cp = &cp->wdc_channel; | |||
7639 | struct pciide_svwsata *ss = sc->sc_cookie; | |||
7640 | ||||
7641 | cp->compat = 0; | |||
7642 | cp->ih = sc->sc_pci_ih; | |||
7643 | ||||
7644 | if (bus_space_subregion(ss->ba5_st, ss->ba5_sh, | |||
7645 | (wdc_cp->channel << 8) + SVWSATA_TF00x00, | |||
7646 | SVWSATA_TF80x20 - SVWSATA_TF00x00, &wdc_cp->cmd_ioh) != 0) { | |||
7647 | printf("%s: couldn't map %s cmd regs\n", | |||
7648 | sc->sc_wdcdev.sc_dev.dv_xname, cp->name); | |||
7649 | return; | |||
7650 | } | |||
7651 | if (bus_space_subregion(ss->ba5_st, ss->ba5_sh, | |||
7652 | (wdc_cp->channel << 8) + SVWSATA_TF80x20, 4, | |||
7653 | &wdc_cp->ctl_ioh) != 0) { | |||
7654 | printf("%s: couldn't map %s ctl regs\n", | |||
7655 | sc->sc_wdcdev.sc_dev.dv_xname, cp->name); | |||
7656 | return; | |||
7657 | } | |||
7658 | wdc_cp->cmd_iot = wdc_cp->ctl_iot = ss->ba5_st; | |||
7659 | wdc_cp->_vtbl = &wdc_svwsata_vtbl; | |||
7660 | wdc_cp->ch_flags |= WDCF_DMA_BEFORE_CMD0x80; | |||
7661 | wdcattach(wdc_cp); | |||
7662 | } | |||
7663 | ||||
7664 | void | |||
7665 | svwsata_drv_probe(struct channel_softc *chp) | |||
7666 | { | |||
7667 | struct pciide_channel *cp = (struct pciide_channel *)chp; | |||
7668 | struct pciide_softc *sc = (struct pciide_softc *)cp->wdc_channel.wdc; | |||
7669 | struct pciide_svwsata *ss = sc->sc_cookie; | |||
7670 | int channel = chp->channel; | |||
7671 | uint32_t scontrol, sstatus; | |||
7672 | uint8_t scnt, sn, cl, ch; | |||
7673 | int s; | |||
7674 | ||||
7675 | /* | |||
7676 | * Request communication initialization sequence, any speed. | |||
7677 | * Performing this is the equivalent of an ATA Reset. | |||
7678 | */ | |||
7679 | scontrol = SControl_DET_INIT(0x1 << 0) | SControl_SPD_ANY(0x0 << 4); | |||
7680 | ||||
7681 | /* | |||
7682 | * XXX We don't yet support SATA power management; disable all | |||
7683 | * power management state transitions. | |||
7684 | */ | |||
7685 | scontrol |= SControl_IPM_NONE(0x3 << 8); | |||
7686 | ||||
7687 | bus_space_write_4(ss->ba5_st, ss->ba5_sh,((ss->ba5_st)->write_4((ss->ba5_sh), ((channel << 8) + 0x48), (scontrol))) | |||
7688 | (channel << 8) + SVWSATA_SCONTROL, scontrol)((ss->ba5_st)->write_4((ss->ba5_sh), ((channel << 8) + 0x48), (scontrol))); | |||
7689 | delay(50 * 1000)(*delay_func)(50 * 1000); | |||
7690 | scontrol &= ~SControl_DET_INIT(0x1 << 0); | |||
7691 | bus_space_write_4(ss->ba5_st, ss->ba5_sh,((ss->ba5_st)->write_4((ss->ba5_sh), ((channel << 8) + 0x48), (scontrol))) | |||
7692 | (channel << 8) + SVWSATA_SCONTROL, scontrol)((ss->ba5_st)->write_4((ss->ba5_sh), ((channel << 8) + 0x48), (scontrol))); | |||
7693 | delay(100 * 1000)(*delay_func)(100 * 1000); | |||
7694 | ||||
7695 | sstatus = bus_space_read_4(ss->ba5_st, ss->ba5_sh,((ss->ba5_st)->read_4((ss->ba5_sh), ((channel << 8) + 0x40))) | |||
7696 | (channel << 8) + SVWSATA_SSTATUS)((ss->ba5_st)->read_4((ss->ba5_sh), ((channel << 8) + 0x40))); | |||
7697 | #if 0 | |||
7698 | printf("%s: port %d: SStatus=0x%08x, SControl=0x%08x\n", | |||
7699 | sc->sc_wdcdev.sc_dev.dv_xname, chp->channel, sstatus, | |||
7700 | bus_space_read_4(ss->ba5_st, ss->ba5_sh,((ss->ba5_st)->read_4((ss->ba5_sh), ((channel << 8) + 0x40))) | |||
7701 | (channel << 8) + SVWSATA_SSTATUS)((ss->ba5_st)->read_4((ss->ba5_sh), ((channel << 8) + 0x40)))); | |||
7702 | #endif | |||
7703 | switch (sstatus & SStatus_DET_mask(0xf << 0)) { | |||
7704 | case SStatus_DET_NODEV(0x0 << 0): | |||
7705 | /* No device; be silent. */ | |||
7706 | break; | |||
7707 | ||||
7708 | case SStatus_DET_DEV_NE(0x1 << 0): | |||
7709 | printf("%s: port %d: device connected, but " | |||
7710 | "communication not established\n", | |||
7711 | sc->sc_wdcdev.sc_dev.dv_xname, chp->channel); | |||
7712 | break; | |||
7713 | ||||
7714 | case SStatus_DET_OFFLINE(0x4 << 0): | |||
7715 | printf("%s: port %d: PHY offline\n", | |||
7716 | sc->sc_wdcdev.sc_dev.dv_xname, chp->channel); | |||
7717 | break; | |||
7718 | ||||
7719 | case SStatus_DET_DEV(0x3 << 0): | |||
7720 | /* | |||
7721 | * XXX ATAPI detection doesn't currently work. Don't | |||
7722 | * XXX know why. But, it's not like the standard method | |||
7723 | * XXX can detect an ATAPI device connected via a SATA/PATA | |||
7724 | * XXX bridge, so at least this is no worse. --thorpej | |||
7725 | */ | |||
7726 | if (chp->_vtbl != NULL((void *)0)) | |||
7727 | CHP_WRITE_REG(chp, wdr_sdh, WDSD_IBM | (0 << 4))((chp)->_vtbl->write_reg)(chp, wdr_sdh, 0xa0 | (0 << 4)); | |||
7728 | else | |||
7729 | bus_space_write_1(chp->cmd_iot, chp->cmd_ioh,((chp->cmd_iot)->write_1((chp->cmd_ioh), (wdr_sdh & 7), (0xa0 | (0 << 4)))) | |||
7730 | wdr_sdh & _WDC_REGMASK, WDSD_IBM | (0 << 4))((chp->cmd_iot)->write_1((chp->cmd_ioh), (wdr_sdh & 7), (0xa0 | (0 << 4)))); | |||
7731 | delay(10)(*delay_func)(10); /* 400ns delay */ | |||
7732 | /* Save register contents. */ | |||
7733 | if (chp->_vtbl != NULL((void *)0)) { | |||
7734 | scnt = CHP_READ_REG(chp, wdr_seccnt)((chp)->_vtbl->read_reg)(chp, wdr_seccnt); | |||
7735 | sn = CHP_READ_REG(chp, wdr_sector)((chp)->_vtbl->read_reg)(chp, wdr_sector); | |||
7736 | cl = CHP_READ_REG(chp, wdr_cyl_lo)((chp)->_vtbl->read_reg)(chp, wdr_cyl_lo); | |||
7737 | ch = CHP_READ_REG(chp, wdr_cyl_hi)((chp)->_vtbl->read_reg)(chp, wdr_cyl_hi); | |||
7738 | } else { | |||
7739 | scnt = bus_space_read_1(chp->cmd_iot,((chp->cmd_iot)->read_1((chp->cmd_ioh), (wdr_seccnt & 7))) | |||
7740 | chp->cmd_ioh, wdr_seccnt & _WDC_REGMASK)((chp->cmd_iot)->read_1((chp->cmd_ioh), (wdr_seccnt & 7))); | |||
7741 | sn = bus_space_read_1(chp->cmd_iot,((chp->cmd_iot)->read_1((chp->cmd_ioh), (wdr_sector & 7))) | |||
7742 | chp->cmd_ioh, wdr_sector & _WDC_REGMASK)((chp->cmd_iot)->read_1((chp->cmd_ioh), (wdr_sector & 7))); | |||
7743 | cl = bus_space_read_1(chp->cmd_iot,((chp->cmd_iot)->read_1((chp->cmd_ioh), (wdr_cyl_lo & 7))) | |||
7744 | chp->cmd_ioh, wdr_cyl_lo & _WDC_REGMASK)((chp->cmd_iot)->read_1((chp->cmd_ioh), (wdr_cyl_lo & 7))); | |||
7745 | ch = bus_space_read_1(chp->cmd_iot,((chp->cmd_iot)->read_1((chp->cmd_ioh), (wdr_cyl_hi & 7))) | |||
7746 | chp->cmd_ioh, wdr_cyl_hi & _WDC_REGMASK)((chp->cmd_iot)->read_1((chp->cmd_ioh), (wdr_cyl_hi & 7))); | |||
7747 | } | |||
7748 | #if 0 | |||
7749 | printf("%s: port %d: scnt=0x%x sn=0x%x cl=0x%x ch=0x%x\n", | |||
7750 | sc->sc_wdcdev.sc_dev.dv_xname, chp->channel, | |||
7751 | scnt, sn, cl, ch); | |||
7752 | #endif | |||
7753 | /* | |||
7754 | * scnt and sn are supposed to be 0x1 for ATAPI, but in some | |||
7755 | * cases we get wrong values here, so ignore it. | |||
7756 | */ | |||
7757 | s = splbio()splraise(0x3); | |||
7758 | if (cl == 0x14 && ch == 0xeb) | |||
7759 | chp->ch_drive[0].drive_flags |= DRIVE_ATAPI0x0002; | |||
7760 | else | |||
7761 | chp->ch_drive[0].drive_flags |= DRIVE_ATA0x0001; | |||
7762 | splx(s)spllower(s); | |||
7763 | ||||
7764 | printf("%s: port %d", | |||
7765 | sc->sc_wdcdev.sc_dev.dv_xname, chp->channel); | |||
7766 | switch ((sstatus & SStatus_SPD_mask(0xf << 4)) >> SStatus_SPD_shift4) { | |||
7767 | case 1: | |||
7768 | printf(": 1.5Gb/s"); | |||
7769 | break; | |||
7770 | case 2: | |||
7771 | printf(": 3.0Gb/s"); | |||
7772 | break; | |||
7773 | } | |||
7774 | printf("\n"); | |||
7775 | break; | |||
7776 | ||||
7777 | default: | |||
7778 | printf("%s: port %d: unknown SStatus: 0x%08x\n", | |||
7779 | sc->sc_wdcdev.sc_dev.dv_xname, chp->channel, sstatus); | |||
7780 | } | |||
7781 | } | |||
7782 | ||||
7783 | u_int8_t | |||
7784 | svwsata_read_reg(struct channel_softc *chp, enum wdc_regs reg) | |||
7785 | { | |||
7786 | if (reg & _WDC_AUX8) { | |||
7787 | return (bus_space_read_4(chp->ctl_iot, chp->ctl_ioh,((chp->ctl_iot)->read_4((chp->ctl_ioh), ((reg & 7 ) << 2))) | |||
7788 | (reg & _WDC_REGMASK) << 2)((chp->ctl_iot)->read_4((chp->ctl_ioh), ((reg & 7 ) << 2)))); | |||
7789 | } else { | |||
7790 | return (bus_space_read_4(chp->cmd_iot, chp->cmd_ioh,((chp->cmd_iot)->read_4((chp->cmd_ioh), ((reg & 7 ) << 2))) | |||
7791 | (reg & _WDC_REGMASK) << 2)((chp->cmd_iot)->read_4((chp->cmd_ioh), ((reg & 7 ) << 2)))); | |||
7792 | } | |||
7793 | } | |||
7794 | ||||
7795 | void | |||
7796 | svwsata_write_reg(struct channel_softc *chp, enum wdc_regs reg, u_int8_t val) | |||
7797 | { | |||
7798 | if (reg & _WDC_AUX8) { | |||
7799 | bus_space_write_4(chp->ctl_iot, chp->ctl_ioh,((chp->ctl_iot)->write_4((chp->ctl_ioh), ((reg & 7) << 2), (val))) | |||
7800 | (reg & _WDC_REGMASK) << 2, val)((chp->ctl_iot)->write_4((chp->ctl_ioh), ((reg & 7) << 2), (val))); | |||
7801 | } else { | |||
7802 | bus_space_write_4(chp->cmd_iot, chp->cmd_ioh,((chp->cmd_iot)->write_4((chp->cmd_ioh), ((reg & 7) << 2), (val))) | |||
7803 | (reg & _WDC_REGMASK) << 2, val)((chp->cmd_iot)->write_4((chp->cmd_ioh), ((reg & 7) << 2), (val))); | |||
7804 | } | |||
7805 | } | |||
7806 | ||||
7807 | void | |||
7808 | svwsata_lba48_write_reg(struct channel_softc *chp, enum wdc_regs reg, u_int16_t val) | |||
7809 | { | |||
7810 | if (reg & _WDC_AUX8) { | |||
7811 | bus_space_write_4(chp->ctl_iot, chp->ctl_ioh,((chp->ctl_iot)->write_4((chp->ctl_ioh), ((reg & 7) << 2), (val))) | |||
7812 | (reg & _WDC_REGMASK) << 2, val)((chp->ctl_iot)->write_4((chp->ctl_ioh), ((reg & 7) << 2), (val))); | |||
7813 | } else { | |||
7814 | bus_space_write_4(chp->cmd_iot, chp->cmd_ioh,((chp->cmd_iot)->write_4((chp->cmd_ioh), ((reg & 7) << 2), (val))) | |||
7815 | (reg & _WDC_REGMASK) << 2, val)((chp->cmd_iot)->write_4((chp->cmd_ioh), ((reg & 7) << 2), (val))); | |||
7816 | } | |||
7817 | } | |||
7818 | ||||
7819 | #define ACARD_IS_850(sc)((sc)->sc_pp->ide_product == 0x0005) \ | |||
7820 | ((sc)->sc_pp->ide_product == PCI_PRODUCT_ACARD_ATP850U0x0005) | |||
7821 | ||||
7822 | void | |||
7823 | acard_chip_map(struct pciide_softc *sc, struct pci_attach_args *pa) | |||
7824 | { | |||
7825 | struct pciide_channel *cp; | |||
7826 | int i; | |||
7827 | pcireg_t interface; | |||
7828 | bus_size_t cmdsize, ctlsize; | |||
7829 | ||||
7830 | /* | |||
7831 | * when the chip is in native mode it identifies itself as a | |||
7832 | * 'misc mass storage'. Fake interface in this case. | |||
7833 | */ | |||
7834 | if (PCI_SUBCLASS(pa->pa_class)(((pa->pa_class) >> 16) & 0xff) == PCI_SUBCLASS_MASS_STORAGE_IDE0x01) { | |||
7835 | interface = PCI_INTERFACE(pa->pa_class)(((pa->pa_class) >> 8) & 0xff); | |||
7836 | } else { | |||
7837 | interface = PCIIDE_INTERFACE_BUS_MASTER_DMA0x80 | | |||
7838 | PCIIDE_INTERFACE_PCI(0)(0x01 << (2 * (0))) | PCIIDE_INTERFACE_PCI(1)(0x01 << (2 * (1))); | |||
7839 | } | |||
7840 | ||||
7841 | printf(": DMA"); | |||
7842 | pciide_mapreg_dma(sc, pa); | |||
7843 | printf("\n"); | |||
7844 | sc->sc_wdcdev.cap = WDC_CAPABILITY_DATA160x0001 | WDC_CAPABILITY_DATA320x0002 | | |||
7845 | WDC_CAPABILITY_MODE0x0004; | |||
7846 | ||||
7847 | if (sc->sc_dma_ok) { | |||
7848 | sc->sc_wdcdev.cap |= WDC_CAPABILITY_DMA0x0008 | WDC_CAPABILITY_UDMA0x0010; | |||
7849 | sc->sc_wdcdev.cap |= WDC_CAPABILITY_IRQACK0x0400; | |||
7850 | sc->sc_wdcdev.irqack = pciide_irqack; | |||
7851 | } | |||
7852 | sc->sc_wdcdev.PIO_cap = 4; | |||
7853 | sc->sc_wdcdev.DMA_cap = 2; | |||
7854 | switch (sc->sc_pp->ide_product) { | |||
7855 | case PCI_PRODUCT_ACARD_ATP850U0x0005: | |||
7856 | sc->sc_wdcdev.UDMA_cap = 2; | |||
7857 | break; | |||
7858 | case PCI_PRODUCT_ACARD_ATP8600x0006: | |||
7859 | case PCI_PRODUCT_ACARD_ATP860A0x0007: | |||
7860 | sc->sc_wdcdev.UDMA_cap = 4; | |||
7861 | break; | |||
7862 | case PCI_PRODUCT_ACARD_ATP865A0x0008: | |||
7863 | case PCI_PRODUCT_ACARD_ATP865R0x0009: | |||
7864 | sc->sc_wdcdev.UDMA_cap = 6; | |||
7865 | break; | |||
7866 | } | |||
7867 | ||||
7868 | sc->sc_wdcdev.set_modes = acard_setup_channel; | |||
7869 | sc->sc_wdcdev.channels = sc->wdc_chanarray; | |||
7870 | sc->sc_wdcdev.nchannels = 2; | |||
7871 | ||||
7872 | for (i = 0; i < sc->sc_wdcdev.nchannels; i++) { | |||
7873 | cp = &sc->pciide_channels[i]; | |||
7874 | if (pciide_chansetup(sc, i, interface) == 0) | |||
7875 | continue; | |||
7876 | if (interface & PCIIDE_INTERFACE_PCI(i)(0x01 << (2 * (i)))) { | |||
7877 | cp->hw_ok = pciide_mapregs_native(pa, cp, &cmdsize, | |||
7878 | &ctlsize, pciide_pci_intr); | |||
7879 | } else { | |||
7880 | cp->hw_ok = pciide_mapregs_compat(pa, cp, i, | |||
7881 | &cmdsize, &ctlsize); | |||
7882 | } | |||
7883 | if (cp->hw_ok == 0) | |||
7884 | return; | |||
7885 | cp->wdc_channel.data32iot = cp->wdc_channel.cmd_iot; | |||
7886 | cp->wdc_channel.data32ioh = cp->wdc_channel.cmd_ioh; | |||
7887 | wdcattach(&cp->wdc_channel); | |||
7888 | acard_setup_channel(&cp->wdc_channel); | |||
7889 | } | |||
7890 | if (!ACARD_IS_850(sc)((sc)->sc_pp->ide_product == 0x0005)) { | |||
7891 | u_int32_t reg; | |||
7892 | reg = pci_conf_read(sc->sc_pc, sc->sc_tag, ATP8x0_CTRL0x48); | |||
7893 | reg &= ~ATP860_CTRL_INT0x00010000; | |||
7894 | pci_conf_write(sc->sc_pc, sc->sc_tag, ATP8x0_CTRL0x48, reg); | |||
7895 | } | |||
7896 | } | |||
7897 | ||||
7898 | void | |||
7899 | acard_setup_channel(struct channel_softc *chp) | |||
7900 | { | |||
7901 | struct ata_drive_datas *drvp; | |||
7902 | struct pciide_channel *cp = (struct pciide_channel *)chp; | |||
7903 | struct pciide_softc *sc = (struct pciide_softc *)cp->wdc_channel.wdc; | |||
7904 | int channel = chp->channel; | |||
7905 | int drive; | |||
7906 | u_int32_t idetime, udma_mode; | |||
7907 | u_int32_t idedma_ctl; | |||
7908 | ||||
7909 | /* setup DMA if needed */ | |||
7910 | pciide_channel_dma_setup(cp); | |||
7911 | ||||
7912 | if (ACARD_IS_850(sc)((sc)->sc_pp->ide_product == 0x0005)) { | |||
7913 | idetime = 0; | |||
7914 | udma_mode = pci_conf_read(sc->sc_pc, sc->sc_tag, ATP850_UDMA0x54); | |||
7915 | udma_mode &= ~ATP850_UDMA_MASK(channel)(0xf << ((channel) * 4)); | |||
7916 | } else { | |||
7917 | idetime = pci_conf_read(sc->sc_pc, sc->sc_tag, ATP860_IDETIME0x40); | |||
7918 | idetime &= ~ATP860_SETTIME_MASK(channel)(0xffff << ((channel) * 16)); | |||
7919 | udma_mode = pci_conf_read(sc->sc_pc, sc->sc_tag, ATP860_UDMA0x44); | |||
7920 | udma_mode &= ~ATP860_UDMA_MASK(channel)(0xff << ((channel) * 8)); | |||
7921 | } | |||
7922 | ||||
7923 | idedma_ctl = 0; | |||
7924 | ||||
7925 | /* Per drive settings */ | |||
7926 | for (drive = 0; drive < 2; drive++) { | |||
7927 | drvp = &chp->ch_drive[drive]; | |||
7928 | /* If no drive, skip */ | |||
7929 | if ((drvp->drive_flags & DRIVE(0x0001|0x0002|0x0004)) == 0) | |||
7930 | continue; | |||
7931 | /* add timing values, setup DMA if needed */ | |||
7932 | if ((chp->wdc->cap & WDC_CAPABILITY_UDMA0x0010) && | |||
7933 | (drvp->drive_flags & DRIVE_UDMA0x0020)) { | |||
7934 | /* use Ultra/DMA */ | |||
7935 | if (ACARD_IS_850(sc)((sc)->sc_pp->ide_product == 0x0005)) { | |||
7936 | idetime |= ATP850_SETTIME(drive,(((((acard_act_udma[drvp->UDMA_mode]) & 0xf) << 8 ) | ((acard_rec_udma[drvp->UDMA_mode]) & 0xf)) << ((drive) * 16)) | |||
7937 | acard_act_udma[drvp->UDMA_mode],(((((acard_act_udma[drvp->UDMA_mode]) & 0xf) << 8 ) | ((acard_rec_udma[drvp->UDMA_mode]) & 0xf)) << ((drive) * 16)) | |||
7938 | acard_rec_udma[drvp->UDMA_mode])(((((acard_act_udma[drvp->UDMA_mode]) & 0xf) << 8 ) | ((acard_rec_udma[drvp->UDMA_mode]) & 0xf)) << ((drive) * 16)); | |||
7939 | udma_mode |= ATP850_UDMA_MODE(channel, drive,(((acard_udma_conf[drvp->UDMA_mode]) & 0x3) << ( (channel) * 4 + (drive) * 2)) | |||
7940 | acard_udma_conf[drvp->UDMA_mode])(((acard_udma_conf[drvp->UDMA_mode]) & 0x3) << ( (channel) * 4 + (drive) * 2)); | |||
7941 | } else { | |||
7942 | idetime |= ATP860_SETTIME(channel, drive,(((((acard_act_udma[drvp->UDMA_mode]) & 0xf) << 4 ) | ((acard_rec_udma[drvp->UDMA_mode]) & 0xf)) << ((channel) * 16 + (drive) * 8)) | |||
7943 | acard_act_udma[drvp->UDMA_mode],(((((acard_act_udma[drvp->UDMA_mode]) & 0xf) << 4 ) | ((acard_rec_udma[drvp->UDMA_mode]) & 0xf)) << ((channel) * 16 + (drive) * 8)) | |||
7944 | acard_rec_udma[drvp->UDMA_mode])(((((acard_act_udma[drvp->UDMA_mode]) & 0xf) << 4 ) | ((acard_rec_udma[drvp->UDMA_mode]) & 0xf)) << ((channel) * 16 + (drive) * 8)); | |||
7945 | udma_mode |= ATP860_UDMA_MODE(channel, drive,(((acard_udma_conf[drvp->UDMA_mode]) & 0xf) << ( (channel) * 8 + (drive) * 4)) | |||
7946 | acard_udma_conf[drvp->UDMA_mode])(((acard_udma_conf[drvp->UDMA_mode]) & 0xf) << ( (channel) * 8 + (drive) * 4)); | |||
7947 | } | |||
7948 | idedma_ctl |= IDEDMA_CTL_DRV_DMA(drive)(0x20 << (drive)); | |||
7949 | } else if ((chp->wdc->cap & WDC_CAPABILITY_DMA0x0008) && | |||
7950 | (drvp->drive_flags & DRIVE_DMA0x0010)) { | |||
7951 | /* use Multiword DMA */ | |||
7952 | drvp->drive_flags &= ~DRIVE_UDMA0x0020; | |||
7953 | if (ACARD_IS_850(sc)((sc)->sc_pp->ide_product == 0x0005)) { | |||
7954 | idetime |= ATP850_SETTIME(drive,(((((acard_act_dma[drvp->DMA_mode]) & 0xf) << 8) | ((acard_rec_dma[drvp->DMA_mode]) & 0xf)) << ( (drive) * 16)) | |||
7955 | acard_act_dma[drvp->DMA_mode],(((((acard_act_dma[drvp->DMA_mode]) & 0xf) << 8) | ((acard_rec_dma[drvp->DMA_mode]) & 0xf)) << ( (drive) * 16)) | |||
7956 | acard_rec_dma[drvp->DMA_mode])(((((acard_act_dma[drvp->DMA_mode]) & 0xf) << 8) | ((acard_rec_dma[drvp->DMA_mode]) & 0xf)) << ( (drive) * 16)); | |||
7957 | } else { | |||
7958 | idetime |= ATP860_SETTIME(channel, drive,(((((acard_act_dma[drvp->DMA_mode]) & 0xf) << 4) | ((acard_rec_dma[drvp->DMA_mode]) & 0xf)) << ( (channel) * 16 + (drive) * 8)) | |||
7959 | acard_act_dma[drvp->DMA_mode],(((((acard_act_dma[drvp->DMA_mode]) & 0xf) << 4) | ((acard_rec_dma[drvp->DMA_mode]) & 0xf)) << ( (channel) * 16 + (drive) * 8)) | |||
7960 | acard_rec_dma[drvp->DMA_mode])(((((acard_act_dma[drvp->DMA_mode]) & 0xf) << 4) | ((acard_rec_dma[drvp->DMA_mode]) & 0xf)) << ( (channel) * 16 + (drive) * 8)); | |||
7961 | } | |||
7962 | idedma_ctl |= IDEDMA_CTL_DRV_DMA(drive)(0x20 << (drive)); | |||
7963 | } else { | |||
7964 | /* PIO only */ | |||
7965 | drvp->drive_flags &= ~(DRIVE_UDMA0x0020 | DRIVE_DMA0x0010); | |||
7966 | if (ACARD_IS_850(sc)((sc)->sc_pp->ide_product == 0x0005)) { | |||
7967 | idetime |= ATP850_SETTIME(drive,(((((acard_act_pio[drvp->PIO_mode]) & 0xf) << 8) | ((acard_rec_pio[drvp->PIO_mode]) & 0xf)) << ( (drive) * 16)) | |||
7968 | acard_act_pio[drvp->PIO_mode],(((((acard_act_pio[drvp->PIO_mode]) & 0xf) << 8) | ((acard_rec_pio[drvp->PIO_mode]) & 0xf)) << ( (drive) * 16)) | |||
7969 | acard_rec_pio[drvp->PIO_mode])(((((acard_act_pio[drvp->PIO_mode]) & 0xf) << 8) | ((acard_rec_pio[drvp->PIO_mode]) & 0xf)) << ( (drive) * 16)); | |||
7970 | } else { | |||
7971 | idetime |= ATP860_SETTIME(channel, drive,(((((acard_act_pio[drvp->PIO_mode]) & 0xf) << 4) | ((acard_rec_pio[drvp->PIO_mode]) & 0xf)) << ( (channel) * 16 + (drive) * 8)) | |||
7972 | acard_act_pio[drvp->PIO_mode],(((((acard_act_pio[drvp->PIO_mode]) & 0xf) << 4) | ((acard_rec_pio[drvp->PIO_mode]) & 0xf)) << ( (channel) * 16 + (drive) * 8)) | |||
7973 | acard_rec_pio[drvp->PIO_mode])(((((acard_act_pio[drvp->PIO_mode]) & 0xf) << 4) | ((acard_rec_pio[drvp->PIO_mode]) & 0xf)) << ( (channel) * 16 + (drive) * 8)); | |||
7974 | } | |||
7975 | pci_conf_write(sc->sc_pc, sc->sc_tag, ATP8x0_CTRL0x48, | |||
7976 | pci_conf_read(sc->sc_pc, sc->sc_tag, ATP8x0_CTRL0x48) | |||
7977 | | ATP8x0_CTRL_EN(channel)(0x00020000 << (channel))); | |||
7978 | } | |||
7979 | } | |||
7980 | ||||
7981 | if (idedma_ctl != 0) { | |||
7982 | /* Add software bits in status register */ | |||
7983 | bus_space_write_1(sc->sc_dma_iot, sc->sc_dma_ioh,((sc->sc_dma_iot)->write_1((sc->sc_dma_ioh), ((0x02 + 0x08 * (channel))), (idedma_ctl))) | |||
7984 | IDEDMA_CTL(channel), idedma_ctl)((sc->sc_dma_iot)->write_1((sc->sc_dma_ioh), ((0x02 + 0x08 * (channel))), (idedma_ctl))); | |||
7985 | } | |||
7986 | pciide_print_modes(cp); | |||
7987 | ||||
7988 | if (ACARD_IS_850(sc)((sc)->sc_pp->ide_product == 0x0005)) { | |||
7989 | pci_conf_write(sc->sc_pc, sc->sc_tag, | |||
7990 | ATP850_IDETIME(channel)(0x40 + (channel) * 4), idetime); | |||
7991 | pci_conf_write(sc->sc_pc, sc->sc_tag, ATP850_UDMA0x54, udma_mode); | |||
7992 | } else { | |||
7993 | pci_conf_write(sc->sc_pc, sc->sc_tag, ATP860_IDETIME0x40, idetime); | |||
7994 | pci_conf_write(sc->sc_pc, sc->sc_tag, ATP860_UDMA0x44, udma_mode); | |||
7995 | } | |||
7996 | } | |||
7997 | ||||
7998 | void | |||
7999 | nforce_chip_map(struct pciide_softc *sc, struct pci_attach_args *pa) | |||
8000 | { | |||
8001 | struct pciide_channel *cp; | |||
8002 | int channel; | |||
8003 | pcireg_t interface = PCI_INTERFACE(pa->pa_class)(((pa->pa_class) >> 8) & 0xff); | |||
8004 | bus_size_t cmdsize, ctlsize; | |||
8005 | u_int32_t conf; | |||
8006 | ||||
8007 | conf = pci_conf_read(sc->sc_pc, sc->sc_tag, NFORCE_CONF0x50); | |||
8008 | WDCDEBUG_PRINT(("%s: conf register 0x%x\n", | |||
8009 | sc->sc_wdcdev.sc_dev.dv_xname, conf), DEBUG_PROBE); | |||
8010 | ||||
8011 | printf(": DMA"); | |||
8012 | pciide_mapreg_dma(sc, pa); | |||
8013 | ||||
8014 | sc->sc_wdcdev.cap = WDC_CAPABILITY_DATA160x0001 | WDC_CAPABILITY_DATA320x0002 | | |||
8015 | WDC_CAPABILITY_MODE0x0004; | |||
8016 | if (sc->sc_dma_ok
| |||
| ||||
8017 | sc->sc_wdcdev.cap |= WDC_CAPABILITY_DMA0x0008 | WDC_CAPABILITY_UDMA0x0010; | |||
8018 | sc->sc_wdcdev.cap |= WDC_CAPABILITY_IRQACK0x0400; | |||
8019 | sc->sc_wdcdev.irqack = pciide_irqack; | |||
8020 | } | |||
8021 | sc->sc_wdcdev.PIO_cap = 4; | |||
8022 | sc->sc_wdcdev.DMA_cap = 2; | |||
8023 | switch (sc->sc_pp->ide_product) { | |||
8024 | case PCI_PRODUCT_NVIDIA_NFORCE_IDE0x01bc: | |||
8025 | sc->sc_wdcdev.UDMA_cap = 5; | |||
8026 | break; | |||
8027 | default: | |||
8028 | sc->sc_wdcdev.UDMA_cap = 6; | |||
8029 | } | |||
8030 | sc->sc_wdcdev.set_modes = nforce_setup_channel; | |||
8031 | sc->sc_wdcdev.channels = sc->wdc_chanarray; | |||
8032 | sc->sc_wdcdev.nchannels = PCIIDE_NUM_CHANNELS2; | |||
8033 | ||||
8034 | pciide_print_channels(sc->sc_wdcdev.nchannels, interface); | |||
8035 | ||||
8036 | for (channel = 0; channel < sc->sc_wdcdev.nchannels; channel++) { | |||
8037 | cp = &sc->pciide_channels[channel]; | |||
8038 | ||||
8039 | if (pciide_chansetup(sc, channel, interface) == 0) | |||
8040 | continue; | |||
8041 | ||||
8042 | if ((conf & NFORCE_CHAN_EN(channel)(0x00000001 << (1 - (channel)))) == 0) { | |||
| ||||
8043 | printf("%s: %s ignored (disabled)\n", | |||
8044 | sc->sc_wdcdev.sc_dev.dv_xname, cp->name); | |||
8045 | cp->hw_ok = 0; | |||
8046 | continue; | |||
8047 | } | |||
8048 | ||||
8049 | pciide_map_compat_intr(pa, cp, channel, interface); | |||
8050 | if (cp->hw_ok == 0) | |||
8051 | continue; | |||
8052 | pciide_mapchan(pa, cp, interface, &cmdsize, &ctlsize, | |||
8053 | nforce_pci_intr); | |||
8054 | if (cp->hw_ok == 0) { | |||
8055 | pciide_unmap_compat_intr(pa, cp, channel, interface); | |||
8056 | continue; | |||
8057 | } | |||
8058 | ||||
8059 | if (pciide_chan_candisable(cp)) { | |||
8060 | conf &= ~NFORCE_CHAN_EN(channel)(0x00000001 << (1 - (channel))); | |||
8061 | pciide_unmap_compat_intr(pa, cp, channel, interface); | |||
8062 | continue; | |||
8063 | } | |||
8064 | ||||
8065 | sc->sc_wdcdev.set_modes(&cp->wdc_channel); | |||
8066 | } | |||
8067 | WDCDEBUG_PRINT(("%s: new conf register 0x%x\n", | |||
8068 | sc->sc_wdcdev.sc_dev.dv_xname, conf), DEBUG_PROBE); | |||
8069 | pci_conf_write(sc->sc_pc, sc->sc_tag, NFORCE_CONF0x50, conf); | |||
8070 | } | |||
8071 | ||||
8072 | void | |||
8073 | nforce_setup_channel(struct channel_softc *chp) | |||
8074 | { | |||
8075 | struct ata_drive_datas *drvp; | |||
8076 | int drive, mode; | |||
8077 | u_int32_t idedma_ctl; | |||
8078 | struct pciide_channel *cp = (struct pciide_channel *)chp; | |||
8079 | struct pciide_softc *sc = (struct pciide_softc *)cp->wdc_channel.wdc; | |||
8080 | int channel = chp->channel; | |||
8081 | u_int32_t conf, piodmatim, piotim, udmatim; | |||
8082 | ||||
8083 | conf = pci_conf_read(sc->sc_pc, sc->sc_tag, NFORCE_CONF0x50); | |||
8084 | piodmatim = pci_conf_read(sc->sc_pc, sc->sc_tag, NFORCE_PIODMATIM0x58); | |||
8085 | piotim = pci_conf_read(sc->sc_pc, sc->sc_tag, NFORCE_PIOTIM0x5c); | |||
8086 | udmatim = pci_conf_read(sc->sc_pc, sc->sc_tag, NFORCE_UDMATIM0x60); | |||
8087 | WDCDEBUG_PRINT(("%s: %s old timing values: piodmatim=0x%x, " | |||
8088 | "piotim=0x%x, udmatim=0x%x\n", sc->sc_wdcdev.sc_dev.dv_xname, | |||
8089 | cp->name, piodmatim, piotim, udmatim), DEBUG_PROBE); | |||
8090 | ||||
8091 | /* Setup DMA if needed */ | |||
8092 | pciide_channel_dma_setup(cp); | |||
8093 | ||||
8094 | /* Clear all bits for this channel */ | |||
8095 | idedma_ctl = 0; | |||
8096 | piodmatim &= ~NFORCE_PIODMATIM_MASK(channel)(0xffff << ((1 - (channel)) * 16)); | |||
8097 | udmatim &= ~NFORCE_UDMATIM_MASK(channel)(0xffff << ((1 - (channel)) * 16)); | |||
8098 | ||||
8099 | /* Per channel settings */ | |||
8100 | for (drive = 0; drive < 2; drive++) { | |||
8101 | drvp = &chp->ch_drive[drive]; | |||
8102 | ||||
8103 | /* If no drive, skip */ | |||
8104 | if ((drvp->drive_flags & DRIVE(0x0001|0x0002|0x0004)) == 0) | |||
8105 | continue; | |||
8106 | ||||
8107 | if ((chp->wdc->cap & WDC_CAPABILITY_UDMA0x0010) != 0 && | |||
8108 | (drvp->drive_flags & DRIVE_UDMA0x0020) != 0) { | |||
8109 | /* Setup UltraDMA mode */ | |||
8110 | drvp->drive_flags &= ~DRIVE_DMA0x0010; | |||
8111 | ||||
8112 | udmatim |= NFORCE_UDMATIM_SET(channel, drive,((nforce_udma[drvp->UDMA_mode]) << ((3 - ((channel) * 2 + (drive))) * 8)) | |||
8113 | nforce_udma[drvp->UDMA_mode])((nforce_udma[drvp->UDMA_mode]) << ((3 - ((channel) * 2 + (drive))) * 8)) | | |||
8114 | NFORCE_UDMA_EN(channel, drive)(0x40 << ((3 - ((channel) * 2 + (drive))) * 8)) | | |||
8115 | NFORCE_UDMA_ENM(channel, drive)(0x80 << ((3 - ((channel) * 2 + (drive))) * 8)); | |||
8116 | ||||
8117 | mode = drvp->PIO_mode; | |||
8118 | } else if ((chp->wdc->cap & WDC_CAPABILITY_DMA0x0008) != 0 && | |||
8119 | (drvp->drive_flags & DRIVE_DMA0x0010) != 0) { | |||
8120 | /* Setup multiword DMA mode */ | |||
8121 | drvp->drive_flags &= ~DRIVE_UDMA0x0020; | |||
8122 | ||||
8123 | /* mode = min(pio, dma + 2) */ | |||
8124 | if (drvp->PIO_mode <= (drvp->DMA_mode + 2)) | |||
8125 | mode = drvp->PIO_mode; | |||
8126 | else | |||
8127 | mode = drvp->DMA_mode + 2; | |||
8128 | } else { | |||
8129 | mode = drvp->PIO_mode; | |||
8130 | goto pio; | |||
8131 | } | |||
8132 | idedma_ctl |= IDEDMA_CTL_DRV_DMA(drive)(0x20 << (drive)); | |||
8133 | ||||
8134 | pio: | |||
8135 | /* Setup PIO mode */ | |||
8136 | if (mode <= 2) { | |||
8137 | drvp->DMA_mode = 0; | |||
8138 | drvp->PIO_mode = 0; | |||
8139 | mode = 0; | |||
8140 | } else { | |||
8141 | drvp->PIO_mode = mode; | |||
8142 | drvp->DMA_mode = mode - 2; | |||
8143 | } | |||
8144 | piodmatim |= NFORCE_PIODMATIM_SET(channel, drive,((nforce_pio[mode]) << ((3 - ((channel) * 2 + (drive))) * 8)) | |||
8145 | nforce_pio[mode])((nforce_pio[mode]) << ((3 - ((channel) * 2 + (drive))) * 8)); | |||
8146 | } | |||
8147 | ||||
8148 | if (idedma_ctl != 0) { | |||
8149 | /* Add software bits in status register */ | |||
8150 | bus_space_write_1(sc->sc_dma_iot, sc->sc_dma_ioh,((sc->sc_dma_iot)->write_1((sc->sc_dma_ioh), ((0x02 + 0x08 * (channel))), (idedma_ctl))) | |||
8151 | IDEDMA_CTL(channel), idedma_ctl)((sc->sc_dma_iot)->write_1((sc->sc_dma_ioh), ((0x02 + 0x08 * (channel))), (idedma_ctl))); | |||
8152 | } | |||
8153 | ||||
8154 | WDCDEBUG_PRINT(("%s: %s new timing values: piodmatim=0x%x, " | |||
8155 | "piotim=0x%x, udmatim=0x%x\n", sc->sc_wdcdev.sc_dev.dv_xname, | |||
8156 | cp->name, piodmatim, piotim, udmatim), DEBUG_PROBE); | |||
8157 | pci_conf_write(sc->sc_pc, sc->sc_tag, NFORCE_PIODMATIM0x58, piodmatim); | |||
8158 | pci_conf_write(sc->sc_pc, sc->sc_tag, NFORCE_UDMATIM0x60, udmatim); | |||
8159 | ||||
8160 | pciide_print_modes(cp); | |||
8161 | } | |||
8162 | ||||
8163 | int | |||
8164 | nforce_pci_intr(void *arg) | |||
8165 | { | |||
8166 | struct pciide_softc *sc = arg; | |||
8167 | struct pciide_channel *cp; | |||
8168 | struct channel_softc *wdc_cp; | |||
8169 | int i, rv, crv; | |||
8170 | u_int32_t dmastat; | |||
8171 | ||||
8172 | rv = 0; | |||
8173 | for (i = 0; i < sc->sc_wdcdev.nchannels; i++) { | |||
8174 | cp = &sc->pciide_channels[i]; | |||
8175 | wdc_cp = &cp->wdc_channel; | |||
8176 | ||||
8177 | /* Skip compat channel */ | |||
8178 | if (cp->compat) | |||
8179 | continue; | |||
8180 | ||||
8181 | dmastat = bus_space_read_1(sc->sc_dma_iot, sc->sc_dma_ioh,((sc->sc_dma_iot)->read_1((sc->sc_dma_ioh), ((0x02 + 0x08 * (i))))) | |||
8182 | IDEDMA_CTL(i))((sc->sc_dma_iot)->read_1((sc->sc_dma_ioh), ((0x02 + 0x08 * (i))))); | |||
8183 | if ((dmastat & IDEDMA_CTL_INTR0x04) == 0) | |||
8184 | continue; | |||
8185 | ||||
8186 | crv = wdcintr(wdc_cp); | |||
8187 | if (crv == 0) | |||
8188 | printf("%s:%d: bogus intr\n", | |||
8189 | sc->sc_wdcdev.sc_dev.dv_xname, i); | |||
8190 | else | |||
8191 | rv = 1; | |||
8192 | } | |||
8193 | return (rv); | |||
8194 | } | |||
8195 | ||||
8196 | void | |||
8197 | artisea_chip_map(struct pciide_softc *sc, struct pci_attach_args *pa) | |||
8198 | { | |||
8199 | struct pciide_channel *cp; | |||
8200 | bus_size_t cmdsize, ctlsize; | |||
8201 | pcireg_t interface; | |||
8202 | int channel; | |||
8203 | ||||
8204 | printf(": DMA"); | |||
8205 | #ifdef PCIIDE_I31244_DISABLEDMA | |||
8206 | if (sc->sc_rev == 0) { | |||
8207 | printf(" disabled due to rev. 0"); | |||
8208 | sc->sc_dma_ok = 0; | |||
8209 | } else | |||
8210 | #endif | |||
8211 | pciide_mapreg_dma(sc, pa); | |||
8212 | printf("\n"); | |||
8213 | ||||
8214 | /* | |||
8215 | * XXX Configure LEDs to show activity. | |||
8216 | */ | |||
8217 | ||||
8218 | sc->sc_wdcdev.cap |= WDC_CAPABILITY_DATA160x0001 | WDC_CAPABILITY_DATA320x0002 | | |||
8219 | WDC_CAPABILITY_MODE0x0004 | WDC_CAPABILITY_SATA0x2000; | |||
8220 | sc->sc_wdcdev.PIO_cap = 4; | |||
8221 | if (sc->sc_dma_ok) { | |||
8222 | sc->sc_wdcdev.cap |= WDC_CAPABILITY_DMA0x0008 | WDC_CAPABILITY_UDMA0x0010; | |||
8223 | sc->sc_wdcdev.cap |= WDC_CAPABILITY_IRQACK0x0400; | |||
8224 | sc->sc_wdcdev.irqack = pciide_irqack; | |||
8225 | sc->sc_wdcdev.DMA_cap = 2; | |||
8226 | sc->sc_wdcdev.UDMA_cap = 6; | |||
8227 | } | |||
8228 | sc->sc_wdcdev.set_modes = sata_setup_channel; | |||
8229 | ||||
8230 | sc->sc_wdcdev.channels = sc->wdc_chanarray; | |||
8231 | sc->sc_wdcdev.nchannels = PCIIDE_NUM_CHANNELS2; | |||
8232 | ||||
8233 | interface = PCI_INTERFACE(pa->pa_class)(((pa->pa_class) >> 8) & 0xff); | |||
8234 | ||||
8235 | for (channel = 0; channel < sc->sc_wdcdev.nchannels; channel++) { | |||
8236 | cp = &sc->pciide_channels[channel]; | |||
8237 | if (pciide_chansetup(sc, channel, interface) == 0) | |||
8238 | continue; | |||
8239 | pciide_mapchan(pa, cp, interface, &cmdsize, &ctlsize, | |||
8240 | pciide_pci_intr); | |||
8241 | if (cp->hw_ok == 0) | |||
8242 | continue; | |||
8243 | pciide_map_compat_intr(pa, cp, channel, interface); | |||
8244 | sata_setup_channel(&cp->wdc_channel); | |||
8245 | } | |||
8246 | } | |||
8247 | ||||
8248 | void | |||
8249 | ite_chip_map(struct pciide_softc *sc, struct pci_attach_args *pa) | |||
8250 | { | |||
8251 | struct pciide_channel *cp; | |||
8252 | int channel; | |||
8253 | pcireg_t interface; | |||
8254 | bus_size_t cmdsize, ctlsize; | |||
8255 | pcireg_t cfg, modectl; | |||
8256 | ||||
8257 | /* | |||
8258 | * Fake interface since IT8212F is claimed to be a ``RAID'' device. | |||
8259 | */ | |||
8260 | interface = PCIIDE_INTERFACE_BUS_MASTER_DMA0x80 | | |||
8261 | PCIIDE_INTERFACE_PCI(0)(0x01 << (2 * (0))) | PCIIDE_INTERFACE_PCI(1)(0x01 << (2 * (1))); | |||
8262 | ||||
8263 | cfg = pci_conf_read(sc->sc_pc, sc->sc_tag, IT_CFG0x40); | |||
8264 | modectl = pci_conf_read(sc->sc_pc, sc->sc_tag, IT_MODE0x50); | |||
8265 | WDCDEBUG_PRINT(("%s: cfg=0x%x, modectl=0x%x\n", | |||
8266 | sc->sc_wdcdev.sc_dev.dv_xname, cfg & IT_CFG_MASK, | |||
8267 | modectl & IT_MODE_MASK), DEBUG_PROBE); | |||
8268 | ||||
8269 | printf(": DMA"); | |||
8270 | pciide_mapreg_dma(sc, pa); | |||
8271 | ||||
8272 | sc->sc_wdcdev.cap = WDC_CAPABILITY_DATA160x0001 | WDC_CAPABILITY_DATA320x0002 | | |||
8273 | WDC_CAPABILITY_MODE0x0004; | |||
8274 | if (sc->sc_dma_ok) { | |||
8275 | sc->sc_wdcdev.cap |= WDC_CAPABILITY_DMA0x0008 | WDC_CAPABILITY_UDMA0x0010; | |||
8276 | sc->sc_wdcdev.cap |= WDC_CAPABILITY_IRQACK0x0400; | |||
8277 | sc->sc_wdcdev.irqack = pciide_irqack; | |||
8278 | } | |||
8279 | sc->sc_wdcdev.PIO_cap = 4; | |||
8280 | sc->sc_wdcdev.DMA_cap = 2; | |||
8281 | sc->sc_wdcdev.UDMA_cap = 6; | |||
8282 | ||||
8283 | sc->sc_wdcdev.set_modes = ite_setup_channel; | |||
8284 | sc->sc_wdcdev.channels = sc->wdc_chanarray; | |||
8285 | sc->sc_wdcdev.nchannels = PCIIDE_NUM_CHANNELS2; | |||
8286 | ||||
8287 | pciide_print_channels(sc->sc_wdcdev.nchannels, interface); | |||
8288 | ||||
8289 | /* Disable RAID */ | |||
8290 | modectl &= ~IT_MODE_RAID10x0100; | |||
8291 | /* Disable CPU firmware mode */ | |||
8292 | modectl &= ~IT_MODE_CPU0x0001; | |||
8293 | ||||
8294 | pci_conf_write(sc->sc_pc, sc->sc_tag, IT_MODE0x50, modectl); | |||
8295 | ||||
8296 | for (channel = 0; channel < sc->sc_wdcdev.nchannels; channel++) { | |||
8297 | cp = &sc->pciide_channels[channel]; | |||
8298 | ||||
8299 | if (pciide_chansetup(sc, channel, interface) == 0) | |||
8300 | continue; | |||
8301 | pciide_mapchan(pa, cp, interface, &cmdsize, &ctlsize, | |||
8302 | pciide_pci_intr); | |||
8303 | sc->sc_wdcdev.set_modes(&cp->wdc_channel); | |||
8304 | } | |||
8305 | ||||
8306 | /* Re-read configuration registers after channels setup */ | |||
8307 | cfg = pci_conf_read(sc->sc_pc, sc->sc_tag, IT_CFG0x40); | |||
8308 | modectl = pci_conf_read(sc->sc_pc, sc->sc_tag, IT_MODE0x50); | |||
8309 | WDCDEBUG_PRINT(("%s: cfg=0x%x, modectl=0x%x\n", | |||
8310 | sc->sc_wdcdev.sc_dev.dv_xname, cfg & IT_CFG_MASK, | |||
8311 | modectl & IT_MODE_MASK), DEBUG_PROBE); | |||
8312 | } | |||
8313 | ||||
8314 | void | |||
8315 | ite_setup_channel(struct channel_softc *chp) | |||
8316 | { | |||
8317 | struct ata_drive_datas *drvp; | |||
8318 | int drive, mode; | |||
8319 | u_int32_t idedma_ctl; | |||
8320 | struct pciide_channel *cp = (struct pciide_channel *)chp; | |||
8321 | struct pciide_softc *sc = (struct pciide_softc *)cp->wdc_channel.wdc; | |||
8322 | int channel = chp->channel; | |||
8323 | pcireg_t cfg, modectl; | |||
8324 | pcireg_t tim; | |||
8325 | ||||
8326 | cfg = pci_conf_read(sc->sc_pc, sc->sc_tag, IT_CFG0x40); | |||
8327 | modectl = pci_conf_read(sc->sc_pc, sc->sc_tag, IT_MODE0x50); | |||
8328 | tim = pci_conf_read(sc->sc_pc, sc->sc_tag, IT_TIM(channel)((channel) ? 0x58 : 0x54)); | |||
8329 | WDCDEBUG_PRINT(("%s:%d: tim=0x%x\n", sc->sc_wdcdev.sc_dev.dv_xname, | |||
8330 | channel, tim), DEBUG_PROBE); | |||
8331 | ||||
8332 | /* Setup DMA if needed */ | |||
8333 | pciide_channel_dma_setup(cp); | |||
8334 | ||||
8335 | /* Clear all bits for this channel */ | |||
8336 | idedma_ctl = 0; | |||
8337 | ||||
8338 | /* Per channel settings */ | |||
8339 | for (drive = 0; drive < 2; drive++) { | |||
8340 | drvp = &chp->ch_drive[drive]; | |||
8341 | ||||
8342 | /* If no drive, skip */ | |||
8343 | if ((drvp->drive_flags & DRIVE(0x0001|0x0002|0x0004)) == 0) | |||
8344 | continue; | |||
8345 | ||||
8346 | if ((chp->wdc->cap & WDC_CAPABILITY_UDMA0x0010) != 0 && | |||
8347 | (drvp->drive_flags & DRIVE_UDMA0x0020) != 0) { | |||
8348 | /* Setup UltraDMA mode */ | |||
8349 | drvp->drive_flags &= ~DRIVE_DMA0x0010; | |||
8350 | modectl &= ~IT_MODE_DMA(channel, drive)(0x0008 << ((channel) * 2 + (drive))); | |||
8351 | ||||
8352 | #if 0 | |||
8353 | /* Check cable, works only in CPU firmware mode */ | |||
8354 | if (drvp->UDMA_mode > 2 && | |||
8355 | (cfg & IT_CFG_CABLE(channel, drive)(0x0010 << ((channel) * 2 + (drive)))) == 0) { | |||
8356 | WDCDEBUG_PRINT(("%s(%s:%d:%d): " | |||
8357 | "80-wire cable not detected\n", | |||
8358 | drvp->drive_name, | |||
8359 | sc->sc_wdcdev.sc_dev.dv_xname, | |||
8360 | channel, drive), DEBUG_PROBE); | |||
8361 | drvp->UDMA_mode = 2; | |||
8362 | } | |||
8363 | #endif | |||
8364 | ||||
8365 | if (drvp->UDMA_mode >= 5) | |||
8366 | tim |= IT_TIM_UDMA5(drive)(0x00800000 << (drive) * 8); | |||
8367 | else | |||
8368 | tim &= ~IT_TIM_UDMA5(drive)(0x00800000 << (drive) * 8); | |||
8369 | ||||
8370 | mode = drvp->PIO_mode; | |||
8371 | } else if ((chp->wdc->cap & WDC_CAPABILITY_DMA0x0008) != 0 && | |||
8372 | (drvp->drive_flags & DRIVE_DMA0x0010) != 0) { | |||
8373 | /* Setup multiword DMA mode */ | |||
8374 | drvp->drive_flags &= ~DRIVE_UDMA0x0020; | |||
8375 | modectl |= IT_MODE_DMA(channel, drive)(0x0008 << ((channel) * 2 + (drive))); | |||
8376 | ||||
8377 | /* mode = min(pio, dma + 2) */ | |||
8378 | if (drvp->PIO_mode <= (drvp->DMA_mode + 2)) | |||
8379 | mode = drvp->PIO_mode; | |||
8380 | else | |||
8381 | mode = drvp->DMA_mode + 2; | |||
8382 | } else { | |||
8383 | mode = drvp->PIO_mode; | |||
8384 | goto pio; | |||
8385 | } | |||
8386 | idedma_ctl |= IDEDMA_CTL_DRV_DMA(drive)(0x20 << (drive)); | |||
8387 | ||||
8388 | pio: | |||
8389 | /* Setup PIO mode */ | |||
8390 | if (mode <= 2) { | |||
8391 | drvp->DMA_mode = 0; | |||
8392 | drvp->PIO_mode = 0; | |||
8393 | mode = 0; | |||
8394 | } else { | |||
8395 | drvp->PIO_mode = mode; | |||
8396 | drvp->DMA_mode = mode - 2; | |||
8397 | } | |||
8398 | ||||
8399 | /* Enable IORDY if PIO mode >= 3 */ | |||
8400 | if (drvp->PIO_mode >= 3) | |||
8401 | cfg |= IT_CFG_IORDY(channel)(0x0001 << (channel)); | |||
8402 | } | |||
8403 | ||||
8404 | WDCDEBUG_PRINT(("%s: tim=0x%x\n", sc->sc_wdcdev.sc_dev.dv_xname, | |||
8405 | tim), DEBUG_PROBE); | |||
8406 | ||||
8407 | pci_conf_write(sc->sc_pc, sc->sc_tag, IT_CFG0x40, cfg); | |||
8408 | pci_conf_write(sc->sc_pc, sc->sc_tag, IT_MODE0x50, modectl); | |||
8409 | pci_conf_write(sc->sc_pc, sc->sc_tag, IT_TIM(channel)((channel) ? 0x58 : 0x54), tim); | |||
8410 | ||||
8411 | if (idedma_ctl != 0) { | |||
8412 | /* Add software bits in status register */ | |||
8413 | bus_space_write_1(sc->sc_dma_iot, sc->sc_dma_ioh,((sc->sc_dma_iot)->write_1((sc->sc_dma_ioh), ((0x02 + 0x08 * (channel))), (idedma_ctl))) | |||
8414 | IDEDMA_CTL(channel), idedma_ctl)((sc->sc_dma_iot)->write_1((sc->sc_dma_ioh), ((0x02 + 0x08 * (channel))), (idedma_ctl))); | |||
8415 | } | |||
8416 | ||||
8417 | pciide_print_modes(cp); | |||
8418 | } | |||
8419 | ||||
8420 | void | |||
8421 | ixp_chip_map(struct pciide_softc *sc, struct pci_attach_args *pa) | |||
8422 | { | |||
8423 | struct pciide_channel *cp; | |||
8424 | int channel; | |||
8425 | pcireg_t interface = PCI_INTERFACE(pa->pa_class)(((pa->pa_class) >> 8) & 0xff); | |||
8426 | bus_size_t cmdsize, ctlsize; | |||
8427 | ||||
8428 | printf(": DMA"); | |||
8429 | pciide_mapreg_dma(sc, pa); | |||
8430 | ||||
8431 | sc->sc_wdcdev.cap = WDC_CAPABILITY_DATA160x0001 | WDC_CAPABILITY_DATA320x0002 | | |||
8432 | WDC_CAPABILITY_MODE0x0004; | |||
8433 | if (sc->sc_dma_ok) { | |||
8434 | sc->sc_wdcdev.cap |= WDC_CAPABILITY_DMA0x0008 | WDC_CAPABILITY_UDMA0x0010; | |||
8435 | sc->sc_wdcdev.cap |= WDC_CAPABILITY_IRQACK0x0400; | |||
8436 | sc->sc_wdcdev.irqack = pciide_irqack; | |||
8437 | } | |||
8438 | sc->sc_wdcdev.PIO_cap = 4; | |||
8439 | sc->sc_wdcdev.DMA_cap = 2; | |||
8440 | sc->sc_wdcdev.UDMA_cap = 6; | |||
8441 | ||||
8442 | sc->sc_wdcdev.set_modes = ixp_setup_channel; | |||
8443 | sc->sc_wdcdev.channels = sc->wdc_chanarray; | |||
8444 | sc->sc_wdcdev.nchannels = PCIIDE_NUM_CHANNELS2; | |||
8445 | ||||
8446 | pciide_print_channels(sc->sc_wdcdev.nchannels, interface); | |||
8447 | ||||
8448 | for (channel = 0; channel < sc->sc_wdcdev.nchannels; channel++) { | |||
8449 | cp = &sc->pciide_channels[channel]; | |||
8450 | if (pciide_chansetup(sc, channel, interface) == 0) | |||
8451 | continue; | |||
8452 | pciide_map_compat_intr(pa, cp, channel, interface); | |||
8453 | if (cp->hw_ok == 0) | |||
8454 | continue; | |||
8455 | pciide_mapchan(pa, cp, interface, &cmdsize, &ctlsize, | |||
8456 | pciide_pci_intr); | |||
8457 | if (cp->hw_ok == 0) { | |||
8458 | pciide_unmap_compat_intr(pa, cp, channel, interface); | |||
8459 | continue; | |||
8460 | } | |||
8461 | sc->sc_wdcdev.set_modes(&cp->wdc_channel); | |||
8462 | } | |||
8463 | } | |||
8464 | ||||
8465 | void | |||
8466 | ixp_setup_channel(struct channel_softc *chp) | |||
8467 | { | |||
8468 | struct ata_drive_datas *drvp; | |||
8469 | int drive, mode; | |||
8470 | u_int32_t idedma_ctl; | |||
8471 | struct pciide_channel *cp = (struct pciide_channel*)chp; | |||
8472 | struct pciide_softc *sc = (struct pciide_softc *)cp->wdc_channel.wdc; | |||
8473 | int channel = chp->channel; | |||
8474 | pcireg_t udma, mdma_timing, pio, pio_timing; | |||
8475 | ||||
8476 | pio_timing = pci_conf_read(sc->sc_pc, sc->sc_tag, IXP_PIO_TIMING0x40); | |||
8477 | pio = pci_conf_read(sc->sc_pc, sc->sc_tag, IXP_PIO_CTL0x48); | |||
8478 | mdma_timing = pci_conf_read(sc->sc_pc, sc->sc_tag, IXP_MDMA_TIMING0x44); | |||
8479 | udma = pci_conf_read(sc->sc_pc, sc->sc_tag, IXP_UDMA_CTL0x54); | |||
8480 | ||||
8481 | /* Setup DMA if needed */ | |||
8482 | pciide_channel_dma_setup(cp); | |||
8483 | ||||
8484 | idedma_ctl = 0; | |||
8485 | ||||
8486 | /* Per channel settings */ | |||
8487 | for (drive = 0; drive < 2; drive++) { | |||
8488 | drvp = &chp->ch_drive[drive]; | |||
8489 | ||||
8490 | /* If no drive, skip */ | |||
8491 | if ((drvp->drive_flags & DRIVE(0x0001|0x0002|0x0004)) == 0) | |||
8492 | continue; | |||
8493 | if ((chp->wdc->cap & WDC_CAPABILITY_UDMA0x0010) != 0 && | |||
8494 | (drvp->drive_flags & DRIVE_UDMA0x0020) != 0) { | |||
8495 | /* Setup UltraDMA mode */ | |||
8496 | idedma_ctl |= IDEDMA_CTL_DRV_DMA(drive)(0x20 << (drive)); | |||
8497 | IXP_UDMA_ENABLE(udma, chp->channel, drive)do { (udma) |= (1 << (2 * (chp->channel) + (drive))) ; } while (0); | |||
8498 | IXP_SET_MODE(udma, chp->channel, drive,do { int __ixpshift = 16 + 8*(chp->channel) + 4*(drive); ( udma) &= ~(0x7 << __ixpshift); (udma) |= (((drvp-> UDMA_mode) & 0x7) << __ixpshift); } while (0) | |||
8499 | drvp->UDMA_mode)do { int __ixpshift = 16 + 8*(chp->channel) + 4*(drive); ( udma) &= ~(0x7 << __ixpshift); (udma) |= (((drvp-> UDMA_mode) & 0x7) << __ixpshift); } while (0); | |||
8500 | mode = drvp->PIO_mode; | |||
8501 | } else if ((chp->wdc->cap & WDC_CAPABILITY_DMA0x0008) != 0 && | |||
8502 | (drvp->drive_flags & DRIVE_DMA0x0010) != 0) { | |||
8503 | /* Setup multiword DMA mode */ | |||
8504 | drvp->drive_flags &= ~DRIVE_UDMA0x0020; | |||
8505 | idedma_ctl |= IDEDMA_CTL_DRV_DMA(drive)(0x20 << (drive)); | |||
8506 | IXP_UDMA_DISABLE(udma, chp->channel, drive)do { (udma) &= ~(1 << (2 * (chp->channel) + (drive ))); } while (0); | |||
8507 | IXP_SET_TIMING(mdma_timing, chp->channel, drive,do { int __ixpshift = 16*(chp->channel) + 8*(drive); (mdma_timing ) &= ~(0xff << __ixpshift); (mdma_timing) |= ((ixp_mdma_timings [drvp->DMA_mode]) & 0xff) << __ixpshift; } while (0) | |||
8508 | ixp_mdma_timings[drvp->DMA_mode])do { int __ixpshift = 16*(chp->channel) + 8*(drive); (mdma_timing ) &= ~(0xff << __ixpshift); (mdma_timing) |= ((ixp_mdma_timings [drvp->DMA_mode]) & 0xff) << __ixpshift; } while (0); | |||
8509 | ||||
8510 | /* mode = min(pio, dma + 2) */ | |||
8511 | if (drvp->PIO_mode <= (drvp->DMA_mode + 2)) | |||
8512 | mode = drvp->PIO_mode; | |||
8513 | else | |||
8514 | mode = drvp->DMA_mode + 2; | |||
8515 | } else { | |||
8516 | mode = drvp->PIO_mode; | |||
8517 | } | |||
8518 | ||||
8519 | /* Setup PIO mode */ | |||
8520 | drvp->PIO_mode = mode; | |||
8521 | if (mode < 2) | |||
8522 | drvp->DMA_mode = 0; | |||
8523 | else | |||
8524 | drvp->DMA_mode = mode - 2; | |||
8525 | /* | |||
8526 | * Set PIO mode and timings | |||
8527 | * Linux driver avoids PIO mode 1, let's do it too. | |||
8528 | */ | |||
8529 | if (drvp->PIO_mode == 1) | |||
8530 | drvp->PIO_mode = 0; | |||
8531 | ||||
8532 | IXP_SET_MODE(pio, chp->channel, drive, drvp->PIO_mode)do { int __ixpshift = 16 + 8*(chp->channel) + 4*(drive); ( pio) &= ~(0x7 << __ixpshift); (pio) |= (((drvp-> PIO_mode) & 0x7) << __ixpshift); } while (0); | |||
8533 | IXP_SET_TIMING(pio_timing, chp->channel, drive,do { int __ixpshift = 16*(chp->channel) + 8*(drive); (pio_timing ) &= ~(0xff << __ixpshift); (pio_timing) |= ((ixp_pio_timings [drvp->PIO_mode]) & 0xff) << __ixpshift; } while (0) | |||
8534 | ixp_pio_timings[drvp->PIO_mode])do { int __ixpshift = 16*(chp->channel) + 8*(drive); (pio_timing ) &= ~(0xff << __ixpshift); (pio_timing) |= ((ixp_pio_timings [drvp->PIO_mode]) & 0xff) << __ixpshift; } while (0); | |||
8535 | } | |||
8536 | ||||
8537 | pci_conf_write(sc->sc_pc, sc->sc_tag, IXP_UDMA_CTL0x54, udma); | |||
8538 | pci_conf_write(sc->sc_pc, sc->sc_tag, IXP_MDMA_TIMING0x44, mdma_timing); | |||
8539 | pci_conf_write(sc->sc_pc, sc->sc_tag, IXP_PIO_CTL0x48, pio); | |||
8540 | pci_conf_write(sc->sc_pc, sc->sc_tag, IXP_PIO_TIMING0x40, pio_timing); | |||
8541 | ||||
8542 | if (idedma_ctl != 0) { | |||
8543 | /* Add software bits in status register */ | |||
8544 | bus_space_write_1(sc->sc_dma_iot, sc->sc_dma_ioh,((sc->sc_dma_iot)->write_1((sc->sc_dma_ioh), ((0x02 + 0x08 * (channel))), (idedma_ctl))) | |||
8545 | IDEDMA_CTL(channel), idedma_ctl)((sc->sc_dma_iot)->write_1((sc->sc_dma_ioh), ((0x02 + 0x08 * (channel))), (idedma_ctl))); | |||
8546 | } | |||
8547 | ||||
8548 | pciide_print_modes(cp); | |||
8549 | } | |||
8550 | ||||
8551 | void | |||
8552 | jmicron_chip_map(struct pciide_softc *sc, struct pci_attach_args *pa) | |||
8553 | { | |||
8554 | struct pciide_channel *cp; | |||
8555 | int channel; | |||
8556 | pcireg_t interface = PCI_INTERFACE(pa->pa_class)(((pa->pa_class) >> 8) & 0xff); | |||
8557 | bus_size_t cmdsize, ctlsize; | |||
8558 | u_int32_t conf; | |||
8559 | ||||
8560 | conf = pci_conf_read(sc->sc_pc, sc->sc_tag, JMICRON_CONF0x40); | |||
8561 | WDCDEBUG_PRINT(("%s: conf register 0x%x\n", | |||
8562 | sc->sc_wdcdev.sc_dev.dv_xname, conf), DEBUG_PROBE); | |||
8563 | ||||
8564 | printf(": DMA"); | |||
8565 | pciide_mapreg_dma(sc, pa); | |||
8566 | ||||
8567 | sc->sc_wdcdev.cap = WDC_CAPABILITY_DATA160x0001 | WDC_CAPABILITY_DATA320x0002 | | |||
8568 | WDC_CAPABILITY_MODE0x0004; | |||
8569 | if (sc->sc_dma_ok) { | |||
8570 | sc->sc_wdcdev.cap |= WDC_CAPABILITY_DMA0x0008 | WDC_CAPABILITY_UDMA0x0010; | |||
8571 | sc->sc_wdcdev.cap |= WDC_CAPABILITY_IRQACK0x0400; | |||
8572 | sc->sc_wdcdev.irqack = pciide_irqack; | |||
8573 | } | |||
8574 | sc->sc_wdcdev.PIO_cap = 4; | |||
8575 | sc->sc_wdcdev.DMA_cap = 2; | |||
8576 | sc->sc_wdcdev.UDMA_cap = 6; | |||
8577 | sc->sc_wdcdev.set_modes = jmicron_setup_channel; | |||
8578 | sc->sc_wdcdev.channels = sc->wdc_chanarray; | |||
8579 | sc->sc_wdcdev.nchannels = PCIIDE_NUM_CHANNELS2; | |||
8580 | ||||
8581 | pciide_print_channels(sc->sc_wdcdev.nchannels, interface); | |||
8582 | ||||
8583 | for (channel = 0; channel < sc->sc_wdcdev.nchannels; channel++) { | |||
8584 | cp = &sc->pciide_channels[channel]; | |||
8585 | ||||
8586 | if (pciide_chansetup(sc, channel, interface) == 0) | |||
8587 | continue; | |||
8588 | ||||
8589 | #if 0 | |||
8590 | if ((conf & JMICRON_CHAN_EN(channel)((channel == 1) ? 4 : 0)) == 0) { | |||
8591 | printf("%s: %s ignored (disabled)\n", | |||
8592 | sc->sc_wdcdev.sc_dev.dv_xname, cp->name); | |||
8593 | cp->hw_ok = 0; | |||
8594 | continue; | |||
8595 | } | |||
8596 | #endif | |||
8597 | ||||
8598 | pciide_map_compat_intr(pa, cp, channel, interface); | |||
8599 | if (cp->hw_ok == 0) | |||
8600 | continue; | |||
8601 | pciide_mapchan(pa, cp, interface, &cmdsize, &ctlsize, | |||
8602 | pciide_pci_intr); | |||
8603 | if (cp->hw_ok == 0) { | |||
8604 | pciide_unmap_compat_intr(pa, cp, channel, interface); | |||
8605 | continue; | |||
8606 | } | |||
8607 | ||||
8608 | if (pciide_chan_candisable(cp)) { | |||
8609 | conf &= ~JMICRON_CHAN_EN(channel)((channel == 1) ? 4 : 0); | |||
8610 | pciide_unmap_compat_intr(pa, cp, channel, interface); | |||
8611 | continue; | |||
8612 | } | |||
8613 | ||||
8614 | sc->sc_wdcdev.set_modes(&cp->wdc_channel); | |||
8615 | } | |||
8616 | WDCDEBUG_PRINT(("%s: new conf register 0x%x\n", | |||
8617 | sc->sc_wdcdev.sc_dev.dv_xname, conf), DEBUG_PROBE); | |||
8618 | pci_conf_write(sc->sc_pc, sc->sc_tag, JMICRON_CONF0x40, conf); | |||
8619 | } | |||
8620 | ||||
8621 | void | |||
8622 | jmicron_setup_channel(struct channel_softc *chp) | |||
8623 | { | |||
8624 | struct ata_drive_datas *drvp; | |||
8625 | int drive, mode; | |||
8626 | u_int32_t idedma_ctl; | |||
8627 | struct pciide_channel *cp = (struct pciide_channel *)chp; | |||
8628 | struct pciide_softc *sc = (struct pciide_softc *)cp->wdc_channel.wdc; | |||
8629 | int channel = chp->channel; | |||
8630 | u_int32_t conf; | |||
8631 | ||||
8632 | conf = pci_conf_read(sc->sc_pc, sc->sc_tag, JMICRON_CONF0x40); | |||
8633 | ||||
8634 | /* Setup DMA if needed */ | |||
8635 | pciide_channel_dma_setup(cp); | |||
8636 | ||||
8637 | /* Clear all bits for this channel */ | |||
8638 | idedma_ctl = 0; | |||
8639 | ||||
8640 | /* Per channel settings */ | |||
8641 | for (drive = 0; drive < 2; drive++) { | |||
8642 | drvp = &chp->ch_drive[drive]; | |||
8643 | ||||
8644 | /* If no drive, skip */ | |||
8645 | if ((drvp->drive_flags & DRIVE(0x0001|0x0002|0x0004)) == 0) | |||
8646 | continue; | |||
8647 | ||||
8648 | if ((chp->wdc->cap & WDC_CAPABILITY_UDMA0x0010) != 0 && | |||
8649 | (drvp->drive_flags & DRIVE_UDMA0x0020) != 0) { | |||
8650 | /* Setup UltraDMA mode */ | |||
8651 | drvp->drive_flags &= ~DRIVE_DMA0x0010; | |||
8652 | ||||
8653 | /* see if cable is up to scratch */ | |||
8654 | if ((conf & JMICRON_CONF_40PIN(1 << 3)) && | |||
8655 | (drvp->UDMA_mode > 2)) | |||
8656 | drvp->UDMA_mode = 2; | |||
8657 | ||||
8658 | mode = drvp->PIO_mode; | |||
8659 | } else if ((chp->wdc->cap & WDC_CAPABILITY_DMA0x0008) != 0 && | |||
8660 | (drvp->drive_flags & DRIVE_DMA0x0010) != 0) { | |||
8661 | /* Setup multiword DMA mode */ | |||
8662 | drvp->drive_flags &= ~DRIVE_UDMA0x0020; | |||
8663 | ||||
8664 | /* mode = min(pio, dma + 2) */ | |||
8665 | if (drvp->PIO_mode <= (drvp->DMA_mode + 2)) | |||
8666 | mode = drvp->PIO_mode; | |||
8667 | else | |||
8668 | mode = drvp->DMA_mode + 2; | |||
8669 | } else { | |||
8670 | mode = drvp->PIO_mode; | |||
8671 | goto pio; | |||
8672 | } | |||
8673 | idedma_ctl |= IDEDMA_CTL_DRV_DMA(drive)(0x20 << (drive)); | |||
8674 | ||||
8675 | pio: | |||
8676 | /* Setup PIO mode */ | |||
8677 | if (mode <= 2) { | |||
8678 | drvp->DMA_mode = 0; | |||
8679 | drvp->PIO_mode = 0; | |||
8680 | } else { | |||
8681 | drvp->PIO_mode = mode; | |||
8682 | drvp->DMA_mode = mode - 2; | |||
8683 | } | |||
8684 | } | |||
8685 | ||||
8686 | if (idedma_ctl != 0) { | |||
8687 | /* Add software bits in status register */ | |||
8688 | bus_space_write_1(sc->sc_dma_iot, sc->sc_dma_ioh,((sc->sc_dma_iot)->write_1((sc->sc_dma_ioh), ((0x02 + 0x08 * (channel))), (idedma_ctl))) | |||
8689 | IDEDMA_CTL(channel), idedma_ctl)((sc->sc_dma_iot)->write_1((sc->sc_dma_ioh), ((0x02 + 0x08 * (channel))), (idedma_ctl))); | |||
8690 | } | |||
8691 | ||||
8692 | pciide_print_modes(cp); | |||
8693 | } | |||
8694 | ||||
8695 | void | |||
8696 | phison_chip_map(struct pciide_softc *sc, struct pci_attach_args *pa) | |||
8697 | { | |||
8698 | struct pciide_channel *cp; | |||
8699 | int channel; | |||
8700 | pcireg_t interface = PCI_INTERFACE(pa->pa_class)(((pa->pa_class) >> 8) & 0xff); | |||
8701 | bus_size_t cmdsize, ctlsize; | |||
8702 | ||||
8703 | sc->chip_unmap = default_chip_unmap; | |||
8704 | ||||
8705 | printf(": DMA"); | |||
8706 | pciide_mapreg_dma(sc, pa); | |||
8707 | ||||
8708 | sc->sc_wdcdev.cap = WDC_CAPABILITY_DATA160x0001 | WDC_CAPABILITY_DATA320x0002 | | |||
8709 | WDC_CAPABILITY_MODE0x0004; | |||
8710 | if (sc->sc_dma_ok) { | |||
8711 | sc->sc_wdcdev.cap |= WDC_CAPABILITY_DMA0x0008 | WDC_CAPABILITY_UDMA0x0010; | |||
8712 | sc->sc_wdcdev.cap |= WDC_CAPABILITY_IRQACK0x0400; | |||
8713 | sc->sc_wdcdev.irqack = pciide_irqack; | |||
8714 | } | |||
8715 | sc->sc_wdcdev.PIO_cap = 4; | |||
8716 | sc->sc_wdcdev.DMA_cap = 2; | |||
8717 | sc->sc_wdcdev.UDMA_cap = 5; | |||
8718 | sc->sc_wdcdev.set_modes = phison_setup_channel; | |||
8719 | sc->sc_wdcdev.channels = sc->wdc_chanarray; | |||
8720 | sc->sc_wdcdev.nchannels = 1; | |||
8721 | ||||
8722 | pciide_print_channels(sc->sc_wdcdev.nchannels, interface); | |||
8723 | ||||
8724 | for (channel = 0; channel < sc->sc_wdcdev.nchannels; channel++) { | |||
8725 | cp = &sc->pciide_channels[channel]; | |||
8726 | ||||
8727 | if (pciide_chansetup(sc, channel, interface) == 0) | |||
8728 | continue; | |||
8729 | ||||
8730 | pciide_map_compat_intr(pa, cp, channel, interface); | |||
8731 | if (cp->hw_ok == 0) | |||
8732 | continue; | |||
8733 | pciide_mapchan(pa, cp, interface, &cmdsize, &ctlsize, | |||
8734 | pciide_pci_intr); | |||
8735 | if (cp->hw_ok == 0) { | |||
8736 | pciide_unmap_compat_intr(pa, cp, channel, interface); | |||
8737 | continue; | |||
8738 | } | |||
8739 | ||||
8740 | sc->sc_wdcdev.set_modes(&cp->wdc_channel); | |||
8741 | } | |||
8742 | } | |||
8743 | ||||
8744 | void | |||
8745 | phison_setup_channel(struct channel_softc *chp) | |||
8746 | { | |||
8747 | struct ata_drive_datas *drvp; | |||
8748 | int drive, mode; | |||
8749 | u_int32_t idedma_ctl; | |||
8750 | struct pciide_channel *cp = (struct pciide_channel *)chp; | |||
8751 | struct pciide_softc *sc = (struct pciide_softc *)cp->wdc_channel.wdc; | |||
8752 | int channel = chp->channel; | |||
8753 | ||||
8754 | /* Setup DMA if needed */ | |||
8755 | pciide_channel_dma_setup(cp); | |||
8756 | ||||
8757 | /* Clear all bits for this channel */ | |||
8758 | idedma_ctl = 0; | |||
8759 | ||||
8760 | /* Per channel settings */ | |||
8761 | for (drive = 0; drive < 2; drive++) { | |||
8762 | drvp = &chp->ch_drive[drive]; | |||
8763 | ||||
8764 | /* If no drive, skip */ | |||
8765 | if ((drvp->drive_flags & DRIVE(0x0001|0x0002|0x0004)) == 0) | |||
8766 | continue; | |||
8767 | ||||
8768 | if ((chp->wdc->cap & WDC_CAPABILITY_UDMA0x0010) != 0 && | |||
8769 | (drvp->drive_flags & DRIVE_UDMA0x0020) != 0) { | |||
8770 | /* Setup UltraDMA mode */ | |||
8771 | drvp->drive_flags &= ~DRIVE_DMA0x0010; | |||
8772 | mode = drvp->PIO_mode; | |||
8773 | } else if ((chp->wdc->cap & WDC_CAPABILITY_DMA0x0008) != 0 && | |||
8774 | (drvp->drive_flags & DRIVE_DMA0x0010) != 0) { | |||
8775 | /* Setup multiword DMA mode */ | |||
8776 | drvp->drive_flags &= ~DRIVE_UDMA0x0020; | |||
8777 | ||||
8778 | /* mode = min(pio, dma + 2) */ | |||
8779 | if (drvp->PIO_mode <= (drvp->DMA_mode + 2)) | |||
8780 | mode = drvp->PIO_mode; | |||
8781 | else | |||
8782 | mode = drvp->DMA_mode + 2; | |||
8783 | } else { | |||
8784 | mode = drvp->PIO_mode; | |||
8785 | goto pio; | |||
8786 | } | |||
8787 | idedma_ctl |= IDEDMA_CTL_DRV_DMA(drive)(0x20 << (drive)); | |||
8788 | ||||
8789 | pio: | |||
8790 | /* Setup PIO mode */ | |||
8791 | if (mode <= 2) { | |||
8792 | drvp->DMA_mode = 0; | |||
8793 | drvp->PIO_mode = 0; | |||
8794 | } else { | |||
8795 | drvp->PIO_mode = mode; | |||
8796 | drvp->DMA_mode = mode - 2; | |||
8797 | } | |||
8798 | } | |||
8799 | ||||
8800 | if (idedma_ctl != 0) { | |||
8801 | /* Add software bits in status register */ | |||
8802 | bus_space_write_1(sc->sc_dma_iot, sc->sc_dma_ioh,((sc->sc_dma_iot)->write_1((sc->sc_dma_ioh), ((0x02 + 0x08 * (channel))), (idedma_ctl))) | |||
8803 | IDEDMA_CTL(channel), idedma_ctl)((sc->sc_dma_iot)->write_1((sc->sc_dma_ioh), ((0x02 + 0x08 * (channel))), (idedma_ctl))); | |||
8804 | } | |||
8805 | ||||
8806 | pciide_print_modes(cp); | |||
8807 | } | |||
8808 | ||||
8809 | void | |||
8810 | sch_chip_map(struct pciide_softc *sc, struct pci_attach_args *pa) | |||
8811 | { | |||
8812 | struct pciide_channel *cp; | |||
8813 | int channel; | |||
8814 | pcireg_t interface = PCI_INTERFACE(pa->pa_class)(((pa->pa_class) >> 8) & 0xff); | |||
8815 | bus_size_t cmdsize, ctlsize; | |||
8816 | ||||
8817 | printf(": DMA"); | |||
8818 | pciide_mapreg_dma(sc, pa); | |||
8819 | ||||
8820 | sc->sc_wdcdev.cap = WDC_CAPABILITY_DATA160x0001 | WDC_CAPABILITY_DATA320x0002 | | |||
8821 | WDC_CAPABILITY_MODE0x0004; | |||
8822 | if (sc->sc_dma_ok) { | |||
8823 | sc->sc_wdcdev.cap |= WDC_CAPABILITY_DMA0x0008 | WDC_CAPABILITY_UDMA0x0010; | |||
8824 | sc->sc_wdcdev.cap |= WDC_CAPABILITY_IRQACK0x0400; | |||
8825 | sc->sc_wdcdev.irqack = pciide_irqack; | |||
8826 | } | |||
8827 | sc->sc_wdcdev.PIO_cap = 4; | |||
8828 | sc->sc_wdcdev.DMA_cap = 2; | |||
8829 | sc->sc_wdcdev.UDMA_cap = 5; | |||
8830 | sc->sc_wdcdev.set_modes = sch_setup_channel; | |||
8831 | sc->sc_wdcdev.channels = sc->wdc_chanarray; | |||
8832 | sc->sc_wdcdev.nchannels = 1; | |||
8833 | ||||
8834 | pciide_print_channels(sc->sc_wdcdev.nchannels, interface); | |||
8835 | ||||
8836 | for (channel = 0; channel < sc->sc_wdcdev.nchannels; channel++) { | |||
8837 | cp = &sc->pciide_channels[channel]; | |||
8838 | ||||
8839 | if (pciide_chansetup(sc, channel, interface) == 0) | |||
8840 | continue; | |||
8841 | ||||
8842 | pciide_map_compat_intr(pa, cp, channel, interface); | |||
8843 | if (cp->hw_ok == 0) | |||
8844 | continue; | |||
8845 | pciide_mapchan(pa, cp, interface, &cmdsize, &ctlsize, | |||
8846 | pciide_pci_intr); | |||
8847 | if (cp->hw_ok == 0) { | |||
8848 | pciide_unmap_compat_intr(pa, cp, channel, interface); | |||
8849 | continue; | |||
8850 | } | |||
8851 | ||||
8852 | sc->sc_wdcdev.set_modes(&cp->wdc_channel); | |||
8853 | } | |||
8854 | } | |||
8855 | ||||
8856 | void | |||
8857 | sch_setup_channel(struct channel_softc *chp) | |||
8858 | { | |||
8859 | struct ata_drive_datas *drvp; | |||
8860 | int drive, mode; | |||
8861 | u_int32_t tim, timaddr; | |||
8862 | struct pciide_channel *cp = (struct pciide_channel *)chp; | |||
8863 | struct pciide_softc *sc = (struct pciide_softc *)cp->wdc_channel.wdc; | |||
8864 | ||||
8865 | /* Setup DMA if needed */ | |||
8866 | pciide_channel_dma_setup(cp); | |||
8867 | ||||
8868 | /* Per channel settings */ | |||
8869 | for (drive = 0; drive < 2; drive++) { | |||
8870 | drvp = &chp->ch_drive[drive]; | |||
8871 | ||||
8872 | /* If no drive, skip */ | |||
8873 | if ((drvp->drive_flags & DRIVE(0x0001|0x0002|0x0004)) == 0) | |||
8874 | continue; | |||
8875 | ||||
8876 | timaddr = (drive == 0) ? SCH_D0TIM0x80 : SCH_D1TIM0x84; | |||
8877 | tim = pci_conf_read(sc->sc_pc, sc->sc_tag, timaddr); | |||
8878 | tim &= ~SCH_TIM_MASK(0x70000 | 0x00300 | 0x00007); | |||
8879 | ||||
8880 | if ((chp->wdc->cap & WDC_CAPABILITY_UDMA0x0010) != 0 && | |||
8881 | (drvp->drive_flags & DRIVE_UDMA0x0020) != 0) { | |||
8882 | /* Setup UltraDMA mode */ | |||
8883 | drvp->drive_flags &= ~DRIVE_DMA0x0010; | |||
8884 | ||||
8885 | mode = drvp->PIO_mode; | |||
8886 | tim |= (drvp->UDMA_mode << 16) | SCH_TIM_SYNCDMA(1U << 31); | |||
8887 | } else if ((chp->wdc->cap & WDC_CAPABILITY_DMA0x0008) != 0 && | |||
8888 | (drvp->drive_flags & DRIVE_DMA0x0010) != 0) { | |||
8889 | /* Setup multiword DMA mode */ | |||
8890 | drvp->drive_flags &= ~DRIVE_UDMA0x0020; | |||
8891 | ||||
8892 | tim &= ~SCH_TIM_SYNCDMA(1U << 31); | |||
8893 | ||||
8894 | /* mode = min(pio, dma + 2) */ | |||
8895 | if (drvp->PIO_mode <= (drvp->DMA_mode + 2)) | |||
8896 | mode = drvp->PIO_mode; | |||
8897 | else | |||
8898 | mode = drvp->DMA_mode + 2; | |||
8899 | } else { | |||
8900 | mode = drvp->PIO_mode; | |||
8901 | goto pio; | |||
8902 | } | |||
8903 | ||||
8904 | pio: | |||
8905 | /* Setup PIO mode */ | |||
8906 | if (mode <= 2) { | |||
8907 | drvp->DMA_mode = 0; | |||
8908 | drvp->PIO_mode = 0; | |||
8909 | } else { | |||
8910 | drvp->PIO_mode = mode; | |||
8911 | drvp->DMA_mode = mode - 2; | |||
8912 | } | |||
8913 | tim |= (drvp->DMA_mode << 8) | (drvp->PIO_mode); | |||
8914 | pci_conf_write(sc->sc_pc, sc->sc_tag, timaddr, tim); | |||
8915 | } | |||
8916 | ||||
8917 | pciide_print_modes(cp); | |||
8918 | } | |||
8919 | ||||
8920 | void | |||
8921 | rdc_chip_map(struct pciide_softc *sc, struct pci_attach_args *pa) | |||
8922 | { | |||
8923 | struct pciide_channel *cp; | |||
8924 | int channel; | |||
8925 | u_int32_t patr; | |||
8926 | pcireg_t interface = PCI_INTERFACE(pa->pa_class)(((pa->pa_class) >> 8) & 0xff); | |||
8927 | bus_size_t cmdsize, ctlsize; | |||
8928 | ||||
8929 | printf(": DMA"); | |||
8930 | pciide_mapreg_dma(sc, pa); | |||
8931 | sc->sc_wdcdev.cap |= WDC_CAPABILITY_DATA160x0001 | WDC_CAPABILITY_DATA320x0002; | |||
8932 | if (sc->sc_dma_ok) { | |||
8933 | sc->sc_wdcdev.cap |= WDC_CAPABILITY_UDMA0x0010 | | |||
8934 | WDC_CAPABILITY_DMA0x0008 | WDC_CAPABILITY_IRQACK0x0400; | |||
8935 | sc->sc_wdcdev.irqack = pciide_irqack; | |||
8936 | sc->sc_wdcdev.dma_init = pciide_dma_init; | |||
8937 | } | |||
8938 | sc->sc_wdcdev.PIO_cap = 4; | |||
8939 | sc->sc_wdcdev.DMA_cap = 2; | |||
8940 | sc->sc_wdcdev.UDMA_cap = 5; | |||
8941 | sc->sc_wdcdev.set_modes = rdc_setup_channel; | |||
8942 | sc->sc_wdcdev.channels = sc->wdc_chanarray; | |||
8943 | sc->sc_wdcdev.nchannels = PCIIDE_NUM_CHANNELS2; | |||
8944 | ||||
8945 | pciide_print_channels(sc->sc_wdcdev.nchannels, interface); | |||
8946 | ||||
8947 | WDCDEBUG_PRINT(("rdc_chip_map: old PATR=0x%x, " | |||
8948 | "PSD1ATR=0x%x, UDCCR=0x%x, IIOCR=0x%x\n", | |||
8949 | pci_conf_read(sc->sc_pc, sc->sc_tag, RDCIDE_PATR), | |||
8950 | pci_conf_read(sc->sc_pc, sc->sc_tag, RDCIDE_PSD1ATR), | |||
8951 | pci_conf_read(sc->sc_pc, sc->sc_tag, RDCIDE_UDCCR), | |||
8952 | pci_conf_read(sc->sc_pc, sc->sc_tag, RDCIDE_IIOCR)), | |||
8953 | DEBUG_PROBE); | |||
8954 | ||||
8955 | for (channel = 0; channel < sc->sc_wdcdev.nchannels; channel++) { | |||
8956 | cp = &sc->pciide_channels[channel]; | |||
8957 | ||||
8958 | if (pciide_chansetup(sc, channel, interface) == 0) | |||
8959 | continue; | |||
8960 | patr = pci_conf_read(sc->sc_pc, sc->sc_tag, RDCIDE_PATR0x40); | |||
8961 | if ((patr & RDCIDE_PATR_EN(channel)(0x8000 << ((channel) * 16))) == 0) { | |||
8962 | printf("%s: %s ignored (disabled)\n", | |||
8963 | sc->sc_wdcdev.sc_dev.dv_xname, cp->name); | |||
8964 | cp->hw_ok = 0; | |||
8965 | continue; | |||
8966 | } | |||
8967 | pciide_map_compat_intr(pa, cp, channel, interface); | |||
8968 | if (cp->hw_ok == 0) | |||
8969 | continue; | |||
8970 | pciide_mapchan(pa, cp, interface, &cmdsize, &ctlsize, | |||
8971 | pciide_pci_intr); | |||
8972 | if (cp->hw_ok == 0) | |||
8973 | goto next; | |||
8974 | if (pciide_chan_candisable(cp)) { | |||
8975 | patr &= ~RDCIDE_PATR_EN(channel)(0x8000 << ((channel) * 16)); | |||
8976 | pci_conf_write(sc->sc_pc, sc->sc_tag, RDCIDE_PATR0x40, | |||
8977 | patr); | |||
8978 | } | |||
8979 | if (cp->hw_ok == 0) | |||
8980 | goto next; | |||
8981 | sc->sc_wdcdev.set_modes(&cp->wdc_channel); | |||
8982 | next: | |||
8983 | if (cp->hw_ok == 0) | |||
8984 | pciide_unmap_compat_intr(pa, cp, channel, interface); | |||
8985 | } | |||
8986 | ||||
8987 | WDCDEBUG_PRINT(("rdc_chip_map: PATR=0x%x, " | |||
8988 | "PSD1ATR=0x%x, UDCCR=0x%x, IIOCR=0x%x\n", | |||
8989 | pci_conf_read(sc->sc_pc, sc->sc_tag, RDCIDE_PATR), | |||
8990 | pci_conf_read(sc->sc_pc, sc->sc_tag, RDCIDE_PSD1ATR), | |||
8991 | pci_conf_read(sc->sc_pc, sc->sc_tag, RDCIDE_UDCCR), | |||
8992 | pci_conf_read(sc->sc_pc, sc->sc_tag, RDCIDE_IIOCR)), | |||
8993 | DEBUG_PROBE); | |||
8994 | } | |||
8995 | ||||
8996 | void | |||
8997 | rdc_setup_channel(struct channel_softc *chp) | |||
8998 | { | |||
8999 | u_int8_t drive; | |||
9000 | u_int32_t patr, psd1atr, udccr, iiocr; | |||
9001 | struct pciide_channel *cp = (struct pciide_channel *)chp; | |||
9002 | struct pciide_softc *sc = (struct pciide_softc *)cp->wdc_channel.wdc; | |||
9003 | struct ata_drive_datas *drvp; | |||
9004 | ||||
9005 | patr = pci_conf_read(sc->sc_pc, sc->sc_tag, RDCIDE_PATR0x40); | |||
9006 | psd1atr = pci_conf_read(sc->sc_pc, sc->sc_tag, RDCIDE_PSD1ATR0x44); | |||
9007 | udccr = pci_conf_read(sc->sc_pc, sc->sc_tag, RDCIDE_UDCCR0x48); | |||
9008 | iiocr = pci_conf_read(sc->sc_pc, sc->sc_tag, RDCIDE_IIOCR0x54); | |||
9009 | ||||
9010 | /* setup DMA */ | |||
9011 | pciide_channel_dma_setup(cp); | |||
9012 | ||||
9013 | /* clear modes */ | |||
9014 | patr = patr & (RDCIDE_PATR_EN(0)(0x8000 << ((0) * 16)) | RDCIDE_PATR_EN(1)(0x8000 << ((1) * 16))); | |||
9015 | psd1atr &= ~RDCIDE_PSD1ATR_SETUP_MASK(chp->channel)(0x0c << (chp->channel * 4)); | |||
9016 | psd1atr &= ~RDCIDE_PSD1ATR_HOLD_MASK(chp->channel)(0x03 << (chp->channel * 4)); | |||
9017 | for (drive = 0; drive < 2; drive++) { | |||
9018 | udccr &= ~RDCIDE_UDCCR_EN(chp->channel, drive)((1 << (drive)) << (chp->channel * 2)); | |||
9019 | udccr &= ~RDCIDE_UDCCR_TIM_MASK(chp->channel, drive)((0x3 << ((drive) * 4)) << (chp->channel * 8)); | |||
9020 | iiocr &= ~RDCIDE_IIOCR_CLK_MASK(chp->channel, drive)((0x1001 << drive) << (chp->channel * 2)); | |||
9021 | } | |||
9022 | /* now setup modes */ | |||
9023 | for (drive = 0; drive < 2; drive++) { | |||
9024 | drvp = &cp->wdc_channel.ch_drive[drive]; | |||
9025 | if ((drvp->drive_flags & DRIVE(0x0001|0x0002|0x0004)) == 0) | |||
9026 | continue; | |||
9027 | if (drvp->drive_flags & DRIVE_ATAPI0x0002) | |||
9028 | patr |= RDCIDE_PATR_ATA(chp->channel, drive)((0x0004 << (drive * 4)) << ((chp->channel) * 16 )); | |||
9029 | if (drive == 0) { | |||
9030 | patr |= RDCIDE_PATR_SETUP(rdcide_setup[drvp->PIO_mode],(((rdcide_setup[drvp->PIO_mode]) << 12) << ((chp ->channel) * 16)) | |||
9031 | chp->channel)(((rdcide_setup[drvp->PIO_mode]) << 12) << ((chp ->channel) * 16)); | |||
9032 | patr |= RDCIDE_PATR_HOLD(rdcide_hold[drvp->PIO_mode],(((rdcide_hold[drvp->PIO_mode]) << 8) << ((chp ->channel) * 16)) | |||
9033 | chp->channel)(((rdcide_hold[drvp->PIO_mode]) << 8) << ((chp ->channel) * 16)); | |||
9034 | } else { | |||
9035 | patr |= RDCIDE_PATR_DEV1_TEN(chp->channel)(0x4000 << ((chp->channel) * 16)); | |||
9036 | psd1atr |= RDCIDE_PSD1ATR_SETUP((((rdcide_setup[drvp->PIO_mode]) << 2) << (chp ->channel * 4)) | |||
9037 | rdcide_setup[drvp->PIO_mode],(((rdcide_setup[drvp->PIO_mode]) << 2) << (chp ->channel * 4)) | |||
9038 | chp->channel)(((rdcide_setup[drvp->PIO_mode]) << 2) << (chp ->channel * 4)); | |||
9039 | psd1atr |= RDCIDE_PSD1ATR_HOLD((((rdcide_hold[drvp->PIO_mode]) << 0) << (chp-> channel * 4)) | |||
9040 | rdcide_hold[drvp->PIO_mode],(((rdcide_hold[drvp->PIO_mode]) << 0) << (chp-> channel * 4)) | |||
9041 | chp->channel)(((rdcide_hold[drvp->PIO_mode]) << 0) << (chp-> channel * 4)); | |||
9042 | } | |||
9043 | if (drvp->PIO_mode > 0) { | |||
9044 | patr |= RDCIDE_PATR_FTIM(chp->channel, drive)((0x0001 << (drive * 4)) << ((chp->channel) * 16 )); | |||
9045 | patr |= RDCIDE_PATR_IORDY(chp->channel, drive)((0x0002 << (drive * 4)) << ((chp->channel) * 16 )); | |||
9046 | } | |||
9047 | if (drvp->drive_flags & DRIVE_DMA0x0010) | |||
9048 | patr |= RDCIDE_PATR_DMAEN(chp->channel, drive)((0x0008 << (drive * 4)) << ((chp->channel) * 16 )); | |||
9049 | if ((drvp->drive_flags & DRIVE_UDMA0x0020) == 0) | |||
9050 | continue; | |||
9051 | ||||
9052 | if ((iiocr & RDCIDE_IIOCR_CABLE(chp->channel, drive)((0x10 << (drive)) << (chp->channel * 2))) == 0 | |||
9053 | && drvp->UDMA_mode > 2) | |||
9054 | drvp->UDMA_mode = 2; | |||
9055 | udccr |= RDCIDE_UDCCR_EN(chp->channel, drive)((1 << (drive)) << (chp->channel * 2)); | |||
9056 | udccr |= RDCIDE_UDCCR_TIM(rdcide_udmatim[drvp->UDMA_mode],(((rdcide_udmatim[drvp->UDMA_mode]) << ((drive) * 4) ) << (chp->channel * 8)) | |||
9057 | chp->channel, drive)(((rdcide_udmatim[drvp->UDMA_mode]) << ((drive) * 4) ) << (chp->channel * 8)); | |||
9058 | iiocr |= RDCIDE_IIOCR_CLK(rdcide_udmaclk[drvp->UDMA_mode],(((rdcide_udmaclk[drvp->UDMA_mode]) << drive) << (chp->channel * 2)) | |||
9059 | chp->channel, drive)(((rdcide_udmaclk[drvp->UDMA_mode]) << drive) << (chp->channel * 2)); | |||
9060 | } | |||
9061 | ||||
9062 | pci_conf_write(sc->sc_pc, sc->sc_tag, RDCIDE_PATR0x40, patr); | |||
9063 | pci_conf_write(sc->sc_pc, sc->sc_tag, RDCIDE_PSD1ATR0x44, psd1atr); | |||
9064 | pci_conf_write(sc->sc_pc, sc->sc_tag, RDCIDE_UDCCR0x48, udccr); | |||
9065 | pci_conf_write(sc->sc_pc, sc->sc_tag, RDCIDE_IIOCR0x54, iiocr); | |||
9066 | } |