This source file includes following definitions.
- cac_pci_findtype
- cac_pci_match
- cac_pci_attach
- cac_pci_l0_submit
- cac_pci_l0_completed
- cac_pci_l0_intr_pending
- cac_pci_l0_intr_enable
- cac_pci_l0_fifo_full
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44 #include <sys/param.h>
45 #include <sys/systm.h>
46 #include <sys/kernel.h>
47 #include <sys/device.h>
48 #include <sys/queue.h>
49
50 #include <machine/endian.h>
51 #include <machine/bus.h>
52
53 #include <dev/pci/pcidevs.h>
54 #include <dev/pci/pcivar.h>
55
56 #include <scsi/scsi_all.h>
57 #include <scsi/scsi_disk.h>
58 #include <scsi/scsiconf.h>
59
60 #include <dev/ic/cacreg.h>
61 #include <dev/ic/cacvar.h>
62
63 void cac_pci_attach(struct device *, struct device *, void *);
64 const struct cac_pci_type *cac_pci_findtype(struct pci_attach_args *);
65 int cac_pci_match(struct device *, void *, void *);
66
67 struct cac_ccb *cac_pci_l0_completed(struct cac_softc *);
68 int cac_pci_l0_fifo_full(struct cac_softc *);
69 void cac_pci_l0_intr_enable(struct cac_softc *, int);
70 int cac_pci_l0_intr_pending(struct cac_softc *);
71 void cac_pci_l0_submit(struct cac_softc *, struct cac_ccb *);
72
73 struct cfattach cac_pci_ca = {
74 sizeof(struct cac_softc), cac_pci_match, cac_pci_attach
75 };
76
77 static const struct cac_linkage cac_pci_l0 = {
78 cac_pci_l0_completed,
79 cac_pci_l0_fifo_full,
80 cac_pci_l0_intr_enable,
81 cac_pci_l0_intr_pending,
82 cac_pci_l0_submit
83 };
84
85 #define CT_STARTFW 0x01
86
87 static const
88 struct cac_pci_type {
89 int ct_subsysid;
90 int ct_flags;
91 const struct cac_linkage *ct_linkage;
92 char *ct_typestr;
93 } cac_pci_type[] = {
94 { 0x40300e11, 0, &cac_l0, "SMART-2/P" },
95 { 0x40310e11, 0, &cac_l0, "SMART-2SL" },
96 { 0x40320e11, 0, &cac_l0, "Smart Array 3200" },
97 { 0x40330e11, 0, &cac_l0, "Smart Array 3100ES" },
98 { 0x40340e11, 0, &cac_l0, "Smart Array 221" },
99 { 0x40400e11, CT_STARTFW, &cac_pci_l0, "Integrated Array" },
100 { 0x40480e11, CT_STARTFW, &cac_pci_l0, "RAID LC2" },
101 { 0x40500e11, 0, &cac_pci_l0, "Smart Array 4200" },
102 { 0x40510e11, 0, &cac_pci_l0, "Smart Array 4200ES" },
103 { 0x40580e11, 0, &cac_pci_l0, "Smart Array 431" },
104 };
105
106 static const
107 struct cac_pci_product {
108 u_short cp_vendor;
109 u_short cp_product;
110 } cac_pci_product[] = {
111 { PCI_VENDOR_COMPAQ, PCI_PRODUCT_COMPAQ_SMART2P },
112 { PCI_VENDOR_DEC, PCI_PRODUCT_DEC_CPQ42XX },
113 { PCI_VENDOR_SYMBIOS, PCI_PRODUCT_SYMBIOS_1510 },
114 };
115
116 const struct cac_pci_type *
117 cac_pci_findtype(pa)
118 struct pci_attach_args *pa;
119 {
120 const struct cac_pci_type *ct;
121 const struct cac_pci_product *cp;
122 pcireg_t subsysid;
123 int i;
124
125 cp = cac_pci_product;
126 i = 0;
127 while (i < sizeof(cac_pci_product) / sizeof(cac_pci_product[0])) {
128 if (PCI_VENDOR(pa->pa_id) == cp->cp_vendor &&
129 PCI_PRODUCT(pa->pa_id) == cp->cp_product)
130 break;
131 cp++;
132 i++;
133 }
134 if (i == sizeof(cac_pci_product) / sizeof(cac_pci_product[0]))
135 return (NULL);
136
137 subsysid = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_SUBSYS_ID_REG);
138 ct = cac_pci_type;
139 i = 0;
140 while (i < sizeof(cac_pci_type) / sizeof(cac_pci_type[0])) {
141 if (subsysid == ct->ct_subsysid)
142 break;
143 ct++;
144 i++;
145 }
146 if (i == sizeof(cac_pci_type) / sizeof(cac_pci_type[0]))
147 return (NULL);
148
149 return (ct);
150 }
151
152 int
153 cac_pci_match(parent, match, aux)
154 struct device *parent;
155 void *match, *aux;
156 {
157
158 return (cac_pci_findtype(aux) != NULL);
159 }
160
161 void
162 cac_pci_attach(parent, self, aux)
163 struct device *parent;
164 struct device *self;
165 void *aux;
166 {
167 struct pci_attach_args *pa;
168 const struct cac_pci_type *ct;
169 struct cac_softc *sc;
170 pci_chipset_tag_t pc;
171 pci_intr_handle_t ih;
172 const char *intrstr;
173 pcireg_t reg;
174 bus_size_t size;
175 int memr, ior, i;
176
177 sc = (struct cac_softc *)self;
178 pa = (struct pci_attach_args *)aux;
179 pc = pa->pa_pc;
180 ct = cac_pci_findtype(pa);
181
182
183
184
185 memr = -1;
186 ior = -1;
187
188 for (i = 0x10; i <= 0x14; i += 4) {
189 reg = pci_conf_read(pa->pa_pc, pa->pa_tag, i);
190
191 if (PCI_MAPREG_TYPE(reg) == PCI_MAPREG_TYPE_IO) {
192 if (ior == -1 && PCI_MAPREG_IO_SIZE(reg) != 0)
193 ior = i;
194 } else {
195 if (memr == -1 && PCI_MAPREG_MEM_SIZE(reg) != 0)
196 memr = i;
197 }
198 }
199
200 if (memr != -1) {
201 if (pci_mapreg_map(pa, memr, PCI_MAPREG_TYPE_MEM, 0,
202 &sc->sc_iot, &sc->sc_ioh, NULL, &size, 0))
203 memr = -1;
204 else
205 ior = -1;
206 }
207 if (ior != -1)
208 if (pci_mapreg_map(pa, ior, PCI_MAPREG_TYPE_IO, 0,
209 &sc->sc_iot, &sc->sc_ioh, NULL, &size, 0))
210 ior = -1;
211 if (memr == -1 && ior == -1) {
212 printf("%s: can't map i/o or memory space\n", self->dv_xname);
213 return;
214 }
215
216 sc->sc_dmat = pa->pa_dmat;
217
218
219 if (pci_intr_map(pa, &ih)) {
220 printf(": can't map interrupt\n");
221 bus_space_unmap(sc->sc_iot, sc->sc_ioh, size);
222 return;
223 }
224 intrstr = pci_intr_string(pc, ih);
225 sc->sc_ih = pci_intr_establish(pc, ih, IPL_BIO, cac_intr,
226 sc, sc->sc_dv.dv_xname);
227 if (sc->sc_ih == NULL) {
228 printf(": can't establish interrupt");
229 if (intrstr != NULL)
230 printf(" at %s", intrstr);
231 printf("\n");
232 bus_space_unmap(sc->sc_iot, sc->sc_ioh, size);
233 return;
234 }
235
236 printf(": %s Compaq %s\n", intrstr, ct->ct_typestr);
237
238
239 sc->sc_cl = ct->ct_linkage;
240 cac_init(sc, (ct->ct_flags & CT_STARTFW) != 0);
241 }
242
243 void
244 cac_pci_l0_submit(struct cac_softc *sc, struct cac_ccb *ccb)
245 {
246
247 bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap, 0,
248 sc->sc_dmamap->dm_mapsize,
249 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
250 cac_outl(sc, CAC_42REG_CMD_FIFO, ccb->ccb_paddr);
251 }
252
253 struct cac_ccb *
254 cac_pci_l0_completed(struct cac_softc *sc)
255 {
256 struct cac_ccb *ccb;
257 u_int32_t off;
258
259 if ((off = cac_inl(sc, CAC_42REG_DONE_FIFO)) == 0xffffffffU)
260 return (NULL);
261
262 cac_outl(sc, CAC_42REG_DONE_FIFO, 0);
263 off = (off & ~3) - sc->sc_ccbs_paddr;
264 ccb = (struct cac_ccb *)(sc->sc_ccbs + off);
265
266 bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap, 0,
267 sc->sc_dmamap->dm_mapsize,
268 BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
269
270 return (ccb);
271 }
272
273 int
274 cac_pci_l0_intr_pending(struct cac_softc *sc)
275 {
276
277 return ((cac_inl(sc, CAC_42REG_STATUS) & CAC_42_EXTINT) != 0);
278 }
279
280 void
281 cac_pci_l0_intr_enable(struct cac_softc *sc, int state)
282 {
283
284 cac_outl(sc, CAC_42REG_INTR_MASK, (state ? 0 : 8));
285 }
286
287 int
288 cac_pci_l0_fifo_full(struct cac_softc *sc)
289 {
290
291 return (cac_inl(sc, CAC_42REG_CMD_FIFO) != 0);
292 }