xref: /netbsd-src/sys/dev/pci/ichsmb.c (revision 4b169a6ba595ae283ca507b26b15fdff40495b1c)
1 /*	$NetBSD: ichsmb.c,v 1.84 2023/07/23 05:54:25 msaitoh 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.84 2023/07/23 05:54:25 msaitoh 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_ADL_N_SMB:
159 		case PCI_PRODUCT_INTEL_C600_SMBUS:
160 		case PCI_PRODUCT_INTEL_C600_SMB_0:
161 		case PCI_PRODUCT_INTEL_C600_SMB_1:
162 		case PCI_PRODUCT_INTEL_C600_SMB_2:
163 		case PCI_PRODUCT_INTEL_C610_SMB:
164 		case PCI_PRODUCT_INTEL_C620_SMB:
165 		case PCI_PRODUCT_INTEL_C620_SMB_S:
166 		case PCI_PRODUCT_INTEL_EP80579_SMB:
167 		case PCI_PRODUCT_INTEL_DH89XXCC_SMB:
168 		case PCI_PRODUCT_INTEL_DH89XXCL_SMB:
169 		case PCI_PRODUCT_INTEL_C2000_PCU_SMBUS:
170 		case PCI_PRODUCT_INTEL_C3K_SMBUS_LEGACY:
171 		case PCI_PRODUCT_INTEL_495_YU_SMB:
172 		case PCI_PRODUCT_INTEL_5HS_H_SMB:
173 		case PCI_PRODUCT_INTEL_5HS_LP_SMB:
174 		case PCI_PRODUCT_INTEL_6HS_H_SMB:
175 		case PCI_PRODUCT_INTEL_6HS_LP_SMB:
176 		case PCI_PRODUCT_INTEL_7HS_SMB:
177 			return 1;
178 		}
179 	}
180 	return 0;
181 }
182 
183 static void
184 ichsmb_attach(device_t parent, device_t self, void *aux)
185 {
186 	struct ichsmb_softc *sc = device_private(self);
187 	struct pci_attach_args *pa = aux;
188 	pcireg_t conf;
189 	const char *intrstr = NULL;
190 	char intrbuf[PCI_INTRSTR_LEN];
191 
192 	sc->sc_dev = self;
193 	sc->sc_pc = pa->pa_pc;
194 
195 	pci_aprint_devinfo(pa, NULL);
196 
197 	mutex_init(&sc->sc_exec_lock, MUTEX_DEFAULT, IPL_BIO);
198 	cv_init(&sc->sc_exec_wait, device_xname(self));
199 
200 	/* Read configuration */
201 	conf = pci_conf_read(pa->pa_pc, pa->pa_tag, SMB_HOSTC);
202 	DPRINTF(("%s: conf 0x%08x\n", device_xname(sc->sc_dev), conf));
203 
204 	if ((conf & SMB_HOSTC_HSTEN) == 0) {
205 		aprint_error_dev(self, "SMBus disabled\n");
206 		goto out;
207 	}
208 
209 	/* Map I/O space */
210 	if (pci_mapreg_map(pa, SMB_BASE, PCI_MAPREG_TYPE_IO, 0,
211 	    &sc->sc_iot, &sc->sc_ioh, NULL, &sc->sc_size)) {
212 		aprint_error_dev(self, "can't map I/O space\n");
213 		goto out;
214 	}
215 
216 	sc->sc_poll = 1;
217 	sc->sc_ih = NULL;
218 	if (conf & SMB_HOSTC_SMIEN) {
219 		/* No PCI IRQ */
220 		aprint_normal_dev(self, "interrupting at SMI\n");
221 	} else {
222 		/* Install interrupt handler */
223 		if (pci_intr_alloc(pa, &sc->sc_pihp, NULL, 0) == 0) {
224 			intrstr = pci_intr_string(pa->pa_pc, sc->sc_pihp[0],
225 			    intrbuf, sizeof(intrbuf));
226 			pci_intr_setattr(pa->pa_pc, &sc->sc_pihp[0],
227 			    PCI_INTR_MPSAFE, true);
228 			sc->sc_ih = pci_intr_establish_xname(pa->pa_pc,
229 			    sc->sc_pihp[0], IPL_BIO, ichsmb_intr, sc,
230 			    device_xname(sc->sc_dev));
231 			if (sc->sc_ih != NULL) {
232 				aprint_normal_dev(self, "interrupting at %s\n",
233 				    intrstr);
234 				sc->sc_poll = 0;
235 			} else {
236 				pci_intr_release(pa->pa_pc, sc->sc_pihp, 1);
237 				sc->sc_pihp = NULL;
238 			}
239 		}
240 		if (sc->sc_poll)
241 			aprint_normal_dev(self, "polling\n");
242 	}
243 
244 	/* Attach I2C bus */
245 	iic_tag_init(&sc->sc_i2c_tag);
246 	sc->sc_i2c_tag.ic_cookie = sc;
247 	sc->sc_i2c_tag.ic_exec = ichsmb_i2c_exec;
248 
249 	/*
250 	 * Probe to see if there's a TCO hanging here instead of the
251 	 * LPCIB and map it if we can.
252 	 */
253 	ichsmb_probe_tco(sc, pa);
254 
255 	sc->sc_i2c_device = NULL;
256 	ichsmb_rescan(self, NULL, NULL);
257 
258 out:	if (!pmf_device_register(self, NULL, NULL))
259 		aprint_error_dev(self, "couldn't establish power handler\n");
260 }
261 
262 static void
263 ichsmb_probe_tco(struct ichsmb_softc *sc, const struct pci_attach_args *pa)
264 {
265 	const device_t self = sc->sc_dev;
266 	const pci_chipset_tag_t pc = sc->sc_pc;
267 	const pcitag_t p2sb_tag = pci_make_tag(pc,
268 	    /*bus*/0, /*dev*/0x1f, /*fn*/1);
269 	const pcitag_t pmc_tag = pci_make_tag(pc,
270 	    /*bus*/0, /*dev*/0x1f, /*fn*/2);
271 	pcireg_t tcoctl, tcobase, p2sbc, sbreglo, sbreghi;
272 	bus_addr_t sbreg, pmbase;
273 	int error = EIO;
274 
275 	/*
276 	 * Only attempt this on devices where we expect to find a TCO.
277 	 */
278 	switch (PCI_PRODUCT(pa->pa_id)) {
279 	case PCI_PRODUCT_INTEL_100SERIES_LP_SMB:
280 	case PCI_PRODUCT_INTEL_100SERIES_SMB:
281 		break;
282 	default:
283 		goto fail;
284 	}
285 
286 	/*
287 	 * Verify the TCO base address register is enabled.
288 	 */
289 	tcoctl = pci_conf_read(pa->pa_pc, pa->pa_tag, SMB_TCOCTL);
290 	aprint_debug_dev(self, "TCOCTL=0x%"PRIx32"\n", tcoctl);
291 	if ((tcoctl & SMB_TCOCTL_TCO_BASE_EN) == 0) {
292 		aprint_debug_dev(self, "TCO disabled\n");
293 		goto fail;
294 	}
295 
296 	/*
297 	 * Verify the TCO base address register has the I/O space bit
298 	 * set -- otherwise we don't know how to interpret the
299 	 * register.
300 	 */
301 	tcobase = pci_conf_read(pa->pa_pc, pa->pa_tag, SMB_TCOBASE);
302 	aprint_debug_dev(self, "TCOBASE=0x%"PRIx32"\n", tcobase);
303 	if ((tcobase & SMB_TCOBASE_IOS) == 0) {
304 		aprint_error_dev(self, "unrecognized TCO space\n");
305 		goto fail;
306 	}
307 
308 	/*
309 	 * Map the TCO I/O space.
310 	 */
311 	sc->sc_tcot = sc->sc_iot;
312 	error = bus_space_map(sc->sc_tcot, tcobase & SMB_TCOBASE_TCOBA,
313 	    TCO_REGSIZE, 0, &sc->sc_tcoh);
314 	if (error) {
315 		aprint_error_dev(self, "failed to map TCO: %d\n", error);
316 		goto fail;
317 	}
318 	sc->sc_tcosz = TCO_REGSIZE;
319 
320 	/*
321 	 * Clear the Hide Device bit so we can map the SBREG_BAR from
322 	 * the P2SB registers; then restore the Hide Device bit so
323 	 * nobody else gets confused.
324 	 *
325 	 * XXX Hope nobody else is trying to touch the P2SB!
326 	 *
327 	 * XXX Should we have a way to lock PCI bus enumeration,
328 	 * e.g. from concurrent drvctl rescan?
329 	 *
330 	 * XXX pci_mapreg_info doesn't work to get the size, somehow
331 	 * comes out as 4.  Datasheet for 100-series chipset says the
332 	 * size is 16 MB, unconditionally, and the type is memory.
333 	 *
334 	 * XXX The above XXX comment was probably a result of PEBCAK
335 	 * when I tried to use 0xe4 instead of 0xe0 for P2SBC -- should
336 	 * try again with pci_mapreg_info or pci_mapreg_map.
337 	 */
338 	p2sbc = pci_conf_read(pc, p2sb_tag, P2SB_P2SBC);
339 	aprint_debug_dev(self, "P2SBC=0x%x\n", p2sbc);
340 	pci_conf_write(pc, p2sb_tag, P2SB_P2SBC, p2sbc & ~P2SB_P2SBC_HIDE);
341 	aprint_debug_dev(self, "P2SBC=0x%x -> 0x%x\n", p2sbc,
342 	    pci_conf_read(pc, p2sb_tag, P2SB_P2SBC));
343 	sbreglo = pci_conf_read(pc, p2sb_tag, P2SB_SBREG_BAR);
344 	sbreghi = pci_conf_read(pc, p2sb_tag, P2SB_SBREG_BARH);
345 	aprint_debug_dev(self, "SBREG_BAR=0x%08x 0x%08x\n", sbreglo, sbreghi);
346 	pci_conf_write(sc->sc_pc, p2sb_tag, P2SB_P2SBC, p2sbc);
347 
348 	/*
349 	 * Map the sideband registers so we can touch the NO_REBOOT
350 	 * bit.
351 	 */
352 	sbreg = ((uint64_t)sbreghi << 32) | (sbreglo & ~__BITS(0,3));
353 	if (((uint64_t)sbreg >> 32) != sbreghi) {
354 		/* paranoia for 32-bit non-PAE */
355 		aprint_error_dev(self, "can't map 64-bit SBREG\n");
356 		goto fail;
357 	}
358 	sc->sc_sbregt = pa->pa_memt;
359 	error = bus_space_map(sc->sc_sbregt, sbreg + SB_SMBUS_BASE,
360 	    SB_SMBUS_SIZE, 0, &sc->sc_sbregh);
361 	if (error) {
362 		aprint_error_dev(self, "failed to map SMBUS sideband: %d\n",
363 		    error);
364 		goto fail;
365 	}
366 	sc->sc_sbregsz = SB_SMBUS_SIZE;
367 
368 	/*
369 	 * Map the power management configuration controller's I/O
370 	 * space.  Older manual call this PMBASE for power management;
371 	 * newer manuals call it ABASE for ACPI.  The chapters
372 	 * describing the registers say `power management' and I can't
373 	 * find any connection to ACPI (I suppose ACPI firmware logic
374 	 * probably peeks and pokes registers here?) so we say PMBASE
375 	 * here.
376 	 *
377 	 * XXX Hope nobody else is trying to touch it!
378 	 */
379 	pmbase = pci_conf_read(pc, pmc_tag, LPCIB_PCI_PMBASE);
380 	aprint_debug_dev(self, "PMBASE=0x%"PRIxBUSADDR"\n", pmbase);
381 	if ((pmbase & 1) != 1) {	/* I/O space bit? */
382 		aprint_error_dev(self, "unrecognized PMC space\n");
383 		goto fail;
384 	}
385 	sc->sc_pmt = sc->sc_iot;
386 	error = bus_space_map(sc->sc_pmt, PCI_MAPREG_IO_ADDR(pmbase),
387 	    LPCIB_PCI_PM_SIZE, 0, &sc->sc_pmh);
388 	if (error) {
389 		aprint_error_dev(self, "failed to map PMC space: %d\n", error);
390 		goto fail;
391 	}
392 	sc->sc_pmsz = LPCIB_PCI_PM_SIZE;
393 
394 	/* Success! */
395 	sc->sc_tco_probed = true;
396 	return;
397 
398 fail:	if (sc->sc_pmsz) {
399 		bus_space_unmap(sc->sc_pmt, sc->sc_pmh, sc->sc_pmsz);
400 		sc->sc_pmsz = 0;
401 	}
402 	if (sc->sc_sbregsz) {
403 		bus_space_unmap(sc->sc_sbregt, sc->sc_sbregh, sc->sc_sbregsz);
404 		sc->sc_sbregsz = 0;
405 	}
406 	if (sc->sc_tcosz) {
407 		bus_space_unmap(sc->sc_tcot, sc->sc_tcoh, sc->sc_tcosz);
408 		sc->sc_tcosz = 0;
409 	}
410 }
411 
412 static int
413 ichsmb_tco_set_noreboot(device_t tco, bool noreboot)
414 {
415 	device_t self = device_parent(tco);
416 	struct ichsmb_softc *sc = device_private(self);
417 	uint32_t gc, gc1;
418 
419 	KASSERTMSG(tco == sc->sc_tco_device || sc->sc_tco_device == NULL,
420 	    "tco=%p child=%p", tco, sc->sc_tco_device);
421 	KASSERTMSG(device_is_a(self, "ichsmb"), "%s@%s",
422 	    device_xname(tco), device_xname(self));
423 
424 	/*
425 	 * Try to clear the No Reboot bit.
426 	 */
427 	gc = bus_space_read_4(sc->sc_sbregt, sc->sc_sbregh, SB_SMBUS_GC);
428 	if (noreboot)
429 		gc |= SB_SMBUS_GC_NR;
430 	else
431 		gc &= ~SB_SMBUS_GC_NR;
432 	bus_space_write_4(sc->sc_sbregt, sc->sc_sbregh, SB_SMBUS_GC, gc);
433 
434 	/*
435 	 * Check whether we could make it what we want.
436 	 */
437 	gc1 = bus_space_read_4(sc->sc_sbregt, sc->sc_sbregh, SB_SMBUS_GC);
438 	aprint_debug_dev(self, "gc=0x%x -> 0x%x\n", gc, gc1);
439 	if ((gc1 & SB_SMBUS_GC_NR) != (gc & SB_SMBUS_GC_NR))
440 		return ENODEV;
441 	return 0;
442 }
443 
444 static int
445 ichsmb_rescan(device_t self, const char *ifattr, const int *locators)
446 {
447 	struct ichsmb_softc *sc = device_private(self);
448 
449 	if (ifattr_match(ifattr, "i2cbus") && sc->sc_i2c_device == NULL) {
450 		struct i2cbus_attach_args iba;
451 
452 		memset(&iba, 0, sizeof(iba));
453 		iba.iba_tag = &sc->sc_i2c_tag;
454 		sc->sc_i2c_device = config_found(self, &iba, iicbus_print,
455 		    CFARGS(.iattr = "i2cbus"));
456 	}
457 	if (sc->sc_tco_probed &&
458 	    ifattr_match(ifattr, "tcoichbus") &&
459 	    sc->sc_tco_device == NULL) {
460 		struct tco_attach_args ta;
461 
462 		memset(&ta, 0, sizeof(ta));
463 		ta.ta_version = TCO_VERSION_SMBUS;
464 		ta.ta_pmt = sc->sc_pmt;
465 		ta.ta_pmh = sc->sc_pmh;
466 		ta.ta_tcot = sc->sc_tcot;
467 		ta.ta_tcoh = sc->sc_tcoh;
468 		ta.ta_set_noreboot = &ichsmb_tco_set_noreboot;
469 		sc->sc_tco_device = config_found(self, &ta, NULL,
470 		    CFARGS(.iattr = "tcoichbus"));
471 	}
472 
473 	return 0;
474 }
475 
476 static int
477 ichsmb_detach(device_t self, int flags)
478 {
479 	struct ichsmb_softc *sc = device_private(self);
480 	int error;
481 
482 	error = config_detach_children(self, flags);
483 	if (error)
484 		return error;
485 
486 	iic_tag_fini(&sc->sc_i2c_tag);
487 
488 	if (sc->sc_ih) {
489 		pci_intr_disestablish(sc->sc_pc, sc->sc_ih);
490 		sc->sc_ih = NULL;
491 	}
492 
493 	if (sc->sc_pihp) {
494 		pci_intr_release(sc->sc_pc, sc->sc_pihp, 1);
495 		sc->sc_pihp = NULL;
496 	}
497 
498 	if (sc->sc_pmsz != 0)
499 		bus_space_unmap(sc->sc_pmt, sc->sc_pmh, sc->sc_pmsz);
500 	if (sc->sc_sbregsz != 0)
501 		bus_space_unmap(sc->sc_sbregt, sc->sc_sbregh, sc->sc_sbregsz);
502 	if (sc->sc_tcosz != 0)
503 		bus_space_unmap(sc->sc_tcot, sc->sc_tcoh, sc->sc_tcosz);
504 	if (sc->sc_size != 0)
505 		bus_space_unmap(sc->sc_iot, sc->sc_ioh, sc->sc_size);
506 
507 	mutex_destroy(&sc->sc_exec_lock);
508 	cv_destroy(&sc->sc_exec_wait);
509 
510 	return 0;
511 }
512 
513 static void
514 ichsmb_chdet(device_t self, device_t child)
515 {
516 	struct ichsmb_softc *sc = device_private(self);
517 
518 	if (sc->sc_i2c_device == child)
519 		sc->sc_i2c_device = NULL;
520 	if (sc->sc_tco_device == child)
521 		sc->sc_tco_device = NULL;
522 }
523 
524 static int
525 ichsmb_i2c_exec(void *cookie, i2c_op_t op, i2c_addr_t addr,
526     const void *cmdbuf, size_t cmdlen, void *buf, size_t len, int flags)
527 {
528 	struct ichsmb_softc *sc = cookie;
529 	const uint8_t *b;
530 	uint8_t ctl = 0, st;
531 	int retries;
532 	char fbuf[64];
533 
534 	DPRINTF(("%s: exec: op %d, addr 0x%02x, cmdlen %zu, len %zu, "
535 	    "flags 0x%02x\n", device_xname(sc->sc_dev), op, addr, cmdlen,
536 	    len, flags));
537 
538 	mutex_enter(&sc->sc_exec_lock);
539 
540 	/* Clear status bits */
541 	bus_space_write_1(sc->sc_iot, sc->sc_ioh, SMB_HS,
542 	    SMB_HS_INTR | SMB_HS_DEVERR | SMB_HS_BUSERR | SMB_HS_FAILED);
543 	bus_space_barrier(sc->sc_iot, sc->sc_ioh, SMB_HS, 1,
544 	    BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE);
545 
546 	/* Wait for bus to be idle */
547 	for (retries = 100; retries > 0; retries--) {
548 		st = bus_space_read_1(sc->sc_iot, sc->sc_ioh, SMB_HS);
549 		if (!(st & SMB_HS_BUSY))
550 			break;
551 		DELAY(ICHIIC_DELAY);
552 	}
553 #ifdef ICHIIC_DEBUG
554 	snprintb(fbuf, sizeof(fbuf), SMB_HS_BITS, st);
555 	printf("%s: exec: st %s\n", device_xname(sc->sc_dev), fbuf);
556 #endif
557 	if (st & SMB_HS_BUSY) {
558 		mutex_exit(&sc->sc_exec_lock);
559 		return (EBUSY);
560 	}
561 
562 	if (sc->sc_poll)
563 		flags |= I2C_F_POLL;
564 
565 	if (!I2C_OP_STOP_P(op) || cmdlen > 1 || len > 2 ||
566 	    (cmdlen == 0 && len > 1)) {
567 		mutex_exit(&sc->sc_exec_lock);
568 		return (EINVAL);
569 	}
570 
571 	/* Setup transfer */
572 	sc->sc_i2c_xfer.op = op;
573 	sc->sc_i2c_xfer.buf = buf;
574 	sc->sc_i2c_xfer.len = len;
575 	sc->sc_i2c_xfer.flags = flags;
576 	sc->sc_i2c_xfer.error = 0;
577 	sc->sc_i2c_xfer.done = false;
578 
579 	/* Set slave address and transfer direction */
580 	bus_space_write_1(sc->sc_iot, sc->sc_ioh, SMB_TXSLVA,
581 	    SMB_TXSLVA_ADDR(addr) |
582 	    (I2C_OP_READ_P(op) ? SMB_TXSLVA_READ : 0));
583 
584 	b = (const uint8_t *)cmdbuf;
585 	if (cmdlen > 0)
586 		/* Set command byte */
587 		bus_space_write_1(sc->sc_iot, sc->sc_ioh, SMB_HCMD, b[0]);
588 
589 	if (I2C_OP_WRITE_P(op)) {
590 		/* Write data */
591 		b = buf;
592 		if (cmdlen == 0 && len == 1)
593 			bus_space_write_1(sc->sc_iot, sc->sc_ioh,
594 			    SMB_HCMD, b[0]);
595 		else if (len > 0)
596 			bus_space_write_1(sc->sc_iot, sc->sc_ioh,
597 			    SMB_HD0, b[0]);
598 		if (len > 1)
599 			bus_space_write_1(sc->sc_iot, sc->sc_ioh,
600 			    SMB_HD1, b[1]);
601 	}
602 
603 	/* Set SMBus command */
604 	if (cmdlen == 0) {
605 		if (len == 0)
606 			ctl = SMB_HC_CMD_QUICK;
607 		else
608 			ctl = SMB_HC_CMD_BYTE;
609 	} else if (len == 1)
610 		ctl = SMB_HC_CMD_BDATA;
611 	else if (len == 2)
612 		ctl = SMB_HC_CMD_WDATA;
613 
614 	if ((flags & I2C_F_POLL) == 0)
615 		ctl |= SMB_HC_INTREN;
616 
617 	/* Start transaction */
618 	ctl |= SMB_HC_START;
619 	bus_space_write_1(sc->sc_iot, sc->sc_ioh, SMB_HC, ctl);
620 
621 	if (flags & I2C_F_POLL) {
622 		/* Poll for completion */
623 		DELAY(ICHIIC_DELAY);
624 		for (retries = 1000; retries > 0; retries--) {
625 			st = bus_space_read_1(sc->sc_iot, sc->sc_ioh, SMB_HS);
626 			if ((st & SMB_HS_BUSY) == 0)
627 				break;
628 			DELAY(ICHIIC_DELAY);
629 		}
630 		if (st & SMB_HS_BUSY)
631 			goto timeout;
632 		ichsmb_intr(sc);
633 	} else {
634 		/* Wait for interrupt */
635 		while (! sc->sc_i2c_xfer.done) {
636 			if (cv_timedwait(&sc->sc_exec_wait, &sc->sc_exec_lock,
637 					 ICHIIC_TIMEOUT * hz))
638 				goto timeout;
639 		}
640 	}
641 
642 	int error = sc->sc_i2c_xfer.error;
643 	mutex_exit(&sc->sc_exec_lock);
644 
645 	return (error);
646 
647 timeout:
648 	/*
649 	 * Transfer timeout. Kill the transaction and clear status bits.
650 	 */
651 	bus_space_write_1(sc->sc_iot, sc->sc_ioh, SMB_HC, SMB_HC_KILL);
652 	DELAY(ICHIIC_DELAY);
653 	st = bus_space_read_1(sc->sc_iot, sc->sc_ioh, SMB_HS);
654 	if ((st & SMB_HS_FAILED) == 0) {
655 		snprintb(fbuf, sizeof(fbuf), SMB_HS_BITS, st);
656 		device_printf(sc->sc_dev, "abort failed, status %s\n",
657 		    fbuf);
658 	}
659 	bus_space_write_1(sc->sc_iot, sc->sc_ioh, SMB_HS, st);
660 	mutex_exit(&sc->sc_exec_lock);
661 	return (ETIMEDOUT);
662 }
663 
664 static int
665 ichsmb_intr(void *arg)
666 {
667 	struct ichsmb_softc *sc = arg;
668 	uint8_t st;
669 	uint8_t *b;
670 	size_t len;
671 #ifdef ICHIIC_DEBUG
672 	char fbuf[64];
673 #endif
674 
675 	/* Read status */
676 	st = bus_space_read_1(sc->sc_iot, sc->sc_ioh, SMB_HS);
677 
678 	/* Clear status bits */
679 	bus_space_write_1(sc->sc_iot, sc->sc_ioh, SMB_HS, st);
680 
681 	/* XXX Ignore SMBALERT# for now */
682 	if ((st & SMB_HS_BUSY) != 0 ||
683 	    (st & (SMB_HS_INTR | SMB_HS_DEVERR | SMB_HS_BUSERR |
684 		SMB_HS_FAILED | SMB_HS_BDONE)) == 0)
685 		/* Interrupt was not for us */
686 		return (0);
687 
688 #ifdef ICHIIC_DEBUG
689 	snprintb(fbuf, sizeof(fbuf), SMB_HS_BITS, st);
690 	printf("%s: intr st %s\n", device_xname(sc->sc_dev), fbuf);
691 #endif
692 
693 	if ((sc->sc_i2c_xfer.flags & I2C_F_POLL) == 0)
694 		mutex_enter(&sc->sc_exec_lock);
695 
696 	/* Check for errors */
697 	if (st & (SMB_HS_DEVERR | SMB_HS_BUSERR | SMB_HS_FAILED)) {
698 		sc->sc_i2c_xfer.error = EIO;
699 		goto done;
700 	}
701 
702 	if (st & SMB_HS_INTR) {
703 		if (I2C_OP_WRITE_P(sc->sc_i2c_xfer.op))
704 			goto done;
705 
706 		/* Read data */
707 		b = sc->sc_i2c_xfer.buf;
708 		len = sc->sc_i2c_xfer.len;
709 		if (len > 0)
710 			b[0] = bus_space_read_1(sc->sc_iot, sc->sc_ioh,
711 			    SMB_HD0);
712 		if (len > 1)
713 			b[1] = bus_space_read_1(sc->sc_iot, sc->sc_ioh,
714 			    SMB_HD1);
715 	}
716 
717 done:
718 	sc->sc_i2c_xfer.done = true;
719 	if ((sc->sc_i2c_xfer.flags & I2C_F_POLL) == 0) {
720 		cv_signal(&sc->sc_exec_wait);
721 		mutex_exit(&sc->sc_exec_lock);
722 	}
723 	return (1);
724 }
725 
726 MODULE(MODULE_CLASS_DRIVER, ichsmb, "pci,iic");
727 
728 #ifdef _MODULE
729 #include "ioconf.c"
730 #endif
731 
732 static int
733 ichsmb_modcmd(modcmd_t cmd, void *opaque)
734 {
735 	int error = 0;
736 
737 	switch (cmd) {
738 	case MODULE_CMD_INIT:
739 #ifdef _MODULE
740 		error = config_init_component(cfdriver_ioconf_ichsmb,
741 		    cfattach_ioconf_ichsmb, cfdata_ioconf_ichsmb);
742 #endif
743 		break;
744 	case MODULE_CMD_FINI:
745 #ifdef _MODULE
746 		error = config_fini_component(cfdriver_ioconf_ichsmb,
747 		    cfattach_ioconf_ichsmb, cfdata_ioconf_ichsmb);
748 #endif
749 		break;
750 	default:
751 #ifdef _MODULE
752 		error = ENOTTY;
753 #endif
754 		break;
755 	}
756 
757 	return error;
758 }
759