ALSA: info - Implement common llseek for binary mode

The llseek implementation is identical for existing driver implementations,
so let's merge to the common layer.  The same code for the text proc file
can be used even for the binary proc file.

The driver can provide its own llseek method if needed.  Then the common
code will be skipped.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
Takashi Iwai
2010-04-13 11:39:47 +02:00
parent d97e1b7823
commit 73029e0ff1
4 changed files with 32 additions and 129 deletions

View 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;
}
break;
case SNDRV_INFO_CONTENT_DATA:
if (entry->c.ops->llseek) {
ret = entry->c.ops->llseek(entry,
data->file_private_data,
file, offset, orig);
goto out;
}
break;
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;
}
ret = -ENXIO;
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;
break;
case SEEK_END:
if (!size)
goto out;
offset += size;
break;
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;
}