d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw/*
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * CDDL HEADER START
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw *
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * The contents of this file are subject to the terms of the
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * Common Development and Distribution License (the "License").
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * You may not use this file except in compliance with the License.
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw *
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * or http://www.opensolaris.org/os/licensing.
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * See the License for the specific language governing permissions
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * and limitations under the License.
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw *
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * When distributing Covered Code, include this CDDL HEADER in each
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * If applicable, add the following below this CDDL HEADER, with the
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * fields enclosed by brackets "[]" replaced with your own identifying
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * information: Portions Copyright [yyyy] [name of copyright owner]
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw *
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * CDDL HEADER END
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw/*
193974072f41a843678abf5f61979c748687e66bSherry Moore * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * Use is subject to license terms.
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw/*
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * This file is part of the Chelsio T1 Ethernet driver.
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw *
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * Copyright (C) 2003-2005 Chelsio Communications. All rights reserved.
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw/*
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * Solaris support routines for common code part of
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * Chelsio PCI Ethernet Driver.
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#include <sys/types.h>
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#include <sys/conf.h>
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#include <sys/stropts.h>
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#include <sys/stream.h>
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#include <sys/strlog.h>
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#include <sys/kmem.h>
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#include <sys/stat.h>
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#include <sys/kstat.h>
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#include <sys/modctl.h>
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#include <sys/errno.h>
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#include <sys/varargs.h>
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#include <sys/ddi.h>
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#include <sys/sunddi.h>
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#include <sys/dlpi.h>
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#include <sys/ethernet.h>
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#include <sys/strsun.h>
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#include "ostypes.h"
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#undef OFFSET
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#include "common.h"
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#include <sys/gld.h>
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#include "oschtoe.h"
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#include "ch.h" /* Chelsio Driver specific parameters */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#include "sge.h"
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#include "regs.h"
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw/*
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * Device specific.
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwstruct pe_reg {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw uint32_t cmd;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw uint32_t addr;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw union {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw uint32_t v32;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw uint64_t v64;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw }vv;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw union {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw uint32_t m32;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw uint64_t m64;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw }mm;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw};
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#define pe_reg_val vv.v32
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#define pe_opt_val vv.v64
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#define pe_mask32 mm.m32
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#define pe_mask64 mm.m64
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwstruct toetool_reg {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw uint32_t cmd;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw uint32_t addr;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw uint32_t val;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw};
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwuint32_t
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwt1_read_reg_4(ch_t *obj, uint32_t reg_val)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw{
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw return (ddi_get32(obj->ch_hbar0, (uint32_t *)(obj->ch_bar0 + reg_val)));
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw}
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwvoid
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwt1_write_reg_4(ch_t *obj, uint32_t reg_val, uint32_t write_val)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw{
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw ddi_put32(obj->ch_hbar0, (uint32_t *)(obj->ch_bar0+reg_val), write_val);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw}
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwuint32_t
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwt1_os_pci_read_config_2(ch_t *obj, uint32_t reg, uint16_t *val)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw{
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw *val = pci_config_get16(obj->ch_hpci, reg);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw return (0);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw}
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwint
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwt1_os_pci_write_config_2(ch_t *obj, uint32_t reg, uint16_t val)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw{
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw pci_config_put16(obj->ch_hpci, reg, val);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw return (0);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw}
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwuint32_t
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwt1_os_pci_read_config_4(ch_t *obj, uint32_t reg, uint32_t *val)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw{
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw *val = pci_config_get32(obj->ch_hpci, reg);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw return (0);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw}
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwint
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwt1_os_pci_write_config_4(ch_t *obj, uint32_t reg, uint32_t val)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw{
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw pci_config_put32(obj->ch_hpci, reg, val);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw return (0);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw}
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwvoid *
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwt1_os_malloc_wait_zero(size_t len)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw{
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw return (kmem_zalloc(len, KM_SLEEP));
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw}
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwvoid
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwt1_os_free(void *adr, size_t len)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw{
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw kmem_free(adr, len);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw}
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwint
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwt1_num_of_ports(ch_t *obj)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw{
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw return (obj->config_data.num_of_ports);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw}
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw/* ARGSUSED */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwint
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwpe_os_mem_copy(ch_t *obj, void *dst, void *src, size_t len)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw{
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw bcopy(src, dst, len);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw return (0);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw}
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwint
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwpe_is_ring_buffer_enabled(ch_t *obj)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw{
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw return (obj->config & CFGMD_RINGB);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw}
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#define PE_READ_REG _IOR('i', 0xAB, 0x18)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#define PE_WRITE_REG _IOW('i', 0xAB, 0x18)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#define PE_READ_PCI _IOR('i', 0xAC, 0x18)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#define PE_WRITE_PCI _IOW('i', 0xAC, 0x18)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#define PE_READ_INTR _IOR('i', 0xAD, 0x20)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#define TOETOOL_GETTPI _IOR('i', 0xAE, 0xc)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#define TOETOOL_SETTPI _IOW('i', 0xAE, 0xc)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwvoid
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwpe_ioctl(ch_t *chp, queue_t *q, mblk_t *mp)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw{
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw struct iocblk *iocp;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw mblk_t *dmp;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw struct pe_reg *pe;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw struct toetool_reg *te;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw uint32_t reg;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw struct sge_intr_counts *se, *sep;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw iocp = (struct iocblk *)mp->b_rptr;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* don't support TRASPARENT ioctls */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (iocp->ioc_count == TRANSPARENT) {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw iocp->ioc_error = ENOTTY;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw goto bad;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw }
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /*
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * sanity checks. There should be a M_DATA mblk following
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * the initial M_IOCTL mblk
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if ((dmp = mp->b_cont) == NULL) {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw iocp->ioc_error = ENOTTY;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw goto bad;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw }
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (dmp->b_datap->db_type != M_DATA) {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw iocp->ioc_error = ENOTTY;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw goto bad;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw }
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw pe = (struct pe_reg *)dmp->b_rptr;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw se = (struct sge_intr_counts *)dmp->b_rptr;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw te = (struct toetool_reg *)dmp->b_rptr;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* now process the ioctl */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw switch (iocp->ioc_cmd) {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw case PE_READ_REG:
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if ((dmp->b_wptr - dmp->b_rptr) != sizeof (*pe)) {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw iocp->ioc_error = ENOTTY;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw goto bad;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw }
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* protect against bad addr values */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw pe->addr &= (uint32_t)~3;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw pe->pe_mask32 = 0xFFFFFFFF;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (pe->addr == 0x950)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw pe->pe_reg_val = reg = t1_sge_get_ptimeout(chp);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw else
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw pe->pe_reg_val = reg = t1_read_reg_4(chp, pe->addr);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw mp->b_datap->db_type = M_IOCACK;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw iocp->ioc_count = sizeof (*pe);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw break;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw case PE_WRITE_REG:
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if ((dmp->b_wptr - dmp->b_rptr) != sizeof (*pe)) {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw iocp->ioc_error = ENOTTY;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw goto bad;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw }
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (pe->addr == 0x950)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw t1_sge_set_ptimeout(chp, pe->pe_reg_val);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw else {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (pe->pe_mask32 != 0xffffffff) {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw reg = t1_read_reg_4(chp, pe->addr);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw pe->pe_reg_val |= (reg & ~pe->pe_mask32);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw }
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw t1_write_reg_4(chp, pe->addr, pe->pe_reg_val);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw }
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (mp->b_cont)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw freemsg(mp->b_cont);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw mp->b_cont = NULL;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw mp->b_datap->db_type = M_IOCACK;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw break;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw case PE_READ_PCI:
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if ((dmp->b_wptr - dmp->b_rptr) != sizeof (*pe)) {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw iocp->ioc_error = ENOTTY;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw goto bad;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw }
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* protect against bad addr values */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw pe->addr &= (uint32_t)~3;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw pe->pe_mask32 = 0xFFFFFFFF;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw pe->pe_reg_val = reg = pci_config_get32(chp->ch_hpci, pe->addr);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw mp->b_datap->db_type = M_IOCACK;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw iocp->ioc_count = sizeof (*pe);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw break;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw case PE_WRITE_PCI:
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if ((dmp->b_wptr - dmp->b_rptr) != sizeof (*pe)) {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw iocp->ioc_error = ENOTTY;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw goto bad;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw }
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (pe->pe_mask32 != 0xffffffff) {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw reg = pci_config_get32(chp->ch_hpci, pe->addr);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw pe->pe_reg_val |= (reg & ~pe->pe_mask32);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw }
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw pci_config_put32(chp->ch_hpci, pe->addr, pe->pe_reg_val);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (mp->b_cont)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw freemsg(mp->b_cont);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw mp->b_cont = NULL;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw mp->b_datap->db_type = M_IOCACK;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw break;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw case PE_READ_INTR:
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if ((dmp->b_wptr - dmp->b_rptr) != sizeof (*se)) {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw iocp->ioc_error = ENOTTY;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw goto bad;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw }
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw sep = sge_get_stat(chp->sge);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw bcopy(sep, se, sizeof (*se));
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw mp->b_datap->db_type = M_IOCACK;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw iocp->ioc_count = sizeof (*se);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw break;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw case TOETOOL_GETTPI:
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if ((dmp->b_wptr - dmp->b_rptr) != sizeof (*te)) {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw iocp->ioc_error = ENOTTY;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw goto bad;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw }
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* protect against bad addr values */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if ((te->addr & 3) != 0) {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw iocp->ioc_error = ENOTTY;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw goto bad;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw }
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) t1_tpi_read(chp, te->addr, &te->val);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw mp->b_datap->db_type = M_IOCACK;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw iocp->ioc_count = sizeof (*te);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw break;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw case TOETOOL_SETTPI:
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if ((dmp->b_wptr - dmp->b_rptr) != sizeof (*te)) {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw iocp->ioc_error = ENOTTY;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw goto bad;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw }
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* protect against bad addr values */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if ((te->addr & 3) != 0) {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw iocp->ioc_error = ENOTTY;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw goto bad;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw }
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) t1_tpi_write(chp, te->addr, te->val);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw mp->b_datap->db_type = M_IOCACK;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw iocp->ioc_count = sizeof (*te);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw break;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw default:
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw iocp->ioc_error = ENOTTY;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw goto bad;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw }
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw qreply(q, mp);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw return;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwbad:
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (mp->b_cont)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw freemsg(mp->b_cont);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw mp->b_cont = NULL;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw mp->b_datap->db_type = M_IOCNAK;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw qreply(q, mp);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw}
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw/*
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * Can't wait for memory here, since we have to use the Solaris dma
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * mechanisms to determine the physical address.
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * flg is either 0 (read) or DMA_OUT (write).
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwvoid *
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwpe_os_malloc_contig_wait_zero(ch_t *chp, size_t len, uint64_t *dma_addr,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw ulong_t *dh, ulong_t *ah, uint32_t flg)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw{
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw void *mem = NULL;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw uint64_t pa;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /*
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * byte swap, consistant mapping & 4k aligned
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw mem = ch_alloc_dma_mem(chp, 1, DMA_4KALN|flg, len, &pa, dh, ah);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (mem == NULL) {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw return (0);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw }
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (dma_addr)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw *dma_addr = pa;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw bzero(mem, len);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw return ((void *)mem);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw}
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw/* ARGSUSED */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwvoid
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwpe_os_free_contig(ch_t *obj, size_t len, void *addr, uint64_t dma_addr,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw ulong_t dh, ulong_t ah)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw{
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw ch_free_dma_mem(dh, ah);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw}
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwvoid
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwt1_fatal_err(ch_t *adapter)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw{
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (adapter->ch_flags & PEINITDONE) {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) sge_stop(adapter->sge);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw t1_interrupts_disable(adapter);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw }
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw CH_ALERT("%s: encountered fatal error, operation suspended\n",
193974072f41a843678abf5f61979c748687e66bSherry Moore adapter_name(adapter));
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw}
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwvoid
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwCH_ALERT(const char *fmt, ...)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw{
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw va_list ap;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw char buf[128];
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* format buf using fmt and arguments contained in ap */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw va_start(ap, fmt);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) vsprintf(buf, fmt, ap);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw va_end(ap);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* pass formatted string to cmn_err(9F) */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw cmn_err(CE_WARN, "%s", buf);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw}
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwvoid
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwCH_WARN(const char *fmt, ...)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw{
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw va_list ap;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw char buf[128];
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* format buf using fmt and arguments contained in ap */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw va_start(ap, fmt);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) vsprintf(buf, fmt, ap);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw va_end(ap);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* pass formatted string to cmn_err(9F) */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw cmn_err(CE_WARN, "%s", buf);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw}
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwvoid
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwCH_ERR(const char *fmt, ...)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw{
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw va_list ap;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw char buf[128];
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* format buf using fmt and arguments contained in ap */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw va_start(ap, fmt);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) vsprintf(buf, fmt, ap);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw va_end(ap);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* pass formatted string to cmn_err(9F) */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw cmn_err(CE_WARN, "%s", buf);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw}
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwu32
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwle32_to_cpu(u32 data)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw{
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#if BYTE_ORDER == BIG_ENDIAN
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw uint8_t *in, t;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw in = (uint8_t *)&data;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw t = in[0];
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw in[0] = in[3];
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw in[3] = t;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw t = in[1];
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw in[1] = in[2];
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw in[2] = t;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#endif
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw return (data);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw}
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw/*
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * This function initializes a polling routine, Poll_func
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * which will be polled ever N Microsecond, where N is
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * provided in the cyclic start routine.
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw/* ARGSUSED */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwvoid
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwch_init_cyclic(void *adapter, p_ch_cyclic_t cyclic,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw void (*poll_func)(void *), void *arg)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw{
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw cyclic->func = poll_func;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw cyclic->arg = arg;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw cyclic->timer = 0;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw}
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw/*
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * Cyclic function which provides a periodic polling
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * capability to Solaris. The poll function provided by
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * the 'ch_init_cyclic' function is called from this
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * here, and this routine launches a new one-shot
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * timer to bring it back in some period later.
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwvoid
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwch_cyclic(p_ch_cyclic_t cyclic)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw{
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (cyclic->timer != 0) {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw cyclic->func(cyclic->arg);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw cyclic->timer = timeout((void(*)(void *))ch_cyclic,
193974072f41a843678abf5f61979c748687e66bSherry Moore (void *)cyclic, cyclic->period);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw }
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw}
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw/*
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * The 'ch_start_cyclic' starts the polling.
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwvoid
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwch_start_cyclic(p_ch_cyclic_t cyclic, unsigned long period)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw{
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw cyclic->period = drv_usectohz(period * 1000);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (cyclic->timer == 0) {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw cyclic->timer = timeout((void(*)(void *))ch_cyclic,
193974072f41a843678abf5f61979c748687e66bSherry Moore (void *)cyclic, cyclic->period);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw }
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw}
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw/*
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * The 'ch_stop_cyclic' stops the polling.
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwvoid
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwch_stop_cyclic(p_ch_cyclic_t cyclic)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw{
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw timeout_id_t timer;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw clock_t value;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw do {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw timer = cyclic->timer;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw cyclic->timer = 0;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw value = untimeout(timer);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (value == 0)
193974072f41a843678abf5f61979c748687e66bSherry Moore drv_usecwait(drv_hztousec(2 * cyclic->period));
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw } while ((timer != 0) && (value == 0));
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw}