Home | History | Annotate | Line # | Download | only in pci
ismt.c revision 1.2
      1  1.1   msaitoh /*-
      2  1.1   msaitoh  * Copyright (c) 2016 The NetBSD Foundation, Inc.
      3  1.1   msaitoh  * All rights reserved.
      4  1.1   msaitoh  *
      5  1.1   msaitoh  * This code is derived from software contributed to The NetBSD Foundation
      6  1.1   msaitoh  * by Masanobu SAITOH.
      7  1.1   msaitoh  *
      8  1.1   msaitoh  * Redistribution and use in source and binary forms, with or without
      9  1.1   msaitoh  * modification, are permitted provided that the following conditions
     10  1.1   msaitoh  * are met:
     11  1.1   msaitoh  * 1. Redistributions of source code must retain the above copyright
     12  1.1   msaitoh  *    notice, this list of conditions and the following disclaimer.
     13  1.1   msaitoh  * 2. Redistributions in binary form must reproduce the above copyright
     14  1.1   msaitoh  *    notice, this list of conditions and the following disclaimer in the
     15  1.1   msaitoh  *    documentation and/or other materials provided with the distribution.
     16  1.1   msaitoh  *
     17  1.1   msaitoh  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     18  1.1   msaitoh  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     19  1.1   msaitoh  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     20  1.1   msaitoh  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     21  1.1   msaitoh  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     22  1.1   msaitoh  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     23  1.1   msaitoh  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     24  1.1   msaitoh  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     25  1.1   msaitoh  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     26  1.1   msaitoh  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     27  1.1   msaitoh  * POSSIBILITY OF SUCH DAMAGE.
     28  1.1   msaitoh  */
     29  1.1   msaitoh 
     30  1.1   msaitoh /*-
     31  1.1   msaitoh  * Copyright (C) 2014 Intel Corporation
     32  1.1   msaitoh  * All rights reserved.
     33  1.1   msaitoh  *
     34  1.1   msaitoh  * Redistribution and use in source and binary forms, with or without
     35  1.1   msaitoh  * modification, are permitted provided that the following conditions
     36  1.1   msaitoh  * are met:
     37  1.1   msaitoh  * 1. Redistributions of source code must retain the above copyright
     38  1.1   msaitoh  *    notice, this list of conditions and the following disclaimer.
     39  1.1   msaitoh  * 2. Redistributions in binary form must reproduce the above copyright
     40  1.1   msaitoh  *    notice, this list of conditions and the following disclaimer in the
     41  1.1   msaitoh  *    documentation and/or other materials provided with the distribution.
     42  1.1   msaitoh  * 3. Neither the name of Intel Corporation nor the names of its
     43  1.1   msaitoh  *    contributors may be used to endorse or promote products derived from
     44  1.1   msaitoh  *    this software without specific prior written permission.
     45  1.1   msaitoh  *
     46  1.1   msaitoh  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
     47  1.1   msaitoh  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     48  1.1   msaitoh  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     49  1.1   msaitoh  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
     50  1.1   msaitoh  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     51  1.1   msaitoh  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     52  1.1   msaitoh  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     53  1.1   msaitoh  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     54  1.1   msaitoh  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     55  1.1   msaitoh  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     56  1.1   msaitoh  * SUCH DAMAGE.
     57  1.1   msaitoh  */
     58  1.1   msaitoh 
     59  1.1   msaitoh #include <sys/cdefs.h>
     60  1.1   msaitoh #if 0
     61  1.1   msaitoh __FBSDID("$FreeBSD: head/sys/dev/ismt/ismt.c 266474 2014-05-20 19:55:06Z jimharris $");
     62  1.1   msaitoh #endif
     63  1.2  christos __KERNEL_RCSID(0, "$NetBSD: ismt.c,v 1.2 2016/01/06 03:53:29 christos Exp $");
     64  1.1   msaitoh 
     65  1.1   msaitoh #include <sys/param.h>
     66  1.1   msaitoh #include <sys/systm.h>
     67  1.1   msaitoh #include <sys/device.h>
     68  1.1   msaitoh #include <sys/errno.h>
     69  1.1   msaitoh #include <sys/kernel.h>
     70  1.1   msaitoh #include <sys/module.h>
     71  1.1   msaitoh #include <sys/mutex.h>
     72  1.1   msaitoh #include <sys/proc.h>
     73  1.1   msaitoh 
     74  1.1   msaitoh #include <sys/bus.h>
     75  1.1   msaitoh 
     76  1.1   msaitoh #include <dev/pci/pcidevs.h>
     77  1.1   msaitoh #include <dev/pci/pcireg.h>
     78  1.1   msaitoh #include <dev/pci/pcivar.h>
     79  1.1   msaitoh 
     80  1.1   msaitoh #include <dev/i2c/i2cvar.h>
     81  1.1   msaitoh 
     82  1.1   msaitoh #define ISMT_DESC_ENTRIES	32
     83  1.1   msaitoh 
     84  1.1   msaitoh /* Hardware Descriptor Constants - Control Field */
     85  1.1   msaitoh #define ISMT_DESC_CWRL	0x01	/* Command/Write Length */
     86  1.1   msaitoh #define ISMT_DESC_BLK	0X04	/* Perform Block Transaction */
     87  1.1   msaitoh #define ISMT_DESC_FAIR	0x08	/* Set fairness flag upon successful arbit. */
     88  1.1   msaitoh #define ISMT_DESC_PEC	0x10	/* Packet Error Code */
     89  1.1   msaitoh #define ISMT_DESC_I2C	0x20	/* I2C Enable */
     90  1.1   msaitoh #define ISMT_DESC_INT	0x40	/* Interrupt */
     91  1.1   msaitoh #define ISMT_DESC_SOE	0x80	/* Stop On Error */
     92  1.1   msaitoh 
     93  1.1   msaitoh /* Hardware Descriptor Constants - Status Field */
     94  1.1   msaitoh #define ISMT_DESC_SCS	0x01	/* Success */
     95  1.1   msaitoh #define ISMT_DESC_DLTO	0x04	/* Data Low Time Out */
     96  1.1   msaitoh #define ISMT_DESC_NAK	0x08	/* NAK Received */
     97  1.1   msaitoh #define ISMT_DESC_CRC	0x10	/* CRC Error */
     98  1.1   msaitoh #define ISMT_DESC_CLTO	0x20	/* Clock Low Time Out */
     99  1.1   msaitoh #define ISMT_DESC_COL	0x40	/* Collisions */
    100  1.1   msaitoh #define ISMT_DESC_LPR	0x80	/* Large Packet Received */
    101  1.1   msaitoh 
    102  1.1   msaitoh /* Macros */
    103  1.1   msaitoh #define ISMT_DESC_ADDR_RW(addr, is_read) ((addr << 1) | (is_read))
    104  1.1   msaitoh 
    105  1.1   msaitoh /* iSMT General Register address offsets (SMBBAR + <addr>) */
    106  1.1   msaitoh #define ISMT_GR_GCTRL		0x000	/* General Control */
    107  1.1   msaitoh #define ISMT_GR_SMTICL		0x008	/* SMT Interrupt Cause Location */
    108  1.1   msaitoh #define ISMT_GR_ERRINTMSK	0x010	/* Error Interrupt Mask */
    109  1.1   msaitoh #define ISMT_GR_ERRAERMSK	0x014	/* Error AER Mask */
    110  1.1   msaitoh #define ISMT_GR_ERRSTS		0x018	/* Error Status */
    111  1.1   msaitoh #define ISMT_GR_ERRINFO		0x01c	/* Error Information */
    112  1.1   msaitoh 
    113  1.1   msaitoh /* iSMT Master Registers */
    114  1.1   msaitoh #define ISMT_MSTR_MDBA		0x100	/* Master Descriptor Base Address */
    115  1.1   msaitoh #define ISMT_MSTR_MCTRL		0x108	/* Master Control */
    116  1.1   msaitoh #define ISMT_MSTR_MSTS		0x10c	/* Master Status */
    117  1.1   msaitoh #define ISMT_MSTR_MDS		0x110	/* Master Descriptor Size */
    118  1.1   msaitoh #define ISMT_MSTR_RPOLICY	0x114	/* Retry Policy */
    119  1.1   msaitoh 
    120  1.1   msaitoh /* iSMT Miscellaneous Registers */
    121  1.1   msaitoh #define ISMT_SPGT	0x300	/* SMBus PHY Global Timing */
    122  1.1   msaitoh 
    123  1.1   msaitoh /* General Control Register (GCTRL) bit definitions */
    124  1.1   msaitoh #define ISMT_GCTRL_TRST	0x04	/* Target Reset */
    125  1.1   msaitoh #define ISMT_GCTRL_KILL	0x08	/* Kill */
    126  1.1   msaitoh #define ISMT_GCTRL_SRST	0x40	/* Soft Reset */
    127  1.1   msaitoh 
    128  1.1   msaitoh /* Master Control Register (MCTRL) bit definitions */
    129  1.1   msaitoh #define ISMT_MCTRL_SS	0x01		/* Start/Stop */
    130  1.1   msaitoh #define ISMT_MCTRL_MEIE	0x10		/* Master Error Interrupt Enable */
    131  1.1   msaitoh #define ISMT_MCTRL_FMHP	0x00ff0000	/* Firmware Master Head Ptr (FMHP) */
    132  1.1   msaitoh 
    133  1.1   msaitoh /* Master Status Register (MSTS) bit definitions */
    134  1.1   msaitoh #define ISMT_MSTS_HMTP	0xff0000	/* HW Master Tail Pointer (HMTP) */
    135  1.1   msaitoh #define ISMT_MSTS_MIS	0x20		/* Master Interrupt Status (MIS) */
    136  1.1   msaitoh #define ISMT_MSTS_MEIS	0x10		/* Master Error Int Status (MEIS) */
    137  1.1   msaitoh #define ISMT_MSTS_IP	0x01		/* In Progress */
    138  1.1   msaitoh 
    139  1.1   msaitoh /* Master Descriptor Size (MDS) bit definitions */
    140  1.1   msaitoh #define ISMT_MDS_MASK	0xff	/* Master Descriptor Size mask (MDS) */
    141  1.1   msaitoh 
    142  1.1   msaitoh /* SMBus PHY Global Timing Register (SPGT) bit definitions */
    143  1.1   msaitoh #define ISMT_SPGT_SPD_MASK	0xc0000000	/* SMBus Speed mask */
    144  1.1   msaitoh #define ISMT_SPGT_SPD_80K	0x00		/* 80 kHz */
    145  1.1   msaitoh #define ISMT_SPGT_SPD_100K	(0x1 << 30)	/* 100 kHz */
    146  1.1   msaitoh #define ISMT_SPGT_SPD_400K	(0x2 << 30)	/* 400 kHz */
    147  1.1   msaitoh #define ISMT_SPGT_SPD_1M	(0x3 << 30)	/* 1 MHz */
    148  1.1   msaitoh 
    149  1.1   msaitoh /* MSI Control Register (MSICTL) bit definitions */
    150  1.1   msaitoh #define ISMT_MSICTL_MSIE	0x01	/* MSI Enable */
    151  1.1   msaitoh 
    152  1.1   msaitoh #define ISMT_MAX_BLOCK_SIZE	32 /* per SMBus spec */
    153  1.1   msaitoh 
    154  1.1   msaitoh #define ISMT_INTR_TIMEOUT	(hz / 50) /* 0.02s */
    155  1.1   msaitoh #define ISMT_POLL_DELAY		100	/* 100usec */
    156  1.1   msaitoh #define ISMT_POLL_COUNT		200	/* 100usec * 200 = 0.02s */
    157  1.1   msaitoh 
    158  1.1   msaitoh //#define ISMT_DEBUG	aprint_debug_dev
    159  1.1   msaitoh #ifndef ISMT_DEBUG
    160  1.1   msaitoh #define ISMT_DEBUG(...)
    161  1.1   msaitoh #endif
    162  1.1   msaitoh 
    163  1.2  christos #define ISMT_LOW(a)	((a) & 0xFFFFFFFFULL)
    164  1.2  christos #define ISMT_HIGH(a)	(((uint64_t)(a) >> 32) & 0xFFFFFFFFFULL)
    165  1.2  christos 
    166  1.1   msaitoh /* iSMT Hardware Descriptor */
    167  1.1   msaitoh struct ismt_desc {
    168  1.1   msaitoh 	uint8_t tgtaddr_rw;	/* target address & r/w bit */
    169  1.1   msaitoh 	uint8_t wr_len_cmd;	/* write length in bytes or a command */
    170  1.1   msaitoh 	uint8_t rd_len;		/* read length */
    171  1.1   msaitoh 	uint8_t control;	/* control bits */
    172  1.1   msaitoh 	uint8_t status;		/* status bits */
    173  1.1   msaitoh 	uint8_t retry;		/* collision retry and retry count */
    174  1.1   msaitoh 	uint8_t rxbytes;	/* received bytes */
    175  1.1   msaitoh 	uint8_t txbytes;	/* transmitted bytes */
    176  1.1   msaitoh 	uint32_t dptr_low;	/* lower 32 bit of the data pointer */
    177  1.1   msaitoh 	uint32_t dptr_high;	/* upper 32 bit of the data pointer */
    178  1.1   msaitoh } __packed;
    179  1.1   msaitoh 
    180  1.1   msaitoh #define DESC_SIZE	(ISMT_DESC_ENTRIES * sizeof(struct ismt_desc))
    181  1.1   msaitoh 
    182  1.1   msaitoh #define DMA_BUFFER_SIZE	64
    183  1.1   msaitoh 
    184  1.1   msaitoh struct ismt_softc {
    185  1.1   msaitoh 	device_t		pcidev;
    186  1.1   msaitoh 	device_t		smbdev;
    187  1.1   msaitoh 
    188  1.1   msaitoh 	struct i2c_controller	sc_i2c_tag;
    189  1.1   msaitoh 	kmutex_t 		sc_i2c_mutex;
    190  1.1   msaitoh 
    191  1.1   msaitoh 	pci_chipset_tag_t	sc_pc;
    192  1.1   msaitoh 	pcitag_t		sc_pcitag;
    193  1.1   msaitoh 	pci_intr_handle_t	*sc_pihp;
    194  1.1   msaitoh 	void			*sc_ih;
    195  1.1   msaitoh 
    196  1.1   msaitoh 	bus_space_tag_t		mmio_tag;
    197  1.1   msaitoh 	bus_space_handle_t	mmio_handle;
    198  1.1   msaitoh 	bus_size_t		mmio_size;
    199  1.1   msaitoh 
    200  1.1   msaitoh 	uint8_t			head;
    201  1.1   msaitoh 
    202  1.1   msaitoh 	struct ismt_desc	*desc;
    203  1.1   msaitoh 	bus_dma_tag_t		desc_dma_tag;
    204  1.1   msaitoh 	bus_dmamap_t		desc_dma_map;
    205  1.1   msaitoh 	bus_dma_segment_t	desc_dma_seg;
    206  1.1   msaitoh 	int			desc_rseg;
    207  1.1   msaitoh 
    208  1.1   msaitoh 	uint8_t			*dma_buffer;
    209  1.1   msaitoh 	bus_dma_tag_t		dma_buffer_dma_tag;
    210  1.1   msaitoh 	bus_dmamap_t		dma_buffer_dma_map;
    211  1.1   msaitoh 	bus_dma_segment_t	dma_buffer_dma_seg;
    212  1.1   msaitoh 	int			dma_buffer_rseg;
    213  1.1   msaitoh 
    214  1.1   msaitoh 	uint8_t			using_msi;
    215  1.1   msaitoh };
    216  1.1   msaitoh 
    217  1.1   msaitoh static int	ismt_intr(void *);
    218  1.1   msaitoh static int	ismt_i2c_acquire_bus(void *, int);
    219  1.1   msaitoh static void	ismt_i2c_release_bus(void *, int);
    220  1.1   msaitoh static int	ismt_i2c_exec(void *, i2c_op_t, i2c_addr_t, const void *,
    221  1.1   msaitoh     size_t, void *, size_t, int);
    222  1.1   msaitoh static struct ismt_desc *ismt_alloc_desc(struct ismt_softc *);
    223  1.1   msaitoh static int	ismt_submit(struct ismt_softc *, struct ismt_desc *,
    224  1.1   msaitoh     i2c_addr_t, uint8_t, int);
    225  1.1   msaitoh static int	ismt_quick(struct ismt_softc *, i2c_addr_t, i2c_op_t, int);
    226  1.1   msaitoh static int	ismt_sendb(struct ismt_softc *, i2c_addr_t, i2c_op_t, char,
    227  1.1   msaitoh     int);
    228  1.1   msaitoh static int	ismt_recvb(struct ismt_softc *, i2c_addr_t, i2c_op_t, int);
    229  1.1   msaitoh static int	ismt_writeb(struct ismt_softc *, i2c_addr_t, i2c_op_t, uint8_t,
    230  1.1   msaitoh     char, int);
    231  1.1   msaitoh static int	ismt_writew(struct ismt_softc *, i2c_addr_t, i2c_op_t, uint8_t,
    232  1.1   msaitoh     uint16_t, int);
    233  1.1   msaitoh static int	ismt_readb(struct ismt_softc *, i2c_addr_t, i2c_op_t, char,
    234  1.1   msaitoh     int);
    235  1.1   msaitoh static int	ismt_readw(struct ismt_softc *, i2c_addr_t, i2c_op_t, char,
    236  1.1   msaitoh     int);
    237  1.1   msaitoh 
    238  1.1   msaitoh static int	ismt_match(device_t, cfdata_t, void *);
    239  1.1   msaitoh static void	ismt_attach(device_t, device_t, void *);
    240  1.1   msaitoh static int	ismt_detach(device_t, int);
    241  1.1   msaitoh static int	ismt_rescan(device_t, const char *, const int *);
    242  1.1   msaitoh static void	ismt_config_interrupts(device_t);
    243  1.1   msaitoh static void	ismt_chdet(device_t, device_t);
    244  1.1   msaitoh 
    245  1.1   msaitoh CFATTACH_DECL3_NEW(ismt, sizeof(struct ismt_softc),
    246  1.1   msaitoh     ismt_match, ismt_attach, ismt_detach, NULL, ismt_rescan, ismt_chdet,
    247  1.1   msaitoh     DVF_DETACH_SHUTDOWN);
    248  1.1   msaitoh 
    249  1.1   msaitoh static int
    250  1.1   msaitoh ismt_intr(void *arg)
    251  1.1   msaitoh {
    252  1.1   msaitoh 	struct ismt_softc *sc = arg;
    253  1.1   msaitoh 	uint32_t val;
    254  1.1   msaitoh 
    255  1.1   msaitoh 	val = bus_space_read_4(sc->mmio_tag, sc->mmio_handle, ISMT_MSTR_MSTS);
    256  1.1   msaitoh 	if ((sc->using_msi == 0)
    257  1.1   msaitoh 	    && (val & (ISMT_MSTS_MIS | ISMT_MSTS_MEIS)) == 0)
    258  1.1   msaitoh 		return 0; /* Not for me */
    259  1.1   msaitoh 
    260  1.1   msaitoh 	ISMT_DEBUG(sc->pcidev, "%s MSTS = 0x%08x\n", __func__, val);
    261  1.1   msaitoh 
    262  1.1   msaitoh 	val |= (ISMT_MSTS_MIS | ISMT_MSTS_MEIS);
    263  1.1   msaitoh 	bus_space_write_4(sc->mmio_tag, sc->mmio_handle, ISMT_MSTR_MSTS, val);
    264  1.1   msaitoh 
    265  1.1   msaitoh 	if (sc->using_msi)
    266  1.1   msaitoh 		wakeup(sc);
    267  1.1   msaitoh 
    268  1.1   msaitoh 	return 1;
    269  1.1   msaitoh }
    270  1.1   msaitoh 
    271  1.1   msaitoh static int
    272  1.1   msaitoh ismt_i2c_acquire_bus(void *cookie, int flags)
    273  1.1   msaitoh {
    274  1.1   msaitoh 	struct ismt_softc *sc = cookie;
    275  1.1   msaitoh 
    276  1.1   msaitoh 	mutex_enter(&sc->sc_i2c_mutex);
    277  1.1   msaitoh 	return 0;
    278  1.1   msaitoh }
    279  1.1   msaitoh 
    280  1.1   msaitoh static void
    281  1.1   msaitoh ismt_i2c_release_bus(void *cookie, int flags)
    282  1.1   msaitoh {
    283  1.1   msaitoh 	struct ismt_softc *sc = cookie;
    284  1.1   msaitoh 
    285  1.1   msaitoh 	mutex_exit(&sc->sc_i2c_mutex);
    286  1.1   msaitoh }
    287  1.1   msaitoh 
    288  1.1   msaitoh static int
    289  1.1   msaitoh ismt_i2c_exec(void *cookie, i2c_op_t op, i2c_addr_t addr,
    290  1.1   msaitoh     const void *cmd, size_t cmdlen, void *buf, size_t buflen, int flags)
    291  1.1   msaitoh {
    292  1.1   msaitoh 	struct ismt_softc *sc = cookie;
    293  1.1   msaitoh 	uint8_t *p = buf;
    294  1.1   msaitoh 	int rv;
    295  1.1   msaitoh 
    296  1.1   msaitoh 	ISMT_DEBUG(sc->pcidev, "exec: op %d, addr 0x%02x, cmdlen %zu, "
    297  1.1   msaitoh  	    " buflen %zu, flags 0x%02x\n", op, addr, cmdlen, buflen, flags);
    298  1.1   msaitoh 
    299  1.1   msaitoh 	if ((cmdlen == 0) && (buflen == 0))
    300  1.1   msaitoh 		return ismt_quick(sc, addr, op, flags);
    301  1.1   msaitoh 
    302  1.1   msaitoh 	if (I2C_OP_READ_P(op) && (cmdlen == 0) && (buflen == 1)) {
    303  1.1   msaitoh 		rv = ismt_recvb(sc, addr, op, flags);
    304  1.1   msaitoh 		if (rv == -1)
    305  1.1   msaitoh 			return -1;
    306  1.1   msaitoh 		*p = (uint8_t)rv;
    307  1.1   msaitoh 		return 0;
    308  1.1   msaitoh 	}
    309  1.1   msaitoh 
    310  1.1   msaitoh 	if ((I2C_OP_READ_P(op)) && (cmdlen == 1) && (buflen == 1)) {
    311  1.1   msaitoh 		rv = ismt_readb(sc, addr, op, *(const uint8_t*)cmd, flags);
    312  1.1   msaitoh 		if (rv == -1)
    313  1.1   msaitoh 			return -1;
    314  1.1   msaitoh 		*p = (uint8_t)rv;
    315  1.1   msaitoh 		return 0;
    316  1.1   msaitoh 	}
    317  1.1   msaitoh 
    318  1.1   msaitoh 	if ((I2C_OP_READ_P(op)) && (cmdlen == 1) && (buflen == 2)) {
    319  1.1   msaitoh 		rv = ismt_readw(sc, addr, op, *(const uint8_t*)cmd, flags);
    320  1.1   msaitoh 		if (rv == -1)
    321  1.1   msaitoh 			return -1;
    322  1.1   msaitoh 		*(uint16_t *)p = (uint16_t)rv;
    323  1.1   msaitoh 		return 0;
    324  1.1   msaitoh 	}
    325  1.1   msaitoh 
    326  1.1   msaitoh 	if ((I2C_OP_WRITE_P(op)) && (cmdlen == 0) && (buflen == 1))
    327  1.1   msaitoh 		return ismt_sendb(sc, addr, op, *(uint8_t*)buf, flags);
    328  1.1   msaitoh 
    329  1.1   msaitoh 	if ((I2C_OP_WRITE_P(op)) && (cmdlen == 1) && (buflen == 1))
    330  1.1   msaitoh 		return ismt_writeb(sc, addr, op, *(const uint8_t*)cmd,
    331  1.1   msaitoh 		    *(uint8_t*)buf, flags);
    332  1.1   msaitoh 
    333  1.1   msaitoh 	if ((I2C_OP_WRITE_P(op)) && (cmdlen == 1) && (buflen == 2))
    334  1.1   msaitoh 		return ismt_writew(sc, addr, op,
    335  1.1   msaitoh 		    *(const uint8_t*)cmd, *((uint16_t *)buf), flags);
    336  1.1   msaitoh 
    337  1.1   msaitoh 	return -1;
    338  1.1   msaitoh }
    339  1.1   msaitoh 
    340  1.1   msaitoh static struct ismt_desc *
    341  1.1   msaitoh ismt_alloc_desc(struct ismt_softc *sc)
    342  1.1   msaitoh {
    343  1.1   msaitoh 	struct ismt_desc *desc;
    344  1.1   msaitoh 
    345  1.1   msaitoh 	KASSERT(mutex_owned(&sc->sc_i2c_mutex));
    346  1.1   msaitoh 
    347  1.1   msaitoh 	desc = &sc->desc[sc->head++];
    348  1.1   msaitoh 	if (sc->head == ISMT_DESC_ENTRIES)
    349  1.1   msaitoh 		sc->head = 0;
    350  1.1   msaitoh 
    351  1.1   msaitoh 	memset(desc, 0, sizeof(*desc));
    352  1.1   msaitoh 
    353  1.1   msaitoh 	return (desc);
    354  1.1   msaitoh }
    355  1.1   msaitoh 
    356  1.1   msaitoh static int
    357  1.1   msaitoh ismt_submit(struct ismt_softc *sc, struct ismt_desc *desc, i2c_addr_t slave,
    358  1.1   msaitoh     uint8_t is_read, int flags)
    359  1.1   msaitoh {
    360  1.1   msaitoh 	uint32_t err, fmhp, val;
    361  1.1   msaitoh 	int timeout, i;
    362  1.1   msaitoh 
    363  1.1   msaitoh 	if (sc->using_msi == 0)
    364  1.1   msaitoh 		flags |= I2C_F_POLL;
    365  1.1   msaitoh 	desc->control |= ISMT_DESC_FAIR;
    366  1.1   msaitoh 	if ((flags & I2C_F_POLL) == 0)
    367  1.1   msaitoh 		desc->control |= ISMT_DESC_INT;
    368  1.1   msaitoh 
    369  1.1   msaitoh 	desc->tgtaddr_rw = ISMT_DESC_ADDR_RW(slave, is_read);
    370  1.2  christos 	desc->dptr_low = ISMT_LOW(sc->dma_buffer_dma_map->dm_segs[0].ds_addr);
    371  1.2  christos 	desc->dptr_high = ISMT_HIGH(sc->dma_buffer_dma_map->dm_segs[0].ds_addr);
    372  1.1   msaitoh 
    373  1.1   msaitoh 	bus_dmamap_sync(sc->desc_dma_tag, sc->desc_dma_map,
    374  1.1   msaitoh 	    desc - &sc->desc[0], sizeof(struct ismt_desc),
    375  1.1   msaitoh 	    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
    376  1.1   msaitoh 
    377  1.1   msaitoh 	fmhp = sc->head << 16;
    378  1.1   msaitoh 	val = bus_space_read_4(sc->mmio_tag, sc->mmio_handle, ISMT_MSTR_MCTRL);
    379  1.1   msaitoh 	val &= ~ISMT_MCTRL_FMHP;
    380  1.1   msaitoh 	val |= fmhp;
    381  1.1   msaitoh 	bus_space_write_4(sc->mmio_tag, sc->mmio_handle, ISMT_MSTR_MCTRL, val);
    382  1.1   msaitoh 
    383  1.1   msaitoh 	/* set the start bit */
    384  1.1   msaitoh 	val = bus_space_read_4(sc->mmio_tag, sc->mmio_handle, ISMT_MSTR_MCTRL);
    385  1.1   msaitoh 	val |= ISMT_MCTRL_SS;
    386  1.1   msaitoh 	bus_space_write_4(sc->mmio_tag, sc->mmio_handle, ISMT_MSTR_MCTRL, val);
    387  1.1   msaitoh 
    388  1.1   msaitoh 	i = 0;
    389  1.1   msaitoh 	if ((flags & I2C_F_POLL) == 0) {
    390  1.1   msaitoh 		timeout = ISMT_INTR_TIMEOUT;
    391  1.1   msaitoh 		if (timeout == 0)
    392  1.1   msaitoh 			timeout = 1;
    393  1.1   msaitoh 		err = tsleep(sc, PWAIT, "ismt_wait", timeout);
    394  1.1   msaitoh 		if (err != 0) {
    395  1.1   msaitoh 			ISMT_DEBUG(sc->pcidev, "%s timeout\n", __func__);
    396  1.1   msaitoh 			return -1;
    397  1.1   msaitoh 		}
    398  1.1   msaitoh 	} else {
    399  1.1   msaitoh 		/* Polling */
    400  1.1   msaitoh 		for (i = 0; i < ISMT_POLL_COUNT; i++) {
    401  1.1   msaitoh 			val = bus_space_read_4(sc->mmio_tag, sc->mmio_handle,
    402  1.1   msaitoh 			    ISMT_MSTR_MSTS);
    403  1.1   msaitoh 			if ((val & (ISMT_MSTS_MIS | ISMT_MSTS_MEIS)) != 0) {
    404  1.1   msaitoh 				ismt_intr(sc);
    405  1.1   msaitoh 				err = 0;
    406  1.1   msaitoh 				break;
    407  1.1   msaitoh 			}
    408  1.1   msaitoh 			delay(ISMT_POLL_DELAY);
    409  1.1   msaitoh 		}
    410  1.1   msaitoh 		if (i >= ISMT_POLL_COUNT) {
    411  1.1   msaitoh 			ISMT_DEBUG(sc->pcidev, "%s polling timeout. "
    412  1.1   msaitoh 			    "MSTS = %08x\n", __func__, val);
    413  1.1   msaitoh 			return -1;
    414  1.1   msaitoh 		}
    415  1.1   msaitoh 	}
    416  1.1   msaitoh 
    417  1.1   msaitoh 	bus_dmamap_sync(sc->desc_dma_tag, sc->desc_dma_map,
    418  1.1   msaitoh 	    desc - &sc->desc[0], sizeof(struct ismt_desc),
    419  1.1   msaitoh 		BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
    420  1.1   msaitoh 	ISMT_DEBUG(sc->pcidev, "%s status=0x%02x\n", __func__, desc->status);
    421  1.1   msaitoh 
    422  1.1   msaitoh 	if (desc->status & ISMT_DESC_SCS)
    423  1.1   msaitoh 		return 0;
    424  1.1   msaitoh 
    425  1.1   msaitoh 	if (desc->status & ISMT_DESC_NAK)
    426  1.1   msaitoh 		return -1;
    427  1.1   msaitoh 
    428  1.1   msaitoh 	if (desc->status & ISMT_DESC_CRC)
    429  1.1   msaitoh 		return -1;
    430  1.1   msaitoh 
    431  1.1   msaitoh 	if (desc->status & ISMT_DESC_COL)
    432  1.1   msaitoh 		return -1;
    433  1.1   msaitoh 
    434  1.1   msaitoh 	if (desc->status & ISMT_DESC_LPR)
    435  1.1   msaitoh 		return -1;
    436  1.1   msaitoh 
    437  1.1   msaitoh 	if (desc->status & (ISMT_DESC_DLTO | ISMT_DESC_CLTO))
    438  1.1   msaitoh 		return -1;
    439  1.1   msaitoh 
    440  1.1   msaitoh 	return -1;
    441  1.1   msaitoh }
    442  1.1   msaitoh 
    443  1.1   msaitoh static int
    444  1.1   msaitoh ismt_quick(struct ismt_softc *sc, i2c_addr_t slave, i2c_op_t op, int flags)
    445  1.1   msaitoh {
    446  1.1   msaitoh 	struct ismt_desc	*desc;
    447  1.1   msaitoh 	int			is_read;
    448  1.1   msaitoh 
    449  1.1   msaitoh 	ISMT_DEBUG(sc->pcidev, "%s\n", __func__);
    450  1.1   msaitoh 
    451  1.1   msaitoh 	desc = ismt_alloc_desc(sc);
    452  1.1   msaitoh 	is_read = I2C_OP_READ_P(op);
    453  1.1   msaitoh 	return (ismt_submit(sc, desc, slave, is_read, flags));
    454  1.1   msaitoh }
    455  1.1   msaitoh 
    456  1.1   msaitoh static int
    457  1.1   msaitoh ismt_sendb(struct ismt_softc *sc, i2c_addr_t slave, i2c_op_t op, char byte,
    458  1.1   msaitoh     int flags)
    459  1.1   msaitoh {
    460  1.1   msaitoh 	struct ismt_desc	*desc;
    461  1.1   msaitoh 
    462  1.1   msaitoh 	ISMT_DEBUG(sc->pcidev, "%s\n", __func__);
    463  1.1   msaitoh 
    464  1.1   msaitoh 	desc = ismt_alloc_desc(sc);
    465  1.1   msaitoh 	desc->control = ISMT_DESC_CWRL;
    466  1.1   msaitoh 	desc->wr_len_cmd = byte;
    467  1.1   msaitoh 
    468  1.1   msaitoh 	return (ismt_submit(sc, desc, slave, 0, flags));
    469  1.1   msaitoh }
    470  1.1   msaitoh 
    471  1.1   msaitoh static int
    472  1.1   msaitoh ismt_recvb(struct ismt_softc *sc, i2c_addr_t slave, i2c_op_t op, int flags)
    473  1.1   msaitoh {
    474  1.1   msaitoh 	struct ismt_desc	*desc;
    475  1.1   msaitoh 	int			err;
    476  1.1   msaitoh 
    477  1.1   msaitoh 	ISMT_DEBUG(sc->pcidev, "%s\n", __func__);
    478  1.1   msaitoh 
    479  1.1   msaitoh 	desc = ismt_alloc_desc(sc);
    480  1.1   msaitoh 	desc->rd_len = 1;
    481  1.1   msaitoh 
    482  1.1   msaitoh 	err = ismt_submit(sc, desc, slave, 1, flags);
    483  1.1   msaitoh 
    484  1.1   msaitoh 	if (err != 0)
    485  1.1   msaitoh 		return (err);
    486  1.1   msaitoh 
    487  1.1   msaitoh 	return sc->dma_buffer[0];
    488  1.1   msaitoh }
    489  1.1   msaitoh 
    490  1.1   msaitoh static int
    491  1.1   msaitoh ismt_writeb(struct ismt_softc *sc, i2c_addr_t slave, i2c_op_t op, uint8_t cmd,
    492  1.1   msaitoh     char byte, int flags)
    493  1.1   msaitoh {
    494  1.1   msaitoh 	struct ismt_desc	*desc;
    495  1.1   msaitoh 
    496  1.1   msaitoh 	ISMT_DEBUG(sc->pcidev, "%s\n", __func__);
    497  1.1   msaitoh 
    498  1.1   msaitoh 	desc = ismt_alloc_desc(sc);
    499  1.1   msaitoh 	desc->wr_len_cmd = 2;
    500  1.1   msaitoh 	sc->dma_buffer[0] = cmd;
    501  1.1   msaitoh 	sc->dma_buffer[1] = byte;
    502  1.1   msaitoh 
    503  1.1   msaitoh 	return (ismt_submit(sc, desc, slave, 0, flags));
    504  1.1   msaitoh }
    505  1.1   msaitoh 
    506  1.1   msaitoh static int
    507  1.1   msaitoh ismt_writew(struct ismt_softc *sc, i2c_addr_t slave, i2c_op_t op, uint8_t cmd,
    508  1.1   msaitoh     uint16_t word, int flags)
    509  1.1   msaitoh {
    510  1.1   msaitoh 	struct ismt_desc	*desc;
    511  1.1   msaitoh 
    512  1.1   msaitoh 	ISMT_DEBUG(sc->pcidev, "%s\n", __func__);
    513  1.1   msaitoh 
    514  1.1   msaitoh 	desc = ismt_alloc_desc(sc);
    515  1.1   msaitoh 	desc->wr_len_cmd = 3;
    516  1.1   msaitoh 	sc->dma_buffer[0] = cmd;
    517  1.1   msaitoh 	sc->dma_buffer[1] = word & 0xFF;
    518  1.1   msaitoh 	sc->dma_buffer[2] = word >> 8;
    519  1.1   msaitoh 
    520  1.1   msaitoh 	return (ismt_submit(sc, desc, slave, 0, flags));
    521  1.1   msaitoh }
    522  1.1   msaitoh 
    523  1.1   msaitoh static int
    524  1.1   msaitoh ismt_readb(struct ismt_softc *sc, i2c_addr_t slave, i2c_op_t op, char cmd,
    525  1.1   msaitoh     int flags)
    526  1.1   msaitoh {
    527  1.1   msaitoh 	struct ismt_desc	*desc;
    528  1.1   msaitoh 	int			err;
    529  1.1   msaitoh 
    530  1.1   msaitoh 	ISMT_DEBUG(sc->pcidev, "%s\n", __func__);
    531  1.1   msaitoh 
    532  1.1   msaitoh 	desc = ismt_alloc_desc(sc);
    533  1.1   msaitoh 	desc->control = ISMT_DESC_CWRL;
    534  1.1   msaitoh 	desc->wr_len_cmd = cmd;
    535  1.1   msaitoh 	desc->rd_len = 1;
    536  1.1   msaitoh 
    537  1.1   msaitoh 	err = ismt_submit(sc, desc, slave, 1, flags);
    538  1.1   msaitoh 
    539  1.1   msaitoh 	if (err != 0)
    540  1.1   msaitoh 		return (err);
    541  1.1   msaitoh 
    542  1.1   msaitoh 	return sc->dma_buffer[0];
    543  1.1   msaitoh }
    544  1.1   msaitoh 
    545  1.1   msaitoh static int
    546  1.1   msaitoh ismt_readw(struct ismt_softc *sc, i2c_addr_t slave, i2c_op_t op, char cmd,
    547  1.1   msaitoh     int flags)
    548  1.1   msaitoh {
    549  1.1   msaitoh 	struct ismt_desc	*desc;
    550  1.1   msaitoh 	uint16_t		word;
    551  1.1   msaitoh 	int			err;
    552  1.1   msaitoh 
    553  1.1   msaitoh 	ISMT_DEBUG(sc->pcidev, "%s\n", __func__);
    554  1.1   msaitoh 
    555  1.1   msaitoh 	desc = ismt_alloc_desc(sc);
    556  1.1   msaitoh 	desc->control = ISMT_DESC_CWRL;
    557  1.1   msaitoh 	desc->wr_len_cmd = cmd;
    558  1.1   msaitoh 	desc->rd_len = 2;
    559  1.1   msaitoh 
    560  1.1   msaitoh 	err = ismt_submit(sc, desc, slave, 1, flags);
    561  1.1   msaitoh 
    562  1.1   msaitoh 	if (err != 0)
    563  1.1   msaitoh 		return (err);
    564  1.1   msaitoh 
    565  1.1   msaitoh 	word = sc->dma_buffer[0] | (sc->dma_buffer[1] << 8);
    566  1.1   msaitoh 
    567  1.1   msaitoh 	return word;
    568  1.1   msaitoh }
    569  1.1   msaitoh 
    570  1.1   msaitoh #if 0
    571  1.1   msaitoh static int
    572  1.1   msaitoh ismt_pcall(struct ismt_softc *sc, i2c_addr_t slave, i2c_op_t op, char cmd,
    573  1.1   msaitoh     uint16_t sdata, uint16_t *rdata, int flags)
    574  1.1   msaitoh {
    575  1.1   msaitoh 	struct ismt_desc	*desc;
    576  1.1   msaitoh 	int			err;
    577  1.1   msaitoh 
    578  1.1   msaitoh 	ISMT_DEBUG(sc->pcidev, "%s\n", __func__);
    579  1.1   msaitoh 
    580  1.1   msaitoh 	desc = ismt_alloc_desc(sc);
    581  1.1   msaitoh 	desc->wr_len_cmd = 3;
    582  1.1   msaitoh 	desc->rd_len = 2;
    583  1.1   msaitoh 	sc->dma_buffer[0] = cmd;
    584  1.1   msaitoh 	sc->dma_buffer[1] = sdata & 0xff;
    585  1.1   msaitoh 	sc->dma_buffer[2] = sdata >> 8;
    586  1.1   msaitoh 
    587  1.1   msaitoh 	err = ismt_submit(sc, desc, slave, 0, flags);
    588  1.1   msaitoh 
    589  1.1   msaitoh 	if (err != 0)
    590  1.1   msaitoh 		return (err);
    591  1.1   msaitoh 
    592  1.1   msaitoh 	*rdata = sc->dma_buffer[0] | (sc->dma_buffer[1] << 8);
    593  1.1   msaitoh 
    594  1.1   msaitoh 	return (err);
    595  1.1   msaitoh }
    596  1.1   msaitoh 
    597  1.1   msaitoh static int
    598  1.1   msaitoh ismt_bwrite(struct ismt_softc *sc, i2c_addr_t slave, i2c_op_t op, char cmd,
    599  1.1   msaitoh     u_char count, char *buf, int flags)
    600  1.1   msaitoh {
    601  1.1   msaitoh 	struct ismt_desc	*desc;
    602  1.1   msaitoh 
    603  1.1   msaitoh 	ISMT_DEBUG(sc->pcidev, "%s\n", __func__);
    604  1.1   msaitoh 
    605  1.1   msaitoh 	if (count == 0 || count > ISMT_MAX_BLOCK_SIZE)
    606  1.1   msaitoh 		return -1;
    607  1.1   msaitoh 
    608  1.1   msaitoh 	desc = ismt_alloc_desc(sc);
    609  1.1   msaitoh 	desc->control = ISMT_DESC_I2C;
    610  1.1   msaitoh 	desc->wr_len_cmd = count + 1;
    611  1.1   msaitoh 	sc->dma_buffer[0] = cmd;
    612  1.1   msaitoh 	memcpy(&sc->dma_buffer[1], buf, count);
    613  1.1   msaitoh 
    614  1.1   msaitoh 	return (ismt_submit(sc, desc, slave, 0, flags));
    615  1.1   msaitoh }
    616  1.1   msaitoh 
    617  1.1   msaitoh static int
    618  1.1   msaitoh ismt_bread(struct ismt_softc *sc, i2c_addr_t slave, i2c_op_t op, char cmd,
    619  1.1   msaitoh     u_char *count, char *buf, int flags)
    620  1.1   msaitoh {
    621  1.1   msaitoh 	struct ismt_desc	*desc;
    622  1.1   msaitoh 	int			err;
    623  1.1   msaitoh 
    624  1.1   msaitoh 	ISMT_DEBUG(sc->pcidev, "%s\n", __func__);
    625  1.1   msaitoh 
    626  1.1   msaitoh 	if (*count == 0 || *count > ISMT_MAX_BLOCK_SIZE)
    627  1.1   msaitoh 		return -1;
    628  1.1   msaitoh 
    629  1.1   msaitoh 	desc = ismt_alloc_desc(sc);
    630  1.1   msaitoh 	desc->control = ISMT_DESC_I2C | ISMT_DESC_CWRL;
    631  1.1   msaitoh 	desc->wr_len_cmd = cmd;
    632  1.1   msaitoh 	desc->rd_len = *count;
    633  1.1   msaitoh 
    634  1.1   msaitoh 	err = ismt_submit(sc, desc, slave, 0, flags);
    635  1.1   msaitoh 
    636  1.1   msaitoh 	if (err != 0)
    637  1.1   msaitoh 		return (err);
    638  1.1   msaitoh 
    639  1.1   msaitoh 	memcpy(buf, sc->dma_buffer, desc->rxbytes);
    640  1.1   msaitoh 	*count = desc->rxbytes;
    641  1.1   msaitoh 
    642  1.1   msaitoh 	return (err);
    643  1.1   msaitoh }
    644  1.1   msaitoh #endif
    645  1.1   msaitoh 
    646  1.1   msaitoh static int
    647  1.1   msaitoh ismt_detach(device_t self, int flags)
    648  1.1   msaitoh {
    649  1.1   msaitoh 	struct ismt_softc	*sc;
    650  1.1   msaitoh 	int rv = 0;
    651  1.1   msaitoh 
    652  1.1   msaitoh 	ISMT_DEBUG(self, "%s\n", __func__);
    653  1.1   msaitoh 	sc = device_private(self);
    654  1.1   msaitoh 	if (sc->smbdev != NULL) {
    655  1.1   msaitoh 		rv = config_detach(sc->smbdev, flags);
    656  1.1   msaitoh 		if (rv != 0)
    657  1.1   msaitoh 			return rv;
    658  1.1   msaitoh 	}
    659  1.1   msaitoh 	if (sc->sc_ih != NULL) {
    660  1.1   msaitoh 		pci_intr_disestablish(sc->sc_pc, sc->sc_ih);
    661  1.1   msaitoh 		sc->sc_ih = NULL;
    662  1.1   msaitoh 	}
    663  1.1   msaitoh 	if (sc->sc_pihp != NULL) {
    664  1.1   msaitoh 		pci_intr_release(sc->sc_pc, sc->sc_pihp, 1);
    665  1.1   msaitoh 		sc->sc_pihp = NULL;
    666  1.1   msaitoh 	}
    667  1.1   msaitoh 
    668  1.1   msaitoh 	bus_dmamap_unload(sc->desc_dma_tag, sc->desc_dma_map);
    669  1.1   msaitoh 	bus_dmamap_unload(sc->dma_buffer_dma_tag, sc->dma_buffer_dma_map);
    670  1.1   msaitoh 
    671  1.1   msaitoh 	bus_dmamem_free(sc->desc_dma_tag, &sc->desc_dma_seg, sc->desc_rseg);
    672  1.1   msaitoh 	bus_dmamem_free(sc->dma_buffer_dma_tag, &sc->dma_buffer_dma_seg,
    673  1.1   msaitoh 	    sc->dma_buffer_rseg);
    674  1.1   msaitoh 
    675  1.1   msaitoh 	if (sc->mmio_size)
    676  1.1   msaitoh 		bus_space_unmap(sc->mmio_tag, sc->mmio_handle, sc->mmio_size);
    677  1.1   msaitoh 
    678  1.1   msaitoh 	mutex_destroy(&sc->sc_i2c_mutex);
    679  1.1   msaitoh 	return rv;
    680  1.1   msaitoh }
    681  1.1   msaitoh 
    682  1.1   msaitoh static void
    683  1.1   msaitoh ismt_attach(device_t parent, device_t self, void *aux)
    684  1.1   msaitoh {
    685  1.1   msaitoh 	struct ismt_softc *sc = device_private(self);
    686  1.1   msaitoh 	struct pci_attach_args *pa = aux;
    687  1.1   msaitoh 	const char *intrstr = NULL;
    688  1.1   msaitoh 	char intrbuf[PCI_INTRSTR_LEN];
    689  1.1   msaitoh 	pcireg_t reg;
    690  1.1   msaitoh 	int val;
    691  1.1   msaitoh 
    692  1.1   msaitoh 	sc->pcidev = self;
    693  1.1   msaitoh 	sc->sc_pc = pa->pa_pc;
    694  1.1   msaitoh 	sc->sc_pcitag = pa->pa_tag;
    695  1.1   msaitoh 
    696  1.1   msaitoh 	/* Enable busmastering */
    697  1.1   msaitoh 	reg = pci_conf_read(sc->sc_pc, sc->sc_pcitag, PCI_COMMAND_STATUS_REG);
    698  1.1   msaitoh 	reg |= PCI_COMMAND_MASTER_ENABLE;
    699  1.1   msaitoh 	pci_conf_write(sc->sc_pc, sc->sc_pcitag, PCI_COMMAND_STATUS_REG, reg);
    700  1.1   msaitoh 
    701  1.1   msaitoh 	pci_aprint_devinfo(pa, NULL);
    702  1.1   msaitoh 
    703  1.1   msaitoh 	/* Map mem space */
    704  1.1   msaitoh 	if (pci_mapreg_map(pa, PCI_BAR0, PCI_MAPREG_TYPE_MEM, 0,
    705  1.1   msaitoh 	    &sc->mmio_tag, &sc->mmio_handle, NULL, &sc->mmio_size)) {
    706  1.1   msaitoh 		aprint_error_dev(self, "can't map mem space\n");
    707  1.1   msaitoh 		goto fail;
    708  1.1   msaitoh 	}
    709  1.1   msaitoh 
    710  1.1   msaitoh 	if (pci_dma64_available(pa)) {
    711  1.1   msaitoh 		sc->desc_dma_tag = pa->pa_dmat64;
    712  1.1   msaitoh 		sc->dma_buffer_dma_tag = pa->pa_dmat64;
    713  1.1   msaitoh 	} else {
    714  1.1   msaitoh 		sc->desc_dma_tag = pa->pa_dmat;
    715  1.1   msaitoh 		sc->dma_buffer_dma_tag = pa->pa_dmat;
    716  1.1   msaitoh 	}
    717  1.1   msaitoh 	bus_dmamem_alloc(sc->desc_dma_tag, DESC_SIZE, PAGE_SIZE, 0,
    718  1.1   msaitoh 	    &sc->desc_dma_seg, ISMT_DESC_ENTRIES, &sc->desc_rseg,
    719  1.1   msaitoh 	    BUS_DMA_WAITOK);
    720  1.1   msaitoh 	bus_dmamem_alloc(sc->dma_buffer_dma_tag, DMA_BUFFER_SIZE, PAGE_SIZE, 0,
    721  1.1   msaitoh 	    &sc->dma_buffer_dma_seg, 1, &sc->dma_buffer_rseg, BUS_DMA_WAITOK);
    722  1.1   msaitoh 
    723  1.1   msaitoh 	bus_dmamem_map(sc->desc_dma_tag, &sc->desc_dma_seg,
    724  1.1   msaitoh 	    sc->desc_rseg, DESC_SIZE, (void **)&sc->desc, BUS_DMA_COHERENT);
    725  1.1   msaitoh 	bus_dmamem_map(sc->dma_buffer_dma_tag, &sc->dma_buffer_dma_seg,
    726  1.1   msaitoh 	    sc->dma_buffer_rseg, DMA_BUFFER_SIZE, (void **)&sc->dma_buffer,
    727  1.1   msaitoh 	    BUS_DMA_COHERENT);
    728  1.1   msaitoh 
    729  1.1   msaitoh 	bus_dmamap_create(sc->desc_dma_tag, DESC_SIZE, 1,
    730  1.1   msaitoh 	    DESC_SIZE, 0, 0, &sc->desc_dma_map);
    731  1.1   msaitoh 	bus_dmamap_create(sc->dma_buffer_dma_tag, DMA_BUFFER_SIZE, 1,
    732  1.1   msaitoh 	    DMA_BUFFER_SIZE, 0, 0, &sc->dma_buffer_dma_map);
    733  1.1   msaitoh 
    734  1.1   msaitoh 	bus_dmamap_load(sc->desc_dma_tag,
    735  1.1   msaitoh 	    sc->desc_dma_map, sc->desc, DESC_SIZE, NULL, 0);
    736  1.1   msaitoh 	bus_dmamap_load(sc->dma_buffer_dma_tag,
    737  1.1   msaitoh 	    sc->dma_buffer_dma_map, sc->dma_buffer, DMA_BUFFER_SIZE,
    738  1.1   msaitoh 	    NULL, 0);
    739  1.1   msaitoh 
    740  1.1   msaitoh 	bus_space_write_4(sc->mmio_tag, sc->mmio_handle, ISMT_MSTR_MDBA,
    741  1.2  christos 	    ISMT_LOW(sc->desc_dma_map->dm_segs[0].ds_addr));
    742  1.1   msaitoh 	bus_space_write_4(sc->mmio_tag, sc->mmio_handle, ISMT_MSTR_MDBA + 4,
    743  1.2  christos 	    ISMT_HIGH(sc->desc_dma_map->dm_segs[0].ds_addr));
    744  1.1   msaitoh 
    745  1.1   msaitoh 	/* initialize the Master Control Register (MCTRL) */
    746  1.1   msaitoh 	bus_space_write_4(sc->mmio_tag, sc->mmio_handle, ISMT_MSTR_MCTRL,
    747  1.1   msaitoh 	    ISMT_MCTRL_MEIE);
    748  1.1   msaitoh 
    749  1.1   msaitoh 	/* initialize the Master Status Register (MSTS) */
    750  1.1   msaitoh 	bus_space_write_4(sc->mmio_tag, sc->mmio_handle, ISMT_MSTR_MSTS, 0);
    751  1.1   msaitoh 
    752  1.1   msaitoh 	/* initialize the Master Descriptor Size (MDS) */
    753  1.1   msaitoh 	val = bus_space_read_4(sc->mmio_tag, sc->mmio_handle, ISMT_MSTR_MDS);
    754  1.1   msaitoh 	val &= ~ISMT_MDS_MASK;
    755  1.1   msaitoh 	val |= (ISMT_DESC_ENTRIES - 1);
    756  1.1   msaitoh 	bus_space_write_4(sc->mmio_tag, sc->mmio_handle, ISMT_MSTR_MDS, val);
    757  1.1   msaitoh 
    758  1.1   msaitoh 	if (pci_intr_alloc(pa, &sc->sc_pihp, NULL, 0)) {
    759  1.1   msaitoh 		aprint_error_dev(self, "couldn't map interrupt\n");
    760  1.1   msaitoh 		return;
    761  1.1   msaitoh 	}
    762  1.1   msaitoh 	intrstr = pci_intr_string(pa->pa_pc, sc->sc_pihp[0], intrbuf,
    763  1.1   msaitoh 	    sizeof(intrbuf));
    764  1.1   msaitoh 	sc->sc_ih = pci_intr_establish(pa->pa_pc, sc->sc_pihp[0], IPL_BIO,
    765  1.1   msaitoh 	    ismt_intr, sc);
    766  1.1   msaitoh 	if (sc->sc_ih == NULL) {
    767  1.1   msaitoh 		aprint_error_dev(sc->pcidev, "unable to establish %s\n",
    768  1.1   msaitoh 		    (pci_intr_type(sc->sc_pihp[0])
    769  1.1   msaitoh 			== PCI_INTR_TYPE_MSI) ? "MSI" : "INTx");
    770  1.1   msaitoh 		/* Polling */
    771  1.1   msaitoh 	}
    772  1.1   msaitoh 
    773  1.1   msaitoh 	if (pci_intr_type(sc->sc_pihp[0]) == PCI_INTR_TYPE_MSI)
    774  1.1   msaitoh 		sc->using_msi = 1;
    775  1.1   msaitoh 
    776  1.1   msaitoh 	aprint_normal_dev(sc->pcidev, "interrupting at %s\n", intrstr);
    777  1.1   msaitoh 
    778  1.1   msaitoh 	sc->smbdev = NULL;
    779  1.1   msaitoh 	mutex_init(&sc->sc_i2c_mutex, MUTEX_DEFAULT, IPL_NONE);
    780  1.1   msaitoh 	if (!pmf_device_register(self, NULL, NULL))
    781  1.1   msaitoh 		aprint_error_dev(self, "couldn't establish power handler\n");
    782  1.1   msaitoh 
    783  1.1   msaitoh 	config_interrupts(self, ismt_config_interrupts);
    784  1.1   msaitoh 	return;
    785  1.1   msaitoh 
    786  1.1   msaitoh fail:
    787  1.1   msaitoh 	ismt_detach(sc->pcidev, 0);
    788  1.1   msaitoh 
    789  1.1   msaitoh 	return;
    790  1.1   msaitoh }
    791  1.1   msaitoh 
    792  1.1   msaitoh static int
    793  1.1   msaitoh ismt_match(device_t parent, cfdata_t match, void *aux)
    794  1.1   msaitoh {
    795  1.1   msaitoh 	struct pci_attach_args *pa = aux;
    796  1.1   msaitoh 
    797  1.1   msaitoh 	if (PCI_VENDOR(pa->pa_id) != PCI_VENDOR_INTEL)
    798  1.1   msaitoh 		return 0;
    799  1.1   msaitoh 
    800  1.1   msaitoh 	switch (PCI_PRODUCT(pa->pa_id)) {
    801  1.1   msaitoh 	case PCI_PRODUCT_INTEL_S1200_SMBUS_0:
    802  1.1   msaitoh 	case PCI_PRODUCT_INTEL_S1200_SMBUS_1:
    803  1.1   msaitoh 	case PCI_PRODUCT_INTEL_C2000_SMBUS:
    804  1.1   msaitoh 		break;
    805  1.1   msaitoh 	default:
    806  1.1   msaitoh 		return 0;
    807  1.1   msaitoh 	}
    808  1.1   msaitoh 
    809  1.1   msaitoh 	return 1;
    810  1.1   msaitoh }
    811  1.1   msaitoh 
    812  1.1   msaitoh static int
    813  1.1   msaitoh ismt_rescan(device_t self, const char *ifattr, const int *flags)
    814  1.1   msaitoh {
    815  1.1   msaitoh 	struct ismt_softc *sc = device_private(self);
    816  1.1   msaitoh 	struct i2cbus_attach_args iba;
    817  1.1   msaitoh 
    818  1.1   msaitoh 	if (!ifattr_match(ifattr, "i2cbus"))
    819  1.1   msaitoh 		return 0;
    820  1.1   msaitoh 
    821  1.1   msaitoh 	if (sc->smbdev)
    822  1.1   msaitoh 		return 0;
    823  1.1   msaitoh 
    824  1.1   msaitoh 	/* Attach I2C bus */
    825  1.1   msaitoh 	sc->sc_i2c_tag.ic_cookie = sc;
    826  1.1   msaitoh 	sc->sc_i2c_tag.ic_acquire_bus = ismt_i2c_acquire_bus;
    827  1.1   msaitoh 	sc->sc_i2c_tag.ic_release_bus = ismt_i2c_release_bus;
    828  1.1   msaitoh 	sc->sc_i2c_tag.ic_exec = ismt_i2c_exec;
    829  1.1   msaitoh 
    830  1.1   msaitoh 	memset(&iba, 0, sizeof(iba));
    831  1.1   msaitoh 	iba.iba_type = I2C_TYPE_SMBUS;
    832  1.1   msaitoh 	iba.iba_tag = &sc->sc_i2c_tag;
    833  1.1   msaitoh 	sc->smbdev = config_found_ia(self, ifattr, &iba, iicbus_print);
    834  1.1   msaitoh 
    835  1.1   msaitoh 	return 0;
    836  1.1   msaitoh }
    837  1.1   msaitoh 
    838  1.1   msaitoh static void
    839  1.1   msaitoh ismt_config_interrupts(device_t self)
    840  1.1   msaitoh {
    841  1.1   msaitoh 	int flags = 0;
    842  1.1   msaitoh 
    843  1.1   msaitoh 	ismt_rescan(self, "i2cbus", &flags);
    844  1.1   msaitoh }
    845  1.1   msaitoh 
    846  1.1   msaitoh static void
    847  1.1   msaitoh ismt_chdet(device_t self, device_t child)
    848  1.1   msaitoh {
    849  1.1   msaitoh 	struct ismt_softc *sc = device_private(self);
    850  1.1   msaitoh 
    851  1.1   msaitoh 	if (sc->smbdev == child)
    852  1.1   msaitoh 		sc->smbdev = NULL;
    853  1.1   msaitoh 
    854  1.1   msaitoh }
    855  1.1   msaitoh 
    856  1.1   msaitoh MODULE(MODULE_CLASS_DRIVER, ismt, "pci");
    857  1.1   msaitoh 
    858  1.1   msaitoh #ifdef _MODULE
    859  1.1   msaitoh #include "ioconf.c"
    860  1.1   msaitoh #endif
    861  1.1   msaitoh 
    862  1.1   msaitoh static int
    863  1.1   msaitoh ismt_modcmd(modcmd_t cmd, void *opaque)
    864  1.1   msaitoh {
    865  1.1   msaitoh 	int error = 0;
    866  1.1   msaitoh 
    867  1.1   msaitoh 	switch (cmd) {
    868  1.1   msaitoh 	case MODULE_CMD_INIT:
    869  1.1   msaitoh #ifdef _MODULE
    870  1.1   msaitoh 		error = config_init_component(cfdriver_ioconf_ismt,
    871  1.1   msaitoh 		    cfattach_ioconf_ismt, cfdata_ioconf_ismt);
    872  1.1   msaitoh #endif
    873  1.1   msaitoh 		return error;
    874  1.1   msaitoh 	case MODULE_CMD_FINI:
    875  1.1   msaitoh #ifdef _MODULE
    876  1.1   msaitoh 		error = config_fini_component(cfdriver_ioconf_ismt,
    877  1.1   msaitoh 		    cfattach_ioconf_ismt, cfdata_ioconf_ismt);
    878  1.1   msaitoh #endif
    879  1.1   msaitoh 		return error;
    880  1.1   msaitoh 	default:
    881  1.1   msaitoh 		return ENOTTY;
    882  1.1   msaitoh 	}
    883  1.1   msaitoh }
    884