ALSA: info - Implement common llseek for binary mode
[pandora-kernel.git] / sound / core / info.c
index f90a6fd..b70564e 100644 (file)
@@ -164,39 +164,43 @@ static loff_t snd_info_entry_llseek(struct file *file, loff_t offset, int orig)
 {
        struct snd_info_private_data *data;
        struct snd_info_entry *entry;
-       loff_t ret;
+       loff_t ret = -EINVAL, size;
 
        data = file->private_data;
        entry = data->entry;
        mutex_lock(&entry->access);
-       switch (entry->content) {
-       case SNDRV_INFO_CONTENT_TEXT:
-               switch (orig) {
-               case SEEK_SET:
-                       file->f_pos = offset;
-                       ret = file->f_pos;
-                       goto out;
-               case SEEK_CUR:
-                       file->f_pos += offset;
-                       ret = file->f_pos;
-                       goto out;
-               case SEEK_END:
-               default:
-                       ret = -EINVAL;
-                       goto out;
-               }
+       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 SNDRV_INFO_CONTENT_DATA:
-               if (entry->c.ops->llseek) {
-                       ret = entry->c.ops->llseek(entry,
-                                                   data->file_private_data,
-                                                   file, offset, orig);
+       case SEEK_CUR:
+               offset += file->f_pos;
+               break;
+       case SEEK_END:
+               if (!size)
                        goto out;
-               }
+               offset += size;
                break;
-       }
-       ret = -ENXIO;
-out:
+       default:
+               goto out;
+       }
+       if (offset < 0)
+               goto out;
+       if (size && offset > size)
+               offset = size;
+       file->f_pos = offset;
+       ret = offset;
+ out:
        mutex_unlock(&entry->access);
        return ret;
 }