1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
7 * with the License.
8 *
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22 /*
23 * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26
27 #pragma ident "%Z%%M% %I% %E% SMI"
28
29 #include <sys/dada/dada.h>
30
31
32 /*
33 * Utility DADA routines
34 */
35
36
37 /*
38 * Polling support routines
39 */
40
41 extern uintptr_t dcd_callback_id;
42
43
44 #ifdef NOT_NEEDED
45 static int dcd_poll_busycnt = DCD_POLL_TIMEOUT;
46 #endif
47
48
49 /*
50 * Common buffer for dcd_lod
51 */
52
53 extern kmutex_t dcd_log_mutex;
54 static char dcd_log_buffer[256];
55
56
57 #define A_TO_TRAN(ap) (ap->a_hba_tran)
58 #define P_TO_TRAN(pkt) ((pkt)->pkt_address.a_hba_tran)
59 #define P_TO_ADDR(pkt) (&((pkt)->pkt_address))
60
61
62 #ifdef NOT_NEEDED
63 int
dcd_poll(struct dcd_pkt * pkt)64 dcd_poll(struct dcd_pkt *pkt)
65 {
66
67 register busy_count, rval = -1, savef;
68 clock_t savet;
69 void (*savec)();
70
71
72 /*
73 * Save old flags
74 */
75 savef = pkt->pkt_flags;
76 savec = pkt->pkt_comp;
77 savet = pkt->pkt_time;
78
79 pkt->pkt_flags |= FLAG_NOINTR;
80
81
82 /*
83 * Set the Pkt_comp to NULL
84 */
85
86 pkt->pkt_comp = 0;
87
88 /*
89 * Set the Pkt time for the polled command
90 */
91 if (pkt->pkt_time == 0) {
92 pkt->pkt_time = DCD_POLL_TIMEOUT;
93 }
94
95
96 /* Now transport the command */
97 for (busy_count = 0; busy_count < dcd_poll_busycnt; busy_count++) {
98 if (dcd_transport(pkt) != TRAN_ACCEPT) {
99 break;
100 }
101 if (pkt->pkt_reason == CMD_INCOMPLETE && pkt->pkt_state == 0) {
102 drv_usecwait(1000000);
103 } else if (pkt->pkt_reason != CMD_CMPLT) {
104 break;
105 } else if (((*pkt->pkt_scbp) & STATUS_ATA_MASK)
106 == STATUS_ATA_BUSY) {
107 drv_usecwait(1000000);
108 } else {
109 rval = 0;
110 break;
111 }
112 }
113
114 pkt->pkt_flags = savef;
115 pkt->pkt_comp = savec;
116 pkt->pkt_time = savet;
117 return (rval);
118 }
119 #endif
120
121
122 /*PRINTFLIKE4*/
123 void
dcd_log(dev_info_t * dev,char * label,uint_t level,const char * fmt,...)124 dcd_log(dev_info_t *dev, char *label, uint_t level, const char *fmt, ...)
125 {
126
127 auto char name[256];
128 va_list ap;
129 int log_only = 0;
130 int boot_only = 0;
131 int console_only = 0;
132
133
134 mutex_enter(&dcd_log_mutex);
135
136
137 if (dev) {
138
139 if (level == CE_PANIC || level == CE_WARN) {
140 (void) sprintf(name, "%s (%s%d):\n",
141 ddi_pathname(dev, dcd_log_buffer), label,
142 ddi_get_instance(dev));
143 } else if (level == CE_NOTE ||
144 level >= (uint_t)DCD_DEBUG) {
145 (void) sprintf(name, "%s%d:", label,
146 ddi_get_instance(dev));
147 } else if (level == CE_CONT) {
148 name[0] = '\0';
149 }
150 } else {
151 (void) sprintf(name, "%s:", label);
152 }
153
154
155 va_start(ap, fmt);
156 (void) vsprintf(dcd_log_buffer, fmt, ap);
157 va_end(ap);
158
159
160 switch (dcd_log_buffer[0]) {
161 case '!':
162 log_only = 1;
163 break;
164 case '?':
165 boot_only = 1;
166 break;
167 case '^':
168 console_only = 1;
169 break;
170 }
171
172 switch (level) {
173
174 case CE_NOTE:
175 level = CE_CONT;
176 /* FALLTHROUGH */
177 case CE_CONT:
178 case CE_WARN:
179 case CE_PANIC:
180 if (boot_only) {
181 cmn_err(level, "?%s\t%s", name,
182 &dcd_log_buffer[1]);
183 } else if (console_only) {
184 cmn_err(level, "^%s\t%s", name,
185 &dcd_log_buffer[1]);
186 } else if (log_only) {
187 cmn_err(level, "!%s\t%s", name,
188 &dcd_log_buffer[1]);
189 } else {
190 cmn_err(level, "%s\t%s", name,
191 dcd_log_buffer);
192 }
193 break;
194 case (uint_t)DCD_DEBUG:
195 default:
196 cmn_err(CE_CONT, "^DEBUG: %s\t%s\n", name,
197 dcd_log_buffer);
198 break;
199 }
200
201 mutex_exit(&dcd_log_mutex);
202 }
203