1 | /* $NetBSD: pciidevar.h,v 1.47 2015/08/24 23:55:04 pooka Exp $ */ |
2 | |
3 | /* |
4 | * Copyright (c) 1998 Christopher G. Demetriou. All rights reserved. |
5 | * |
6 | * Redistribution and use in source and binary forms, with or without |
7 | * modification, are permitted provided that the following conditions |
8 | * are met: |
9 | * 1. Redistributions of source code must retain the above copyright |
10 | * notice, this list of conditions and the following disclaimer. |
11 | * 2. Redistributions in binary form must reproduce the above copyright |
12 | * notice, this list of conditions and the following disclaimer in the |
13 | * documentation and/or other materials provided with the distribution. |
14 | * 3. All advertising materials mentioning features or use of this software |
15 | * must display the following acknowledgement: |
16 | * This product includes software developed by Christopher G. Demetriou |
17 | * for the NetBSD Project. |
18 | * 4. The name of the author may not be used to endorse or promote products |
19 | * derived from this software without specific prior written permission |
20 | * |
21 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
22 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
23 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
24 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
25 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
26 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
27 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
28 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
29 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
30 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
31 | */ |
32 | |
33 | #ifndef _DEV_PCI_PCIIDEVAR_H_ |
34 | #define _DEV_PCI_PCIIDEVAR_H_ |
35 | |
36 | /* |
37 | * PCI IDE driver exported software structures. |
38 | * |
39 | * Author: Christopher G. Demetriou, March 2, 1998. |
40 | */ |
41 | |
42 | #ifdef _KERNEL_OPT |
43 | #include "opt_pciide.h" |
44 | #endif |
45 | |
46 | #include <dev/ata/atavar.h> |
47 | #include <dev/ic/wdcreg.h> |
48 | #include <dev/ic/wdcvar.h> |
49 | #include <sys/device_if.h> |
50 | |
51 | /* options passed via the 'flags' config keyword */ |
52 | #define PCIIDE_OPTIONS_DMA 0x01 |
53 | #define PCIIDE_OPTIONS_NODMA 0x02 |
54 | |
55 | #ifndef ATADEBUG |
56 | #define ATADEBUG |
57 | #endif |
58 | |
59 | #define DEBUG_DMA 0x01 |
60 | #define DEBUG_XFERS 0x02 |
61 | #define DEBUG_FUNCS 0x08 |
62 | #define DEBUG_PROBE 0x10 |
63 | #ifdef ATADEBUG |
64 | extern int atadebug_pciide_mask; |
65 | #define ATADEBUG_PRINT(args, level) \ |
66 | if (atadebug_pciide_mask & (level)) printf args |
67 | #else |
68 | #define ATADEBUG_PRINT(args, level) |
69 | #endif |
70 | |
71 | /* |
72 | * While standard PCI IDE controllers only have 2 channels, it is |
73 | * common for PCI SATA controllers to have more. Here we define |
74 | * the maximum number of channels that any one PCI IDE device can |
75 | * have. |
76 | */ |
77 | #define PCIIDE_MAX_CHANNELS 4 |
78 | |
79 | struct pciide_softc { |
80 | struct wdc_softc sc_wdcdev; /* common wdc definitions */ |
81 | pci_chipset_tag_t sc_pc; /* PCI registers info */ |
82 | pcitag_t sc_tag; |
83 | void *sc_pci_ih; /* PCI interrupt handle */ |
84 | #if NATA_DMA |
85 | int sc_dma_ok; /* bus-master DMA info */ |
86 | /* |
87 | * sc_dma_ioh may only be used to allocate the dma_iohs |
88 | * array in the channels (see below), or by chip-dependent |
89 | * code that knows what it's doing, as the registers may |
90 | * be laid out differently. All code in pciide_common.c |
91 | * must use the channel->dma_iohs array. |
92 | */ |
93 | bus_space_tag_t sc_dma_iot; |
94 | bus_space_handle_t sc_dma_ioh; |
95 | bus_size_t sc_dma_ios; |
96 | bus_dma_tag_t sc_dmat; |
97 | |
98 | /* |
99 | * Some controllers might have DMA restrictions other than |
100 | * the norm. |
101 | */ |
102 | bus_size_t sc_dma_maxsegsz; |
103 | bus_size_t sc_dma_boundary; |
104 | |
105 | /* For VIA/AMD/nVidia */ |
106 | bus_addr_t sc_apo_regbase; |
107 | |
108 | /* For Cypress */ |
109 | const struct cy82c693_handle *sc_cy_handle; |
110 | int sc_cy_compatchan; |
111 | |
112 | /* for SiS */ |
113 | u_int8_t sis_type; |
114 | |
115 | /* |
116 | * For Silicon Image SATALink, Serverworks SATA, Artisea SATA |
117 | * and Promise SATA |
118 | */ |
119 | bus_space_tag_t sc_ba5_st; |
120 | bus_space_handle_t sc_ba5_sh; |
121 | bus_size_t sc_ba5_ss; |
122 | int sc_ba5_en; |
123 | #endif /* NATA_DMA */ |
124 | |
125 | /* Vendor info (for interpreting Chip description) */ |
126 | pcireg_t sc_pci_id; |
127 | /* Chip description */ |
128 | const struct pciide_product_desc *sc_pp; |
129 | /* common definitions */ |
130 | struct ata_channel *wdc_chanarray[PCIIDE_MAX_CHANNELS]; |
131 | /* internal bookkeeping */ |
132 | struct pciide_channel { /* per-channel data */ |
133 | struct ata_channel ata_channel; /* generic part */ |
134 | const char *name; |
135 | int compat; /* is it compat? */ |
136 | void *ih; /* compat or pci handle */ |
137 | bus_space_handle_t ctl_baseioh; /* ctrl regs blk, native mode */ |
138 | bus_size_t ctl_ios; |
139 | #if NATA_DMA |
140 | /* DMA tables and DMA map for xfer, for each drive */ |
141 | struct pciide_dma_maps { |
142 | bus_dma_segment_t dmamap_table_seg; |
143 | int dmamap_table_nseg; |
144 | bus_dmamap_t dmamap_table; |
145 | struct idedma_table *dma_table; |
146 | bus_dmamap_t dmamap_xfer; |
147 | int dma_flags; |
148 | } dma_maps[WDC_MAXDRIVES]; |
149 | bus_space_handle_t dma_iohs[IDEDMA_NREGS]; |
150 | /* |
151 | * Some controllers require certain bits to |
152 | * always be set for proper operation of the |
153 | * controller. Set those bits here, if they're |
154 | * required. |
155 | */ |
156 | uint8_t idedma_cmd; |
157 | #endif /* NATA_DMA */ |
158 | } pciide_channels[PCIIDE_MAX_CHANNELS]; |
159 | |
160 | pcireg_t sc_pm_reg[4]; |
161 | }; |
162 | |
163 | /* Given an ata_channel, get the pciide_softc. */ |
164 | #define CHAN_TO_PCIIDE(chp) ((struct pciide_softc *) (chp)->ch_atac) |
165 | |
166 | /* Given an ata_channel, get the pciide_channel. */ |
167 | #define CHAN_TO_PCHAN(chp) ((struct pciide_channel *) (chp)) |
168 | |
169 | struct pciide_product_desc { |
170 | u_int32_t ide_product; |
171 | int ide_flags; |
172 | const char *ide_name; |
173 | /* map and setup chip, probe drives */ |
174 | void (*chip_map)(struct pciide_softc*, const struct pci_attach_args*); |
175 | }; |
176 | |
177 | /* Flags for ide_flags */ |
178 | #define IDE_16BIT_IOSPACE 0x0002 /* I/O space BARS ignore upper word */ |
179 | |
180 | |
181 | /* inlines for reading/writing 8-bit PCI registers */ |
182 | static inline u_int8_t pciide_pci_read(pci_chipset_tag_t, pcitag_t, int); |
183 | static inline void pciide_pci_write(pci_chipset_tag_t, pcitag_t, |
184 | int, u_int8_t); |
185 | |
186 | static inline u_int8_t |
187 | pciide_pci_read(pci_chipset_tag_t pc, pcitag_t pa, int reg) |
188 | { |
189 | |
190 | return (pci_conf_read(pc, pa, (reg & ~0x03)) >> |
191 | ((reg & 0x03) * 8) & 0xff); |
192 | } |
193 | |
194 | static inline void |
195 | pciide_pci_write(pci_chipset_tag_t pc, pcitag_t pa, int reg, uint8_t val) |
196 | { |
197 | pcireg_t pcival; |
198 | |
199 | pcival = pci_conf_read(pc, pa, (reg & ~0x03)); |
200 | pcival &= ~(0xff << ((reg & 0x03) * 8)); |
201 | pcival |= (val << ((reg & 0x03) * 8)); |
202 | pci_conf_write(pc, pa, (reg & ~0x03), pcival); |
203 | } |
204 | |
205 | void default_chip_map(struct pciide_softc*, const struct pci_attach_args*); |
206 | void sata_setup_channel(struct ata_channel*); |
207 | |
208 | void pciide_channel_dma_setup(struct pciide_channel *); |
209 | int pciide_dma_table_setup(struct pciide_softc*, int, int); |
210 | void pciide_dma_table_teardown(struct pciide_softc *, int, int); |
211 | |
212 | int pciide_dma_dmamap_setup(struct pciide_softc *, int, int, |
213 | void *, size_t, int); |
214 | int pciide_dma_init(void*, int, int, void *, size_t, int); |
215 | void pciide_dma_start(void*, int, int); |
216 | int pciide_dma_finish(void*, int, int, int); |
217 | void pciide_irqack(struct ata_channel *); |
218 | |
219 | /* |
220 | * Functions defined by machine-dependent code. |
221 | */ |
222 | |
223 | /* Attach compat interrupt handler, returning handle or NULL if failed. */ |
224 | #ifdef __HAVE_PCIIDE_MACHDEP_COMPAT_INTR_ESTABLISH |
225 | void *pciide_machdep_compat_intr_establish(device_t, |
226 | const struct pci_attach_args *, int, int (*)(void *), void *); |
227 | #endif |
228 | #ifdef __HAVE_PCIIDE_MACHDEP_COMPAT_INTR_DISESTABLISH |
229 | void pciide_machdep_compat_intr_disestablish(device_t, |
230 | pci_chipset_tag_t, int, void *); |
231 | #endif |
232 | |
233 | const struct pciide_product_desc* pciide_lookup_product |
234 | (u_int32_t, const struct pciide_product_desc *); |
235 | void pciide_common_attach(struct pciide_softc *, |
236 | const struct pci_attach_args *, |
237 | const struct pciide_product_desc *); |
238 | int pciide_common_detach(struct pciide_softc *, int); |
239 | int pciide_detach(device_t, int); |
240 | |
241 | int pciide_chipen(struct pciide_softc *, const struct pci_attach_args *); |
242 | void pciide_mapregs_compat(const struct pci_attach_args *, |
243 | struct pciide_channel *, int); |
244 | void pciide_mapregs_native(const struct pci_attach_args *, |
245 | struct pciide_channel *, int (*pci_intr)(void *)); |
246 | void pciide_mapreg_dma(struct pciide_softc *, |
247 | const struct pci_attach_args *); |
248 | int pciide_chansetup(struct pciide_softc *, int, pcireg_t); |
249 | void pciide_mapchan(const struct pci_attach_args *, |
250 | struct pciide_channel *, pcireg_t, int (*pci_intr)(void *)); |
251 | void pciide_map_compat_intr(const struct pci_attach_args *, |
252 | struct pciide_channel *, int); |
253 | void pciide_unmap_compat_intr(pci_chipset_tag_t, |
254 | struct pciide_channel *, int); |
255 | int pciide_compat_intr(void *); |
256 | int pciide_pci_intr(void *); |
257 | |
258 | #endif /* _DEV_PCI_PCIIDEVAR_H_ */ |
259 | |