Annotation of sys/dev/pci/siop_pci_common.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: siop_pci_common.c,v 1.15 2006/04/20 20:31:12 miod Exp $ */
2: /* $NetBSD: siop_pci_common.c,v 1.25 2005/06/28 00:28:42 thorpej Exp $ */
3:
4: /*
5: * Copyright (c) 2000 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: * 3. All advertising materials mentioning features or use of this software
16: * must display the following acknowledgement:
17: * This product includes software developed by Manuel Bouyer.
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: /* SYM53c8xx PCI-SCSI I/O Processors driver: PCI front-end */
34:
35: #include <sys/param.h>
36: #include <sys/systm.h>
37: #include <sys/device.h>
38: #include <sys/malloc.h>
39: #include <sys/buf.h>
40: #include <sys/kernel.h>
41:
42: #include <machine/endian.h>
43:
44: #include <dev/pci/pcireg.h>
45: #include <dev/pci/pcivar.h>
46: #include <dev/pci/pcidevs.h>
47:
48: #include <scsi/scsi_all.h>
49: #include <scsi/scsiconf.h>
50:
51: #include <dev/ic/siopreg.h>
52: #include <dev/ic/siopvar_common.h>
53: #include <dev/pci/siop_pci_common.h>
54:
55: /* List (array, really :) of chips we know how to handle */
56: const struct siop_product_desc siop_products[] = {
57: { PCI_PRODUCT_SYMBIOS_810,
58: 0x00,
59: SF_PCI_RL | SF_CHIP_LS,
60: 4, 8, 3, 250, 0
61: },
62: { PCI_PRODUCT_SYMBIOS_810,
63: 0x10,
64: SF_PCI_RL | SF_PCI_BOF | SF_CHIP_PF | SF_CHIP_LS,
65: 4, 8, 3, 250, 0
66: },
67: { PCI_PRODUCT_SYMBIOS_815,
68: 0x00,
69: SF_PCI_RL | SF_PCI_BOF,
70: 4, 8, 3, 250, 0
71: },
72: { PCI_PRODUCT_SYMBIOS_820,
73: 0x00,
74: SF_PCI_RL | SF_CHIP_LS | SF_BUS_WIDE,
75: 4, 8, 3, 250, 0
76: },
77: { PCI_PRODUCT_SYMBIOS_825,
78: 0x00,
79: SF_PCI_RL | SF_PCI_BOF | SF_BUS_WIDE,
80: 4, 8, 3, 250, 0
81: },
82: { PCI_PRODUCT_SYMBIOS_825,
83: 0x10,
84: SF_PCI_RL | SF_PCI_CLS | SF_PCI_WRI | SF_PCI_RM |
85: SF_CHIP_FIFO | SF_CHIP_PF | SF_CHIP_RAM | SF_CHIP_LS | SF_CHIP_10REGS |
86: SF_BUS_WIDE,
87: 7, 8, 3, 250, 4096
88: },
89: { PCI_PRODUCT_SYMBIOS_860,
90: 0x00,
91: SF_PCI_RL | SF_PCI_CLS | SF_PCI_WRI | SF_PCI_RM |
92: SF_CHIP_PF | SF_CHIP_LS |
93: SF_BUS_ULTRA,
94: 4, 8, 5, 125, 0
95: },
96: { PCI_PRODUCT_SYMBIOS_875,
97: 0x00,
98: SF_PCI_RL | SF_PCI_CLS | SF_PCI_WRI | SF_PCI_RM |
99: SF_CHIP_FIFO | SF_CHIP_PF | SF_CHIP_RAM | SF_CHIP_LS | SF_CHIP_10REGS |
100: SF_BUS_ULTRA | SF_BUS_WIDE,
101: 7, 16, 5, 125, 4096
102: },
103: { PCI_PRODUCT_SYMBIOS_875,
104: 0x02,
105: SF_PCI_RL | SF_PCI_CLS | SF_PCI_WRI | SF_PCI_RM |
106: SF_CHIP_FIFO | SF_CHIP_PF | SF_CHIP_RAM | SF_CHIP_DBLR |
107: SF_CHIP_LS | SF_CHIP_10REGS |
108: SF_BUS_ULTRA | SF_BUS_WIDE,
109: 7, 16, 5, 125, 4096
110: },
111: { PCI_PRODUCT_SYMBIOS_875J,
112: 0x00,
113: SF_PCI_RL | SF_PCI_CLS | SF_PCI_WRI | SF_PCI_RM |
114: SF_CHIP_FIFO | SF_CHIP_PF | SF_CHIP_RAM | SF_CHIP_DBLR |
115: SF_CHIP_LS | SF_CHIP_10REGS |
116: SF_BUS_ULTRA | SF_BUS_WIDE,
117: 7, 16, 5, 125, 4096
118: },
119: { PCI_PRODUCT_SYMBIOS_885,
120: 0x00,
121: SF_PCI_RL | SF_PCI_CLS | SF_PCI_WRI | SF_PCI_RM |
122: SF_CHIP_FIFO | SF_CHIP_PF | SF_CHIP_RAM | SF_CHIP_DBLR |
123: SF_CHIP_LS | SF_CHIP_10REGS |
124: SF_BUS_ULTRA | SF_BUS_WIDE,
125: 7, 16, 5, 125, 4096
126: },
127: { PCI_PRODUCT_SYMBIOS_895,
128: 0x00,
129: SF_PCI_RL | SF_PCI_CLS | SF_PCI_WRI | SF_PCI_RM |
130: SF_CHIP_FIFO | SF_CHIP_PF | SF_CHIP_RAM | SF_CHIP_QUAD |
131: SF_CHIP_LS | SF_CHIP_10REGS |
132: SF_BUS_ULTRA2 | SF_BUS_WIDE,
133: 7, 31, 7, 62, 4096
134: },
135: { PCI_PRODUCT_SYMBIOS_896,
136: 0x00,
137: SF_PCI_RL | SF_PCI_CLS | SF_PCI_WRI | SF_PCI_RM |
138: SF_CHIP_LEDC | SF_CHIP_FIFO | SF_CHIP_PF | SF_CHIP_RAM | SF_CHIP_QUAD |
139: SF_CHIP_LS | SF_CHIP_10REGS |
140: SF_BUS_ULTRA2 | SF_BUS_WIDE,
141: 7, 31, 7, 62, 8192
142: },
143: { PCI_PRODUCT_SYMBIOS_895A,
144: 0x00,
145: SF_PCI_RL | SF_PCI_CLS | SF_PCI_WRI | SF_PCI_RM |
146: SF_CHIP_LEDC | SF_CHIP_FIFO | SF_CHIP_PF | SF_CHIP_RAM | SF_CHIP_QUAD |
147: SF_CHIP_LS | SF_CHIP_10REGS |
148: SF_BUS_ULTRA2 | SF_BUS_WIDE,
149: 7, 31, 7, 62, 8192
150: },
151: { PCI_PRODUCT_SYMBIOS_1010,
152: 0x00,
153: SF_PCI_RL | SF_PCI_CLS | SF_PCI_WRI | SF_PCI_RM |
154: SF_CHIP_LEDC | SF_CHIP_FIFO | SF_CHIP_PF | SF_CHIP_RAM |
155: SF_CHIP_LS | SF_CHIP_10REGS | SF_CHIP_DFBC | SF_CHIP_DBLR |
156: SF_CHIP_GEBUG |
157: SF_BUS_ULTRA3 | SF_BUS_WIDE,
158: 7, 31, 0, 62, 8192
159: },
160: { PCI_PRODUCT_SYMBIOS_1010,
161: 0x01,
162: SF_PCI_RL | SF_PCI_CLS | SF_PCI_WRI | SF_PCI_RM |
163: SF_CHIP_LEDC | SF_CHIP_FIFO | SF_CHIP_PF | SF_CHIP_RAM |
164: SF_CHIP_LS | SF_CHIP_10REGS | SF_CHIP_DFBC | SF_CHIP_DBLR | SF_CHIP_DT |
165: SF_CHIP_GEBUG |
166: SF_BUS_ULTRA3 | SF_BUS_WIDE,
167: 7, 62, 0, 62, 8192
168: },
169: { PCI_PRODUCT_SYMBIOS_1010_2,
170: 0x00,
171: SF_PCI_RL | SF_PCI_CLS | SF_PCI_WRI | SF_PCI_RM |
172: SF_CHIP_LEDC | SF_CHIP_FIFO | SF_CHIP_PF | SF_CHIP_RAM |
173: SF_CHIP_LS | SF_CHIP_10REGS | SF_CHIP_DFBC | SF_CHIP_DBLR | SF_CHIP_DT |
174: SF_CHIP_AAIP |
175: SF_BUS_ULTRA3 | SF_BUS_WIDE,
176: 7, 62, 0, 62, 8192
177: },
178: { PCI_PRODUCT_SYMBIOS_1510D,
179: 0x00,
180: SF_PCI_RL | SF_PCI_CLS | SF_PCI_WRI | SF_PCI_RM |
181: SF_CHIP_FIFO | SF_CHIP_PF | SF_CHIP_RAM | SF_CHIP_QUAD |
182: SF_CHIP_LS | SF_CHIP_10REGS |
183: SF_BUS_ULTRA2 | SF_BUS_WIDE,
184: 7, 31, 7, 62, 4096
185: },
186: { 0,
187: 0x00,
188: 0x00,
189: 0, 0, 0, 0, 0
190: },
191: };
192:
193: const struct siop_product_desc *
194: siop_lookup_product(u_int32_t id, int rev)
195: {
196: const struct siop_product_desc *pp;
197: const struct siop_product_desc *rp = NULL;
198:
199: if (PCI_VENDOR(id) != PCI_VENDOR_SYMBIOS)
200: return NULL;
201:
202: for (pp = siop_products; pp->product != 0; pp++) {
203: if (PCI_PRODUCT(id) == pp->product && pp->revision <= rev)
204: if (rp == NULL || pp->revision > rp->revision)
205: rp = pp;
206: }
207: return rp;
208: }
209:
210: int
211: siop_pci_attach_common(struct siop_pci_common_softc *pci_sc,
212: struct siop_common_softc *siop_sc, struct pci_attach_args *pa,
213: int (*intr)(void*))
214: {
215: pci_chipset_tag_t pc = pa->pa_pc;
216: pcitag_t tag = pa->pa_tag;
217: const char *intrstr;
218: pci_intr_handle_t intrhandle;
219: bus_space_tag_t iot, memt;
220: bus_space_handle_t ioh, memh;
221: pcireg_t memtype;
222: int memh_valid, ioh_valid;
223: bus_addr_t ioaddr, memaddr;
224: bus_size_t memsize, iosize;
225:
226: pci_sc->sc_pp =
227: siop_lookup_product(pa->pa_id, PCI_REVISION(pa->pa_class));
228: if (pci_sc->sc_pp == NULL) {
229: printf(": broken match/attach!\n");
230: return 0;
231: }
232: /* copy interesting infos about the chip */
233: siop_sc->features = pci_sc->sc_pp->features;
234: #ifdef SIOP_SYMLED /* XXX Should be a devprop! */
235: siop_sc->features |= SF_CHIP_LED0;
236: #endif
237: siop_sc->maxburst = pci_sc->sc_pp->maxburst;
238: siop_sc->maxoff = pci_sc->sc_pp->maxoff;
239: siop_sc->clock_div = pci_sc->sc_pp->clock_div;
240: siop_sc->clock_period = pci_sc->sc_pp->clock_period;
241: siop_sc->ram_size = pci_sc->sc_pp->ram_size;
242:
243: siop_sc->sc_reset = siop_pci_reset;
244: pci_sc->sc_pc = pc;
245: pci_sc->sc_tag = tag;
246: siop_sc->sc_dmat = pa->pa_dmat;
247:
248: memtype = pci_mapreg_type(pa->pa_pc, pa->pa_tag, 0x14);
249: switch (memtype) {
250: case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT:
251: case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_64BIT:
252: memh_valid = (pci_mapreg_map(pa, 0x14, memtype, 0,
253: &memt, &memh, &memaddr, NULL, 0) == 0);
254: break;
255: default:
256: memh_valid = 0;
257: }
258:
259: ioh_valid = (pci_mapreg_map(pa, 0x10, PCI_MAPREG_TYPE_IO, 0,
260: &iot, &ioh, &ioaddr, &iosize, 0) == 0);
261:
262: if (memh_valid) {
263: siop_sc->sc_rt = memt;
264: siop_sc->sc_rh = memh;
265: siop_sc->sc_raddr = memaddr;
266: } else if (ioh_valid) {
267: siop_sc->sc_rt = iot;
268: siop_sc->sc_rh = ioh;
269: siop_sc->sc_raddr = ioaddr;
270: } else {
271: printf(": unable to map device registers\n");
272: return 0;
273: }
274:
275: if (pci_intr_map(pa, &intrhandle) != 0) {
276: printf(": couldn't map interrupt\n");
277: bus_space_unmap(siop_sc->sc_rt, siop_sc->sc_rh, iosize);
278: return 0;
279: }
280: intrstr = pci_intr_string(pa->pa_pc, intrhandle);
281: pci_sc->sc_ih = pci_intr_establish(pa->pa_pc, intrhandle, IPL_BIO,
282: intr, siop_sc, siop_sc->sc_dev.dv_xname);
283: if (pci_sc->sc_ih != NULL) {
284: printf(": %s",
285: intrstr ? intrstr : "?");
286: } else {
287: printf(": couldn't establish interrupt");
288: if (intrstr != NULL)
289: printf(" at %s", intrstr);
290: printf("\n");
291: bus_space_unmap(siop_sc->sc_rt, siop_sc->sc_rh, iosize);
292: return 0;
293: }
294:
295: if (siop_sc->features & SF_CHIP_RAM) {
296: int bar;
297: switch (memtype) {
298: case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT:
299: bar = 0x18;
300: break;
301: case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_64BIT:
302: bar = 0x1c;
303: break;
304: default:
305: printf(": invalid memory type %d\n", memtype);
306: return 0;
307: }
308: if (pci_mapreg_map(pa, bar, memtype, 0,
309: &siop_sc->sc_ramt, &siop_sc->sc_ramh,
310: &siop_sc->sc_scriptaddr, &memsize, 0) == 0) {
311: printf(", using %luK of on-board RAM",
312: (u_long)memsize / 1024);
313: } else {
314: printf(", can't map on-board RAM");
315: siop_sc->features &= ~SF_CHIP_RAM;
316: }
317: }
318:
319: printf("\n");
320:
321: return 1;
322: }
323:
324: void
325: siop_pci_reset(struct siop_common_softc *sc)
326: {
327: int dmode;
328:
329: dmode = bus_space_read_1(sc->sc_rt, sc->sc_rh, SIOP_DMODE);
330: if (sc->features & SF_PCI_RL)
331: dmode |= DMODE_ERL;
332: if (sc->features & SF_PCI_RM)
333: dmode |= DMODE_ERMP;
334: if (sc->features & SF_PCI_BOF)
335: dmode |= DMODE_BOF;
336: if (sc->features & SF_PCI_CLS)
337: bus_space_write_1(sc->sc_rt, sc->sc_rh, SIOP_DCNTL,
338: bus_space_read_1(sc->sc_rt, sc->sc_rh, SIOP_DCNTL) |
339: DCNTL_CLSE);
340: if (sc->features & SF_PCI_WRI)
341: bus_space_write_1(sc->sc_rt, sc->sc_rh, SIOP_CTEST3,
342: bus_space_read_1(sc->sc_rt, sc->sc_rh, SIOP_CTEST3) |
343: CTEST3_WRIE);
344: if (sc->maxburst) {
345: int ctest5 = bus_space_read_1(sc->sc_rt, sc->sc_rh,
346: SIOP_CTEST5);
347: bus_space_write_1(sc->sc_rt, sc->sc_rh, SIOP_CTEST4,
348: bus_space_read_1(sc->sc_rt, sc->sc_rh, SIOP_CTEST4) &
349: ~CTEST4_BDIS);
350: dmode &= ~DMODE_BL_MASK;
351: dmode |= ((sc->maxburst - 1) << DMODE_BL_SHIFT) & DMODE_BL_MASK;
352: ctest5 &= ~CTEST5_BBCK;
353: ctest5 |= (sc->maxburst - 1) & CTEST5_BBCK;
354: bus_space_write_1(sc->sc_rt, sc->sc_rh, SIOP_CTEST5, ctest5);
355: } else {
356: bus_space_write_1(sc->sc_rt, sc->sc_rh, SIOP_CTEST4,
357: bus_space_read_1(sc->sc_rt, sc->sc_rh, SIOP_CTEST4) |
358: CTEST4_BDIS);
359: }
360: bus_space_write_1(sc->sc_rt, sc->sc_rh, SIOP_DMODE, dmode);
361: }
CVSweb