xref: /netbsd-src/sys/dev/pci/ichsmb.c (revision 782713e6c126f1866c6d9cfdee4ceb49483b5828)
1 /*	$NetBSD: ichsmb.c,v 1.82 2023/04/12 06:39:15 riastradh Exp $	*/
2 /*	$OpenBSD: ichiic.c,v 1.44 2020/10/07 11:23:05 jsg Exp $	*/
3 
4 /*
5  * Copyright (c) 2005, 2006 Alexander Yurchenko <grange@openbsd.org>
6  *
7  * Permission to use, copy, modify, and distribute this software for any
8  * purpose with or without fee is hereby granted, provided that the above
9  * copyright notice and this permission notice appear in all copies.
10  *
11  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18  */
19 
20 /*
21  * Intel ICH SMBus controller driver.
22  */
23 
24 #include <sys/cdefs.h>
25 __KERNEL_RCSID(0, "$NetBSD: ichsmb.c,v 1.82 2023/04/12 06:39:15 riastradh Exp $");
26 
27 #include <sys/param.h>
28 #include <sys/device.h>
29 #include <sys/errno.h>
30 #include <sys/kernel.h>
31 #include <sys/mutex.h>
32 #include <sys/condvar.h>
33 #include <sys/module.h>
34 
35 #include <sys/bus.h>
36 
37 #include <dev/pci/pcidevs.h>
38 #include <dev/pci/pcireg.h>
39 #include <dev/pci/pcivar.h>
40 
41 #include <dev/ic/i82801lpcreg.h>
42 
43 #include <dev/i2c/i2cvar.h>
44 
45 #include <x86/pci/tco.h>
46 
47 #ifdef ICHIIC_DEBUG
48 #define DPRINTF(x) printf x
49 #else
50 #define DPRINTF(x)
51 #endif
52 
53 #define ICHIIC_DELAY	100
54 #define ICHIIC_TIMEOUT	1
55 
56 struct ichsmb_softc {
57 	device_t		sc_dev;
58 
59 	bus_space_tag_t		sc_iot;
60 	bus_space_handle_t	sc_ioh;
61 	bus_size_t		sc_size;
62 	pci_chipset_tag_t	sc_pc;
63 	void *			sc_ih;
64 	int			sc_poll;
65 	pci_intr_handle_t	*sc_pihp;
66 
67 	kmutex_t		sc_exec_lock;
68 	kcondvar_t		sc_exec_wait;
69 
70 	struct i2c_controller	sc_i2c_tag;
71 	struct {
72 		i2c_op_t     op;
73 		void *       buf;
74 		size_t       len;
75 		int          flags;
76 		int          error;
77 		bool         done;
78 	}			sc_i2c_xfer;
79 	device_t		sc_i2c_device;
80 
81 	bus_space_tag_t		sc_tcot;
82 	bus_space_handle_t	sc_tcoh;
83 	bus_size_t		sc_tcosz;
84 	bus_space_tag_t		sc_sbregt;
85 	bus_space_handle_t	sc_sbregh;
86 	bus_size_t		sc_sbregsz;
87 	bus_space_tag_t		sc_pmt;
88 	bus_space_handle_t	sc_pmh;
89 	bus_size_t		sc_pmsz;
90 	bool			sc_tco_probed;
91 	device_t		sc_tco_device;
92 };
93 
94 static int	ichsmb_match(device_t, cfdata_t, void *);
95 static void	ichsmb_attach(device_t, device_t, void *);
96 static int	ichsmb_detach(device_t, int);
97 static int	ichsmb_rescan(device_t, const char *, const int *);
98 static void	ichsmb_chdet(device_t, device_t);
99 
100 static void	ichsmb_probe_tco(struct ichsmb_softc *,
101 		    const struct pci_attach_args *);
102 
103 static int	ichsmb_i2c_exec(void *, i2c_op_t, i2c_addr_t, const void *,
104 		    size_t, void *, size_t, int);
105 
106 static int	ichsmb_intr(void *);
107 
108 #include "ioconf.h"
109 
110 CFATTACH_DECL3_NEW(ichsmb, sizeof(struct ichsmb_softc),
111     ichsmb_match, ichsmb_attach, ichsmb_detach, NULL, ichsmb_rescan,
112     ichsmb_chdet, DVF_DETACH_SHUTDOWN);
113 
114 
115 static int
116 ichsmb_match(device_t parent, cfdata_t match, void *aux)
117 {
118 	struct pci_attach_args *pa = aux;
119 
120 	if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_INTEL) {
121 		switch (PCI_PRODUCT(pa->pa_id)) {
122 		case PCI_PRODUCT_INTEL_6300ESB_SMB:
123 		case PCI_PRODUCT_INTEL_63XXESB_SMB:
124 		case PCI_PRODUCT_INTEL_82801AA_SMB:
125 		case PCI_PRODUCT_INTEL_82801AB_SMB:
126 		case PCI_PRODUCT_INTEL_82801BA_SMB:
127 		case PCI_PRODUCT_INTEL_82801CA_SMB:
128 		case PCI_PRODUCT_INTEL_82801DB_SMB:
129 		case PCI_PRODUCT_INTEL_82801E_SMB:
130 		case PCI_PRODUCT_INTEL_82801EB_SMB:
131 		case PCI_PRODUCT_INTEL_82801FB_SMB:
132 		case PCI_PRODUCT_INTEL_82801G_SMB:
133 		case PCI_PRODUCT_INTEL_82801H_SMB:
134 		case PCI_PRODUCT_INTEL_82801I_SMB:
135 		case PCI_PRODUCT_INTEL_82801JD_SMB:
136 		case PCI_PRODUCT_INTEL_82801JI_SMB:
137 		case PCI_PRODUCT_INTEL_3400_SMB:
138 		case PCI_PRODUCT_INTEL_6SERIES_SMB:
139 		case PCI_PRODUCT_INTEL_7SERIES_SMB:
140 		case PCI_PRODUCT_INTEL_8SERIES_SMB:
141 		case PCI_PRODUCT_INTEL_9SERIES_SMB:
142 		case PCI_PRODUCT_INTEL_100SERIES_SMB:
143 		case PCI_PRODUCT_INTEL_100SERIES_LP_SMB:
144 		case PCI_PRODUCT_INTEL_2HS_SMB:
145 		case PCI_PRODUCT_INTEL_3HS_SMB:
146 		case PCI_PRODUCT_INTEL_3HS_U_SMB:
147 		case PCI_PRODUCT_INTEL_4HS_H_SMB:
148 		case PCI_PRODUCT_INTEL_4HS_V_SMB:
149 		case PCI_PRODUCT_INTEL_CORE4G_M_SMB:
150 		case PCI_PRODUCT_INTEL_CORE5G_M_SMB:
151 		case PCI_PRODUCT_INTEL_CMTLK_SMB:
152 		case PCI_PRODUCT_INTEL_BAYTRAIL_PCU_SMB:
153 		case PCI_PRODUCT_INTEL_BSW_PCU_SMB:
154 		case PCI_PRODUCT_INTEL_APL_SMB:
155 		case PCI_PRODUCT_INTEL_GLK_SMB:
156 		case PCI_PRODUCT_INTEL_EHL_SMB:
157 		case PCI_PRODUCT_INTEL_JSL_SMB:
158 		case PCI_PRODUCT_INTEL_C600_SMBUS:
159 		case PCI_PRODUCT_INTEL_C600_SMB_0:
160 		case PCI_PRODUCT_INTEL_C600_SMB_1:
161 		case PCI_PRODUCT_INTEL_C600_SMB_2:
162 		case PCI_PRODUCT_INTEL_C610_SMB:
163 		case PCI_PRODUCT_INTEL_C620_SMB:
164 		case PCI_PRODUCT_INTEL_C620_SMB_S:
165 		case PCI_PRODUCT_INTEL_EP80579_SMB:
166 		case PCI_PRODUCT_INTEL_DH89XXCC_SMB:
167 		case PCI_PRODUCT_INTEL_DH89XXCL_SMB:
168 		case PCI_PRODUCT_INTEL_C2000_PCU_SMBUS:
169 		case PCI_PRODUCT_INTEL_C3K_SMBUS_LEGACY:
170 		case PCI_PRODUCT_INTEL_495_YU_SMB:
171 		case PCI_PRODUCT_INTEL_5HS_H_SMB:
172 		case PCI_PRODUCT_INTEL_5HS_LP_SMB:
173 		case PCI_PRODUCT_INTEL_6HS_H_SMB:
174 		case PCI_PRODUCT_INTEL_6HS_LP_SMB:
175 			return 1;
176 		}
177 	}
178 	return 0;
179 }
180 
181 static void
182 ichsmb_attach(device_t parent, device_t self, void *aux)
183 {
184 	struct ichsmb_softc *sc = device_private(self);
185 	struct pci_attach_args *pa = aux;
186 	pcireg_t conf;
187 	const char *intrstr = NULL;
188 	char intrbuf[PCI_INTRSTR_LEN];
189 
190 	sc->sc_dev = self;
191 	sc->sc_pc = pa->pa_pc;
192 
193 	pci_aprint_devinfo(pa, NULL);
194 
195 	mutex_init(&sc->sc_exec_lock, MUTEX_DEFAULT, IPL_BIO);
196 	cv_init(&sc->sc_exec_wait, device_xname(self));
197 
198 	/* Read configuration */
199 	conf = pci_conf_read(pa->pa_pc, pa->pa_tag, SMB_HOSTC);
200 	DPRINTF(("%s: conf 0x%08x\n", device_xname(sc->sc_dev), conf));
201 
202 	if ((conf & SMB_HOSTC_HSTEN) == 0) {
203 		aprint_error_dev(self, "SMBus disabled\n");
204 		goto out;
205 	}
206 
207 	/* Map I/O space */
208 	if (pci_mapreg_map(pa, SMB_BASE, PCI_MAPREG_TYPE_IO, 0,
209 	    &sc->sc_iot, &sc->sc_ioh, NULL, &sc->sc_size)) {
210 		aprint_error_dev(self, "can't map I/O space\n");
211 		goto out;
212 	}
213 
214 	sc->sc_poll = 1;
215 	sc->sc_ih = NULL;
216 	if (conf & SMB_HOSTC_SMIEN) {
217 		/* No PCI IRQ */
218 		aprint_normal_dev(self, "interrupting at SMI\n");
219 	} else {
220 		/* Install interrupt handler */
221 		if (pci_intr_alloc(pa, &sc->sc_pihp, NULL, 0) == 0) {
222 			intrstr = pci_intr_string(pa->pa_pc, sc->sc_pihp[0],
223 			    intrbuf, sizeof(intrbuf));
224 			pci_intr_setattr(pa->pa_pc, &sc->sc_pihp[0],
225 			    PCI_INTR_MPSAFE, true);
226 			sc->sc_ih = pci_intr_establish_xname(pa->pa_pc,
227 			    sc->sc_pihp[0], IPL_BIO, ichsmb_intr, sc,
228 			    device_xname(sc->sc_dev));
229 			if (sc->sc_ih != NULL) {
230 				aprint_normal_dev(self, "interrupting at %s\n",
231 				    intrstr);
232 				sc->sc_poll = 0;
233 			} else {
234 				pci_intr_release(pa->pa_pc, sc->sc_pihp, 1);
235 				sc->sc_pihp = NULL;
236 			}
237 		}
238 		if (sc->sc_poll)
239 			aprint_normal_dev(self, "polling\n");
240 	}
241 
242 	/* Attach I2C bus */
243 	iic_tag_init(&sc->sc_i2c_tag);
244 	sc->sc_i2c_tag.ic_cookie = sc;
245 	sc->sc_i2c_tag.ic_exec = ichsmb_i2c_exec;
246 
247 	/*
248 	 * Probe to see if there's a TCO hanging here instead of the
249 	 * LPCIB and map it if we can.
250 	 */
251 	ichsmb_probe_tco(sc, pa);
252 
253 	sc->sc_i2c_device = NULL;
254 	ichsmb_rescan(self, NULL, NULL);
255 
256 out:	if (!pmf_device_register(self, NULL, NULL))
257 		aprint_error_dev(self, "couldn't establish power handler\n");
258 }
259 
260 static void
261 ichsmb_probe_tco(struct ichsmb_softc *sc, const struct pci_attach_args *pa)
262 {
263 	const device_t self = sc->sc_dev;
264 	const pci_chipset_tag_t pc = sc->sc_pc;
265 	const pcitag_t p2sb_tag = pci_make_tag(pc,
266 	    /*bus*/0, /*dev*/0x1f, /*fn*/1);
267 	const pcitag_t pmc_tag = pci_make_tag(pc,
268 	    /*bus*/0, /*dev*/0x1f, /*fn*/2);
269 	pcireg_t tcoctl, tcobase, p2sbc, sbreglo, sbreghi;
270 	bus_addr_t sbreg, pmbase;
271 	int error = EIO;
272 
273 	/*
274 	 * Only attempt this on devices where we expect to find a TCO.
275 	 */
276 	switch (PCI_PRODUCT(pa->pa_id)) {
277 	case PCI_PRODUCT_INTEL_100SERIES_LP_SMB:
278 	case PCI_PRODUCT_INTEL_100SERIES_SMB:
279 		break;
280 	default:
281 		goto fail;
282 	}
283 
284 	/*
285 	 * Verify the TCO base address register is enabled.
286 	 */
287 	tcoctl = pci_conf_read(pa->pa_pc, pa->pa_tag, SMB_TCOCTL);
288 	aprint_debug_dev(self, "TCOCTL=0x%"PRIx32"\n", tcoctl);
289 	if ((tcoctl & SMB_TCOCTL_TCO_BASE_EN) == 0) {
290 		aprint_debug_dev(self, "TCO disabled\n");
291 		goto fail;
292 	}
293 
294 	/*
295 	 * Verify the TCO base address register has the I/O space bit
296 	 * set -- otherwise we don't know how to interpret the
297 	 * register.
298 	 */
299 	tcobase = pci_conf_read(pa->pa_pc, pa->pa_tag, SMB_TCOBASE);
300 	aprint_debug_dev(self, "TCOBASE=0x%"PRIx32"\n", tcobase);
301 	if ((tcobase & SMB_TCOBASE_IOS) == 0) {
302 		aprint_error_dev(self, "unrecognized TCO space\n");
303 		goto fail;
304 	}
305 
306 	/*
307 	 * Map the TCO I/O space.
308 	 */
309 	sc->sc_tcot = sc->sc_iot;
310 	error = bus_space_map(sc->sc_tcot, tcobase & SMB_TCOBASE_TCOBA,
311 	    TCO_REGSIZE, 0, &sc->sc_tcoh);
312 	if (error) {
313 		aprint_error_dev(self, "failed to map TCO: %d\n", error);
314 		goto fail;
315 	}
316 	sc->sc_tcosz = TCO_REGSIZE;
317 
318 	/*
319 	 * Clear the Hide Device bit so we can map the SBREG_BAR from
320 	 * the P2SB registers; then restore the Hide Device bit so
321 	 * nobody else gets confused.
322 	 *
323 	 * XXX Hope nobody else is trying to touch the P2SB!
324 	 *
325 	 * XXX Should we have a way to lock PCI bus enumeration,
326 	 * e.g. from concurrent drvctl rescan?
327 	 *
328 	 * XXX pci_mapreg_info doesn't work to get the size, somehow
329 	 * comes out as 4.  Datasheet for 100-series chipset says the
330 	 * size is 16 MB, unconditionally, and the type is memory.
331 	 *
332 	 * XXX The above XXX comment was probably a result of PEBCAK
333 	 * when I tried to use 0xe4 instead of 0xe0 for P2SBC -- should
334 	 * try again with pci_mapreg_info or pci_mapreg_map.
335 	 */
336 	p2sbc = pci_conf_read(pc, p2sb_tag, P2SB_P2SBC);
337 	aprint_debug_dev(self, "P2SBC=0x%x\n", p2sbc);
338 	pci_conf_write(pc, p2sb_tag, P2SB_P2SBC, p2sbc & ~P2SB_P2SBC_HIDE);
339 	aprint_debug_dev(self, "P2SBC=0x%x -> 0x%x\n", p2sbc,
340 	    pci_conf_read(pc, p2sb_tag, P2SB_P2SBC));
341 	sbreglo = pci_conf_read(pc, p2sb_tag, P2SB_SBREG_BAR);
342 	sbreghi = pci_conf_read(pc, p2sb_tag, P2SB_SBREG_BARH);
343 	aprint_debug_dev(self, "SBREG_BAR=0x%08x 0x%08x\n", sbreglo, sbreghi);
344 	pci_conf_write(sc->sc_pc, p2sb_tag, P2SB_P2SBC, p2sbc);
345 
346 	/*
347 	 * Map the sideband registers so we can touch the NO_REBOOT
348 	 * bit.
349 	 */
350 	sbreg = ((uint64_t)sbreghi << 32) | (sbreglo & ~__BITS(0,3));
351 	if (((uint64_t)sbreg >> 32) != sbreghi) {
352 		/* paranoia for 32-bit non-PAE */
353 		aprint_error_dev(self, "can't map 64-bit SBREG\n");
354 		goto fail;
355 	}
356 	sc->sc_sbregt = pa->pa_memt;
357 	error = bus_space_map(sc->sc_sbregt, sbreg + SB_SMBUS_BASE,
358 	    SB_SMBUS_SIZE, 0, &sc->sc_sbregh);
359 	if (error) {
360 		aprint_error_dev(self, "failed to map SMBUS sideband: %d\n",
361 		    error);
362 		goto fail;
363 	}
364 	sc->sc_sbregsz = SB_SMBUS_SIZE;
365 
366 	/*
367 	 * Map the power management configuration controller's I/O
368 	 * space.  Older manual call this PMBASE for power management;
369 	 * newer manuals call it ABASE for ACPI.  The chapters
370 	 * describing the registers say `power management' and I can't
371 	 * find any connection to ACPI (I suppose ACPI firmware logic
372 	 * probably peeks and pokes registers here?) so we say PMBASE
373 	 * here.
374 	 *
375 	 * XXX Hope nobody else is trying to touch it!
376 	 */
377 	pmbase = pci_conf_read(pc, pmc_tag, LPCIB_PCI_PMBASE);
378 	aprint_debug_dev(self, "PMBASE=0x%"PRIxBUSADDR"\n", pmbase);
379 	if ((pmbase & 1) != 1) {	/* I/O space bit? */
380 		aprint_error_dev(self, "unrecognized PMC space\n");
381 		goto fail;
382 	}
383 	sc->sc_pmt = sc->sc_iot;
384 	error = bus_space_map(sc->sc_pmt, PCI_MAPREG_IO_ADDR(pmbase),
385 	    LPCIB_PCI_PM_SIZE, 0, &sc->sc_pmh);
386 	if (error) {
387 		aprint_error_dev(self, "failed to map PMC space: %d\n", error);
388 		goto fail;
389 	}
390 	sc->sc_pmsz = LPCIB_PCI_PM_SIZE;
391 
392 	/* Success! */
393 	sc->sc_tco_probed = true;
394 	return;
395 
396 fail:	if (sc->sc_pmsz) {
397 		bus_space_unmap(sc->sc_pmt, sc->sc_pmh, sc->sc_pmsz);
398 		sc->sc_pmsz = 0;
399 	}
400 	if (sc->sc_sbregsz) {
401 		bus_space_unmap(sc->sc_sbregt, sc->sc_sbregh, sc->sc_sbregsz);
402 		sc->sc_sbregsz = 0;
403 	}
404 	if (sc->sc_tcosz) {
405 		bus_space_unmap(sc->sc_tcot, sc->sc_tcoh, sc->sc_tcosz);
406 		sc->sc_tcosz = 0;
407 	}
408 }
409 
410 static int
411 ichsmb_tco_set_noreboot(device_t tco, bool noreboot)
412 {
413 	device_t self = device_parent(tco);
414 	struct ichsmb_softc *sc = device_private(self);
415 	uint32_t gc, gc1;
416 
417 	KASSERTMSG(tco == sc->sc_tco_device || sc->sc_tco_device == NULL,
418 	    "tco=%p child=%p", tco, sc->sc_tco_device);
419 	KASSERTMSG(device_is_a(self, "ichsmb"), "%s@%s",
420 	    device_xname(tco), device_xname(self));
421 
422 	/*
423 	 * Try to clear the No Reboot bit.
424 	 */
425 	gc = bus_space_read_4(sc->sc_sbregt, sc->sc_sbregh, SB_SMBUS_GC);
426 	if (noreboot)
427 		gc |= SB_SMBUS_GC_NR;
428 	else
429 		gc &= ~SB_SMBUS_GC_NR;
430 	bus_space_write_4(sc->sc_sbregt, sc->sc_sbregh, SB_SMBUS_GC, gc);
431 
432 	/*
433 	 * Check whether we could make it what we want.
434 	 */
435 	gc1 = bus_space_read_4(sc->sc_sbregt, sc->sc_sbregh, SB_SMBUS_GC);
436 	aprint_debug_dev(self, "gc=0x%x -> 0x%x\n", gc, gc1);
437 	if ((gc1 & SB_SMBUS_GC_NR) != (gc & SB_SMBUS_GC_NR))
438 		return ENODEV;
439 	return 0;
440 }
441 
442 static int
443 ichsmb_rescan(device_t self, const char *ifattr, const int *locators)
444 {
445 	struct ichsmb_softc *sc = device_private(self);
446 
447 	if (ifattr_match(ifattr, "i2cbus") && sc->sc_i2c_device == NULL) {
448 		struct i2cbus_attach_args iba;
449 
450 		memset(&iba, 0, sizeof(iba));
451 		iba.iba_tag = &sc->sc_i2c_tag;
452 		sc->sc_i2c_device = config_found(self, &iba, iicbus_print,
453 		    CFARGS(.iattr = "i2cbus"));
454 	}
455 	if (sc->sc_tco_probed &&
456 	    ifattr_match(ifattr, "tcoichbus") &&
457 	    sc->sc_tco_device == NULL) {
458 		struct tco_attach_args ta;
459 
460 		memset(&ta, 0, sizeof(ta));
461 		ta.ta_version = TCO_VERSION_SMBUS;
462 		ta.ta_pmt = sc->sc_pmt;
463 		ta.ta_pmh = sc->sc_pmh;
464 		ta.ta_tcot = sc->sc_tcot;
465 		ta.ta_tcoh = sc->sc_tcoh;
466 		ta.ta_set_noreboot = &ichsmb_tco_set_noreboot;
467 		sc->sc_tco_device = config_found(self, &ta, NULL,
468 		    CFARGS(.iattr = "tcoichbus"));
469 	}
470 
471 	return 0;
472 }
473 
474 static int
475 ichsmb_detach(device_t self, int flags)
476 {
477 	struct ichsmb_softc *sc = device_private(self);
478 	int error;
479 
480 	error = config_detach_children(self, flags);
481 	if (error)
482 		return error;
483 
484 	iic_tag_fini(&sc->sc_i2c_tag);
485 
486 	if (sc->sc_ih) {
487 		pci_intr_disestablish(sc->sc_pc, sc->sc_ih);
488 		sc->sc_ih = NULL;
489 	}
490 
491 	if (sc->sc_pihp) {
492 		pci_intr_release(sc->sc_pc, sc->sc_pihp, 1);
493 		sc->sc_pihp = NULL;
494 	}
495 
496 	if (sc->sc_pmsz != 0)
497 		bus_space_unmap(sc->sc_pmt, sc->sc_pmh, sc->sc_pmsz);
498 	if (sc->sc_sbregsz != 0)
499 		bus_space_unmap(sc->sc_sbregt, sc->sc_sbregh, sc->sc_sbregsz);
500 	if (sc->sc_tcosz != 0)
501 		bus_space_unmap(sc->sc_tcot, sc->sc_tcoh, sc->sc_tcosz);
502 	if (sc->sc_size != 0)
503 		bus_space_unmap(sc->sc_iot, sc->sc_ioh, sc->sc_size);
504 
505 	mutex_destroy(&sc->sc_exec_lock);
506 	cv_destroy(&sc->sc_exec_wait);
507 
508 	return 0;
509 }
510 
511 static void
512 ichsmb_chdet(device_t self, device_t child)
513 {
514 	struct ichsmb_softc *sc = device_private(self);
515 
516 	if (sc->sc_i2c_device == child)
517 		sc->sc_i2c_device = NULL;
518 	if (sc->sc_tco_device == child)
519 		sc->sc_tco_device = NULL;
520 }
521 
522 static int
523 ichsmb_i2c_exec(void *cookie, i2c_op_t op, i2c_addr_t addr,
524     const void *cmdbuf, size_t cmdlen, void *buf, size_t len, int flags)
525 {
526 	struct ichsmb_softc *sc = cookie;
527 	const uint8_t *b;
528 	uint8_t ctl = 0, st;
529 	int retries;
530 	char fbuf[64];
531 
532 	DPRINTF(("%s: exec: op %d, addr 0x%02x, cmdlen %zu, len %zu, "
533 	    "flags 0x%02x\n", device_xname(sc->sc_dev), op, addr, cmdlen,
534 	    len, flags));
535 
536 	mutex_enter(&sc->sc_exec_lock);
537 
538 	/* Clear status bits */
539 	bus_space_write_1(sc->sc_iot, sc->sc_ioh, SMB_HS,
540 	    SMB_HS_INTR | SMB_HS_DEVERR | SMB_HS_BUSERR | SMB_HS_FAILED);
541 	bus_space_barrier(sc->sc_iot, sc->sc_ioh, SMB_HS, 1,
542 	    BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE);
543 
544 	/* Wait for bus to be idle */
545 	for (retries = 100; retries > 0; retries--) {
546 		st = bus_space_read_1(sc->sc_iot, sc->sc_ioh, SMB_HS);
547 		if (!(st & SMB_HS_BUSY))
548 			break;
549 		DELAY(ICHIIC_DELAY);
550 	}
551 #ifdef ICHIIC_DEBUG
552 	snprintb(fbuf, sizeof(fbuf), SMB_HS_BITS, st);
553 	printf("%s: exec: st %s\n", device_xname(sc->sc_dev), fbuf);
554 #endif
555 	if (st & SMB_HS_BUSY) {
556 		mutex_exit(&sc->sc_exec_lock);
557 		return (EBUSY);
558 	}
559 
560 	if (sc->sc_poll)
561 		flags |= I2C_F_POLL;
562 
563 	if (!I2C_OP_STOP_P(op) || cmdlen > 1 || len > 2 ||
564 	    (cmdlen == 0 && len > 1)) {
565 		mutex_exit(&sc->sc_exec_lock);
566 		return (EINVAL);
567 	}
568 
569 	/* Setup transfer */
570 	sc->sc_i2c_xfer.op = op;
571 	sc->sc_i2c_xfer.buf = buf;
572 	sc->sc_i2c_xfer.len = len;
573 	sc->sc_i2c_xfer.flags = flags;
574 	sc->sc_i2c_xfer.error = 0;
575 	sc->sc_i2c_xfer.done = false;
576 
577 	/* Set slave address and transfer direction */
578 	bus_space_write_1(sc->sc_iot, sc->sc_ioh, SMB_TXSLVA,
579 	    SMB_TXSLVA_ADDR(addr) |
580 	    (I2C_OP_READ_P(op) ? SMB_TXSLVA_READ : 0));
581 
582 	b = (const uint8_t *)cmdbuf;
583 	if (cmdlen > 0)
584 		/* Set command byte */
585 		bus_space_write_1(sc->sc_iot, sc->sc_ioh, SMB_HCMD, b[0]);
586 
587 	if (I2C_OP_WRITE_P(op)) {
588 		/* Write data */
589 		b = buf;
590 		if (cmdlen == 0 && len == 1)
591 			bus_space_write_1(sc->sc_iot, sc->sc_ioh,
592 			    SMB_HCMD, b[0]);
593 		else if (len > 0)
594 			bus_space_write_1(sc->sc_iot, sc->sc_ioh,
595 			    SMB_HD0, b[0]);
596 		if (len > 1)
597 			bus_space_write_1(sc->sc_iot, sc->sc_ioh,
598 			    SMB_HD1, b[1]);
599 	}
600 
601 	/* Set SMBus command */
602 	if (cmdlen == 0) {
603 		if (len == 0)
604 			ctl = SMB_HC_CMD_QUICK;
605 		else
606 			ctl = SMB_HC_CMD_BYTE;
607 	} else if (len == 1)
608 		ctl = SMB_HC_CMD_BDATA;
609 	else if (len == 2)
610 		ctl = SMB_HC_CMD_WDATA;
611 
612 	if ((flags & I2C_F_POLL) == 0)
613 		ctl |= SMB_HC_INTREN;
614 
615 	/* Start transaction */
616 	ctl |= SMB_HC_START;
617 	bus_space_write_1(sc->sc_iot, sc->sc_ioh, SMB_HC, ctl);
618 
619 	if (flags & I2C_F_POLL) {
620 		/* Poll for completion */
621 		DELAY(ICHIIC_DELAY);
622 		for (retries = 1000; retries > 0; retries--) {
623 			st = bus_space_read_1(sc->sc_iot, sc->sc_ioh, SMB_HS);
624 			if ((st & SMB_HS_BUSY) == 0)
625 				break;
626 			DELAY(ICHIIC_DELAY);
627 		}
628 		if (st & SMB_HS_BUSY)
629 			goto timeout;
630 		ichsmb_intr(sc);
631 	} else {
632 		/* Wait for interrupt */
633 		while (! sc->sc_i2c_xfer.done) {
634 			if (cv_timedwait(&sc->sc_exec_wait, &sc->sc_exec_lock,
635 					 ICHIIC_TIMEOUT * hz))
636 				goto timeout;
637 		}
638 	}
639 
640 	int error = sc->sc_i2c_xfer.error;
641 	mutex_exit(&sc->sc_exec_lock);
642 
643 	return (error);
644 
645 timeout:
646 	/*
647 	 * Transfer timeout. Kill the transaction and clear status bits.
648 	 */
649 	bus_space_write_1(sc->sc_iot, sc->sc_ioh, SMB_HC, SMB_HC_KILL);
650 	DELAY(ICHIIC_DELAY);
651 	st = bus_space_read_1(sc->sc_iot, sc->sc_ioh, SMB_HS);
652 	if ((st & SMB_HS_FAILED) == 0) {
653 		snprintb(fbuf, sizeof(fbuf), SMB_HS_BITS, st);
654 		aprint_error_dev(sc->sc_dev, "abort failed, status %s\n",
655 		    fbuf);
656 	}
657 	bus_space_write_1(sc->sc_iot, sc->sc_ioh, SMB_HS, st);
658 	mutex_exit(&sc->sc_exec_lock);
659 	return (ETIMEDOUT);
660 }
661 
662 static int
663 ichsmb_intr(void *arg)
664 {
665 	struct ichsmb_softc *sc = arg;
666 	uint8_t st;
667 	uint8_t *b;
668 	size_t len;
669 #ifdef ICHIIC_DEBUG
670 	char fbuf[64];
671 #endif
672 
673 	/* Read status */
674 	st = bus_space_read_1(sc->sc_iot, sc->sc_ioh, SMB_HS);
675 
676 	/* Clear status bits */
677 	bus_space_write_1(sc->sc_iot, sc->sc_ioh, SMB_HS, st);
678 
679 	/* XXX Ignore SMBALERT# for now */
680 	if ((st & SMB_HS_BUSY) != 0 ||
681 	    (st & (SMB_HS_INTR | SMB_HS_DEVERR | SMB_HS_BUSERR |
682 		SMB_HS_FAILED | SMB_HS_BDONE)) == 0)
683 		/* Interrupt was not for us */
684 		return (0);
685 
686 #ifdef ICHIIC_DEBUG
687 	snprintb(fbuf, sizeof(fbuf), SMB_HS_BITS, st);
688 	printf("%s: intr st %s\n", device_xname(sc->sc_dev), fbuf);
689 #endif
690 
691 	if ((sc->sc_i2c_xfer.flags & I2C_F_POLL) == 0)
692 		mutex_enter(&sc->sc_exec_lock);
693 
694 	/* Check for errors */
695 	if (st & (SMB_HS_DEVERR | SMB_HS_BUSERR | SMB_HS_FAILED)) {
696 		sc->sc_i2c_xfer.error = EIO;
697 		goto done;
698 	}
699 
700 	if (st & SMB_HS_INTR) {
701 		if (I2C_OP_WRITE_P(sc->sc_i2c_xfer.op))
702 			goto done;
703 
704 		/* Read data */
705 		b = sc->sc_i2c_xfer.buf;
706 		len = sc->sc_i2c_xfer.len;
707 		if (len > 0)
708 			b[0] = bus_space_read_1(sc->sc_iot, sc->sc_ioh,
709 			    SMB_HD0);
710 		if (len > 1)
711 			b[1] = bus_space_read_1(sc->sc_iot, sc->sc_ioh,
712 			    SMB_HD1);
713 	}
714 
715 done:
716 	sc->sc_i2c_xfer.done = true;
717 	if ((sc->sc_i2c_xfer.flags & I2C_F_POLL) == 0) {
718 		cv_signal(&sc->sc_exec_wait);
719 		mutex_exit(&sc->sc_exec_lock);
720 	}
721 	return (1);
722 }
723 
724 MODULE(MODULE_CLASS_DRIVER, ichsmb, "pci,iic");
725 
726 #ifdef _MODULE
727 #include "ioconf.c"
728 #endif
729 
730 static int
731 ichsmb_modcmd(modcmd_t cmd, void *opaque)
732 {
733 	int error = 0;
734 
735 	switch (cmd) {
736 	case MODULE_CMD_INIT:
737 #ifdef _MODULE
738 		error = config_init_component(cfdriver_ioconf_ichsmb,
739 		    cfattach_ioconf_ichsmb, cfdata_ioconf_ichsmb);
740 #endif
741 		break;
742 	case MODULE_CMD_FINI:
743 #ifdef _MODULE
744 		error = config_fini_component(cfdriver_ioconf_ichsmb,
745 		    cfattach_ioconf_ichsmb, cfdata_ioconf_ichsmb);
746 #endif
747 		break;
748 	default:
749 #ifdef _MODULE
750 		error = ENOTTY;
751 #endif
752 		break;
753 	}
754 
755 	return error;
756 }
757