Blame view
sound/core/info.c
23 KB
1da177e4c Linux-2.6.12-rc2 |
1 2 |
/* * Information interface for ALSA driver |
c1017a4cd [ALSA] Changed Ja... |
3 |
* Copyright (c) by Jaroslav Kysela <perex@perex.cz> |
1da177e4c Linux-2.6.12-rc2 |
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
* * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ |
1da177e4c Linux-2.6.12-rc2 |
21 |
#include <linux/init.h> |
1da177e4c Linux-2.6.12-rc2 |
22 |
#include <linux/time.h> |
27ac792ca PAGE_ALIGN(): cor... |
23 |
#include <linux/mm.h> |
5a0e3ad6a include cleanup: ... |
24 |
#include <linux/slab.h> |
1da177e4c Linux-2.6.12-rc2 |
25 |
#include <linux/smp_lock.h> |
543537bd9 [PATCH] create a ... |
26 |
#include <linux/string.h> |
1da177e4c Linux-2.6.12-rc2 |
27 28 29 30 31 |
#include <sound/core.h> #include <sound/minors.h> #include <sound/info.h> #include <sound/version.h> #include <linux/proc_fs.h> |
1a60d4c5a [ALSA] semaphore ... |
32 |
#include <linux/mutex.h> |
1da177e4c Linux-2.6.12-rc2 |
33 34 35 36 37 |
#include <stdarg.h> /* * */ |
e28563cce [ALSA] Optimize f... |
38 |
#ifdef CONFIG_PROC_FS |
1da177e4c Linux-2.6.12-rc2 |
39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
int snd_info_check_reserved_words(const char *str) { static char *reserved[] = { "version", "meminfo", "memdebug", "detect", "devices", "oss", "cards", "timers", "synth", "pcm", "seq", NULL }; char **xstr = reserved; while (*xstr) { if (!strcmp(*xstr, str)) return 0; xstr++; } if (!strncmp(str, "card", 4)) return 0; return 1; } |
1a60d4c5a [ALSA] semaphore ... |
67 |
static DEFINE_MUTEX(info_mutex); |
1da177e4c Linux-2.6.12-rc2 |
68 |
|
24c1f9318 [ALSA] Remove xxx... |
69 70 71 72 |
struct snd_info_private_data { struct snd_info_buffer *rbuffer; struct snd_info_buffer *wbuffer; struct snd_info_entry *entry; |
1da177e4c Linux-2.6.12-rc2 |
73 |
void *file_private_data; |
24c1f9318 [ALSA] Remove xxx... |
74 |
}; |
1da177e4c Linux-2.6.12-rc2 |
75 76 77 |
static int snd_info_version_init(void); static int snd_info_version_done(void); |
746d4a02e [ALSA] Fix discon... |
78 |
static void snd_info_disconnect(struct snd_info_entry *entry); |
1da177e4c Linux-2.6.12-rc2 |
79 |
|
7e4eeec8a [ALSA] Make buffe... |
80 81 82 83 84 85 86 |
/* resize the proc r/w buffer */ static int resize_info_buffer(struct snd_info_buffer *buffer, unsigned int nsize) { char *nbuf; nsize = PAGE_ALIGN(nsize); |
9983aa62c ALSA: info - Use ... |
87 |
nbuf = krealloc(buffer->buffer, nsize, GFP_KERNEL); |
7e4eeec8a [ALSA] Make buffe... |
88 89 |
if (! nbuf) return -ENOMEM; |
7e4eeec8a [ALSA] Make buffe... |
90 91 92 93 |
buffer->buffer = nbuf; buffer->len = nsize; return 0; } |
1da177e4c Linux-2.6.12-rc2 |
94 95 96 97 98 99 100 101 102 |
/** * snd_iprintf - printf on the procfs buffer * @buffer: the procfs buffer * @fmt: the printf format * * Outputs the string on the procfs buffer just like printf(). * * Returns the size of output string. */ |
4f7454a99 ALSA: Add const p... |
103 |
int snd_iprintf(struct snd_info_buffer *buffer, const char *fmt, ...) |
1da177e4c Linux-2.6.12-rc2 |
104 105 106 |
{ va_list args; int len, res; |
7e4eeec8a [ALSA] Make buffe... |
107 |
int err = 0; |
1da177e4c Linux-2.6.12-rc2 |
108 |
|
f001c3acf [ALSA] Insert mig... |
109 |
might_sleep(); |
1da177e4c Linux-2.6.12-rc2 |
110 111 112 113 |
if (buffer->stop || buffer->error) return 0; len = buffer->len - buffer->size; va_start(args, fmt); |
7e4eeec8a [ALSA] Make buffe... |
114 |
for (;;) { |
dbedca39f [ALSA] Fix re-use... |
115 116 117 118 |
va_list ap; va_copy(ap, args); res = vsnprintf(buffer->buffer + buffer->curr, len, fmt, ap); va_end(ap); |
7e4eeec8a [ALSA] Make buffe... |
119 120 121 122 123 124 |
if (res < len) break; err = resize_info_buffer(buffer, buffer->len + PAGE_SIZE); if (err < 0) break; len = buffer->len - buffer->size; |
1da177e4c Linux-2.6.12-rc2 |
125 |
} |
7e4eeec8a [ALSA] Make buffe... |
126 127 128 129 |
va_end(args); if (err < 0) return err; |
1da177e4c Linux-2.6.12-rc2 |
130 131 132 133 |
buffer->curr += res; buffer->size += res; return res; } |
c0d3fb39e [ALSA] Clean up E... |
134 |
EXPORT_SYMBOL(snd_iprintf); |
1da177e4c Linux-2.6.12-rc2 |
135 136 137 |
/* */ |
6581f4e74 [ALSA] Remove zer... |
138 139 |
static struct proc_dir_entry *snd_proc_root; struct snd_info_entry *snd_seq_root; |
c0d3fb39e [ALSA] Clean up E... |
140 |
EXPORT_SYMBOL(snd_seq_root); |
1da177e4c Linux-2.6.12-rc2 |
141 |
#ifdef CONFIG_SND_OSSEMUL |
6581f4e74 [ALSA] Remove zer... |
142 |
struct snd_info_entry *snd_oss_root; |
1da177e4c Linux-2.6.12-rc2 |
143 |
#endif |
1da177e4c Linux-2.6.12-rc2 |
144 145 146 147 148 149 150 151 152 |
static void snd_remove_proc_entry(struct proc_dir_entry *parent, struct proc_dir_entry *de) { if (de) remove_proc_entry(de->name, parent); } static loff_t snd_info_entry_llseek(struct file *file, loff_t offset, int orig) { |
24c1f9318 [ALSA] Remove xxx... |
153 |
struct snd_info_private_data *data; |
1da177e4c Linux-2.6.12-rc2 |
154 |
struct snd_info_entry *entry; |
73029e0ff ALSA: info - Impl... |
155 |
loff_t ret = -EINVAL, size; |
1da177e4c Linux-2.6.12-rc2 |
156 157 158 |
data = file->private_data; entry = data->entry; |
5b5cd553e ALSA: info - Remo... |
159 |
mutex_lock(&entry->access); |
73029e0ff ALSA: info - Impl... |
160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 |
if (entry->content == SNDRV_INFO_CONTENT_DATA && entry->c.ops->llseek) { offset = entry->c.ops->llseek(entry, data->file_private_data, file, offset, orig); goto out; } if (entry->content == SNDRV_INFO_CONTENT_DATA) size = entry->size; else size = 0; switch (orig) { case SEEK_SET: break; case SEEK_CUR: offset += file->f_pos; |
1da177e4c Linux-2.6.12-rc2 |
176 |
break; |
73029e0ff ALSA: info - Impl... |
177 178 |
case SEEK_END: if (!size) |
1da177e4c Linux-2.6.12-rc2 |
179 |
goto out; |
73029e0ff ALSA: info - Impl... |
180 |
offset += size; |
1da177e4c Linux-2.6.12-rc2 |
181 |
break; |
73029e0ff ALSA: info - Impl... |
182 183 |
default: goto out; |
1da177e4c Linux-2.6.12-rc2 |
184 |
} |
73029e0ff ALSA: info - Impl... |
185 186 187 188 189 190 191 |
if (offset < 0) goto out; if (size && offset > size) offset = size; file->f_pos = offset; ret = offset; out: |
5b5cd553e ALSA: info - Remo... |
192 |
mutex_unlock(&entry->access); |
1da177e4c Linux-2.6.12-rc2 |
193 194 195 196 197 198 |
return ret; } static ssize_t snd_info_entry_read(struct file *file, char __user *buffer, size_t count, loff_t * offset) { |
24c1f9318 [ALSA] Remove xxx... |
199 |
struct snd_info_private_data *data; |
1da177e4c Linux-2.6.12-rc2 |
200 |
struct snd_info_entry *entry; |
24c1f9318 [ALSA] Remove xxx... |
201 |
struct snd_info_buffer *buf; |
1da177e4c Linux-2.6.12-rc2 |
202 203 204 205 |
size_t size = 0; loff_t pos; data = file->private_data; |
7eaa943c8 ALSA: Kill snd_as... |
206 207 |
if (snd_BUG_ON(!data)) return -ENXIO; |
1da177e4c Linux-2.6.12-rc2 |
208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 |
pos = *offset; if (pos < 0 || (long) pos != pos || (ssize_t) count < 0) return -EIO; if ((unsigned long) pos + (unsigned long) count < (unsigned long) pos) return -EIO; entry = data->entry; switch (entry->content) { case SNDRV_INFO_CONTENT_TEXT: buf = data->rbuffer; if (buf == NULL) return -EIO; if (pos >= buf->size) return 0; size = buf->size - pos; size = min(count, size); if (copy_to_user(buffer, buf->buffer + pos, size)) return -EFAULT; break; case SNDRV_INFO_CONTENT_DATA: |
d97e1b782 ALSA: info - Chec... |
227 228 229 230 231 |
if (pos >= entry->size) return 0; if (entry->c.ops->read) { size = entry->size - pos; size = min(count, size); |
1da177e4c Linux-2.6.12-rc2 |
232 233 |
size = entry->c.ops->read(entry, data->file_private_data, |
d97e1b782 ALSA: info - Chec... |
234 235 |
file, buffer, size, pos); } |
1da177e4c Linux-2.6.12-rc2 |
236 237 238 239 240 241 242 243 244 245 |
break; } if ((ssize_t) size > 0) *offset = pos + size; return size; } static ssize_t snd_info_entry_write(struct file *file, const char __user *buffer, size_t count, loff_t * offset) { |
24c1f9318 [ALSA] Remove xxx... |
246 |
struct snd_info_private_data *data; |
1da177e4c Linux-2.6.12-rc2 |
247 |
struct snd_info_entry *entry; |
24c1f9318 [ALSA] Remove xxx... |
248 |
struct snd_info_buffer *buf; |
7e4eeec8a [ALSA] Make buffe... |
249 |
ssize_t size = 0; |
1da177e4c Linux-2.6.12-rc2 |
250 251 252 |
loff_t pos; data = file->private_data; |
7eaa943c8 ALSA: Kill snd_as... |
253 254 |
if (snd_BUG_ON(!data)) return -ENXIO; |
1da177e4c Linux-2.6.12-rc2 |
255 256 257 258 259 260 261 262 263 264 265 |
entry = data->entry; pos = *offset; if (pos < 0 || (long) pos != pos || (ssize_t) count < 0) return -EIO; if ((unsigned long) pos + (unsigned long) count < (unsigned long) pos) return -EIO; switch (entry->content) { case SNDRV_INFO_CONTENT_TEXT: buf = data->wbuffer; if (buf == NULL) return -EIO; |
f4a747f15 [ALSA] fix a wron... |
266 |
mutex_lock(&entry->access); |
7e4eeec8a [ALSA] Make buffe... |
267 268 269 270 271 272 273 274 |
if (pos + count >= buf->len) { if (resize_info_buffer(buf, pos + count)) { mutex_unlock(&entry->access); return -ENOMEM; } } if (copy_from_user(buf->buffer + pos, buffer, count)) { mutex_unlock(&entry->access); |
1da177e4c Linux-2.6.12-rc2 |
275 |
return -EFAULT; |
7e4eeec8a [ALSA] Make buffe... |
276 277 278 279 |
} buf->size = pos + count; mutex_unlock(&entry->access); size = count; |
1da177e4c Linux-2.6.12-rc2 |
280 281 |
break; case SNDRV_INFO_CONTENT_DATA: |
d97e1b782 ALSA: info - Chec... |
282 283 284 |
if (entry->c.ops->write && count > 0) { size_t maxsize = entry->size - pos; count = min(count, maxsize); |
1da177e4c Linux-2.6.12-rc2 |
285 286 287 |
size = entry->c.ops->write(entry, data->file_private_data, file, buffer, count, pos); |
d97e1b782 ALSA: info - Chec... |
288 |
} |
1da177e4c Linux-2.6.12-rc2 |
289 290 291 292 293 294 295 296 297 |
break; } if ((ssize_t) size > 0) *offset = pos + size; return size; } static int snd_info_entry_open(struct inode *inode, struct file *file) { |
24c1f9318 [ALSA] Remove xxx... |
298 299 300 |
struct snd_info_entry *entry; struct snd_info_private_data *data; struct snd_info_buffer *buffer; |
1da177e4c Linux-2.6.12-rc2 |
301 302 |
struct proc_dir_entry *p; int mode, err; |
1a60d4c5a [ALSA] semaphore ... |
303 |
mutex_lock(&info_mutex); |
1da177e4c Linux-2.6.12-rc2 |
304 |
p = PDE(inode); |
24c1f9318 [ALSA] Remove xxx... |
305 |
entry = p == NULL ? NULL : (struct snd_info_entry *)p->data; |
746d4a02e [ALSA] Fix discon... |
306 |
if (entry == NULL || ! entry->p) { |
1a60d4c5a [ALSA] semaphore ... |
307 |
mutex_unlock(&info_mutex); |
1da177e4c Linux-2.6.12-rc2 |
308 309 310 311 312 313 314 315 |
return -ENODEV; } if (!try_module_get(entry->module)) { err = -EFAULT; goto __error1; } mode = file->f_flags & O_ACCMODE; if (mode == O_RDONLY || mode == O_RDWR) { |
7e4eeec8a [ALSA] Make buffe... |
316 |
if ((entry->content == SNDRV_INFO_CONTENT_DATA && |
1da177e4c Linux-2.6.12-rc2 |
317 318 319 320 321 322 |
entry->c.ops->read == NULL)) { err = -ENODEV; goto __error; } } if (mode == O_WRONLY || mode == O_RDWR) { |
7e4eeec8a [ALSA] Make buffe... |
323 |
if ((entry->content == SNDRV_INFO_CONTENT_DATA && |
1da177e4c Linux-2.6.12-rc2 |
324 325 326 327 328 |
entry->c.ops->write == NULL)) { err = -ENODEV; goto __error; } } |
ca2c09665 [ALSA] Replace wi... |
329 |
data = kzalloc(sizeof(*data), GFP_KERNEL); |
1da177e4c Linux-2.6.12-rc2 |
330 331 332 333 334 335 336 337 |
if (data == NULL) { err = -ENOMEM; goto __error; } data->entry = entry; switch (entry->content) { case SNDRV_INFO_CONTENT_TEXT: if (mode == O_RDONLY || mode == O_RDWR) { |
ca2c09665 [ALSA] Replace wi... |
338 |
buffer = kzalloc(sizeof(*buffer), GFP_KERNEL); |
7e4eeec8a [ALSA] Make buffe... |
339 340 |
if (buffer == NULL) goto __nomem; |
1da177e4c Linux-2.6.12-rc2 |
341 |
data->rbuffer = buffer; |
7e4eeec8a [ALSA] Make buffe... |
342 343 344 345 |
buffer->len = PAGE_SIZE; buffer->buffer = kmalloc(buffer->len, GFP_KERNEL); if (buffer->buffer == NULL) goto __nomem; |
1da177e4c Linux-2.6.12-rc2 |
346 347 |
} if (mode == O_WRONLY || mode == O_RDWR) { |
ca2c09665 [ALSA] Replace wi... |
348 |
buffer = kzalloc(sizeof(*buffer), GFP_KERNEL); |
7e4eeec8a [ALSA] Make buffe... |
349 350 |
if (buffer == NULL) goto __nomem; |
1da177e4c Linux-2.6.12-rc2 |
351 |
data->wbuffer = buffer; |
7e4eeec8a [ALSA] Make buffe... |
352 353 354 355 |
buffer->len = PAGE_SIZE; buffer->buffer = kmalloc(buffer->len, GFP_KERNEL); if (buffer->buffer == NULL) goto __nomem; |
1da177e4c Linux-2.6.12-rc2 |
356 357 358 359 360 361 362 363 364 365 366 367 368 |
} break; case SNDRV_INFO_CONTENT_DATA: /* data */ if (entry->c.ops->open) { if ((err = entry->c.ops->open(entry, mode, &data->file_private_data)) < 0) { kfree(data); goto __error; } } break; } file->private_data = data; |
1a60d4c5a [ALSA] semaphore ... |
369 |
mutex_unlock(&info_mutex); |
1da177e4c Linux-2.6.12-rc2 |
370 371 372 |
if (entry->content == SNDRV_INFO_CONTENT_TEXT && (mode == O_RDONLY || mode == O_RDWR)) { if (entry->c.text.read) { |
1a60d4c5a [ALSA] semaphore ... |
373 |
mutex_lock(&entry->access); |
1da177e4c Linux-2.6.12-rc2 |
374 |
entry->c.text.read(entry, data->rbuffer); |
1a60d4c5a [ALSA] semaphore ... |
375 |
mutex_unlock(&entry->access); |
1da177e4c Linux-2.6.12-rc2 |
376 377 378 |
} } return 0; |
7e4eeec8a [ALSA] Make buffe... |
379 380 381 382 383 384 385 386 387 388 389 |
__nomem: if (data->rbuffer) { kfree(data->rbuffer->buffer); kfree(data->rbuffer); } if (data->wbuffer) { kfree(data->wbuffer->buffer); kfree(data->wbuffer); } kfree(data); err = -ENOMEM; |
1da177e4c Linux-2.6.12-rc2 |
390 391 392 |
__error: module_put(entry->module); __error1: |
1a60d4c5a [ALSA] semaphore ... |
393 |
mutex_unlock(&info_mutex); |
1da177e4c Linux-2.6.12-rc2 |
394 395 396 397 398 |
return err; } static int snd_info_entry_release(struct inode *inode, struct file *file) { |
24c1f9318 [ALSA] Remove xxx... |
399 400 |
struct snd_info_entry *entry; struct snd_info_private_data *data; |
1da177e4c Linux-2.6.12-rc2 |
401 402 403 404 405 406 407 |
int mode; mode = file->f_flags & O_ACCMODE; data = file->private_data; entry = data->entry; switch (entry->content) { case SNDRV_INFO_CONTENT_TEXT: |
7e4eeec8a [ALSA] Make buffe... |
408 409 |
if (data->rbuffer) { kfree(data->rbuffer->buffer); |
1da177e4c Linux-2.6.12-rc2 |
410 411 |
kfree(data->rbuffer); } |
7e4eeec8a [ALSA] Make buffe... |
412 |
if (data->wbuffer) { |
1da177e4c Linux-2.6.12-rc2 |
413 414 415 416 417 418 419 420 421 |
if (entry->c.text.write) { entry->c.text.write(entry, data->wbuffer); if (data->wbuffer->error) { snd_printk(KERN_WARNING "data write error to %s (%i) ", entry->name, data->wbuffer->error); } } |
7e4eeec8a [ALSA] Make buffe... |
422 |
kfree(data->wbuffer->buffer); |
1da177e4c Linux-2.6.12-rc2 |
423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 |
kfree(data->wbuffer); } break; case SNDRV_INFO_CONTENT_DATA: if (entry->c.ops->release) entry->c.ops->release(entry, mode, data->file_private_data); break; } module_put(entry->module); kfree(data); return 0; } static unsigned int snd_info_entry_poll(struct file *file, poll_table * wait) { |
24c1f9318 [ALSA] Remove xxx... |
439 |
struct snd_info_private_data *data; |
1da177e4c Linux-2.6.12-rc2 |
440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 |
struct snd_info_entry *entry; unsigned int mask; data = file->private_data; if (data == NULL) return 0; entry = data->entry; mask = 0; switch (entry->content) { case SNDRV_INFO_CONTENT_DATA: if (entry->c.ops->poll) return entry->c.ops->poll(entry, data->file_private_data, file, wait); if (entry->c.ops->read) mask |= POLLIN | POLLRDNORM; if (entry->c.ops->write) mask |= POLLOUT | POLLWRNORM; break; } return mask; } |
d99e98891 [ALSA] Remove BKL... |
462 463 |
static long snd_info_entry_ioctl(struct file *file, unsigned int cmd, unsigned long arg) |
1da177e4c Linux-2.6.12-rc2 |
464 |
{ |
24c1f9318 [ALSA] Remove xxx... |
465 |
struct snd_info_private_data *data; |
1da177e4c Linux-2.6.12-rc2 |
466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 |
struct snd_info_entry *entry; data = file->private_data; if (data == NULL) return 0; entry = data->entry; switch (entry->content) { case SNDRV_INFO_CONTENT_DATA: if (entry->c.ops->ioctl) return entry->c.ops->ioctl(entry, data->file_private_data, file, cmd, arg); break; } return -ENOTTY; } |
1da177e4c Linux-2.6.12-rc2 |
482 483 |
static int snd_info_entry_mmap(struct file *file, struct vm_area_struct *vma) { |
7bc563239 [PATCH] struct pa... |
484 |
struct inode *inode = file->f_path.dentry->d_inode; |
24c1f9318 [ALSA] Remove xxx... |
485 |
struct snd_info_private_data *data; |
1da177e4c Linux-2.6.12-rc2 |
486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 |
struct snd_info_entry *entry; data = file->private_data; if (data == NULL) return 0; entry = data->entry; switch (entry->content) { case SNDRV_INFO_CONTENT_DATA: if (entry->c.ops->mmap) return entry->c.ops->mmap(entry, data->file_private_data, inode, file, vma); break; } return -ENXIO; } |
9c2e08c59 [PATCH] mark stru... |
502 |
static const struct file_operations snd_info_entry_operations = |
1da177e4c Linux-2.6.12-rc2 |
503 |
{ |
d99e98891 [ALSA] Remove BKL... |
504 505 506 507 508 509 510 511 512 |
.owner = THIS_MODULE, .llseek = snd_info_entry_llseek, .read = snd_info_entry_read, .write = snd_info_entry_write, .poll = snd_info_entry_poll, .unlocked_ioctl = snd_info_entry_ioctl, .mmap = snd_info_entry_mmap, .open = snd_info_entry_open, .release = snd_info_entry_release, |
1da177e4c Linux-2.6.12-rc2 |
513 |
}; |
1da177e4c Linux-2.6.12-rc2 |
514 515 516 |
int __init snd_info_init(void) { struct proc_dir_entry *p; |
99b762338 proc 2/2: remove ... |
517 |
p = create_proc_entry("asound", S_IFDIR | S_IRUGO | S_IXUGO, NULL); |
1da177e4c Linux-2.6.12-rc2 |
518 519 520 521 522 |
if (p == NULL) return -ENOMEM; snd_proc_root = p; #ifdef CONFIG_SND_OSSEMUL { |
24c1f9318 [ALSA] Remove xxx... |
523 |
struct snd_info_entry *entry; |
1da177e4c Linux-2.6.12-rc2 |
524 525 526 527 528 529 530 531 532 533 534 535 |
if ((entry = snd_info_create_module_entry(THIS_MODULE, "oss", NULL)) == NULL) return -ENOMEM; entry->mode = S_IFDIR | S_IRUGO | S_IXUGO; if (snd_info_register(entry) < 0) { snd_info_free_entry(entry); return -ENOMEM; } snd_oss_root = entry; } #endif #if defined(CONFIG_SND_SEQUENCER) || defined(CONFIG_SND_SEQUENCER_MODULE) { |
24c1f9318 [ALSA] Remove xxx... |
536 |
struct snd_info_entry *entry; |
1da177e4c Linux-2.6.12-rc2 |
537 538 539 540 541 542 543 544 545 546 547 |
if ((entry = snd_info_create_module_entry(THIS_MODULE, "seq", NULL)) == NULL) return -ENOMEM; entry->mode = S_IFDIR | S_IRUGO | S_IXUGO; if (snd_info_register(entry) < 0) { snd_info_free_entry(entry); return -ENOMEM; } snd_seq_root = entry; } #endif snd_info_version_init(); |
1da177e4c Linux-2.6.12-rc2 |
548 549 550 551 552 553 554 555 556 557 558 |
snd_minor_info_init(); snd_minor_info_oss_init(); snd_card_info_init(); return 0; } int __exit snd_info_done(void) { snd_card_info_done(); snd_minor_info_oss_done(); snd_minor_info_done(); |
1da177e4c Linux-2.6.12-rc2 |
559 560 561 |
snd_info_version_done(); if (snd_proc_root) { #if defined(CONFIG_SND_SEQUENCER) || defined(CONFIG_SND_SEQUENCER_MODULE) |
746d4a02e [ALSA] Fix discon... |
562 |
snd_info_free_entry(snd_seq_root); |
1da177e4c Linux-2.6.12-rc2 |
563 564 |
#endif #ifdef CONFIG_SND_OSSEMUL |
746d4a02e [ALSA] Fix discon... |
565 |
snd_info_free_entry(snd_oss_root); |
1da177e4c Linux-2.6.12-rc2 |
566 |
#endif |
c74c120a2 proc: remove proc... |
567 |
snd_remove_proc_entry(NULL, snd_proc_root); |
1da177e4c Linux-2.6.12-rc2 |
568 569 570 571 572 573 574 575 576 577 578 579 580 |
} return 0; } /* */ /* * create a card proc file * called from init.c */ |
24c1f9318 [ALSA] Remove xxx... |
581 |
int snd_info_card_create(struct snd_card *card) |
1da177e4c Linux-2.6.12-rc2 |
582 583 |
{ char str[8]; |
24c1f9318 [ALSA] Remove xxx... |
584 |
struct snd_info_entry *entry; |
1da177e4c Linux-2.6.12-rc2 |
585 |
|
7eaa943c8 ALSA: Kill snd_as... |
586 587 |
if (snd_BUG_ON(!card)) return -ENXIO; |
1da177e4c Linux-2.6.12-rc2 |
588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 |
sprintf(str, "card%i", card->number); if ((entry = snd_info_create_module_entry(card->module, str, NULL)) == NULL) return -ENOMEM; entry->mode = S_IFDIR | S_IRUGO | S_IXUGO; if (snd_info_register(entry) < 0) { snd_info_free_entry(entry); return -ENOMEM; } card->proc_root = entry; return 0; } /* * register the card proc file * called from init.c */ |
24c1f9318 [ALSA] Remove xxx... |
605 |
int snd_info_card_register(struct snd_card *card) |
1da177e4c Linux-2.6.12-rc2 |
606 607 |
{ struct proc_dir_entry *p; |
7eaa943c8 ALSA: Kill snd_as... |
608 609 |
if (snd_BUG_ON(!card)) return -ENXIO; |
1da177e4c Linux-2.6.12-rc2 |
610 611 612 613 614 615 616 617 618 619 620 621 |
if (!strcmp(card->id, card->proc_root->name)) return 0; p = proc_symlink(card->id, snd_proc_root, card->proc_root->name); if (p == NULL) return -ENOMEM; card->proc_root_link = p; return 0; } /* |
c2eb9c4ea ALSA: when card i... |
622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 |
* called on card->id change */ void snd_info_card_id_change(struct snd_card *card) { mutex_lock(&info_mutex); if (card->proc_root_link) { snd_remove_proc_entry(snd_proc_root, card->proc_root_link); card->proc_root_link = NULL; } if (strcmp(card->id, card->proc_root->name)) card->proc_root_link = proc_symlink(card->id, snd_proc_root, card->proc_root->name); mutex_unlock(&info_mutex); } /* |
1da177e4c Linux-2.6.12-rc2 |
639 640 641 |
* de-register the card proc file * called from init.c */ |
746d4a02e [ALSA] Fix discon... |
642 |
void snd_info_card_disconnect(struct snd_card *card) |
1da177e4c Linux-2.6.12-rc2 |
643 |
{ |
7eaa943c8 ALSA: Kill snd_as... |
644 645 |
if (!card) return; |
746d4a02e [ALSA] Fix discon... |
646 |
mutex_lock(&info_mutex); |
1da177e4c Linux-2.6.12-rc2 |
647 648 649 650 |
if (card->proc_root_link) { snd_remove_proc_entry(snd_proc_root, card->proc_root_link); card->proc_root_link = NULL; } |
746d4a02e [ALSA] Fix discon... |
651 652 653 654 655 656 657 658 659 660 661 |
if (card->proc_root) snd_info_disconnect(card->proc_root); mutex_unlock(&info_mutex); } /* * release the card proc file resources * called from init.c */ int snd_info_card_free(struct snd_card *card) { |
7eaa943c8 ALSA: Kill snd_as... |
662 663 |
if (!card) return 0; |
746d4a02e [ALSA] Fix discon... |
664 665 |
snd_info_free_entry(card->proc_root); card->proc_root = NULL; |
1da177e4c Linux-2.6.12-rc2 |
666 667 668 669 670 671 672 673 674 675 676 677 678 679 |
return 0; } /** * snd_info_get_line - read one line from the procfs buffer * @buffer: the procfs buffer * @line: the buffer to store * @len: the max. buffer size - 1 * * Reads one line from the buffer and stores the string. * * Returns zero if successful, or 1 if error or EOF. */ |
24c1f9318 [ALSA] Remove xxx... |
680 |
int snd_info_get_line(struct snd_info_buffer *buffer, char *line, int len) |
1da177e4c Linux-2.6.12-rc2 |
681 682 683 684 685 686 |
{ int c = -1; if (len <= 0 || buffer->stop || buffer->error) return 1; while (--len > 0) { |
7e4eeec8a [ALSA] Make buffe... |
687 |
c = buffer->buffer[buffer->curr++]; |
1da177e4c Linux-2.6.12-rc2 |
688 689 |
if (c == ' ') { |
7e4eeec8a [ALSA] Make buffe... |
690 |
if (buffer->curr >= buffer->size) |
1da177e4c Linux-2.6.12-rc2 |
691 |
buffer->stop = 1; |
1da177e4c Linux-2.6.12-rc2 |
692 693 694 |
break; } *line++ = c; |
7e4eeec8a [ALSA] Make buffe... |
695 |
if (buffer->curr >= buffer->size) { |
1da177e4c Linux-2.6.12-rc2 |
696 697 698 699 700 701 |
buffer->stop = 1; break; } } while (c != ' ' && !buffer->stop) { |
7e4eeec8a [ALSA] Make buffe... |
702 703 |
c = buffer->buffer[buffer->curr++]; if (buffer->curr >= buffer->size) |
1da177e4c Linux-2.6.12-rc2 |
704 |
buffer->stop = 1; |
1da177e4c Linux-2.6.12-rc2 |
705 706 707 708 |
} *line = '\0'; return 0; } |
c0d3fb39e [ALSA] Clean up E... |
709 |
EXPORT_SYMBOL(snd_info_get_line); |
1da177e4c Linux-2.6.12-rc2 |
710 |
/** |
856def8a4 [ALSA] typo-fix a... |
711 |
* snd_info_get_str - parse a string token |
1da177e4c Linux-2.6.12-rc2 |
712 713 714 715 716 717 718 719 720 721 |
* @dest: the buffer to store the string token * @src: the original string * @len: the max. length of token - 1 * * Parses the original string and copy a token to the given * string buffer. * * Returns the updated pointer of the original string so that * it can be used for the next call. */ |
4f7454a99 ALSA: Add const p... |
722 |
const char *snd_info_get_str(char *dest, const char *src, int len) |
1da177e4c Linux-2.6.12-rc2 |
723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 |
{ int c; while (*src == ' ' || *src == '\t') src++; if (*src == '"' || *src == '\'') { c = *src++; while (--len > 0 && *src && *src != c) { *dest++ = *src++; } if (*src == c) src++; } else { while (--len > 0 && *src && *src != ' ' && *src != '\t') { *dest++ = *src++; } } *dest = 0; while (*src == ' ' || *src == '\t') src++; return src; } |
c0d3fb39e [ALSA] Clean up E... |
745 |
EXPORT_SYMBOL(snd_info_get_str); |
1da177e4c Linux-2.6.12-rc2 |
746 747 748 749 750 751 752 753 754 755 756 757 |
/** * snd_info_create_entry - create an info entry * @name: the proc file name * * Creates an info entry with the given file name and initializes as * the default state. * * Usually called from other functions such as * snd_info_create_card_entry(). * * Returns the pointer of the new instance, or NULL on failure. */ |
24c1f9318 [ALSA] Remove xxx... |
758 |
static struct snd_info_entry *snd_info_create_entry(const char *name) |
1da177e4c Linux-2.6.12-rc2 |
759 |
{ |
24c1f9318 [ALSA] Remove xxx... |
760 |
struct snd_info_entry *entry; |
ca2c09665 [ALSA] Replace wi... |
761 |
entry = kzalloc(sizeof(*entry), GFP_KERNEL); |
1da177e4c Linux-2.6.12-rc2 |
762 763 |
if (entry == NULL) return NULL; |
543537bd9 [PATCH] create a ... |
764 |
entry->name = kstrdup(name, GFP_KERNEL); |
1da177e4c Linux-2.6.12-rc2 |
765 766 767 768 769 770 |
if (entry->name == NULL) { kfree(entry); return NULL; } entry->mode = S_IFREG | S_IRUGO; entry->content = SNDRV_INFO_CONTENT_TEXT; |
1a60d4c5a [ALSA] semaphore ... |
771 |
mutex_init(&entry->access); |
746d4a02e [ALSA] Fix discon... |
772 773 |
INIT_LIST_HEAD(&entry->children); INIT_LIST_HEAD(&entry->list); |
1da177e4c Linux-2.6.12-rc2 |
774 775 776 777 778 779 780 781 782 783 784 785 786 |
return entry; } /** * snd_info_create_module_entry - create an info entry for the given module * @module: the module pointer * @name: the file name * @parent: the parent directory * * Creates a new info entry and assigns it to the given module. * * Returns the pointer of the new instance, or NULL on failure. */ |
24c1f9318 [ALSA] Remove xxx... |
787 |
struct snd_info_entry *snd_info_create_module_entry(struct module * module, |
1da177e4c Linux-2.6.12-rc2 |
788 |
const char *name, |
24c1f9318 [ALSA] Remove xxx... |
789 |
struct snd_info_entry *parent) |
1da177e4c Linux-2.6.12-rc2 |
790 |
{ |
24c1f9318 [ALSA] Remove xxx... |
791 |
struct snd_info_entry *entry = snd_info_create_entry(name); |
1da177e4c Linux-2.6.12-rc2 |
792 793 794 795 796 797 |
if (entry) { entry->module = module; entry->parent = parent; } return entry; } |
c0d3fb39e [ALSA] Clean up E... |
798 |
EXPORT_SYMBOL(snd_info_create_module_entry); |
1da177e4c Linux-2.6.12-rc2 |
799 800 801 802 803 804 805 806 807 808 |
/** * snd_info_create_card_entry - create an info entry for the given card * @card: the card instance * @name: the file name * @parent: the parent directory * * Creates a new info entry and assigns it to the given card. * * Returns the pointer of the new instance, or NULL on failure. */ |
24c1f9318 [ALSA] Remove xxx... |
809 |
struct snd_info_entry *snd_info_create_card_entry(struct snd_card *card, |
1da177e4c Linux-2.6.12-rc2 |
810 |
const char *name, |
24c1f9318 [ALSA] Remove xxx... |
811 |
struct snd_info_entry * parent) |
1da177e4c Linux-2.6.12-rc2 |
812 |
{ |
24c1f9318 [ALSA] Remove xxx... |
813 |
struct snd_info_entry *entry = snd_info_create_entry(name); |
1da177e4c Linux-2.6.12-rc2 |
814 815 816 817 818 819 820 |
if (entry) { entry->module = card->module; entry->card = card; entry->parent = parent; } return entry; } |
c0d3fb39e [ALSA] Clean up E... |
821 |
EXPORT_SYMBOL(snd_info_create_card_entry); |
746d4a02e [ALSA] Fix discon... |
822 |
static void snd_info_disconnect(struct snd_info_entry *entry) |
1da177e4c Linux-2.6.12-rc2 |
823 |
{ |
746d4a02e [ALSA] Fix discon... |
824 825 |
struct list_head *p, *n; struct proc_dir_entry *root; |
1da177e4c Linux-2.6.12-rc2 |
826 |
|
746d4a02e [ALSA] Fix discon... |
827 828 829 830 831 832 833 834 |
list_for_each_safe(p, n, &entry->children) { snd_info_disconnect(list_entry(p, struct snd_info_entry, list)); } if (! entry->p) return; list_del_init(&entry->list); root = entry->parent == NULL ? snd_proc_root : entry->parent->p; |
7eaa943c8 ALSA: Kill snd_as... |
835 |
snd_BUG_ON(!root); |
746d4a02e [ALSA] Fix discon... |
836 837 |
snd_remove_proc_entry(root, entry->p); entry->p = NULL; |
1da177e4c Linux-2.6.12-rc2 |
838 |
} |
746d4a02e [ALSA] Fix discon... |
839 |
static int snd_info_dev_free_entry(struct snd_device *device) |
1da177e4c Linux-2.6.12-rc2 |
840 |
{ |
24c1f9318 [ALSA] Remove xxx... |
841 |
struct snd_info_entry *entry = device->device_data; |
746d4a02e [ALSA] Fix discon... |
842 |
snd_info_free_entry(entry); |
1da177e4c Linux-2.6.12-rc2 |
843 844 |
return 0; } |
746d4a02e [ALSA] Fix discon... |
845 |
static int snd_info_dev_register_entry(struct snd_device *device) |
1da177e4c Linux-2.6.12-rc2 |
846 |
{ |
24c1f9318 [ALSA] Remove xxx... |
847 |
struct snd_info_entry *entry = device->device_data; |
746d4a02e [ALSA] Fix discon... |
848 |
return snd_info_register(entry); |
1da177e4c Linux-2.6.12-rc2 |
849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 |
} /** * snd_card_proc_new - create an info entry for the given card * @card: the card instance * @name: the file name * @entryp: the pointer to store the new info entry * * Creates a new info entry and assigns it to the given card. * Unlike snd_info_create_card_entry(), this function registers the * info entry as an ALSA device component, so that it can be * unregistered/released without explicit call. * Also, you don't have to register this entry via snd_info_register(), * since this will be registered by snd_card_register() automatically. * * The parent is assumed as card->proc_root. * * For releasing this entry, use snd_device_free() instead of * snd_info_free_entry(). * * Returns zero if successful, or a negative error code on failure. */ |
24c1f9318 [ALSA] Remove xxx... |
871 872 |
int snd_card_proc_new(struct snd_card *card, const char *name, struct snd_info_entry **entryp) |
1da177e4c Linux-2.6.12-rc2 |
873 |
{ |
24c1f9318 [ALSA] Remove xxx... |
874 |
static struct snd_device_ops ops = { |
1da177e4c Linux-2.6.12-rc2 |
875 876 |
.dev_free = snd_info_dev_free_entry, .dev_register = snd_info_dev_register_entry, |
746d4a02e [ALSA] Fix discon... |
877 |
/* disconnect is done via snd_info_card_disconnect() */ |
1da177e4c Linux-2.6.12-rc2 |
878 |
}; |
24c1f9318 [ALSA] Remove xxx... |
879 |
struct snd_info_entry *entry; |
1da177e4c Linux-2.6.12-rc2 |
880 881 882 883 884 885 886 887 888 889 890 891 892 |
int err; entry = snd_info_create_card_entry(card, name, card->proc_root); if (! entry) return -ENOMEM; if ((err = snd_device_new(card, SNDRV_DEV_INFO, entry, &ops)) < 0) { snd_info_free_entry(entry); return err; } if (entryp) *entryp = entry; return 0; } |
c0d3fb39e [ALSA] Clean up E... |
893 |
EXPORT_SYMBOL(snd_card_proc_new); |
1da177e4c Linux-2.6.12-rc2 |
894 895 896 897 898 899 |
/** * snd_info_free_entry - release the info entry * @entry: the info entry * * Releases the info entry. Don't call this after registered. */ |
24c1f9318 [ALSA] Remove xxx... |
900 |
void snd_info_free_entry(struct snd_info_entry * entry) |
1da177e4c Linux-2.6.12-rc2 |
901 902 903 |
{ if (entry == NULL) return; |
746d4a02e [ALSA] Fix discon... |
904 905 906 907 908 |
if (entry->p) { mutex_lock(&info_mutex); snd_info_disconnect(entry); mutex_unlock(&info_mutex); } |
1da177e4c Linux-2.6.12-rc2 |
909 910 911 912 913 |
kfree(entry->name); if (entry->private_free) entry->private_free(entry); kfree(entry); } |
c0d3fb39e [ALSA] Clean up E... |
914 |
EXPORT_SYMBOL(snd_info_free_entry); |
1da177e4c Linux-2.6.12-rc2 |
915 916 917 918 919 920 921 922 |
/** * snd_info_register - register the info entry * @entry: the info entry * * Registers the proc info entry. * * Returns zero if successful, or a negative error code on failure. */ |
24c1f9318 [ALSA] Remove xxx... |
923 |
int snd_info_register(struct snd_info_entry * entry) |
1da177e4c Linux-2.6.12-rc2 |
924 925 |
{ struct proc_dir_entry *root, *p = NULL; |
7eaa943c8 ALSA: Kill snd_as... |
926 927 |
if (snd_BUG_ON(!entry)) return -ENXIO; |
1da177e4c Linux-2.6.12-rc2 |
928 |
root = entry->parent == NULL ? snd_proc_root : entry->parent->p; |
1a60d4c5a [ALSA] semaphore ... |
929 |
mutex_lock(&info_mutex); |
99b762338 proc 2/2: remove ... |
930 |
p = create_proc_entry(entry->name, entry->mode, root); |
1da177e4c Linux-2.6.12-rc2 |
931 |
if (!p) { |
1a60d4c5a [ALSA] semaphore ... |
932 |
mutex_unlock(&info_mutex); |
1da177e4c Linux-2.6.12-rc2 |
933 934 |
return -ENOMEM; } |
1da177e4c Linux-2.6.12-rc2 |
935 936 937 938 939 |
if (!S_ISDIR(entry->mode)) p->proc_fops = &snd_info_entry_operations; p->size = entry->size; p->data = entry; entry->p = p; |
746d4a02e [ALSA] Fix discon... |
940 941 |
if (entry->parent) list_add_tail(&entry->list, &entry->parent->children); |
1a60d4c5a [ALSA] semaphore ... |
942 |
mutex_unlock(&info_mutex); |
1da177e4c Linux-2.6.12-rc2 |
943 944 |
return 0; } |
c0d3fb39e [ALSA] Clean up E... |
945 |
EXPORT_SYMBOL(snd_info_register); |
1da177e4c Linux-2.6.12-rc2 |
946 947 948 |
/* */ |
6581f4e74 [ALSA] Remove zer... |
949 |
static struct snd_info_entry *snd_info_version_entry; |
1da177e4c Linux-2.6.12-rc2 |
950 |
|
24c1f9318 [ALSA] Remove xxx... |
951 |
static void snd_info_version_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer) |
1da177e4c Linux-2.6.12-rc2 |
952 953 954 955 956 957 958 959 960 961 |
{ snd_iprintf(buffer, "Advanced Linux Sound Architecture Driver Version " CONFIG_SND_VERSION CONFIG_SND_DATE ". " ); } static int __init snd_info_version_init(void) { |
24c1f9318 [ALSA] Remove xxx... |
962 |
struct snd_info_entry *entry; |
1da177e4c Linux-2.6.12-rc2 |
963 964 965 966 |
entry = snd_info_create_module_entry(THIS_MODULE, "version", NULL); if (entry == NULL) return -ENOMEM; |
1da177e4c Linux-2.6.12-rc2 |
967 968 969 970 971 972 973 974 975 976 977 |
entry->c.text.read = snd_info_version_read; if (snd_info_register(entry) < 0) { snd_info_free_entry(entry); return -ENOMEM; } snd_info_version_entry = entry; return 0; } static int __exit snd_info_version_done(void) { |
746d4a02e [ALSA] Fix discon... |
978 |
snd_info_free_entry(snd_info_version_entry); |
1da177e4c Linux-2.6.12-rc2 |
979 980 981 982 |
return 0; } #endif /* CONFIG_PROC_FS */ |