xref: /openbsd/sys/dev/pci/qlw_pci.c (revision 73471bf0)
1 /*	$OpenBSD: qlw_pci.c,v 1.11 2021/05/01 16:11:16 visa Exp $ */
2 
3 /*
4  * Copyright (c) 2011 David Gwynne <dlg@openbsd.org>
5  * Copyright (c) 2013, 2014 Jonathan Matthew <jmatthew@openbsd.org>
6  * Copyright (c) 2014 Mark Kettenis <kettenis@openbsd.org>
7  *
8  * Permission to use, copy, modify, and distribute this software for any
9  * purpose with or without fee is hereby granted, provided that the above
10  * copyright notice and this permission notice appear in all copies.
11  *
12  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
13  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
14  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
15  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
16  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
18  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19  */
20 
21 #include "bio.h"
22 
23 #include <sys/param.h>
24 #include <sys/systm.h>
25 #include <sys/kernel.h>
26 #include <sys/malloc.h>
27 #include <sys/device.h>
28 #include <sys/sensors.h>
29 #include <sys/rwlock.h>
30 
31 #include <machine/bus.h>
32 
33 #include <dev/pci/pcireg.h>
34 #include <dev/pci/pcivar.h>
35 #include <dev/pci/pcidevs.h>
36 
37 #ifdef __sparc64__
38 #include <dev/ofw/openfirm.h>
39 #endif
40 
41 #include <scsi/scsi_all.h>
42 #include <scsi/scsiconf.h>
43 
44 #include <dev/ic/qlwreg.h>
45 #include <dev/ic/qlwvar.h>
46 
47 #ifndef ISP_NOFIRMWARE
48 #include <dev/microcode/isp/asm_1040.h>
49 #include <dev/microcode/isp/asm_1080.h>
50 #include <dev/microcode/isp/asm_12160.h>
51 #endif
52 
53 #define QLW_PCI_MEM_BAR		0x14
54 #define QLW_PCI_IO_BAR		0x10
55 
56 int	qlw_pci_match(struct device *, void *, void *);
57 void	qlw_pci_attach(struct device *, struct device *, void *);
58 int	qlw_pci_detach(struct device *, int);
59 
60 struct qlw_pci_softc {
61 	struct qlw_softc	psc_qlw;
62 
63 	pci_chipset_tag_t	psc_pc;
64 	pcitag_t		psc_tag;
65 
66 	void			*psc_ih;
67 };
68 
69 struct cfattach qlw_pci_ca = {
70 	sizeof(struct qlw_pci_softc),
71 	qlw_pci_match,
72 	qlw_pci_attach
73 };
74 
75 static const struct pci_matchid qlw_devices[] = {
76 	{ PCI_VENDOR_QLOGIC,	PCI_PRODUCT_QLOGIC_ISP1020 },
77 	{ PCI_VENDOR_QLOGIC,	PCI_PRODUCT_QLOGIC_ISP1240 },
78 	{ PCI_VENDOR_QLOGIC,	PCI_PRODUCT_QLOGIC_ISP1080 },
79 	{ PCI_VENDOR_QLOGIC,	PCI_PRODUCT_QLOGIC_ISP1280 },
80 	{ PCI_VENDOR_QLOGIC,	PCI_PRODUCT_QLOGIC_ISP10160 },
81 	{ PCI_VENDOR_QLOGIC,	PCI_PRODUCT_QLOGIC_ISP12160 },
82 };
83 
84 int
85 qlw_pci_match(struct device *parent, void *match, void *aux)
86 {
87 	struct pci_attach_args *pa = aux;
88 
89 	/* Silly AMI MegaRAID exposes its ISP12160 to us. */
90 	if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_QLOGIC_ISP12160) {
91 		pcireg_t subid;
92 
93 		subid = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_SUBVEND_0);
94 		if (PCI_VENDOR(subid) == PCI_VENDOR_AMI)
95 			return (0);
96 	}
97 
98 	return (pci_matchbyid(aux, qlw_devices, nitems(qlw_devices)) * 2);
99 }
100 
101 void
102 qlw_pci_attach(struct device *parent, struct device *self, void *aux)
103 {
104 	struct qlw_pci_softc *psc = (void *)self;
105 	struct qlw_softc *sc = &psc->psc_qlw;
106 	struct pci_attach_args *pa = aux;
107 	pci_intr_handle_t ih;
108 	const char *intrstr;
109 	u_int32_t pcictl;
110 #ifdef __sparc64__
111 	int node, initiator;
112 #endif
113 
114 	pcireg_t bars[] = { QLW_PCI_MEM_BAR, QLW_PCI_IO_BAR };
115 	pcireg_t memtype;
116 	int r;
117 
118 	psc->psc_pc = pa->pa_pc;
119 	psc->psc_tag = pa->pa_tag;
120 	psc->psc_ih = NULL;
121 	sc->sc_dmat = pa->pa_dmat;
122 	sc->sc_ios = 0;
123 
124 	for (r = 0; r < nitems(bars); r++) {
125 		memtype = pci_mapreg_type(psc->psc_pc, psc->psc_tag, bars[r]);
126 		if (pci_mapreg_map(pa, bars[r], memtype, 0,
127 		    &sc->sc_iot, &sc->sc_ioh, NULL, &sc->sc_ios, 0) == 0)
128 			break;
129 
130 		sc->sc_ios = 0;
131 	}
132 	if (sc->sc_ios == 0) {
133 		printf(": unable to map registers\n");
134 		return;
135 	}
136 
137 	if (pci_intr_map(pa, &ih)) {
138 		printf(": unable to map interrupt\n");
139 		goto unmap;
140 	}
141 	intrstr = pci_intr_string(psc->psc_pc, ih);
142 	psc->psc_ih = pci_intr_establish(psc->psc_pc, ih, IPL_BIO,
143 	    qlw_intr, sc, DEVNAME(sc));
144 	if (psc->psc_ih == NULL) {
145 		printf(": unable to establish interrupt");
146 		if (intrstr != NULL)
147 			printf(" at %s", intrstr);
148 		printf("\n");
149 		goto deintr;
150 	}
151 
152 	printf(": %s\n", intrstr);
153 
154 	pcictl = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG);
155 	pcictl |= PCI_COMMAND_INVALIDATE_ENABLE |
156 	    PCI_COMMAND_PARITY_ENABLE | PCI_COMMAND_SERR_ENABLE;
157 	pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG, pcictl);
158 
159 	pcictl = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_BHLC_REG);
160 	pcictl &= ~(PCI_LATTIMER_MASK << PCI_LATTIMER_SHIFT);
161 	pcictl &= ~(PCI_CACHELINE_MASK << PCI_CACHELINE_SHIFT);
162 	pcictl |= (0x80 << PCI_LATTIMER_SHIFT);
163 	pcictl |= (0x10 << PCI_CACHELINE_SHIFT);
164 	pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_BHLC_REG, pcictl);
165 
166 	pcictl = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_ROM_REG);
167 	pcictl &= ~1;
168 	pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_ROM_REG, pcictl);
169 
170 	switch (PCI_PRODUCT(pa->pa_id)) {
171 	case PCI_PRODUCT_QLOGIC_ISP1020:
172 		sc->sc_isp_gen = QLW_GEN_ISP1040;
173 		switch (PCI_REVISION(pa->pa_class)) {
174 		case 0:
175 			sc->sc_isp_type = QLW_ISP1020;
176 			break;
177 		case 1:
178 			sc->sc_isp_type = QLW_ISP1020A;
179 			break;
180 		case 2:
181 			sc->sc_isp_type = QLW_ISP1040;
182 			break;
183 		case 3:
184 			sc->sc_isp_type = QLW_ISP1040A;
185 			break;
186 		case 4:
187 			sc->sc_isp_type = QLW_ISP1040B;
188 			break;
189 		case 5:
190 		default:
191 			sc->sc_isp_type = QLW_ISP1040C;
192 			break;
193 		}
194 		sc->sc_numbusses = 1;
195 		if (PCI_REVISION(pa->pa_class) < 2)
196 			sc->sc_clock = 40; /* ISP1020/1020A */
197 		else
198 			sc->sc_clock = 60; /* ISP1040/1040A/1040B/1040C */
199 		break;
200 
201 	case PCI_PRODUCT_QLOGIC_ISP1240:
202 		sc->sc_isp_gen = QLW_GEN_ISP1080;
203 		sc->sc_isp_type = QLW_ISP1240;
204 		sc->sc_numbusses = 2;
205 		sc->sc_clock = 60;
206 		break;
207 
208 	case PCI_PRODUCT_QLOGIC_ISP1080:
209 		sc->sc_isp_gen = QLW_GEN_ISP1080;
210 		sc->sc_isp_type = QLW_ISP1080;
211 		sc->sc_numbusses = 1;
212 		sc->sc_clock = 100;
213 		break;
214 
215 	case PCI_PRODUCT_QLOGIC_ISP1280:
216 		sc->sc_isp_gen = QLW_GEN_ISP1080;
217 		sc->sc_isp_type = QLW_ISP1280;
218 		sc->sc_numbusses = 2;
219 		sc->sc_clock = 100;
220 		break;
221 
222 	case PCI_PRODUCT_QLOGIC_ISP10160:
223 		sc->sc_isp_gen = QLW_GEN_ISP12160;
224 		sc->sc_isp_type = QLW_ISP10160;
225 		sc->sc_numbusses = 1;
226 		sc->sc_clock = 100;
227 		break;
228 
229 	case PCI_PRODUCT_QLOGIC_ISP12160:
230 		sc->sc_isp_gen = QLW_GEN_ISP12160;
231 		sc->sc_isp_type = QLW_ISP12160;
232 		sc->sc_numbusses = 2;
233 		sc->sc_clock = 100;
234 		break;
235 
236 	default:
237 		printf("unknown pci id %x", pa->pa_id);
238 		return;
239 	}
240 
241 #ifndef ISP_NOFIRMWARE
242 	switch (sc->sc_isp_gen) {
243 	case QLW_GEN_ISP1040:
244 		sc->sc_firmware = isp_1040_risc_code;
245 		break;
246 	case QLW_GEN_ISP1080:
247 		sc->sc_firmware = isp_1080_risc_code;
248 		break;
249 	case QLW_GEN_ISP12160:
250 		sc->sc_firmware = isp_12160_risc_code;
251 		break;
252 	default:
253 		break;
254 	}
255 #endif
256 
257 	/*
258 	 * The standard SCSI initiator ID is 7.
259 	 * Add-on cards should have a valid nvram, which will override
260 	 * these defaults.
261 	 */
262 	sc->sc_initiator[0] = sc->sc_initiator[1] = 7;
263 
264 #ifdef __sparc64__
265 	/*
266 	 * Walk up the Open Firmware device tree until we find a
267 	 * "scsi-initiator-id" property.
268 	 */
269 	node = PCITAG_NODE(pa->pa_tag);
270 	while (node) {
271 		if (OF_getprop(node, "scsi-initiator-id",
272 		    &initiator, sizeof(initiator)) == sizeof(initiator)) {
273 			/*
274 			 * Override the SCSI initiator ID provided by
275 			 * the nvram.
276 			 */
277 			sc->sc_flags |= QLW_FLAG_INITIATOR;
278 			sc->sc_initiator[0] = sc->sc_initiator[1] = initiator;
279 			break;
280 		}
281 		node = OF_parent(node);
282 	}
283 #endif
284 
285 	sc->sc_host_cmd_ctrl = QLW_HOST_CMD_CTRL_PCI;
286 	sc->sc_mbox_base = QLW_MBOX_BASE_PCI;
287 
288 	if (qlw_attach(sc) != 0) {
289 		/* error printed by qlw_attach */
290 		goto deintr;
291 	}
292 
293 	return;
294 
295 deintr:
296 	pci_intr_disestablish(psc->psc_pc, psc->psc_ih);
297 	psc->psc_ih = NULL;
298 unmap:
299 	bus_space_unmap(sc->sc_iot, sc->sc_ioh, sc->sc_ios);
300 	sc->sc_ios = 0;
301 }
302 
303 int
304 qlw_pci_detach(struct device *self, int flags)
305 {
306 	struct qlw_pci_softc *psc = (struct qlw_pci_softc *)self;
307 	struct qlw_softc *sc = &psc->psc_qlw;
308 	int rv;
309 
310 	if (psc->psc_ih == NULL) {
311 		/* we didnt attach properly, so nothing to detach */
312 		return (0);
313 	}
314 
315 	rv = qlw_detach(sc, flags);
316 	if (rv != 0)
317 		return (rv);
318 
319 	pci_intr_disestablish(psc->psc_pc, psc->psc_ih);
320 	psc->psc_ih = NULL;
321 
322 	bus_space_unmap(sc->sc_iot, sc->sc_ioh, sc->sc_ios);
323 	sc->sc_ios = 0;
324 
325 	return (0);
326 }
327