1d39a76e7Sxw161283 /* 2d39a76e7Sxw161283 * CDDL HEADER START 3d39a76e7Sxw161283 * 4d39a76e7Sxw161283 * The contents of this file are subject to the terms of the 5d39a76e7Sxw161283 * Common Development and Distribution License (the "License"). 6d39a76e7Sxw161283 * You may not use this file except in compliance with the License. 7d39a76e7Sxw161283 * 8d39a76e7Sxw161283 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9d39a76e7Sxw161283 * or http://www.opensolaris.org/os/licensing. 10d39a76e7Sxw161283 * See the License for the specific language governing permissions 11d39a76e7Sxw161283 * and limitations under the License. 12d39a76e7Sxw161283 * 13d39a76e7Sxw161283 * When distributing Covered Code, include this CDDL HEADER in each 14d39a76e7Sxw161283 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15d39a76e7Sxw161283 * If applicable, add the following below this CDDL HEADER, with the 16d39a76e7Sxw161283 * fields enclosed by brackets "[]" replaced with your own identifying 17d39a76e7Sxw161283 * information: Portions Copyright [yyyy] [name of copyright owner] 18d39a76e7Sxw161283 * 19d39a76e7Sxw161283 * CDDL HEADER END 20d39a76e7Sxw161283 */ 21d39a76e7Sxw161283 22d39a76e7Sxw161283 /* 23*19397407SSherry Moore * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 24d39a76e7Sxw161283 * Use is subject to license terms. 25d39a76e7Sxw161283 */ 26d39a76e7Sxw161283 27d39a76e7Sxw161283 /* 28d39a76e7Sxw161283 * This file is part of the Chelsio T1 Ethernet driver. 29d39a76e7Sxw161283 * 30d39a76e7Sxw161283 * Copyright (C) 2003-2005 Chelsio Communications. All rights reserved. 31d39a76e7Sxw161283 */ 32d39a76e7Sxw161283 33d39a76e7Sxw161283 /* 34d39a76e7Sxw161283 * Solaris support routines for common code part of 35d39a76e7Sxw161283 * Chelsio PCI Ethernet Driver. 36d39a76e7Sxw161283 */ 37d39a76e7Sxw161283 38d39a76e7Sxw161283 #include <sys/types.h> 39d39a76e7Sxw161283 #include <sys/conf.h> 40d39a76e7Sxw161283 #include <sys/stropts.h> 41d39a76e7Sxw161283 #include <sys/stream.h> 42d39a76e7Sxw161283 #include <sys/strlog.h> 43d39a76e7Sxw161283 #include <sys/kmem.h> 44d39a76e7Sxw161283 #include <sys/stat.h> 45d39a76e7Sxw161283 #include <sys/kstat.h> 46d39a76e7Sxw161283 #include <sys/modctl.h> 47d39a76e7Sxw161283 #include <sys/errno.h> 48d39a76e7Sxw161283 #include <sys/varargs.h> 49d39a76e7Sxw161283 #include <sys/ddi.h> 50d39a76e7Sxw161283 #include <sys/sunddi.h> 51d39a76e7Sxw161283 #include <sys/dlpi.h> 52d39a76e7Sxw161283 #include <sys/ethernet.h> 53d39a76e7Sxw161283 #include <sys/strsun.h> 54d39a76e7Sxw161283 #include "ostypes.h" 55d39a76e7Sxw161283 #undef OFFSET 56d39a76e7Sxw161283 #include "common.h" 57d39a76e7Sxw161283 #include <sys/gld.h> 58d39a76e7Sxw161283 #include "oschtoe.h" 59d39a76e7Sxw161283 #include "ch.h" /* Chelsio Driver specific parameters */ 60d39a76e7Sxw161283 #include "sge.h" 61d39a76e7Sxw161283 #include "regs.h" 62d39a76e7Sxw161283 63d39a76e7Sxw161283 /* 64d39a76e7Sxw161283 * Device specific. 65d39a76e7Sxw161283 */ 66d39a76e7Sxw161283 struct pe_reg { 67d39a76e7Sxw161283 uint32_t cmd; 68d39a76e7Sxw161283 uint32_t addr; 69d39a76e7Sxw161283 union { 70d39a76e7Sxw161283 uint32_t v32; 71d39a76e7Sxw161283 uint64_t v64; 72d39a76e7Sxw161283 }vv; 73d39a76e7Sxw161283 union { 74d39a76e7Sxw161283 uint32_t m32; 75d39a76e7Sxw161283 uint64_t m64; 76d39a76e7Sxw161283 }mm; 77d39a76e7Sxw161283 }; 78d39a76e7Sxw161283 #define pe_reg_val vv.v32 79d39a76e7Sxw161283 #define pe_opt_val vv.v64 80d39a76e7Sxw161283 #define pe_mask32 mm.m32 81d39a76e7Sxw161283 #define pe_mask64 mm.m64 82d39a76e7Sxw161283 83d39a76e7Sxw161283 struct toetool_reg { 84d39a76e7Sxw161283 uint32_t cmd; 85d39a76e7Sxw161283 uint32_t addr; 86d39a76e7Sxw161283 uint32_t val; 87d39a76e7Sxw161283 }; 88d39a76e7Sxw161283 89d39a76e7Sxw161283 uint32_t 90d39a76e7Sxw161283 t1_read_reg_4(ch_t *obj, uint32_t reg_val) 91d39a76e7Sxw161283 { 92d39a76e7Sxw161283 return (ddi_get32(obj->ch_hbar0, (uint32_t *)(obj->ch_bar0 + reg_val))); 93d39a76e7Sxw161283 } 94d39a76e7Sxw161283 95d39a76e7Sxw161283 void 96d39a76e7Sxw161283 t1_write_reg_4(ch_t *obj, uint32_t reg_val, uint32_t write_val) 97d39a76e7Sxw161283 { 98d39a76e7Sxw161283 ddi_put32(obj->ch_hbar0, (uint32_t *)(obj->ch_bar0+reg_val), write_val); 99d39a76e7Sxw161283 } 100d39a76e7Sxw161283 101d39a76e7Sxw161283 uint32_t 102d39a76e7Sxw161283 t1_os_pci_read_config_2(ch_t *obj, uint32_t reg, uint16_t *val) 103d39a76e7Sxw161283 { 104d39a76e7Sxw161283 *val = pci_config_get16(obj->ch_hpci, reg); 105d39a76e7Sxw161283 return (0); 106d39a76e7Sxw161283 } 107d39a76e7Sxw161283 108d39a76e7Sxw161283 int 109d39a76e7Sxw161283 t1_os_pci_write_config_2(ch_t *obj, uint32_t reg, uint16_t val) 110d39a76e7Sxw161283 { 111d39a76e7Sxw161283 pci_config_put16(obj->ch_hpci, reg, val); 112d39a76e7Sxw161283 return (0); 113d39a76e7Sxw161283 } 114d39a76e7Sxw161283 115d39a76e7Sxw161283 uint32_t 116d39a76e7Sxw161283 t1_os_pci_read_config_4(ch_t *obj, uint32_t reg, uint32_t *val) 117d39a76e7Sxw161283 { 118d39a76e7Sxw161283 *val = pci_config_get32(obj->ch_hpci, reg); 119d39a76e7Sxw161283 return (0); 120d39a76e7Sxw161283 } 121d39a76e7Sxw161283 122d39a76e7Sxw161283 int 123d39a76e7Sxw161283 t1_os_pci_write_config_4(ch_t *obj, uint32_t reg, uint32_t val) 124d39a76e7Sxw161283 { 125d39a76e7Sxw161283 pci_config_put32(obj->ch_hpci, reg, val); 126d39a76e7Sxw161283 return (0); 127d39a76e7Sxw161283 } 128d39a76e7Sxw161283 129d39a76e7Sxw161283 void * 130d39a76e7Sxw161283 t1_os_malloc_wait_zero(size_t len) 131d39a76e7Sxw161283 { 132d39a76e7Sxw161283 return (kmem_zalloc(len, KM_SLEEP)); 133d39a76e7Sxw161283 } 134d39a76e7Sxw161283 135d39a76e7Sxw161283 void 136d39a76e7Sxw161283 t1_os_free(void *adr, size_t len) 137d39a76e7Sxw161283 { 138d39a76e7Sxw161283 kmem_free(adr, len); 139d39a76e7Sxw161283 } 140d39a76e7Sxw161283 141d39a76e7Sxw161283 int 142d39a76e7Sxw161283 t1_num_of_ports(ch_t *obj) 143d39a76e7Sxw161283 { 144d39a76e7Sxw161283 return (obj->config_data.num_of_ports); 145d39a76e7Sxw161283 } 146d39a76e7Sxw161283 147d39a76e7Sxw161283 /* ARGSUSED */ 148d39a76e7Sxw161283 int 149d39a76e7Sxw161283 pe_os_mem_copy(ch_t *obj, void *dst, void *src, size_t len) 150d39a76e7Sxw161283 { 151d39a76e7Sxw161283 bcopy(src, dst, len); 152d39a76e7Sxw161283 return (0); 153d39a76e7Sxw161283 } 154d39a76e7Sxw161283 155d39a76e7Sxw161283 int 156d39a76e7Sxw161283 pe_is_ring_buffer_enabled(ch_t *obj) 157d39a76e7Sxw161283 { 158d39a76e7Sxw161283 return (obj->config & CFGMD_RINGB); 159d39a76e7Sxw161283 } 160d39a76e7Sxw161283 161d39a76e7Sxw161283 #define PE_READ_REG _IOR('i', 0xAB, 0x18) 162d39a76e7Sxw161283 #define PE_WRITE_REG _IOW('i', 0xAB, 0x18) 163d39a76e7Sxw161283 #define PE_READ_PCI _IOR('i', 0xAC, 0x18) 164d39a76e7Sxw161283 #define PE_WRITE_PCI _IOW('i', 0xAC, 0x18) 165d39a76e7Sxw161283 #define PE_READ_INTR _IOR('i', 0xAD, 0x20) 166d39a76e7Sxw161283 #define TOETOOL_GETTPI _IOR('i', 0xAE, 0xc) 167d39a76e7Sxw161283 #define TOETOOL_SETTPI _IOW('i', 0xAE, 0xc) 168d39a76e7Sxw161283 169d39a76e7Sxw161283 void 170d39a76e7Sxw161283 pe_ioctl(ch_t *chp, queue_t *q, mblk_t *mp) 171d39a76e7Sxw161283 { 172d39a76e7Sxw161283 struct iocblk *iocp; 173d39a76e7Sxw161283 mblk_t *dmp; 174d39a76e7Sxw161283 struct pe_reg *pe; 175d39a76e7Sxw161283 struct toetool_reg *te; 176d39a76e7Sxw161283 uint32_t reg; 177d39a76e7Sxw161283 struct sge_intr_counts *se, *sep; 178d39a76e7Sxw161283 179d39a76e7Sxw161283 iocp = (struct iocblk *)mp->b_rptr; 180d39a76e7Sxw161283 181d39a76e7Sxw161283 /* don't support TRASPARENT ioctls */ 182d39a76e7Sxw161283 if (iocp->ioc_count == TRANSPARENT) { 183d39a76e7Sxw161283 iocp->ioc_error = ENOTTY; 184d39a76e7Sxw161283 goto bad; 185d39a76e7Sxw161283 } 186d39a76e7Sxw161283 187d39a76e7Sxw161283 /* 188d39a76e7Sxw161283 * sanity checks. There should be a M_DATA mblk following 189d39a76e7Sxw161283 * the initial M_IOCTL mblk 190d39a76e7Sxw161283 */ 191d39a76e7Sxw161283 if ((dmp = mp->b_cont) == NULL) { 192d39a76e7Sxw161283 iocp->ioc_error = ENOTTY; 193d39a76e7Sxw161283 goto bad; 194d39a76e7Sxw161283 } 195d39a76e7Sxw161283 196d39a76e7Sxw161283 if (dmp->b_datap->db_type != M_DATA) { 197d39a76e7Sxw161283 iocp->ioc_error = ENOTTY; 198d39a76e7Sxw161283 goto bad; 199d39a76e7Sxw161283 } 200d39a76e7Sxw161283 201d39a76e7Sxw161283 pe = (struct pe_reg *)dmp->b_rptr; 202d39a76e7Sxw161283 se = (struct sge_intr_counts *)dmp->b_rptr; 203d39a76e7Sxw161283 te = (struct toetool_reg *)dmp->b_rptr; 204d39a76e7Sxw161283 205d39a76e7Sxw161283 /* now process the ioctl */ 206d39a76e7Sxw161283 switch (iocp->ioc_cmd) { 207d39a76e7Sxw161283 case PE_READ_REG: 208d39a76e7Sxw161283 209d39a76e7Sxw161283 if ((dmp->b_wptr - dmp->b_rptr) != sizeof (*pe)) { 210d39a76e7Sxw161283 iocp->ioc_error = ENOTTY; 211d39a76e7Sxw161283 goto bad; 212d39a76e7Sxw161283 } 213d39a76e7Sxw161283 214d39a76e7Sxw161283 /* protect against bad addr values */ 215d39a76e7Sxw161283 pe->addr &= (uint32_t)~3; 216d39a76e7Sxw161283 217d39a76e7Sxw161283 pe->pe_mask32 = 0xFFFFFFFF; 218d39a76e7Sxw161283 219d39a76e7Sxw161283 if (pe->addr == 0x950) 220d39a76e7Sxw161283 pe->pe_reg_val = reg = t1_sge_get_ptimeout(chp); 221d39a76e7Sxw161283 else 222d39a76e7Sxw161283 pe->pe_reg_val = reg = t1_read_reg_4(chp, pe->addr); 223d39a76e7Sxw161283 224d39a76e7Sxw161283 mp->b_datap->db_type = M_IOCACK; 225d39a76e7Sxw161283 iocp->ioc_count = sizeof (*pe); 226d39a76e7Sxw161283 227d39a76e7Sxw161283 break; 228d39a76e7Sxw161283 229d39a76e7Sxw161283 case PE_WRITE_REG: 230d39a76e7Sxw161283 231d39a76e7Sxw161283 if ((dmp->b_wptr - dmp->b_rptr) != sizeof (*pe)) { 232d39a76e7Sxw161283 iocp->ioc_error = ENOTTY; 233d39a76e7Sxw161283 goto bad; 234d39a76e7Sxw161283 } 235d39a76e7Sxw161283 236d39a76e7Sxw161283 if (pe->addr == 0x950) 237d39a76e7Sxw161283 t1_sge_set_ptimeout(chp, pe->pe_reg_val); 238d39a76e7Sxw161283 else { 239d39a76e7Sxw161283 if (pe->pe_mask32 != 0xffffffff) { 240d39a76e7Sxw161283 reg = t1_read_reg_4(chp, pe->addr); 241d39a76e7Sxw161283 pe->pe_reg_val |= (reg & ~pe->pe_mask32); 242d39a76e7Sxw161283 } 243d39a76e7Sxw161283 244d39a76e7Sxw161283 t1_write_reg_4(chp, pe->addr, pe->pe_reg_val); 245d39a76e7Sxw161283 } 246d39a76e7Sxw161283 247d39a76e7Sxw161283 if (mp->b_cont) 248d39a76e7Sxw161283 freemsg(mp->b_cont); 249d39a76e7Sxw161283 mp->b_cont = NULL; 250d39a76e7Sxw161283 mp->b_datap->db_type = M_IOCACK; 251d39a76e7Sxw161283 break; 252d39a76e7Sxw161283 253d39a76e7Sxw161283 case PE_READ_PCI: 254d39a76e7Sxw161283 255d39a76e7Sxw161283 if ((dmp->b_wptr - dmp->b_rptr) != sizeof (*pe)) { 256d39a76e7Sxw161283 iocp->ioc_error = ENOTTY; 257d39a76e7Sxw161283 goto bad; 258d39a76e7Sxw161283 } 259d39a76e7Sxw161283 260d39a76e7Sxw161283 /* protect against bad addr values */ 261d39a76e7Sxw161283 pe->addr &= (uint32_t)~3; 262d39a76e7Sxw161283 263d39a76e7Sxw161283 pe->pe_mask32 = 0xFFFFFFFF; 264d39a76e7Sxw161283 pe->pe_reg_val = reg = pci_config_get32(chp->ch_hpci, pe->addr); 265d39a76e7Sxw161283 mp->b_datap->db_type = M_IOCACK; 266d39a76e7Sxw161283 iocp->ioc_count = sizeof (*pe); 267d39a76e7Sxw161283 268d39a76e7Sxw161283 break; 269d39a76e7Sxw161283 270d39a76e7Sxw161283 case PE_WRITE_PCI: 271d39a76e7Sxw161283 272d39a76e7Sxw161283 if ((dmp->b_wptr - dmp->b_rptr) != sizeof (*pe)) { 273d39a76e7Sxw161283 iocp->ioc_error = ENOTTY; 274d39a76e7Sxw161283 goto bad; 275d39a76e7Sxw161283 } 276d39a76e7Sxw161283 277d39a76e7Sxw161283 if (pe->pe_mask32 != 0xffffffff) { 278d39a76e7Sxw161283 reg = pci_config_get32(chp->ch_hpci, pe->addr); 279d39a76e7Sxw161283 pe->pe_reg_val |= (reg & ~pe->pe_mask32); 280d39a76e7Sxw161283 } 281d39a76e7Sxw161283 282d39a76e7Sxw161283 pci_config_put32(chp->ch_hpci, pe->addr, pe->pe_reg_val); 283d39a76e7Sxw161283 284d39a76e7Sxw161283 if (mp->b_cont) 285d39a76e7Sxw161283 freemsg(mp->b_cont); 286d39a76e7Sxw161283 mp->b_cont = NULL; 287d39a76e7Sxw161283 mp->b_datap->db_type = M_IOCACK; 288d39a76e7Sxw161283 break; 289d39a76e7Sxw161283 290d39a76e7Sxw161283 case PE_READ_INTR: 291d39a76e7Sxw161283 292d39a76e7Sxw161283 if ((dmp->b_wptr - dmp->b_rptr) != sizeof (*se)) { 293d39a76e7Sxw161283 iocp->ioc_error = ENOTTY; 294d39a76e7Sxw161283 goto bad; 295d39a76e7Sxw161283 } 296d39a76e7Sxw161283 297d39a76e7Sxw161283 sep = sge_get_stat(chp->sge); 298d39a76e7Sxw161283 bcopy(sep, se, sizeof (*se)); 299d39a76e7Sxw161283 mp->b_datap->db_type = M_IOCACK; 300d39a76e7Sxw161283 iocp->ioc_count = sizeof (*se); 301d39a76e7Sxw161283 break; 302d39a76e7Sxw161283 303d39a76e7Sxw161283 case TOETOOL_GETTPI: 304d39a76e7Sxw161283 305d39a76e7Sxw161283 if ((dmp->b_wptr - dmp->b_rptr) != sizeof (*te)) { 306d39a76e7Sxw161283 iocp->ioc_error = ENOTTY; 307d39a76e7Sxw161283 goto bad; 308d39a76e7Sxw161283 } 309d39a76e7Sxw161283 310d39a76e7Sxw161283 /* protect against bad addr values */ 311d39a76e7Sxw161283 if ((te->addr & 3) != 0) { 312d39a76e7Sxw161283 iocp->ioc_error = ENOTTY; 313d39a76e7Sxw161283 goto bad; 314d39a76e7Sxw161283 } 315d39a76e7Sxw161283 316d39a76e7Sxw161283 (void) t1_tpi_read(chp, te->addr, &te->val); 317d39a76e7Sxw161283 mp->b_datap->db_type = M_IOCACK; 318d39a76e7Sxw161283 iocp->ioc_count = sizeof (*te); 319d39a76e7Sxw161283 320d39a76e7Sxw161283 break; 321d39a76e7Sxw161283 322d39a76e7Sxw161283 case TOETOOL_SETTPI: 323d39a76e7Sxw161283 324d39a76e7Sxw161283 if ((dmp->b_wptr - dmp->b_rptr) != sizeof (*te)) { 325d39a76e7Sxw161283 iocp->ioc_error = ENOTTY; 326d39a76e7Sxw161283 goto bad; 327d39a76e7Sxw161283 } 328d39a76e7Sxw161283 329d39a76e7Sxw161283 /* protect against bad addr values */ 330d39a76e7Sxw161283 if ((te->addr & 3) != 0) { 331d39a76e7Sxw161283 iocp->ioc_error = ENOTTY; 332d39a76e7Sxw161283 goto bad; 333d39a76e7Sxw161283 } 334d39a76e7Sxw161283 335d39a76e7Sxw161283 (void) t1_tpi_write(chp, te->addr, te->val); 336d39a76e7Sxw161283 337d39a76e7Sxw161283 mp->b_datap->db_type = M_IOCACK; 338d39a76e7Sxw161283 iocp->ioc_count = sizeof (*te); 339d39a76e7Sxw161283 340d39a76e7Sxw161283 break; 341d39a76e7Sxw161283 342d39a76e7Sxw161283 default: 343d39a76e7Sxw161283 iocp->ioc_error = ENOTTY; 344d39a76e7Sxw161283 goto bad; 345d39a76e7Sxw161283 } 346d39a76e7Sxw161283 347d39a76e7Sxw161283 qreply(q, mp); 348d39a76e7Sxw161283 349d39a76e7Sxw161283 return; 350d39a76e7Sxw161283 351d39a76e7Sxw161283 bad: 352d39a76e7Sxw161283 if (mp->b_cont) 353d39a76e7Sxw161283 freemsg(mp->b_cont); 354d39a76e7Sxw161283 mp->b_cont = NULL; 355d39a76e7Sxw161283 mp->b_datap->db_type = M_IOCNAK; 356d39a76e7Sxw161283 357d39a76e7Sxw161283 qreply(q, mp); 358d39a76e7Sxw161283 } 359d39a76e7Sxw161283 360d39a76e7Sxw161283 /* 361d39a76e7Sxw161283 * Can't wait for memory here, since we have to use the Solaris dma 362d39a76e7Sxw161283 * mechanisms to determine the physical address. 363d39a76e7Sxw161283 * flg is either 0 (read) or DMA_OUT (write). 364d39a76e7Sxw161283 */ 365d39a76e7Sxw161283 void * 366d39a76e7Sxw161283 pe_os_malloc_contig_wait_zero(ch_t *chp, size_t len, uint64_t *dma_addr, 367d39a76e7Sxw161283 ulong_t *dh, ulong_t *ah, uint32_t flg) 368d39a76e7Sxw161283 { 369d39a76e7Sxw161283 void *mem = NULL; 370d39a76e7Sxw161283 uint64_t pa; 371d39a76e7Sxw161283 372d39a76e7Sxw161283 /* 373d39a76e7Sxw161283 * byte swap, consistant mapping & 4k aligned 374d39a76e7Sxw161283 */ 375d39a76e7Sxw161283 mem = ch_alloc_dma_mem(chp, 1, DMA_4KALN|flg, len, &pa, dh, ah); 376d39a76e7Sxw161283 if (mem == NULL) { 377d39a76e7Sxw161283 return (0); 378d39a76e7Sxw161283 } 379d39a76e7Sxw161283 380d39a76e7Sxw161283 if (dma_addr) 381d39a76e7Sxw161283 *dma_addr = pa; 382d39a76e7Sxw161283 383d39a76e7Sxw161283 bzero(mem, len); 384d39a76e7Sxw161283 385d39a76e7Sxw161283 return ((void *)mem); 386d39a76e7Sxw161283 } 387d39a76e7Sxw161283 388d39a76e7Sxw161283 /* ARGSUSED */ 389d39a76e7Sxw161283 void 390d39a76e7Sxw161283 pe_os_free_contig(ch_t *obj, size_t len, void *addr, uint64_t dma_addr, 391d39a76e7Sxw161283 ulong_t dh, ulong_t ah) 392d39a76e7Sxw161283 { 393d39a76e7Sxw161283 ch_free_dma_mem(dh, ah); 394d39a76e7Sxw161283 } 395d39a76e7Sxw161283 396d39a76e7Sxw161283 void 397d39a76e7Sxw161283 t1_fatal_err(ch_t *adapter) 398d39a76e7Sxw161283 { 399d39a76e7Sxw161283 if (adapter->ch_flags & PEINITDONE) { 400d39a76e7Sxw161283 (void) sge_stop(adapter->sge); 401d39a76e7Sxw161283 t1_interrupts_disable(adapter); 402d39a76e7Sxw161283 } 403d39a76e7Sxw161283 CH_ALERT("%s: encountered fatal error, operation suspended\n", 404d39a76e7Sxw161283 adapter_name(adapter)); 405d39a76e7Sxw161283 } 406d39a76e7Sxw161283 407d39a76e7Sxw161283 void 408d39a76e7Sxw161283 CH_ALERT(const char *fmt, ...) 409d39a76e7Sxw161283 { 410d39a76e7Sxw161283 va_list ap; 411d39a76e7Sxw161283 char buf[128]; 412d39a76e7Sxw161283 413d39a76e7Sxw161283 /* format buf using fmt and arguments contained in ap */ 414d39a76e7Sxw161283 415d39a76e7Sxw161283 va_start(ap, fmt); 416d39a76e7Sxw161283 (void) vsprintf(buf, fmt, ap); 417d39a76e7Sxw161283 va_end(ap); 418d39a76e7Sxw161283 419d39a76e7Sxw161283 /* pass formatted string to cmn_err(9F) */ 420d39a76e7Sxw161283 cmn_err(CE_WARN, "%s", buf); 421d39a76e7Sxw161283 } 422d39a76e7Sxw161283 423d39a76e7Sxw161283 void 424d39a76e7Sxw161283 CH_WARN(const char *fmt, ...) 425d39a76e7Sxw161283 { 426d39a76e7Sxw161283 va_list ap; 427d39a76e7Sxw161283 char buf[128]; 428d39a76e7Sxw161283 429d39a76e7Sxw161283 /* format buf using fmt and arguments contained in ap */ 430d39a76e7Sxw161283 431d39a76e7Sxw161283 va_start(ap, fmt); 432d39a76e7Sxw161283 (void) vsprintf(buf, fmt, ap); 433d39a76e7Sxw161283 va_end(ap); 434d39a76e7Sxw161283 435d39a76e7Sxw161283 /* pass formatted string to cmn_err(9F) */ 436d39a76e7Sxw161283 cmn_err(CE_WARN, "%s", buf); 437d39a76e7Sxw161283 } 438d39a76e7Sxw161283 439d39a76e7Sxw161283 void 440d39a76e7Sxw161283 CH_ERR(const char *fmt, ...) 441d39a76e7Sxw161283 { 442d39a76e7Sxw161283 va_list ap; 443d39a76e7Sxw161283 char buf[128]; 444d39a76e7Sxw161283 445d39a76e7Sxw161283 /* format buf using fmt and arguments contained in ap */ 446d39a76e7Sxw161283 447d39a76e7Sxw161283 va_start(ap, fmt); 448d39a76e7Sxw161283 (void) vsprintf(buf, fmt, ap); 449d39a76e7Sxw161283 va_end(ap); 450d39a76e7Sxw161283 451d39a76e7Sxw161283 /* pass formatted string to cmn_err(9F) */ 452d39a76e7Sxw161283 cmn_err(CE_WARN, "%s", buf); 453d39a76e7Sxw161283 } 454d39a76e7Sxw161283 455d39a76e7Sxw161283 u32 456d39a76e7Sxw161283 le32_to_cpu(u32 data) 457d39a76e7Sxw161283 { 458d39a76e7Sxw161283 #if BYTE_ORDER == BIG_ENDIAN 459d39a76e7Sxw161283 uint8_t *in, t; 460d39a76e7Sxw161283 in = (uint8_t *)&data; 461d39a76e7Sxw161283 t = in[0]; 462d39a76e7Sxw161283 in[0] = in[3]; 463d39a76e7Sxw161283 in[3] = t; 464d39a76e7Sxw161283 t = in[1]; 465d39a76e7Sxw161283 in[1] = in[2]; 466d39a76e7Sxw161283 in[2] = t; 467d39a76e7Sxw161283 #endif 468d39a76e7Sxw161283 return (data); 469d39a76e7Sxw161283 } 470d39a76e7Sxw161283 471d39a76e7Sxw161283 /* 472d39a76e7Sxw161283 * This function initializes a polling routine, Poll_func 473d39a76e7Sxw161283 * which will be polled ever N Microsecond, where N is 474d39a76e7Sxw161283 * provided in the cyclic start routine. 475d39a76e7Sxw161283 */ 476d39a76e7Sxw161283 /* ARGSUSED */ 477d39a76e7Sxw161283 void 478d39a76e7Sxw161283 ch_init_cyclic(void *adapter, p_ch_cyclic_t cyclic, 479d39a76e7Sxw161283 void (*poll_func)(void *), void *arg) 480d39a76e7Sxw161283 { 481d39a76e7Sxw161283 cyclic->func = poll_func; 482d39a76e7Sxw161283 cyclic->arg = arg; 483d39a76e7Sxw161283 cyclic->timer = 0; 484d39a76e7Sxw161283 } 485d39a76e7Sxw161283 486d39a76e7Sxw161283 /* 487d39a76e7Sxw161283 * Cyclic function which provides a periodic polling 488d39a76e7Sxw161283 * capability to Solaris. The poll function provided by 489d39a76e7Sxw161283 * the 'ch_init_cyclic' function is called from this 490d39a76e7Sxw161283 * here, and this routine launches a new one-shot 491d39a76e7Sxw161283 * timer to bring it back in some period later. 492d39a76e7Sxw161283 */ 493d39a76e7Sxw161283 void 494d39a76e7Sxw161283 ch_cyclic(p_ch_cyclic_t cyclic) 495d39a76e7Sxw161283 { 496d39a76e7Sxw161283 if (cyclic->timer != 0) { 497d39a76e7Sxw161283 cyclic->func(cyclic->arg); 498d39a76e7Sxw161283 cyclic->timer = timeout((void(*)(void *))ch_cyclic, 499d39a76e7Sxw161283 (void *)cyclic, cyclic->period); 500d39a76e7Sxw161283 } 501d39a76e7Sxw161283 } 502d39a76e7Sxw161283 503d39a76e7Sxw161283 /* 504d39a76e7Sxw161283 * The 'ch_start_cyclic' starts the polling. 505d39a76e7Sxw161283 */ 506d39a76e7Sxw161283 void 507d39a76e7Sxw161283 ch_start_cyclic(p_ch_cyclic_t cyclic, unsigned long period) 508d39a76e7Sxw161283 { 509d39a76e7Sxw161283 cyclic->period = drv_usectohz(period * 1000); 510d39a76e7Sxw161283 if (cyclic->timer == 0) { 511d39a76e7Sxw161283 cyclic->timer = timeout((void(*)(void *))ch_cyclic, 512d39a76e7Sxw161283 (void *)cyclic, cyclic->period); 513d39a76e7Sxw161283 } 514d39a76e7Sxw161283 } 515d39a76e7Sxw161283 516d39a76e7Sxw161283 /* 517d39a76e7Sxw161283 * The 'ch_stop_cyclic' stops the polling. 518d39a76e7Sxw161283 */ 519d39a76e7Sxw161283 void 520d39a76e7Sxw161283 ch_stop_cyclic(p_ch_cyclic_t cyclic) 521d39a76e7Sxw161283 { 522d39a76e7Sxw161283 timeout_id_t timer; 523d39a76e7Sxw161283 clock_t value; 524d39a76e7Sxw161283 525d39a76e7Sxw161283 do { 526d39a76e7Sxw161283 timer = cyclic->timer; 527d39a76e7Sxw161283 cyclic->timer = 0; 528d39a76e7Sxw161283 value = untimeout(timer); 529d39a76e7Sxw161283 if (value == 0) 530*19397407SSherry Moore drv_usecwait(drv_hztousec(2 * cyclic->period)); 531d39a76e7Sxw161283 } while ((timer != 0) && (value == 0)); 532d39a76e7Sxw161283 } 533