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
t1_read_reg_4(ch_t * obj,uint32_t reg_val)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
t1_write_reg_4(ch_t * obj,uint32_t reg_val,uint32_t write_val)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
t1_os_pci_read_config_2(ch_t * obj,uint32_t reg,uint16_t * val)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
t1_os_pci_write_config_2(ch_t * obj,uint32_t reg,uint16_t val)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
t1_os_pci_read_config_4(ch_t * obj,uint32_t reg,uint32_t * val)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
t1_os_pci_write_config_4(ch_t * obj,uint32_t reg,uint32_t val)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 *
t1_os_malloc_wait_zero(size_t len)130d39a76e7Sxw161283 t1_os_malloc_wait_zero(size_t len)
131d39a76e7Sxw161283 {
132d39a76e7Sxw161283 return (kmem_zalloc(len, KM_SLEEP));
133d39a76e7Sxw161283 }
134d39a76e7Sxw161283
135d39a76e7Sxw161283 void
t1_os_free(void * adr,size_t len)136d39a76e7Sxw161283 t1_os_free(void *adr, size_t len)
137d39a76e7Sxw161283 {
138d39a76e7Sxw161283 kmem_free(adr, len);
139d39a76e7Sxw161283 }
140d39a76e7Sxw161283
141d39a76e7Sxw161283 int
t1_num_of_ports(ch_t * obj)142d39a76e7Sxw161283 t1_num_of_ports(ch_t *obj)
143d39a76e7Sxw161283 {
144d39a76e7Sxw161283 return (obj->config_data.num_of_ports);
145d39a76e7Sxw161283 }
146d39a76e7Sxw161283
147d39a76e7Sxw161283 /* ARGSUSED */
148d39a76e7Sxw161283 int
pe_os_mem_copy(ch_t * obj,void * dst,void * src,size_t len)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
pe_is_ring_buffer_enabled(ch_t * obj)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
pe_ioctl(ch_t * chp,queue_t * q,mblk_t * mp)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 *
pe_os_malloc_contig_wait_zero(ch_t * chp,size_t len,uint64_t * dma_addr,ulong_t * dh,ulong_t * ah,uint32_t flg)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
pe_os_free_contig(ch_t * obj,size_t len,void * addr,uint64_t dma_addr,ulong_t dh,ulong_t ah)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
t1_fatal_err(ch_t * adapter)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
CH_ALERT(const char * fmt,...)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
CH_WARN(const char * fmt,...)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
CH_ERR(const char * fmt,...)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
le32_to_cpu(u32 data)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
ch_init_cyclic(void * adapter,p_ch_cyclic_t cyclic,void (* poll_func)(void *),void * arg)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
ch_cyclic(p_ch_cyclic_t cyclic)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
ch_start_cyclic(p_ch_cyclic_t cyclic,unsigned long period)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
ch_stop_cyclic(p_ch_cyclic_t cyclic)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