Print this page
5253 kmem_alloc/kmem_zalloc won't fail with KM_SLEEP
5254 getrbuf won't fail with KM_SLEEP
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/uts/common/io/beep.c
+++ new/usr/src/uts/common/io/beep.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
↓ open down ↓ |
15 lines elided |
↑ open up ↑ |
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21 /*
22 22 * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
23 23 * Use is subject to license terms.
24 24 */
25 25
26 -#pragma ident "%Z%%M% %I% %E% SMI"
27 -
28 26 /*
29 27 * This is the Beep module for supporting keyboard beep for keyboards
30 28 * that do not have the beeping feature within themselves
31 29 *
32 30 */
33 31
34 32 #include <sys/types.h>
35 33 #include <sys/conf.h>
36 34
37 35 #include <sys/ddi.h>
38 36 #include <sys/sunddi.h>
39 37 #include <sys/modctl.h>
40 38 #include <sys/ddi_impldefs.h>
41 39 #include <sys/kmem.h>
42 40
43 41 #include <sys/beep.h>
44 42 #include <sys/inttypes.h>
45 43
46 44 /*
47 45 * Debug stuff
48 46 * BEEP_DEBUG used for errors
49 47 * BEEP_DEBUG1 prints when beep_debug > 1 and used for normal messages
50 48 */
51 49 #ifdef DEBUG
52 50 int beep_debug = 0;
53 51 #define BEEP_DEBUG(args) if (beep_debug) cmn_err args
54 52 #define BEEP_DEBUG1(args) if (beep_debug > 1) cmn_err args
55 53 #else
56 54 #define BEEP_DEBUG(args)
57 55 #define BEEP_DEBUG1(args)
58 56 #endif
59 57
60 58 int beep_queue_size = BEEP_QUEUE_SIZE;
61 59
62 60 /*
63 61 * Note that mutex_init is not called on the mutex in beep_state,
64 62 * But assumes that zeroed memory does not need to call mutex_init,
65 63 * as documented in mutex.c
66 64 */
67 65
68 66 beep_state_t beep_state;
69 67
70 68 beep_params_t beep_params[] = {
71 69 {BEEP_CONSOLE, 900, 200},
72 70 {BEEP_TYPE4, 2000, 0},
73 71 {BEEP_DEFAULT, 1000, 200}, /* Must be last */
74 72 };
75 73
76 74
77 75 /*
78 76 * beep_init:
79 77 * Allocate the beep_queue structure
80 78 * Initialize beep_state structure
81 79 * Called from beep driver attach routine
82 80 */
83 81
84 82 int
85 83 beep_init(void *arg,
86 84 beep_on_func_t beep_on_func,
87 85 beep_off_func_t beep_off_func,
88 86 beep_freq_func_t beep_freq_func)
89 87 {
90 88 beep_entry_t *queue;
91 89
92 90 BEEP_DEBUG1((CE_CONT,
93 91 "beep_init(0x%lx, 0x%lx, 0x%lx, 0x%lx) : start.",
94 92 (unsigned long) arg,
95 93 (unsigned long) beep_on_func,
96 94 (unsigned long) beep_off_func,
97 95 (unsigned long) beep_freq_func));
98 96
99 97 mutex_enter(&beep_state.mutex);
100 98
101 99 if (beep_state.mode != BEEP_UNINIT) {
102 100 mutex_exit(&beep_state.mutex);
103 101 BEEP_DEBUG((CE_WARN,
104 102 "beep_init : beep_state already initialized."));
↓ open down ↓ |
67 lines elided |
↑ open up ↑ |
105 103 return (DDI_SUCCESS);
106 104 }
107 105
108 106 queue = kmem_zalloc(sizeof (beep_entry_t) * beep_queue_size,
109 107 KM_SLEEP);
110 108
111 109 BEEP_DEBUG1((CE_CONT,
112 110 "beep_init : beep_queue kmem_zalloc(%d) = 0x%lx.",
113 111 (int)sizeof (beep_entry_t) * beep_queue_size,
114 112 (unsigned long)queue));
115 -
116 - if (queue == NULL) {
117 - BEEP_DEBUG((CE_WARN,
118 - "beep_init : kmem_zalloc of beep_queue failed."));
119 - return (DDI_FAILURE);
120 - }
121 113
122 114 beep_state.arg = arg;
123 115 beep_state.mode = BEEP_OFF;
124 116 beep_state.beep_freq = beep_freq_func;
125 117 beep_state.beep_on = beep_on_func;
126 118 beep_state.beep_off = beep_off_func;
127 119 beep_state.timeout_id = 0;
128 120
129 121 beep_state.queue_head = 0;
130 122 beep_state.queue_tail = 0;
131 123 beep_state.queue_size = beep_queue_size;
132 124 beep_state.queue = queue;
133 125
134 126 mutex_exit(&beep_state.mutex);
135 127
136 128 BEEP_DEBUG1((CE_CONT, "beep_init : done."));
137 129 return (DDI_SUCCESS);
138 130 }
139 131
140 132
141 133 int
142 134 beep_fini(void)
143 135 {
144 136 BEEP_DEBUG1((CE_CONT, "beep_fini() : start."));
145 137
146 138 (void) beeper_off();
147 139
148 140 mutex_enter(&beep_state.mutex);
149 141
150 142 if (beep_state.mode == BEEP_UNINIT) {
151 143 mutex_exit(&beep_state.mutex);
152 144 BEEP_DEBUG((CE_WARN,
153 145 "beep_fini : beep_state already uninitialized."));
154 146 return (0);
155 147 }
156 148
157 149 if (beep_state.queue != NULL)
158 150 kmem_free(beep_state.queue,
159 151 sizeof (beep_entry_t) * beep_state.queue_size);
160 152
161 153 beep_state.arg = (void *)NULL;
162 154 beep_state.mode = BEEP_UNINIT;
163 155 beep_state.beep_freq = (beep_freq_func_t)NULL;
164 156 beep_state.beep_on = (beep_on_func_t)NULL;
165 157 beep_state.beep_off = (beep_off_func_t)NULL;
166 158 beep_state.timeout_id = 0;
167 159
168 160 beep_state.queue_head = 0;
169 161 beep_state.queue_tail = 0;
170 162 beep_state.queue_size = 0;
171 163 beep_state.queue = (beep_entry_t *)NULL;
172 164
173 165 mutex_exit(&beep_state.mutex);
174 166
175 167 BEEP_DEBUG1((CE_CONT, "beep_fini() : done."));
176 168
177 169 return (0);
178 170 }
179 171
180 172
181 173 int
182 174 beeper_off(void)
183 175 {
184 176 BEEP_DEBUG1((CE_CONT, "beeper_off : start."));
185 177
186 178 mutex_enter(&beep_state.mutex);
187 179
188 180 if (beep_state.mode == BEEP_UNINIT) {
189 181 mutex_exit(&beep_state.mutex);
190 182 return (ENXIO);
191 183 }
192 184
193 185 if (beep_state.mode == BEEP_TIMED) {
194 186 (void) untimeout(beep_state.timeout_id);
195 187 beep_state.timeout_id = 0;
196 188 }
197 189
198 190 if (beep_state.mode != BEEP_OFF) {
199 191 beep_state.mode = BEEP_OFF;
200 192
201 193 if (beep_state.beep_off != NULL)
202 194 (*beep_state.beep_off)(beep_state.arg);
203 195 }
204 196
205 197 beep_state.queue_head = 0;
206 198 beep_state.queue_tail = 0;
207 199
208 200 mutex_exit(&beep_state.mutex);
209 201
210 202 BEEP_DEBUG1((CE_CONT, "beeper_off : done."));
211 203
212 204 return (0);
213 205 }
214 206
215 207 int
216 208 beeper_freq(enum beep_type type, int freq)
217 209 {
218 210 beep_params_t *bp;
219 211
220 212 BEEP_DEBUG1((CE_CONT, "beeper_freq(%d, %d) : start", type, freq));
221 213
222 214 /*
223 215 * The frequency value is limited to the range of [0 - 32767]
224 216 */
225 217 if (freq < 0 || freq > INT16_MAX)
226 218 return (EINVAL);
227 219
228 220 for (bp = beep_params; bp->type != BEEP_DEFAULT; bp++) {
229 221 if (bp->type == type)
230 222 break;
231 223 }
232 224
233 225 if (bp->type != type) {
234 226 BEEP_DEBUG((CE_WARN, "beeper_freq : invalid type."));
235 227
236 228 return (EINVAL);
237 229 }
238 230
239 231 bp->frequency = freq;
240 232
241 233 BEEP_DEBUG1((CE_CONT, "beeper_freq : done."));
242 234 return (0);
243 235 }
244 236
245 237 /*
246 238 * beep :
247 239 * Start beeping for period specified by the type value,
248 240 * from the value in the beep_param structure in milliseconds.
249 241 */
250 242 int
251 243 beep(enum beep_type type)
252 244 {
253 245
254 246 beep_params_t *bp;
255 247
256 248 BEEP_DEBUG1((CE_CONT, "beep(%d) : start.", type));
257 249
258 250 for (bp = beep_params; bp->type != BEEP_DEFAULT; bp++) {
259 251 if (bp->type == type)
260 252 break;
261 253 }
262 254
263 255 if (bp->type != type) {
264 256
265 257 BEEP_DEBUG((CE_WARN, "beep : invalid type."));
266 258
267 259 /* If type doesn't match, return silently without beeping */
268 260 return (EINVAL);
269 261 }
270 262
271 263 return (beep_mktone(bp->frequency, bp->duration));
272 264 }
273 265
274 266
275 267 /*ARGSUSED*/
276 268 int
277 269 beep_polled(enum beep_type type)
278 270 {
279 271 /*
280 272 * No-op at this time.
281 273 *
282 274 * Don't think we can make this work in general, as tem_safe
283 275 * has a requirement of no mutexes, but kbd sends messages
284 276 * through streams.
285 277 */
286 278
287 279 BEEP_DEBUG1((CE_CONT, "beep_polled(%d)", type));
288 280
289 281 return (0);
290 282 }
291 283
292 284 /*
293 285 * beeper_on :
294 286 * Turn the beeper on
295 287 */
296 288 int
297 289 beeper_on(enum beep_type type)
298 290 {
299 291 beep_params_t *bp;
300 292 int status = 0;
301 293
302 294 BEEP_DEBUG1((CE_CONT, "beeper_on(%d) : start.", type));
303 295
304 296 for (bp = beep_params; bp->type != BEEP_DEFAULT; bp++) {
305 297 if (bp->type == type)
306 298 break;
307 299 }
308 300
309 301 if (bp->type != type) {
310 302
311 303 BEEP_DEBUG((CE_WARN, "beeper_on : invalid type."));
312 304
313 305 /* If type doesn't match, return silently without beeping */
314 306 return (EINVAL);
315 307 }
316 308
317 309 mutex_enter(&beep_state.mutex);
318 310
319 311 if (beep_state.mode == BEEP_UNINIT) {
320 312 status = ENXIO;
321 313
322 314 /* Start another beep only if the previous one is over */
323 315 } else if (beep_state.mode == BEEP_OFF) {
324 316 if (bp->frequency != 0) {
325 317 beep_state.mode = BEEP_ON;
326 318
327 319 if (beep_state.beep_freq != NULL)
328 320 (*beep_state.beep_freq)(beep_state.arg,
329 321 bp->frequency);
330 322
331 323 if (beep_state.beep_on != NULL)
332 324 (*beep_state.beep_on)(beep_state.arg);
333 325 }
334 326 } else {
335 327 status = EBUSY;
336 328 }
337 329
338 330 mutex_exit(&beep_state.mutex);
339 331
340 332 BEEP_DEBUG1((CE_CONT, "beeper_on : done, status %d.", status));
341 333
342 334 return (status);
343 335 }
344 336
345 337
346 338 int
347 339 beep_mktone(int frequency, int duration)
348 340 {
349 341 int next;
350 342 int status = 0;
351 343
352 344 BEEP_DEBUG1((CE_CONT, "beep_mktone(%d, %d) : start.", frequency,
353 345 duration));
354 346
355 347 /*
356 348 * The frequency value is limited to the range of [0 - 32767]
357 349 */
358 350 if (frequency < 0 || frequency > INT16_MAX)
359 351 return (EINVAL);
360 352
361 353 mutex_enter(&beep_state.mutex);
362 354
363 355 if (beep_state.mode == BEEP_UNINIT) {
364 356 status = ENXIO;
365 357
366 358 } else if (beep_state.mode == BEEP_TIMED) {
367 359
368 360 /* If already processing a beep, queue this one */
369 361
370 362 if (frequency != 0) {
371 363 next = beep_state.queue_tail + 1;
372 364 if (next == beep_state.queue_size)
373 365 next = 0;
374 366
375 367 if (next != beep_state.queue_head) {
376 368 /*
377 369 * If there is room in the queue,
378 370 * add this entry
379 371 */
380 372
381 373 beep_state.queue[beep_state.queue_tail].
382 374 frequency = (unsigned short)frequency;
383 375
384 376 beep_state.queue[beep_state.queue_tail].
385 377 duration = (unsigned short)duration;
386 378
387 379 beep_state.queue_tail = next;
388 380 } else {
389 381 status = EAGAIN;
390 382 }
391 383 }
392 384
393 385 } else if (beep_state.mode == BEEP_OFF) {
394 386
395 387 /* Start another beep only if the previous one is over */
396 388
397 389 if (frequency != 0) {
398 390 beep_state.mode = BEEP_TIMED;
399 391
400 392 if (beep_state.beep_freq != NULL)
401 393 (*beep_state.beep_freq)(beep_state.arg,
402 394 frequency);
403 395
404 396 if (beep_state.beep_on != NULL)
405 397 (*beep_state.beep_on)(beep_state.arg);
406 398
407 399 /*
408 400 * Set timeout for ending the beep after the
409 401 * specified time
410 402 */
411 403
412 404 beep_state.timeout_id = timeout(beep_timeout, NULL,
413 405 drv_usectohz(duration * 1000));
414 406 }
415 407 } else {
416 408 status = EBUSY;
417 409 }
418 410
419 411 mutex_exit(&beep_state.mutex);
420 412
421 413 BEEP_DEBUG1((CE_CONT, "beep_mktone : done, status %d.", status));
422 414
423 415 return (status);
424 416 }
425 417
426 418
427 419 /*
428 420 * Turn the beeper off which had been turned on from beep()
429 421 * for a specified period of time
430 422 */
431 423 /*ARGSUSED*/
432 424 void
433 425 beep_timeout(void *arg)
434 426 {
435 427 int frequency;
436 428 int duration;
437 429 int next;
438 430
439 431 BEEP_DEBUG1((CE_CONT, "beeper_timeout : start."));
440 432
441 433 mutex_enter(&beep_state.mutex);
442 434
443 435 beep_state.timeout_id = 0;
444 436
445 437 if (beep_state.mode == BEEP_UNINIT) {
446 438 mutex_exit(&beep_state.mutex);
447 439 BEEP_DEBUG1((CE_CONT, "beep_timeout : uninitialized."));
448 440 return;
449 441 }
450 442
451 443 if ((beep_state.mode == BEEP_ON) ||
452 444 (beep_state.mode == BEEP_TIMED)) {
453 445
454 446 beep_state.mode = BEEP_OFF;
455 447
456 448 if (beep_state.beep_off != NULL)
457 449 (*beep_state.beep_off)(beep_state.arg);
458 450 }
459 451
460 452 if (beep_state.queue_head != beep_state.queue_tail) {
461 453
462 454 next = beep_state.queue_head;
463 455
464 456 frequency = beep_state.queue[next].frequency;
465 457
466 458 duration = beep_state.queue[next].duration;
467 459
468 460 next++;
469 461 if (next == beep_state.queue_size)
470 462 next = 0;
471 463
472 464 beep_state.queue_head = next;
473 465
474 466 beep_state.mode = BEEP_TIMED;
475 467
476 468 if (frequency != 0) {
477 469 if (beep_state.beep_freq != NULL)
478 470 (*beep_state.beep_freq)(beep_state.arg,
479 471 frequency);
480 472
481 473 if (beep_state.beep_on != NULL)
482 474 (*beep_state.beep_on)(beep_state.arg);
483 475 }
484 476
485 477 /* Set timeout for ending the beep after the specified time */
486 478
487 479 beep_state.timeout_id = timeout(beep_timeout, NULL,
488 480 drv_usectohz(duration * 1000));
489 481 }
490 482
491 483 mutex_exit(&beep_state.mutex);
492 484
493 485 BEEP_DEBUG1((CE_CONT, "beep_timeout : done."));
494 486 }
495 487
496 488
497 489 /*
498 490 * Return true (1) if we are sounding a tone.
499 491 */
500 492 int
501 493 beep_busy(void)
502 494 {
503 495 int status;
504 496
505 497 BEEP_DEBUG1((CE_CONT, "beep_busy : start."));
506 498
507 499 mutex_enter(&beep_state.mutex);
508 500
509 501 status = beep_state.mode != BEEP_UNINIT &&
510 502 beep_state.mode != BEEP_OFF;
511 503
512 504 mutex_exit(&beep_state.mutex);
513 505
514 506 BEEP_DEBUG1((CE_CONT, "beep_busy : status %d.", status));
515 507
516 508 return (status);
517 509 }
↓ open down ↓ |
387 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX