1 /*        $NetBSD: pciidevar.h,v 1.51 2021/12/26 16:08:21 andvar 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           /* for CMD Technology 064x */
126           uint sc_cmd_act_channel;
127 
128           /* Vendor info (for interpreting Chip description) */
129           pcireg_t sc_pci_id;
130           /* Chip description */
131           const struct pciide_product_desc *sc_pp;
132           /* common definitions */
133           struct ata_channel *wdc_chanarray[PCIIDE_MAX_CHANNELS];
134           /* internal bookkeeping */
135           struct pciide_channel {                           /* per-channel data */
136                     struct ata_channel ata_channel; /* generic part */
137                     const char          *name;
138                     int                 compat;   /* is it compat? */
139                     void                *ih;      /* compat or pci handle */
140                     bus_space_handle_t ctl_baseioh; /* ctrl regs blk, native mode */
141                     bus_size_t      ctl_ios;
142 #if NATA_DMA
143                     /* DMA tables and DMA map for xfer, for each drive */
144                     struct pciide_dma_maps {
145                               bus_dma_segment_t dmamap_table_seg;
146                               int             dmamap_table_nseg;
147                               bus_dmamap_t    dmamap_table;
148                               struct idedma_table *dma_table;
149                               bus_dmamap_t    dmamap_xfer;
150                               int dma_flags;
151                     } dma_maps[WDC_MAXDRIVES];
152                     bus_space_handle_t  dma_iohs[IDEDMA_NREGS];
153                     /*
154                      * Some controllers require certain bits to
155                      * always be set for proper operation of the
156                      * controller.  Set those bits here, if they're
157                      * required.
158                      */
159                     uint8_t             idedma_cmd;
160 #endif    /* NATA_DMA */
161           } pciide_channels[PCIIDE_MAX_CHANNELS];
162 
163           pcireg_t            sc_pm_reg[4];
164 };
165 
166 /* Given an ata_channel, get the pciide_softc. */
167 #define   CHAN_TO_PCIIDE(chp) ((struct pciide_softc *) (chp)->ch_atac)
168 
169 /* Given an ata_channel, get the pciide_channel. */
170 #define   CHAN_TO_PCHAN(chp)  ((struct pciide_channel *) (chp))
171 
172 struct pciide_product_desc {
173           u_int32_t ide_product;
174           int ide_flags;
175           const char *ide_name;
176           /* map and setup chip, probe drives */
177           void (*chip_map)(struct pciide_softc*, const struct pci_attach_args*);
178 };
179 
180 /* Flags for ide_flags */
181 #define   IDE_16BIT_IOSPACE   0x0002 /* I/O space BARS ignore upper word */
182 #define   IDE_SHARED_CHANNELS 0x0004 /* channels are not independent */
183 
184 
185 /* inlines for reading/writing 8-bit PCI registers */
186 static __inline u_int8_t pciide_pci_read(pci_chipset_tag_t, pcitag_t, int);
187 static __inline void pciide_pci_write(pci_chipset_tag_t, pcitag_t,
188                                                      int, u_int8_t);
189 
190 static __inline u_int8_t
pciide_pci_read(pci_chipset_tag_t pc,pcitag_t pa,int reg)191 pciide_pci_read(pci_chipset_tag_t pc, pcitag_t pa, int reg)
192 {
193 
194           return (pci_conf_read(pc, pa, (reg & ~0x03)) >>
195               ((reg & 0x03) * 8) & 0xff);
196 }
197 
198 static __inline void
pciide_pci_write(pci_chipset_tag_t pc,pcitag_t pa,int reg,uint8_t val)199 pciide_pci_write(pci_chipset_tag_t pc, pcitag_t pa, int reg, uint8_t val)
200 {
201           pcireg_t pcival;
202 
203           pcival = pci_conf_read(pc, pa, (reg & ~0x03));
204           pcival &= ~(0xff << ((reg & 0x03) * 8));
205           pcival |= (val << ((reg & 0x03) * 8));
206           pci_conf_write(pc, pa, (reg & ~0x03), pcival);
207 }
208 
209 void default_chip_map(struct pciide_softc*, const struct pci_attach_args*);
210 void sata_setup_channel(struct ata_channel*);
211 
212 void pciide_channel_dma_setup(struct pciide_channel *);
213 int  pciide_dma_table_setup(struct pciide_softc*, int, int);
214 void pciide_dma_table_teardown(struct pciide_softc *, int, int);
215 
216 int  pciide_dma_dmamap_setup(struct pciide_softc *, int, int,
217                                         void *, size_t, int);
218 int  pciide_dma_init(void*, int, int, void *, size_t, int);
219 void pciide_dma_start(void*, int, int);
220 int  pciide_dma_finish(void*, int, int, int);
221 void pciide_irqack(struct ata_channel *);
222 
223 /*
224  * Functions defined by machine-dependent code.
225  */
226 
227 /* Attach compat interrupt handler, returning handle or NULL if failed. */
228 #ifdef __HAVE_PCIIDE_MACHDEP_COMPAT_INTR_ESTABLISH
229 void      *pciide_machdep_compat_intr_establish(device_t,
230               const struct pci_attach_args *, int, int (*)(void *), void *);
231 #endif
232 #ifdef __HAVE_PCIIDE_MACHDEP_COMPAT_INTR_DISESTABLISH
233 void      pciide_machdep_compat_intr_disestablish(device_t,
234               pci_chipset_tag_t, int,  void *);
235 #endif
236 
237 const struct pciide_product_desc* pciide_lookup_product
238           (u_int32_t, const struct pciide_product_desc *);
239 void      pciide_common_attach(struct pciide_softc *,
240                     const struct pci_attach_args *,
241                     const struct pciide_product_desc *);
242 int       pciide_common_detach(struct pciide_softc *, int);
243 int       pciide_detach(device_t, int);
244 
245 int       pciide_chipen(struct pciide_softc *, const struct pci_attach_args *);
246 void      pciide_mapregs_compat(const struct pci_attach_args *,
247               struct pciide_channel *, int);
248 void      pciide_mapregs_native(const struct pci_attach_args *,
249               struct pciide_channel *, int (*pci_intr)(void *));
250 void      pciide_mapreg_dma(struct pciide_softc *,
251               const struct pci_attach_args *);
252 int       pciide_chansetup(struct pciide_softc *, int, pcireg_t);
253 void      pciide_mapchan(const struct pci_attach_args *,
254               struct pciide_channel *, pcireg_t, int (*pci_intr)(void *));
255 void      pciide_map_compat_intr(const struct pci_attach_args *,
256               struct pciide_channel *, int);
257 void      pciide_unmap_compat_intr(pci_chipset_tag_t,
258               struct pciide_channel *, int);
259 int       pciide_compat_intr(void *);
260 int       pciide_pci_intr(void *);
261 
262 #endif /* _DEV_PCI_PCIIDEVAR_H_ */
263