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