aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2010-04-13 05:39:47 -0400
committerTakashi Iwai <tiwai@suse.de>2010-04-13 06:01:20 -0400
commit73029e0ff18dfac8a1aab1dc188e1e150bbe3adc (patch)
tree680d00a2e5bc124b5b1b642508a47a90e3c47b3f
parentd97e1b78239c7e7e441088e0b644bd3b076002e6 (diff)
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>
-rw-r--r--sound/core/info.c56
-rw-r--r--sound/drivers/opl4/opl4_proc.c24
-rw-r--r--sound/isa/gus/gus_mem_proc.c26
-rw-r--r--sound/pci/mixart/mixart.c51
4 files changed, 30 insertions, 127 deletions
diff --git a/sound/core/info.c b/sound/core/info.c
index f90a6fd43fb4..b70564ed8b37 100644
--- a/sound/core/info.c
+++ b/sound/core/info.c
@@ -164,39 +164,43 @@ static loff_t snd_info_entry_llseek(struct file *file, loff_t offset, int orig)
164{ 164{
165 struct snd_info_private_data *data; 165 struct snd_info_private_data *data;
166 struct snd_info_entry *entry; 166 struct snd_info_entry *entry;
167 loff_t ret; 167 loff_t ret = -EINVAL, size;
168 168
169 data = file->private_data; 169 data = file->private_data;
170 entry = data->entry; 170 entry = data->entry;
171 mutex_lock(&entry->access); 171 mutex_lock(&entry->access);
172 switch (entry->content) { 172 if (entry->content == SNDRV_INFO_CONTENT_DATA &&
173 case SNDRV_INFO_CONTENT_TEXT: 173 entry->c.ops->llseek) {
174 switch (orig) { 174 offset = entry->c.ops->llseek(entry,
175 case SEEK_SET: 175 data->file_private_data,
176 file->f_pos = offset; 176 file, offset, orig);
177 ret = file->f_pos; 177 goto out;
178 goto out; 178 }
179 case SEEK_CUR: 179 if (entry->content == SNDRV_INFO_CONTENT_DATA)
180 file->f_pos += offset; 180 size = entry->size;
181 ret = file->f_pos; 181 else
182 goto out; 182 size = 0;
183 case SEEK_END: 183 switch (orig) {
184 default: 184 case SEEK_SET:
185 ret = -EINVAL;
186 goto out;
187 }
188 break; 185 break;
189 case SNDRV_INFO_CONTENT_DATA: 186 case SEEK_CUR:
190 if (entry->c.ops->llseek) { 187 offset += file->f_pos;
191 ret = entry->c.ops->llseek(entry, 188 break;
192 data->file_private_data, 189 case SEEK_END:
193 file, offset, orig); 190 if (!size)
194 goto out; 191 goto out;
195 } 192 offset += size;
196 break; 193 break;
197 } 194 default:
198 ret = -ENXIO; 195 goto out;
199out: 196 }
197 if (offset < 0)
198 goto out;
199 if (size && offset > size)
200 offset = size;
201 file->f_pos = offset;
202 ret = offset;
203 out:
200 mutex_unlock(&entry->access); 204 mutex_unlock(&entry->access);
201 return ret; 205 return ret;
202} 206}
diff --git a/sound/drivers/opl4/opl4_proc.c b/sound/drivers/opl4/opl4_proc.c
index 210b89de06d7..c5c13c4c260e 100644
--- a/sound/drivers/opl4/opl4_proc.c
+++ b/sound/drivers/opl4/opl4_proc.c
@@ -90,35 +90,11 @@ static ssize_t snd_opl4_mem_proc_write(struct snd_info_entry *entry,
90 return count; 90 return count;
91} 91}
92 92
93static loff_t snd_opl4_mem_proc_llseek(struct snd_info_entry *entry,
94 void *file_private_data,
95 struct file *file,
96 loff_t offset, int orig)
97{
98 switch (orig) {
99 case SEEK_SET:
100 file->f_pos = offset;
101 break;
102 case SEEK_CUR:
103 file->f_pos += offset;
104 break;
105 case SEEK_END: /* offset is negative */
106 file->f_pos = entry->size + offset;
107 break;
108 default:
109 return -EINVAL;
110 }
111 if (file->f_pos > entry->size)
112 file->f_pos = entry->size;
113 return file->f_pos;
114}
115
116static struct snd_info_entry_ops snd_opl4_mem_proc_ops = { 93static struct snd_info_entry_ops snd_opl4_mem_proc_ops = {
117 .open = snd_opl4_mem_proc_open, 94 .open = snd_opl4_mem_proc_open,
118 .release = snd_opl4_mem_proc_release, 95 .release = snd_opl4_mem_proc_release,
119 .read = snd_opl4_mem_proc_read, 96 .read = snd_opl4_mem_proc_read,
120 .write = snd_opl4_mem_proc_write, 97 .write = snd_opl4_mem_proc_write,
121 .llseek = snd_opl4_mem_proc_llseek,
122}; 98};
123 99
124int snd_opl4_create_proc(struct snd_opl4 *opl4) 100int snd_opl4_create_proc(struct snd_opl4 *opl4)
diff --git a/sound/isa/gus/gus_mem_proc.c b/sound/isa/gus/gus_mem_proc.c
index faa2bec8f6b6..2ccb3fadd7be 100644
--- a/sound/isa/gus/gus_mem_proc.c
+++ b/sound/isa/gus/gus_mem_proc.c
@@ -46,31 +46,6 @@ static ssize_t snd_gf1_mem_proc_dump(struct snd_info_entry *entry,
46 return count; 46 return count;
47} 47}
48 48
49static loff_t snd_gf1_mem_proc_llseek(struct snd_info_entry *entry,
50 void *private_file_data,
51 struct file *file,
52 loff_t offset, int orig)
53{
54 struct gus_proc_private *priv = entry->private_data;
55
56 switch (orig) {
57 case SEEK_SET:
58 file->f_pos = offset;
59 break;
60 case SEEK_CUR:
61 file->f_pos += offset;
62 break;
63 case SEEK_END: /* offset is negative */
64 file->f_pos = priv->size + offset;
65 break;
66 default:
67 return -EINVAL;
68 }
69 if (file->f_pos > priv->size)
70 file->f_pos = priv->size;
71 return file->f_pos;
72}
73
74static void snd_gf1_mem_proc_free(struct snd_info_entry *entry) 49static void snd_gf1_mem_proc_free(struct snd_info_entry *entry)
75{ 50{
76 struct gus_proc_private *priv = entry->private_data; 51 struct gus_proc_private *priv = entry->private_data;
@@ -79,7 +54,6 @@ static void snd_gf1_mem_proc_free(struct snd_info_entry *entry)
79 54
80static struct snd_info_entry_ops snd_gf1_mem_proc_ops = { 55static struct snd_info_entry_ops snd_gf1_mem_proc_ops = {
81 .read = snd_gf1_mem_proc_dump, 56 .read = snd_gf1_mem_proc_dump,
82 .llseek = snd_gf1_mem_proc_llseek,
83}; 57};
84 58
85int snd_gf1_mem_proc_init(struct snd_gus_card * gus) 59int snd_gf1_mem_proc_init(struct snd_gus_card * gus)
diff --git a/sound/pci/mixart/mixart.c b/sound/pci/mixart/mixart.c
index be95e005c81d..6c3fd4d1c49d 100644
--- a/sound/pci/mixart/mixart.c
+++ b/sound/pci/mixart/mixart.c
@@ -1102,55 +1102,6 @@ static int snd_mixart_free(struct mixart_mgr *mgr)
1102/* 1102/*
1103 * proc interface 1103 * proc interface
1104 */ 1104 */
1105static loff_t snd_mixart_BA0_llseek(struct snd_info_entry *entry,
1106 void *private_file_data,
1107 struct file *file,
1108 loff_t offset, int orig)
1109{
1110 offset = offset & ~3; /* 4 bytes aligned */
1111
1112 switch(orig) {
1113 case SEEK_SET:
1114 file->f_pos = offset;
1115 break;
1116 case SEEK_CUR:
1117 file->f_pos += offset;
1118 break;
1119 case SEEK_END: /* offset is negative */
1120 file->f_pos = MIXART_BA0_SIZE + offset;
1121 break;
1122 default:
1123 return -EINVAL;
1124 }
1125 if(file->f_pos > MIXART_BA0_SIZE)
1126 file->f_pos = MIXART_BA0_SIZE;
1127 return file->f_pos;
1128}
1129
1130static loff_t snd_mixart_BA1_llseek(struct snd_info_entry *entry,
1131 void *private_file_data,
1132 struct file *file,
1133 loff_t offset, int orig)
1134{
1135 offset = offset & ~3; /* 4 bytes aligned */
1136
1137 switch(orig) {
1138 case SEEK_SET:
1139 file->f_pos = offset;
1140 break;
1141 case SEEK_CUR:
1142 file->f_pos += offset;
1143 break;
1144 case SEEK_END: /* offset is negative */
1145 file->f_pos = MIXART_BA1_SIZE + offset;
1146 break;
1147 default:
1148 return -EINVAL;
1149 }
1150 if(file->f_pos > MIXART_BA1_SIZE)
1151 file->f_pos = MIXART_BA1_SIZE;
1152 return file->f_pos;
1153}
1154 1105
1155/* 1106/*
1156 mixart_BA0 proc interface for BAR 0 - read callback 1107 mixart_BA0 proc interface for BAR 0 - read callback
@@ -1186,12 +1137,10 @@ static ssize_t snd_mixart_BA1_read(struct snd_info_entry *entry,
1186 1137
1187static struct snd_info_entry_ops snd_mixart_proc_ops_BA0 = { 1138static struct snd_info_entry_ops snd_mixart_proc_ops_BA0 = {
1188 .read = snd_mixart_BA0_read, 1139 .read = snd_mixart_BA0_read,
1189 .llseek = snd_mixart_BA0_llseek
1190}; 1140};
1191 1141
1192static struct snd_info_entry_ops snd_mixart_proc_ops_BA1 = { 1142static struct snd_info_entry_ops snd_mixart_proc_ops_BA1 = {
1193 .read = snd_mixart_BA1_read, 1143 .read = snd_mixart_BA1_read,
1194 .llseek = snd_mixart_BA1_llseek
1195}; 1144};
1196 1145
1197 1146