10572ccaaSJim Harris /*-
20572ccaaSJim Harris * Copyright (C) 2014 Intel Corporation
30572ccaaSJim Harris * All rights reserved.
40572ccaaSJim Harris *
50572ccaaSJim Harris * Redistribution and use in source and binary forms, with or without
60572ccaaSJim Harris * modification, are permitted provided that the following conditions
70572ccaaSJim Harris * are met:
80572ccaaSJim Harris * 1. Redistributions of source code must retain the above copyright
90572ccaaSJim Harris * notice, this list of conditions and the following disclaimer.
100572ccaaSJim Harris * 2. Redistributions in binary form must reproduce the above copyright
110572ccaaSJim Harris * notice, this list of conditions and the following disclaimer in the
120572ccaaSJim Harris * documentation and/or other materials provided with the distribution.
130572ccaaSJim Harris * 3. Neither the name of Intel Corporation nor the names of its
140572ccaaSJim Harris * contributors may be used to endorse or promote products derived from
150572ccaaSJim Harris * this software without specific prior written permission.
160572ccaaSJim Harris *
170572ccaaSJim Harris * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
180572ccaaSJim Harris * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
190572ccaaSJim Harris * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
200572ccaaSJim Harris * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
210572ccaaSJim Harris * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
220572ccaaSJim Harris * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
230572ccaaSJim Harris * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
240572ccaaSJim Harris * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
250572ccaaSJim Harris * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
260572ccaaSJim Harris * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
270572ccaaSJim Harris * SUCH DAMAGE.
280572ccaaSJim Harris */
290572ccaaSJim Harris
300572ccaaSJim Harris #include <sys/param.h>
310572ccaaSJim Harris #include <sys/systm.h>
320572ccaaSJim Harris #include <sys/bus.h>
330572ccaaSJim Harris #include <sys/errno.h>
340572ccaaSJim Harris #include <sys/kernel.h>
350572ccaaSJim Harris #include <sys/lock.h>
360572ccaaSJim Harris #include <sys/module.h>
370572ccaaSJim Harris #include <sys/priority.h>
380572ccaaSJim Harris #include <sys/proc.h>
390572ccaaSJim Harris #include <sys/syslog.h>
400572ccaaSJim Harris
410572ccaaSJim Harris #include <machine/bus.h>
420572ccaaSJim Harris #include <sys/rman.h>
430572ccaaSJim Harris #include <machine/resource.h>
440572ccaaSJim Harris
450572ccaaSJim Harris #include <dev/pci/pcireg.h>
460572ccaaSJim Harris #include <dev/pci/pcivar.h>
470572ccaaSJim Harris #include <dev/smbus/smbconf.h>
480572ccaaSJim Harris
490572ccaaSJim Harris #include "smbus_if.h"
500572ccaaSJim Harris
510572ccaaSJim Harris #define ISMT_DESC_ENTRIES 32
520572ccaaSJim Harris
530572ccaaSJim Harris /* Hardware Descriptor Constants - Control Field */
540572ccaaSJim Harris #define ISMT_DESC_CWRL 0x01 /* Command/Write Length */
550572ccaaSJim Harris #define ISMT_DESC_BLK 0X04 /* Perform Block Transaction */
560572ccaaSJim Harris #define ISMT_DESC_FAIR 0x08 /* Set fairness flag upon successful arbit. */
570572ccaaSJim Harris #define ISMT_DESC_PEC 0x10 /* Packet Error Code */
580572ccaaSJim Harris #define ISMT_DESC_I2C 0x20 /* I2C Enable */
590572ccaaSJim Harris #define ISMT_DESC_INT 0x40 /* Interrupt */
600572ccaaSJim Harris #define ISMT_DESC_SOE 0x80 /* Stop On Error */
610572ccaaSJim Harris
620572ccaaSJim Harris /* Hardware Descriptor Constants - Status Field */
630572ccaaSJim Harris #define ISMT_DESC_SCS 0x01 /* Success */
640572ccaaSJim Harris #define ISMT_DESC_DLTO 0x04 /* Data Low Time Out */
650572ccaaSJim Harris #define ISMT_DESC_NAK 0x08 /* NAK Received */
660572ccaaSJim Harris #define ISMT_DESC_CRC 0x10 /* CRC Error */
670572ccaaSJim Harris #define ISMT_DESC_CLTO 0x20 /* Clock Low Time Out */
680572ccaaSJim Harris #define ISMT_DESC_COL 0x40 /* Collisions */
690572ccaaSJim Harris #define ISMT_DESC_LPR 0x80 /* Large Packet Received */
700572ccaaSJim Harris
710572ccaaSJim Harris /* Macros */
72d681bc9eSJustin Hibbits #define ISMT_DESC_ADDR_RW(addr, is_read) ((addr) | (is_read))
730572ccaaSJim Harris
740572ccaaSJim Harris /* iSMT General Register address offsets (SMBBAR + <addr>) */
750572ccaaSJim Harris #define ISMT_GR_GCTRL 0x000 /* General Control */
760572ccaaSJim Harris #define ISMT_GR_SMTICL 0x008 /* SMT Interrupt Cause Location */
770572ccaaSJim Harris #define ISMT_GR_ERRINTMSK 0x010 /* Error Interrupt Mask */
780572ccaaSJim Harris #define ISMT_GR_ERRAERMSK 0x014 /* Error AER Mask */
790572ccaaSJim Harris #define ISMT_GR_ERRSTS 0x018 /* Error Status */
800572ccaaSJim Harris #define ISMT_GR_ERRINFO 0x01c /* Error Information */
810572ccaaSJim Harris
820572ccaaSJim Harris /* iSMT Master Registers */
830572ccaaSJim Harris #define ISMT_MSTR_MDBA 0x100 /* Master Descriptor Base Address */
840572ccaaSJim Harris #define ISMT_MSTR_MCTRL 0x108 /* Master Control */
850572ccaaSJim Harris #define ISMT_MSTR_MSTS 0x10c /* Master Status */
860572ccaaSJim Harris #define ISMT_MSTR_MDS 0x110 /* Master Descriptor Size */
870572ccaaSJim Harris #define ISMT_MSTR_RPOLICY 0x114 /* Retry Policy */
880572ccaaSJim Harris
890572ccaaSJim Harris /* iSMT Miscellaneous Registers */
900572ccaaSJim Harris #define ISMT_SPGT 0x300 /* SMBus PHY Global Timing */
910572ccaaSJim Harris
920572ccaaSJim Harris /* General Control Register (GCTRL) bit definitions */
930572ccaaSJim Harris #define ISMT_GCTRL_TRST 0x04 /* Target Reset */
940572ccaaSJim Harris #define ISMT_GCTRL_KILL 0x08 /* Kill */
950572ccaaSJim Harris #define ISMT_GCTRL_SRST 0x40 /* Soft Reset */
960572ccaaSJim Harris
970572ccaaSJim Harris /* Master Control Register (MCTRL) bit definitions */
980572ccaaSJim Harris #define ISMT_MCTRL_SS 0x01 /* Start/Stop */
990572ccaaSJim Harris #define ISMT_MCTRL_MEIE 0x10 /* Master Error Interrupt Enable */
1000572ccaaSJim Harris #define ISMT_MCTRL_FMHP 0x00ff0000 /* Firmware Master Head Ptr (FMHP) */
1010572ccaaSJim Harris
1020572ccaaSJim Harris /* Master Status Register (MSTS) bit definitions */
1030572ccaaSJim Harris #define ISMT_MSTS_HMTP 0xff0000 /* HW Master Tail Pointer (HMTP) */
1040572ccaaSJim Harris #define ISMT_MSTS_MIS 0x20 /* Master Interrupt Status (MIS) */
1050572ccaaSJim Harris #define ISMT_MSTS_MEIS 0x10 /* Master Error Int Status (MEIS) */
1060572ccaaSJim Harris #define ISMT_MSTS_IP 0x01 /* In Progress */
1070572ccaaSJim Harris
1080572ccaaSJim Harris /* Master Descriptor Size (MDS) bit definitions */
1090572ccaaSJim Harris #define ISMT_MDS_MASK 0xff /* Master Descriptor Size mask (MDS) */
1100572ccaaSJim Harris
1110572ccaaSJim Harris /* SMBus PHY Global Timing Register (SPGT) bit definitions */
1120572ccaaSJim Harris #define ISMT_SPGT_SPD_MASK 0xc0000000 /* SMBus Speed mask */
1130572ccaaSJim Harris #define ISMT_SPGT_SPD_80K 0x00 /* 80 kHz */
1140572ccaaSJim Harris #define ISMT_SPGT_SPD_100K (0x1 << 30) /* 100 kHz */
1150572ccaaSJim Harris #define ISMT_SPGT_SPD_400K (0x2 << 30) /* 400 kHz */
1160572ccaaSJim Harris #define ISMT_SPGT_SPD_1M (0x3 << 30) /* 1 MHz */
1170572ccaaSJim Harris
1180572ccaaSJim Harris /* MSI Control Register (MSICTL) bit definitions */
1190572ccaaSJim Harris #define ISMT_MSICTL_MSIE 0x01 /* MSI Enable */
1200572ccaaSJim Harris
1210572ccaaSJim Harris #define ISMT_MAX_BLOCK_SIZE 32 /* per SMBus spec */
1220572ccaaSJim Harris
1230572ccaaSJim Harris //#define ISMT_DEBUG device_printf
1240572ccaaSJim Harris #ifndef ISMT_DEBUG
1250572ccaaSJim Harris #define ISMT_DEBUG(...)
1260572ccaaSJim Harris #endif
1270572ccaaSJim Harris
1280572ccaaSJim Harris /* iSMT Hardware Descriptor */
1290572ccaaSJim Harris struct ismt_desc {
1300572ccaaSJim Harris uint8_t tgtaddr_rw; /* target address & r/w bit */
1310572ccaaSJim Harris uint8_t wr_len_cmd; /* write length in bytes or a command */
1320572ccaaSJim Harris uint8_t rd_len; /* read length */
1330572ccaaSJim Harris uint8_t control; /* control bits */
1340572ccaaSJim Harris uint8_t status; /* status bits */
1350572ccaaSJim Harris uint8_t retry; /* collision retry and retry count */
1360572ccaaSJim Harris uint8_t rxbytes; /* received bytes */
1370572ccaaSJim Harris uint8_t txbytes; /* transmitted bytes */
1380572ccaaSJim Harris uint32_t dptr_low; /* lower 32 bit of the data pointer */
1390572ccaaSJim Harris uint32_t dptr_high; /* upper 32 bit of the data pointer */
1400572ccaaSJim Harris } __packed;
1410572ccaaSJim Harris
1420572ccaaSJim Harris #define DESC_SIZE (ISMT_DESC_ENTRIES * sizeof(struct ismt_desc))
1430572ccaaSJim Harris
1440572ccaaSJim Harris #define DMA_BUFFER_SIZE 64
1450572ccaaSJim Harris
1460572ccaaSJim Harris struct ismt_softc {
1470572ccaaSJim Harris device_t pcidev;
1480572ccaaSJim Harris device_t smbdev;
1490572ccaaSJim Harris
1500572ccaaSJim Harris struct thread *bus_reserved;
1510572ccaaSJim Harris
1520572ccaaSJim Harris int intr_rid;
1530572ccaaSJim Harris struct resource *intr_res;
1540572ccaaSJim Harris void *intr_handle;
1550572ccaaSJim Harris
1560572ccaaSJim Harris bus_space_tag_t mmio_tag;
1570572ccaaSJim Harris bus_space_handle_t mmio_handle;
1580572ccaaSJim Harris int mmio_rid;
1590572ccaaSJim Harris struct resource *mmio_res;
1600572ccaaSJim Harris
1610572ccaaSJim Harris uint8_t head;
1620572ccaaSJim Harris
1630572ccaaSJim Harris struct ismt_desc *desc;
1640572ccaaSJim Harris bus_dma_tag_t desc_dma_tag;
1650572ccaaSJim Harris bus_dmamap_t desc_dma_map;
1660572ccaaSJim Harris uint64_t desc_bus_addr;
1670572ccaaSJim Harris
1680572ccaaSJim Harris uint8_t *dma_buffer;
1690572ccaaSJim Harris bus_dma_tag_t dma_buffer_dma_tag;
1700572ccaaSJim Harris bus_dmamap_t dma_buffer_dma_map;
1710572ccaaSJim Harris uint64_t dma_buffer_bus_addr;
1720572ccaaSJim Harris
1730572ccaaSJim Harris uint8_t using_msi;
1740572ccaaSJim Harris };
1750572ccaaSJim Harris
1760572ccaaSJim Harris static void
ismt_intr(void * arg)1770572ccaaSJim Harris ismt_intr(void *arg)
1780572ccaaSJim Harris {
1790572ccaaSJim Harris struct ismt_softc *sc = arg;
1800572ccaaSJim Harris uint32_t val;
1810572ccaaSJim Harris
1820572ccaaSJim Harris val = bus_read_4(sc->mmio_res, ISMT_MSTR_MSTS);
1830572ccaaSJim Harris ISMT_DEBUG(sc->pcidev, "%s MSTS=0x%x\n", __func__, val);
1840572ccaaSJim Harris
1850572ccaaSJim Harris val |= (ISMT_MSTS_MIS | ISMT_MSTS_MEIS);
1860572ccaaSJim Harris bus_write_4(sc->mmio_res, ISMT_MSTR_MSTS, val);
1870572ccaaSJim Harris
1880572ccaaSJim Harris wakeup(sc);
1890572ccaaSJim Harris }
1900572ccaaSJim Harris
1910572ccaaSJim Harris static int
ismt_callback(device_t dev,int index,void * data)1920572ccaaSJim Harris ismt_callback(device_t dev, int index, void *data)
1930572ccaaSJim Harris {
1940572ccaaSJim Harris struct ismt_softc *sc;
1950572ccaaSJim Harris int acquired, err;
1960572ccaaSJim Harris
1970572ccaaSJim Harris sc = device_get_softc(dev);
1980572ccaaSJim Harris
1990572ccaaSJim Harris switch (index) {
2000572ccaaSJim Harris case SMB_REQUEST_BUS:
2010572ccaaSJim Harris acquired = atomic_cmpset_ptr(
2020572ccaaSJim Harris (uintptr_t *)&sc->bus_reserved,
2030572ccaaSJim Harris (uintptr_t)NULL, (uintptr_t)curthread);
2040572ccaaSJim Harris ISMT_DEBUG(dev, "SMB_REQUEST_BUS acquired=%d\n", acquired);
2050572ccaaSJim Harris if (acquired)
2060572ccaaSJim Harris err = 0;
2070572ccaaSJim Harris else
2080572ccaaSJim Harris err = EWOULDBLOCK;
2090572ccaaSJim Harris break;
2100572ccaaSJim Harris case SMB_RELEASE_BUS:
2110572ccaaSJim Harris KASSERT(sc->bus_reserved == curthread,
2120572ccaaSJim Harris ("SMB_RELEASE_BUS called by wrong thread\n"));
2130572ccaaSJim Harris ISMT_DEBUG(dev, "SMB_RELEASE_BUS\n");
2140572ccaaSJim Harris atomic_store_rel_ptr((uintptr_t *)&sc->bus_reserved,
2150572ccaaSJim Harris (uintptr_t)NULL);
2160572ccaaSJim Harris err = 0;
2170572ccaaSJim Harris break;
2180572ccaaSJim Harris default:
2190572ccaaSJim Harris err = SMB_EABORT;
2200572ccaaSJim Harris break;
2210572ccaaSJim Harris }
2220572ccaaSJim Harris
2230572ccaaSJim Harris return (err);
2240572ccaaSJim Harris }
2250572ccaaSJim Harris
2260572ccaaSJim Harris static struct ismt_desc *
ismt_alloc_desc(struct ismt_softc * sc)2270572ccaaSJim Harris ismt_alloc_desc(struct ismt_softc *sc)
2280572ccaaSJim Harris {
2290572ccaaSJim Harris struct ismt_desc *desc;
2300572ccaaSJim Harris
2310572ccaaSJim Harris KASSERT(sc->bus_reserved == curthread,
2320572ccaaSJim Harris ("curthread %p did not request bus (%p has reserved)\n",
2330572ccaaSJim Harris curthread, sc->bus_reserved));
2340572ccaaSJim Harris
2350572ccaaSJim Harris desc = &sc->desc[sc->head++];
2360572ccaaSJim Harris if (sc->head == ISMT_DESC_ENTRIES)
2370572ccaaSJim Harris sc->head = 0;
2380572ccaaSJim Harris
2390572ccaaSJim Harris memset(desc, 0, sizeof(*desc));
2400572ccaaSJim Harris
2410572ccaaSJim Harris return (desc);
2420572ccaaSJim Harris }
2430572ccaaSJim Harris
2440572ccaaSJim Harris static int
ismt_submit(struct ismt_softc * sc,struct ismt_desc * desc,uint8_t slave,uint8_t is_read)2450572ccaaSJim Harris ismt_submit(struct ismt_softc *sc, struct ismt_desc *desc, uint8_t slave,
2460572ccaaSJim Harris uint8_t is_read)
2470572ccaaSJim Harris {
2480572ccaaSJim Harris uint32_t err, fmhp, val;
2490572ccaaSJim Harris
2500572ccaaSJim Harris desc->control |= ISMT_DESC_FAIR;
2510572ccaaSJim Harris if (sc->using_msi)
2520572ccaaSJim Harris desc->control |= ISMT_DESC_INT;
2530572ccaaSJim Harris
2540572ccaaSJim Harris desc->tgtaddr_rw = ISMT_DESC_ADDR_RW(slave, is_read);
2550572ccaaSJim Harris desc->dptr_low = (sc->dma_buffer_bus_addr & 0xFFFFFFFFLL);
2560572ccaaSJim Harris desc->dptr_high = (sc->dma_buffer_bus_addr >> 32);
2570572ccaaSJim Harris
2580572ccaaSJim Harris wmb();
2590572ccaaSJim Harris
2600572ccaaSJim Harris fmhp = sc->head << 16;
2610572ccaaSJim Harris val = bus_read_4(sc->mmio_res, ISMT_MSTR_MCTRL);
2620572ccaaSJim Harris val &= ~ISMT_MCTRL_FMHP;
2630572ccaaSJim Harris val |= fmhp;
2640572ccaaSJim Harris bus_write_4(sc->mmio_res, ISMT_MSTR_MCTRL, val);
2650572ccaaSJim Harris
2660572ccaaSJim Harris /* set the start bit */
2670572ccaaSJim Harris val = bus_read_4(sc->mmio_res, ISMT_MSTR_MCTRL);
2680572ccaaSJim Harris val |= ISMT_MCTRL_SS;
2690572ccaaSJim Harris bus_write_4(sc->mmio_res, ISMT_MSTR_MCTRL, val);
2700572ccaaSJim Harris
2710572ccaaSJim Harris err = tsleep(sc, PWAIT, "ismt_wait", 5 * hz);
2720572ccaaSJim Harris
2730572ccaaSJim Harris if (err != 0) {
2740572ccaaSJim Harris ISMT_DEBUG(sc->pcidev, "%s timeout\n", __func__);
2750572ccaaSJim Harris return (SMB_ETIMEOUT);
2760572ccaaSJim Harris }
2770572ccaaSJim Harris
2780572ccaaSJim Harris ISMT_DEBUG(sc->pcidev, "%s status=0x%x\n", __func__, desc->status);
2790572ccaaSJim Harris
2800572ccaaSJim Harris if (desc->status & ISMT_DESC_SCS)
2810572ccaaSJim Harris return (SMB_ENOERR);
2820572ccaaSJim Harris
2830572ccaaSJim Harris if (desc->status & ISMT_DESC_NAK)
2840572ccaaSJim Harris return (SMB_ENOACK);
2850572ccaaSJim Harris
2860572ccaaSJim Harris if (desc->status & ISMT_DESC_CRC)
2870572ccaaSJim Harris return (SMB_EBUSERR);
2880572ccaaSJim Harris
2890572ccaaSJim Harris if (desc->status & ISMT_DESC_COL)
2900572ccaaSJim Harris return (SMB_ECOLLI);
2910572ccaaSJim Harris
2920572ccaaSJim Harris if (desc->status & ISMT_DESC_LPR)
2930572ccaaSJim Harris return (SMB_EINVAL);
2940572ccaaSJim Harris
2950572ccaaSJim Harris if (desc->status & (ISMT_DESC_DLTO | ISMT_DESC_CLTO))
2960572ccaaSJim Harris return (SMB_ETIMEOUT);
2970572ccaaSJim Harris
2980572ccaaSJim Harris return (SMB_EBUSERR);
2990572ccaaSJim Harris }
3000572ccaaSJim Harris
3010572ccaaSJim Harris
3020572ccaaSJim Harris static int
ismt_quick(device_t dev,u_char slave,int how)3030572ccaaSJim Harris ismt_quick(device_t dev, u_char slave, int how)
3040572ccaaSJim Harris {
3050572ccaaSJim Harris struct ismt_desc *desc;
3060572ccaaSJim Harris struct ismt_softc *sc;
3070572ccaaSJim Harris int is_read;
3080572ccaaSJim Harris
3090572ccaaSJim Harris ISMT_DEBUG(dev, "%s\n", __func__);
3100572ccaaSJim Harris
3110572ccaaSJim Harris if (how != SMB_QREAD && how != SMB_QWRITE) {
3120572ccaaSJim Harris return (SMB_ENOTSUPP);
3130572ccaaSJim Harris }
3140572ccaaSJim Harris
3150572ccaaSJim Harris sc = device_get_softc(dev);
3160572ccaaSJim Harris desc = ismt_alloc_desc(sc);
3170572ccaaSJim Harris is_read = (how == SMB_QREAD ? 1 : 0);
3180572ccaaSJim Harris return (ismt_submit(sc, desc, slave, is_read));
3190572ccaaSJim Harris }
3200572ccaaSJim Harris
3210572ccaaSJim Harris static int
ismt_sendb(device_t dev,u_char slave,char byte)3220572ccaaSJim Harris ismt_sendb(device_t dev, u_char slave, char byte)
3230572ccaaSJim Harris {
3240572ccaaSJim Harris struct ismt_desc *desc;
3250572ccaaSJim Harris struct ismt_softc *sc;
3260572ccaaSJim Harris
3270572ccaaSJim Harris ISMT_DEBUG(dev, "%s\n", __func__);
3280572ccaaSJim Harris
3290572ccaaSJim Harris sc = device_get_softc(dev);
3300572ccaaSJim Harris desc = ismt_alloc_desc(sc);
3310572ccaaSJim Harris desc->control = ISMT_DESC_CWRL;
3320572ccaaSJim Harris desc->wr_len_cmd = byte;
3330572ccaaSJim Harris
3340572ccaaSJim Harris return (ismt_submit(sc, desc, slave, 0));
3350572ccaaSJim Harris }
3360572ccaaSJim Harris
3370572ccaaSJim Harris static int
ismt_recvb(device_t dev,u_char slave,char * byte)3380572ccaaSJim Harris ismt_recvb(device_t dev, u_char slave, char *byte)
3390572ccaaSJim Harris {
3400572ccaaSJim Harris struct ismt_desc *desc;
3410572ccaaSJim Harris struct ismt_softc *sc;
3420572ccaaSJim Harris int err;
3430572ccaaSJim Harris
3440572ccaaSJim Harris ISMT_DEBUG(dev, "%s\n", __func__);
3450572ccaaSJim Harris
3460572ccaaSJim Harris sc = device_get_softc(dev);
3470572ccaaSJim Harris desc = ismt_alloc_desc(sc);
3480572ccaaSJim Harris desc->rd_len = 1;
3490572ccaaSJim Harris
3500572ccaaSJim Harris err = ismt_submit(sc, desc, slave, 1);
3510572ccaaSJim Harris
3520572ccaaSJim Harris if (err != SMB_ENOERR)
3530572ccaaSJim Harris return (err);
3540572ccaaSJim Harris
3550572ccaaSJim Harris *byte = sc->dma_buffer[0];
3560572ccaaSJim Harris
3570572ccaaSJim Harris return (err);
3580572ccaaSJim Harris }
3590572ccaaSJim Harris
3600572ccaaSJim Harris static int
ismt_writeb(device_t dev,u_char slave,char cmd,char byte)3610572ccaaSJim Harris ismt_writeb(device_t dev, u_char slave, char cmd, char byte)
3620572ccaaSJim Harris {
3630572ccaaSJim Harris struct ismt_desc *desc;
3640572ccaaSJim Harris struct ismt_softc *sc;
3650572ccaaSJim Harris
3660572ccaaSJim Harris ISMT_DEBUG(dev, "%s\n", __func__);
3670572ccaaSJim Harris
3680572ccaaSJim Harris sc = device_get_softc(dev);
3690572ccaaSJim Harris desc = ismt_alloc_desc(sc);
3700572ccaaSJim Harris desc->wr_len_cmd = 2;
3710572ccaaSJim Harris sc->dma_buffer[0] = cmd;
3720572ccaaSJim Harris sc->dma_buffer[1] = byte;
3730572ccaaSJim Harris
3740572ccaaSJim Harris return (ismt_submit(sc, desc, slave, 0));
3750572ccaaSJim Harris }
3760572ccaaSJim Harris
3770572ccaaSJim Harris static int
ismt_writew(device_t dev,u_char slave,char cmd,short word)3780572ccaaSJim Harris ismt_writew(device_t dev, u_char slave, char cmd, short word)
3790572ccaaSJim Harris {
3800572ccaaSJim Harris struct ismt_desc *desc;
3810572ccaaSJim Harris struct ismt_softc *sc;
3820572ccaaSJim Harris
3830572ccaaSJim Harris ISMT_DEBUG(dev, "%s\n", __func__);
3840572ccaaSJim Harris
3850572ccaaSJim Harris sc = device_get_softc(dev);
3860572ccaaSJim Harris desc = ismt_alloc_desc(sc);
3870572ccaaSJim Harris desc->wr_len_cmd = 3;
3880572ccaaSJim Harris sc->dma_buffer[0] = cmd;
3890572ccaaSJim Harris sc->dma_buffer[1] = word & 0xFF;
3900572ccaaSJim Harris sc->dma_buffer[2] = word >> 8;
3910572ccaaSJim Harris
3920572ccaaSJim Harris return (ismt_submit(sc, desc, slave, 0));
3930572ccaaSJim Harris }
3940572ccaaSJim Harris
3950572ccaaSJim Harris static int
ismt_readb(device_t dev,u_char slave,char cmd,char * byte)3960572ccaaSJim Harris ismt_readb(device_t dev, u_char slave, char cmd, char *byte)
3970572ccaaSJim Harris {
3980572ccaaSJim Harris struct ismt_desc *desc;
3990572ccaaSJim Harris struct ismt_softc *sc;
4000572ccaaSJim Harris int err;
4010572ccaaSJim Harris
4020572ccaaSJim Harris ISMT_DEBUG(dev, "%s\n", __func__);
4030572ccaaSJim Harris
4040572ccaaSJim Harris sc = device_get_softc(dev);
4050572ccaaSJim Harris desc = ismt_alloc_desc(sc);
4060572ccaaSJim Harris desc->control = ISMT_DESC_CWRL;
4070572ccaaSJim Harris desc->wr_len_cmd = cmd;
4080572ccaaSJim Harris desc->rd_len = 1;
4090572ccaaSJim Harris
4100572ccaaSJim Harris err = ismt_submit(sc, desc, slave, 1);
4110572ccaaSJim Harris
4120572ccaaSJim Harris if (err != SMB_ENOERR)
4130572ccaaSJim Harris return (err);
4140572ccaaSJim Harris
4150572ccaaSJim Harris *byte = sc->dma_buffer[0];
4160572ccaaSJim Harris
4170572ccaaSJim Harris return (err);
4180572ccaaSJim Harris }
4190572ccaaSJim Harris
4200572ccaaSJim Harris static int
ismt_readw(device_t dev,u_char slave,char cmd,short * word)4210572ccaaSJim Harris ismt_readw(device_t dev, u_char slave, char cmd, short *word)
4220572ccaaSJim Harris {
4230572ccaaSJim Harris struct ismt_desc *desc;
4240572ccaaSJim Harris struct ismt_softc *sc;
4250572ccaaSJim Harris int err;
4260572ccaaSJim Harris
4270572ccaaSJim Harris ISMT_DEBUG(dev, "%s\n", __func__);
4280572ccaaSJim Harris
4290572ccaaSJim Harris sc = device_get_softc(dev);
4300572ccaaSJim Harris desc = ismt_alloc_desc(sc);
4310572ccaaSJim Harris desc->control = ISMT_DESC_CWRL;
4320572ccaaSJim Harris desc->wr_len_cmd = cmd;
4330572ccaaSJim Harris desc->rd_len = 2;
4340572ccaaSJim Harris
4350572ccaaSJim Harris err = ismt_submit(sc, desc, slave, 1);
4360572ccaaSJim Harris
4370572ccaaSJim Harris if (err != SMB_ENOERR)
4380572ccaaSJim Harris return (err);
4390572ccaaSJim Harris
4400572ccaaSJim Harris *word = sc->dma_buffer[0] | (sc->dma_buffer[1] << 8);
4410572ccaaSJim Harris
4420572ccaaSJim Harris return (err);
4430572ccaaSJim Harris }
4440572ccaaSJim Harris
4450572ccaaSJim Harris static int
ismt_pcall(device_t dev,u_char slave,char cmd,short sdata,short * rdata)4460572ccaaSJim Harris ismt_pcall(device_t dev, u_char slave, char cmd, short sdata, short *rdata)
4470572ccaaSJim Harris {
4480572ccaaSJim Harris struct ismt_desc *desc;
4490572ccaaSJim Harris struct ismt_softc *sc;
4500572ccaaSJim Harris int err;
4510572ccaaSJim Harris
4520572ccaaSJim Harris ISMT_DEBUG(dev, "%s\n", __func__);
4530572ccaaSJim Harris
4540572ccaaSJim Harris sc = device_get_softc(dev);
4550572ccaaSJim Harris desc = ismt_alloc_desc(sc);
4560572ccaaSJim Harris desc->wr_len_cmd = 3;
4570572ccaaSJim Harris desc->rd_len = 2;
4580572ccaaSJim Harris sc->dma_buffer[0] = cmd;
4590572ccaaSJim Harris sc->dma_buffer[1] = sdata & 0xff;
4600572ccaaSJim Harris sc->dma_buffer[2] = sdata >> 8;
4610572ccaaSJim Harris
4620572ccaaSJim Harris err = ismt_submit(sc, desc, slave, 0);
4630572ccaaSJim Harris
4640572ccaaSJim Harris if (err != SMB_ENOERR)
4650572ccaaSJim Harris return (err);
4660572ccaaSJim Harris
4670572ccaaSJim Harris *rdata = sc->dma_buffer[0] | (sc->dma_buffer[1] << 8);
4680572ccaaSJim Harris
4690572ccaaSJim Harris return (err);
4700572ccaaSJim Harris }
4710572ccaaSJim Harris
4720572ccaaSJim Harris static int
ismt_bwrite(device_t dev,u_char slave,char cmd,u_char count,char * buf)4730572ccaaSJim Harris ismt_bwrite(device_t dev, u_char slave, char cmd, u_char count, char *buf)
4740572ccaaSJim Harris {
4750572ccaaSJim Harris struct ismt_desc *desc;
4760572ccaaSJim Harris struct ismt_softc *sc;
4770572ccaaSJim Harris
4780572ccaaSJim Harris ISMT_DEBUG(dev, "%s\n", __func__);
4790572ccaaSJim Harris
4800572ccaaSJim Harris if (count == 0 || count > ISMT_MAX_BLOCK_SIZE)
4810572ccaaSJim Harris return (SMB_EINVAL);
4820572ccaaSJim Harris
4830572ccaaSJim Harris sc = device_get_softc(dev);
4840572ccaaSJim Harris desc = ismt_alloc_desc(sc);
4850572ccaaSJim Harris desc->control = ISMT_DESC_I2C;
4860572ccaaSJim Harris desc->wr_len_cmd = count + 1;
4870572ccaaSJim Harris sc->dma_buffer[0] = cmd;
4880572ccaaSJim Harris memcpy(&sc->dma_buffer[1], buf, count);
4890572ccaaSJim Harris
4900572ccaaSJim Harris return (ismt_submit(sc, desc, slave, 0));
4910572ccaaSJim Harris }
4920572ccaaSJim Harris
4930572ccaaSJim Harris static int
ismt_bread(device_t dev,u_char slave,char cmd,u_char * count,char * buf)4940572ccaaSJim Harris ismt_bread(device_t dev, u_char slave, char cmd, u_char *count, char *buf)
4950572ccaaSJim Harris {
4960572ccaaSJim Harris struct ismt_desc *desc;
4970572ccaaSJim Harris struct ismt_softc *sc;
4980572ccaaSJim Harris int err;
4990572ccaaSJim Harris
5000572ccaaSJim Harris ISMT_DEBUG(dev, "%s\n", __func__);
5010572ccaaSJim Harris
5020572ccaaSJim Harris if (*count == 0 || *count > ISMT_MAX_BLOCK_SIZE)
5030572ccaaSJim Harris return (SMB_EINVAL);
5040572ccaaSJim Harris
5050572ccaaSJim Harris sc = device_get_softc(dev);
5060572ccaaSJim Harris desc = ismt_alloc_desc(sc);
5070572ccaaSJim Harris desc->control = ISMT_DESC_I2C | ISMT_DESC_CWRL;
5080572ccaaSJim Harris desc->wr_len_cmd = cmd;
5090572ccaaSJim Harris desc->rd_len = *count;
5100572ccaaSJim Harris
5110572ccaaSJim Harris err = ismt_submit(sc, desc, slave, 0);
5120572ccaaSJim Harris
5130572ccaaSJim Harris if (err != SMB_ENOERR)
5140572ccaaSJim Harris return (err);
5150572ccaaSJim Harris
5160572ccaaSJim Harris memcpy(buf, sc->dma_buffer, desc->rxbytes);
5170572ccaaSJim Harris *count = desc->rxbytes;
5180572ccaaSJim Harris
5190572ccaaSJim Harris return (err);
5200572ccaaSJim Harris }
5210572ccaaSJim Harris
5220572ccaaSJim Harris static int
ismt_detach(device_t dev)5230572ccaaSJim Harris ismt_detach(device_t dev)
5240572ccaaSJim Harris {
5250572ccaaSJim Harris struct ismt_softc *sc;
5260572ccaaSJim Harris int error;
5270572ccaaSJim Harris
5280572ccaaSJim Harris ISMT_DEBUG(dev, "%s\n", __func__);
5290572ccaaSJim Harris sc = device_get_softc(dev);
5300572ccaaSJim Harris
5310572ccaaSJim Harris error = bus_generic_detach(dev);
5320572ccaaSJim Harris if (error)
5330572ccaaSJim Harris return (error);
5340572ccaaSJim Harris
5350572ccaaSJim Harris if (sc->intr_handle != NULL) {
5360572ccaaSJim Harris bus_teardown_intr(dev, sc->intr_res, sc->intr_handle);
5370572ccaaSJim Harris sc->intr_handle = NULL;
5380572ccaaSJim Harris }
5390572ccaaSJim Harris if (sc->intr_res != NULL) {
5400572ccaaSJim Harris bus_release_resource(dev,
5410572ccaaSJim Harris SYS_RES_IRQ, sc->intr_rid, sc->intr_res);
5420572ccaaSJim Harris sc->intr_res = NULL;
5430572ccaaSJim Harris }
5440572ccaaSJim Harris if (sc->using_msi == 1)
5450572ccaaSJim Harris pci_release_msi(dev);
5460572ccaaSJim Harris
5470572ccaaSJim Harris if (sc->mmio_res != NULL) {
5480572ccaaSJim Harris bus_release_resource(dev,
5490572ccaaSJim Harris SYS_RES_MEMORY, sc->mmio_rid, sc->mmio_res);
5500572ccaaSJim Harris sc->mmio_res = NULL;
5510572ccaaSJim Harris }
5520572ccaaSJim Harris
5530572ccaaSJim Harris bus_dmamap_unload(sc->desc_dma_tag, sc->desc_dma_map);
5540572ccaaSJim Harris bus_dmamap_unload(sc->dma_buffer_dma_tag, sc->dma_buffer_dma_map);
5550572ccaaSJim Harris
5560572ccaaSJim Harris bus_dmamem_free(sc->desc_dma_tag, sc->desc,
5570572ccaaSJim Harris sc->desc_dma_map);
5580572ccaaSJim Harris bus_dmamem_free(sc->dma_buffer_dma_tag, sc->dma_buffer,
5590572ccaaSJim Harris sc->dma_buffer_dma_map);
5600572ccaaSJim Harris
5610572ccaaSJim Harris bus_dma_tag_destroy(sc->desc_dma_tag);
5620572ccaaSJim Harris bus_dma_tag_destroy(sc->dma_buffer_dma_tag);
5630572ccaaSJim Harris
5640572ccaaSJim Harris pci_disable_busmaster(dev);
5650572ccaaSJim Harris
5660572ccaaSJim Harris return 0;
5670572ccaaSJim Harris }
5680572ccaaSJim Harris
5690572ccaaSJim Harris static void
ismt_single_map(void * arg,bus_dma_segment_t * seg,int nseg,int error)5700572ccaaSJim Harris ismt_single_map(void *arg, bus_dma_segment_t *seg, int nseg, int error)
5710572ccaaSJim Harris {
5720572ccaaSJim Harris uint64_t *bus_addr = (uint64_t *)arg;
5730572ccaaSJim Harris
5740572ccaaSJim Harris KASSERT(error == 0, ("%s: error=%d\n", __func__, error));
5750572ccaaSJim Harris KASSERT(nseg == 1, ("%s: nseg=%d\n", __func__, nseg));
5760572ccaaSJim Harris
5770572ccaaSJim Harris *bus_addr = seg[0].ds_addr;
5780572ccaaSJim Harris }
5790572ccaaSJim Harris
5800572ccaaSJim Harris static int
ismt_attach(device_t dev)5810572ccaaSJim Harris ismt_attach(device_t dev)
5820572ccaaSJim Harris {
5830572ccaaSJim Harris struct ismt_softc *sc = device_get_softc(dev);
5840572ccaaSJim Harris int err, num_vectors, val;
5850572ccaaSJim Harris
5860572ccaaSJim Harris sc->pcidev = dev;
5870572ccaaSJim Harris pci_enable_busmaster(dev);
5880572ccaaSJim Harris
5890572ccaaSJim Harris if ((sc->smbdev = device_add_child(dev, "smbus", -1)) == NULL) {
5900572ccaaSJim Harris device_printf(dev, "no smbus child found\n");
5910572ccaaSJim Harris err = ENXIO;
5920572ccaaSJim Harris goto fail;
5930572ccaaSJim Harris }
5940572ccaaSJim Harris
5950572ccaaSJim Harris sc->mmio_rid = PCIR_BAR(0);
5960572ccaaSJim Harris sc->mmio_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
5970572ccaaSJim Harris &sc->mmio_rid, RF_ACTIVE);
5980572ccaaSJim Harris if (sc->mmio_res == NULL) {
5990572ccaaSJim Harris device_printf(dev, "cannot allocate mmio region\n");
6000572ccaaSJim Harris err = ENOMEM;
6010572ccaaSJim Harris goto fail;
6020572ccaaSJim Harris }
6030572ccaaSJim Harris
6040572ccaaSJim Harris sc->mmio_tag = rman_get_bustag(sc->mmio_res);
6050572ccaaSJim Harris sc->mmio_handle = rman_get_bushandle(sc->mmio_res);
6060572ccaaSJim Harris
6070572ccaaSJim Harris /* Attach "smbus" child */
608*18250ec6SJohn Baldwin bus_attach_children(dev);
6090572ccaaSJim Harris
6100572ccaaSJim Harris bus_dma_tag_create(bus_get_dma_tag(dev), 4, PAGE_SIZE,
6110572ccaaSJim Harris BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, NULL, NULL,
6120572ccaaSJim Harris DESC_SIZE, 1, DESC_SIZE,
6130572ccaaSJim Harris 0, NULL, NULL, &sc->desc_dma_tag);
6140572ccaaSJim Harris
6150572ccaaSJim Harris bus_dma_tag_create(bus_get_dma_tag(dev), 4, PAGE_SIZE,
6160572ccaaSJim Harris BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, NULL, NULL,
6170572ccaaSJim Harris DMA_BUFFER_SIZE, 1, DMA_BUFFER_SIZE,
6180572ccaaSJim Harris 0, NULL, NULL, &sc->dma_buffer_dma_tag);
6190572ccaaSJim Harris
6200572ccaaSJim Harris bus_dmamap_create(sc->desc_dma_tag, 0,
6210572ccaaSJim Harris &sc->desc_dma_map);
6220572ccaaSJim Harris bus_dmamap_create(sc->dma_buffer_dma_tag, 0,
6230572ccaaSJim Harris &sc->dma_buffer_dma_map);
6240572ccaaSJim Harris
6250572ccaaSJim Harris bus_dmamem_alloc(sc->desc_dma_tag,
6260572ccaaSJim Harris (void **)&sc->desc, BUS_DMA_WAITOK,
6270572ccaaSJim Harris &sc->desc_dma_map);
6280572ccaaSJim Harris bus_dmamem_alloc(sc->dma_buffer_dma_tag,
6290572ccaaSJim Harris (void **)&sc->dma_buffer, BUS_DMA_WAITOK,
6300572ccaaSJim Harris &sc->dma_buffer_dma_map);
6310572ccaaSJim Harris
6320572ccaaSJim Harris bus_dmamap_load(sc->desc_dma_tag,
6330572ccaaSJim Harris sc->desc_dma_map, sc->desc, DESC_SIZE,
6340572ccaaSJim Harris ismt_single_map, &sc->desc_bus_addr, 0);
6350572ccaaSJim Harris bus_dmamap_load(sc->dma_buffer_dma_tag,
6360572ccaaSJim Harris sc->dma_buffer_dma_map, sc->dma_buffer, DMA_BUFFER_SIZE,
6370572ccaaSJim Harris ismt_single_map, &sc->dma_buffer_bus_addr, 0);
6380572ccaaSJim Harris
6390572ccaaSJim Harris bus_write_4(sc->mmio_res, ISMT_MSTR_MDBA,
6400572ccaaSJim Harris (sc->desc_bus_addr & 0xFFFFFFFFLL));
6410572ccaaSJim Harris bus_write_4(sc->mmio_res, ISMT_MSTR_MDBA + 4,
6420572ccaaSJim Harris (sc->desc_bus_addr >> 32));
6430572ccaaSJim Harris
6440572ccaaSJim Harris /* initialize the Master Control Register (MCTRL) */
6450572ccaaSJim Harris bus_write_4(sc->mmio_res, ISMT_MSTR_MCTRL, ISMT_MCTRL_MEIE);
6460572ccaaSJim Harris
6470572ccaaSJim Harris /* initialize the Master Status Register (MSTS) */
6480572ccaaSJim Harris bus_write_4(sc->mmio_res, ISMT_MSTR_MSTS, 0);
6490572ccaaSJim Harris
6500572ccaaSJim Harris /* initialize the Master Descriptor Size (MDS) */
6510572ccaaSJim Harris val = bus_read_4(sc->mmio_res, ISMT_MSTR_MDS);
6520572ccaaSJim Harris val &= ~ISMT_MDS_MASK;
6530572ccaaSJim Harris val |= (ISMT_DESC_ENTRIES - 1);
6540572ccaaSJim Harris bus_write_4(sc->mmio_res, ISMT_MSTR_MDS, val);
6550572ccaaSJim Harris
6560572ccaaSJim Harris sc->using_msi = 1;
6570572ccaaSJim Harris
6580572ccaaSJim Harris if (pci_msi_count(dev) == 0) {
6590572ccaaSJim Harris sc->using_msi = 0;
6600572ccaaSJim Harris goto intx;
6610572ccaaSJim Harris }
6620572ccaaSJim Harris
6630572ccaaSJim Harris num_vectors = 1;
6640572ccaaSJim Harris if (pci_alloc_msi(dev, &num_vectors) != 0) {
6650572ccaaSJim Harris sc->using_msi = 0;
6660572ccaaSJim Harris goto intx;
6670572ccaaSJim Harris }
6680572ccaaSJim Harris
6690572ccaaSJim Harris sc->intr_rid = 1;
6700572ccaaSJim Harris sc->intr_res = bus_alloc_resource_any(dev, SYS_RES_IRQ,
6710572ccaaSJim Harris &sc->intr_rid, RF_ACTIVE);
6720572ccaaSJim Harris
6730572ccaaSJim Harris if (sc->intr_res == NULL) {
6740572ccaaSJim Harris sc->using_msi = 0;
6750572ccaaSJim Harris pci_release_msi(dev);
6760572ccaaSJim Harris }
6770572ccaaSJim Harris
6780572ccaaSJim Harris intx:
6790572ccaaSJim Harris if (sc->using_msi == 0) {
6800572ccaaSJim Harris sc->intr_rid = 0;
6810572ccaaSJim Harris sc->intr_res = bus_alloc_resource_any(dev, SYS_RES_IRQ,
6820572ccaaSJim Harris &sc->intr_rid, RF_SHAREABLE | RF_ACTIVE);
6830572ccaaSJim Harris if (sc->intr_res == NULL) {
6840572ccaaSJim Harris device_printf(dev, "cannot allocate irq\n");
6850572ccaaSJim Harris err = ENXIO;
6860572ccaaSJim Harris goto fail;
6870572ccaaSJim Harris }
6880572ccaaSJim Harris }
6890572ccaaSJim Harris
6900572ccaaSJim Harris ISMT_DEBUG(dev, "using_msi = %d\n", sc->using_msi);
6910572ccaaSJim Harris
6920572ccaaSJim Harris err = bus_setup_intr(dev, sc->intr_res,
6930572ccaaSJim Harris INTR_TYPE_MISC | INTR_MPSAFE, NULL, ismt_intr, sc,
6940572ccaaSJim Harris &sc->intr_handle);
6950572ccaaSJim Harris if (err != 0) {
6960572ccaaSJim Harris device_printf(dev, "cannot setup interrupt\n");
6970572ccaaSJim Harris err = ENXIO;
6980572ccaaSJim Harris goto fail;
6990572ccaaSJim Harris }
7000572ccaaSJim Harris
7010572ccaaSJim Harris return (0);
7020572ccaaSJim Harris
7030572ccaaSJim Harris fail:
7040572ccaaSJim Harris ismt_detach(dev);
7050572ccaaSJim Harris return (err);
7060572ccaaSJim Harris }
7070572ccaaSJim Harris
7080572ccaaSJim Harris #define ID_INTEL_S1200_SMT0 0x0c598086
7090572ccaaSJim Harris #define ID_INTEL_S1200_SMT1 0x0c5a8086
7100572ccaaSJim Harris #define ID_INTEL_C2000_SMT 0x1f158086
7115df2e54cSJustin Hibbits #define ID_INTEL_C3000_SMT 0x19ac8086
7120572ccaaSJim Harris
7130572ccaaSJim Harris static int
ismt_probe(device_t dev)7140572ccaaSJim Harris ismt_probe(device_t dev)
7150572ccaaSJim Harris {
7160572ccaaSJim Harris const char *desc;
7170572ccaaSJim Harris
7180572ccaaSJim Harris switch (pci_get_devid(dev)) {
7190572ccaaSJim Harris case ID_INTEL_S1200_SMT0:
7200572ccaaSJim Harris desc = "Atom Processor S1200 SMBus 2.0 Controller 0";
7210572ccaaSJim Harris break;
7220572ccaaSJim Harris case ID_INTEL_S1200_SMT1:
7230572ccaaSJim Harris desc = "Atom Processor S1200 SMBus 2.0 Controller 1";
7240572ccaaSJim Harris break;
7250572ccaaSJim Harris case ID_INTEL_C2000_SMT:
7260572ccaaSJim Harris desc = "Atom Processor C2000 SMBus 2.0";
7270572ccaaSJim Harris break;
7285df2e54cSJustin Hibbits case ID_INTEL_C3000_SMT:
7295df2e54cSJustin Hibbits desc = "Atom Processor C3000 SMBus 2.0";
7305df2e54cSJustin Hibbits break;
7310572ccaaSJim Harris default:
7320572ccaaSJim Harris return (ENXIO);
7330572ccaaSJim Harris }
7340572ccaaSJim Harris
7350572ccaaSJim Harris device_set_desc(dev, desc);
7360572ccaaSJim Harris return (BUS_PROBE_DEFAULT);
7370572ccaaSJim Harris }
7380572ccaaSJim Harris
7390572ccaaSJim Harris /* Device methods */
7400572ccaaSJim Harris static device_method_t ismt_pci_methods[] = {
7410572ccaaSJim Harris DEVMETHOD(device_probe, ismt_probe),
7420572ccaaSJim Harris DEVMETHOD(device_attach, ismt_attach),
7430572ccaaSJim Harris DEVMETHOD(device_detach, ismt_detach),
7440572ccaaSJim Harris
7450572ccaaSJim Harris DEVMETHOD(smbus_callback, ismt_callback),
7460572ccaaSJim Harris DEVMETHOD(smbus_quick, ismt_quick),
7470572ccaaSJim Harris DEVMETHOD(smbus_sendb, ismt_sendb),
7480572ccaaSJim Harris DEVMETHOD(smbus_recvb, ismt_recvb),
7490572ccaaSJim Harris DEVMETHOD(smbus_writeb, ismt_writeb),
7500572ccaaSJim Harris DEVMETHOD(smbus_writew, ismt_writew),
7510572ccaaSJim Harris DEVMETHOD(smbus_readb, ismt_readb),
7520572ccaaSJim Harris DEVMETHOD(smbus_readw, ismt_readw),
7530572ccaaSJim Harris DEVMETHOD(smbus_pcall, ismt_pcall),
7540572ccaaSJim Harris DEVMETHOD(smbus_bwrite, ismt_bwrite),
7550572ccaaSJim Harris DEVMETHOD(smbus_bread, ismt_bread),
7560572ccaaSJim Harris
7570572ccaaSJim Harris DEVMETHOD_END
7580572ccaaSJim Harris };
7590572ccaaSJim Harris
7600572ccaaSJim Harris static driver_t ismt_pci_driver = {
7610572ccaaSJim Harris "ismt",
7620572ccaaSJim Harris ismt_pci_methods,
7630572ccaaSJim Harris sizeof(struct ismt_softc)
7640572ccaaSJim Harris };
7650572ccaaSJim Harris
766dfee3204SJohn Baldwin DRIVER_MODULE(ismt, pci, ismt_pci_driver, 0, 0);
767c6d39765SJohn Baldwin DRIVER_MODULE(smbus, ismt, smbus_driver, 0, 0);
7680572ccaaSJim Harris
7690572ccaaSJim Harris MODULE_DEPEND(ismt, pci, 1, 1, 1);
7700572ccaaSJim Harris MODULE_DEPEND(ismt, smbus, SMBUS_MINVER, SMBUS_PREFVER, SMBUS_MAXVER);
7710572ccaaSJim Harris MODULE_VERSION(ismt, 1);
772