struct snd_info_entry *entry;
loff_t ret;
- data = snd_magic_cast(snd_info_private_data_t, file->private_data, return -ENXIO);
+ data = file->private_data;
entry = data->entry;
lock_kernel();
switch (entry->content) {
struct snd_info_entry *entry;
snd_info_buffer_t *buf;
size_t size = 0;
+ loff_t pos;
- data = snd_magic_cast(snd_info_private_data_t, file->private_data, return -ENXIO);
+ data = file->private_data;
snd_assert(data != NULL, return -ENXIO);
+ 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 (file->f_pos >= (long)buf->size)
+ if (pos >= buf->size)
return 0;
- size = buf->size - file->f_pos;
+ size = buf->size - pos;
size = min(count, size);
- if (copy_to_user(buffer, buf->buffer + file->f_pos, size))
+ if (copy_to_user(buffer, buf->buffer + pos, size))
return -EFAULT;
- file->f_pos += size;
break;
case SNDRV_INFO_CONTENT_DATA:
if (entry->c.ops->read)
- return entry->c.ops->read(entry,
+ size = entry->c.ops->read(entry,
data->file_private_data,
- file, buffer, count);
+ file, buffer, count, pos);
break;
}
+ if ((ssize_t) size > 0)
+ *offset = pos + size;
return size;
}
struct snd_info_entry *entry;
snd_info_buffer_t *buf;
size_t size = 0;
+ loff_t pos;
- data = snd_magic_cast(snd_info_private_data_t, file->private_data, return -ENXIO);
+ data = file->private_data;
snd_assert(data != NULL, return -ENXIO);
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;
- if (file->f_pos < 0)
- return -EINVAL;
- if (file->f_pos >= (long)buf->len)
+ if (pos >= buf->len)
return -ENOMEM;
- size = buf->len - file->f_pos;
+ size = buf->len - pos;
size = min(count, size);
- if (copy_from_user(buf->buffer + file->f_pos, buffer, size))
+ if (copy_from_user(buf->buffer + pos, buffer, size))
return -EFAULT;
- if ((long)buf->size < file->f_pos + size)
- buf->size = file->f_pos + size;
- file->f_pos += size;
+ if ((long)buf->size < pos + size)
+ buf->size = pos + size;
break;
case SNDRV_INFO_CONTENT_DATA:
if (entry->c.ops->write)
- return entry->c.ops->write(entry,
+ size = entry->c.ops->write(entry,
data->file_private_data,
- file, buffer, count);
+ file, buffer, count, pos);
break;
}
+ if ((ssize_t) size > 0)
+ *offset = pos + size;
return size;
}
goto __error;
}
}
- data = snd_magic_kcalloc(snd_info_private_data_t, 0, GFP_KERNEL);
+ data = kcalloc(1, sizeof(*data), GFP_KERNEL);
if (data == NULL) {
err = -ENOMEM;
goto __error;
switch (entry->content) {
case SNDRV_INFO_CONTENT_TEXT:
if (mode == O_RDONLY || mode == O_RDWR) {
- buffer = (snd_info_buffer_t *)
- snd_kcalloc(sizeof(snd_info_buffer_t), GFP_KERNEL);
+ buffer = kcalloc(1, sizeof(*buffer), GFP_KERNEL);
if (buffer == NULL) {
- snd_magic_kfree(data);
+ kfree(data);
err = -ENOMEM;
goto __error;
}
buffer->buffer = vmalloc(buffer->len);
if (buffer->buffer == NULL) {
kfree(buffer);
- snd_magic_kfree(data);
+ kfree(data);
err = -ENOMEM;
goto __error;
}
data->rbuffer = buffer;
}
if (mode == O_WRONLY || mode == O_RDWR) {
- buffer = (snd_info_buffer_t *)
- snd_kcalloc(sizeof(snd_info_buffer_t), GFP_KERNEL);
+ buffer = kcalloc(1, sizeof(*buffer), GFP_KERNEL);
if (buffer == NULL) {
if (mode == O_RDWR) {
vfree(data->rbuffer->buffer);
kfree(data->rbuffer);
}
- snd_magic_kfree(data);
+ kfree(data);
err = -ENOMEM;
goto __error;
}
kfree(data->rbuffer);
}
kfree(buffer);
- snd_magic_kfree(data);
+ kfree(data);
err = -ENOMEM;
goto __error;
}
if (entry->c.ops->open) {
if ((err = entry->c.ops->open(entry, mode,
&data->file_private_data)) < 0) {
- snd_magic_kfree(data);
+ kfree(data);
goto __error;
}
}
int mode;
mode = file->f_flags & O_ACCMODE;
- data = snd_magic_cast(snd_info_private_data_t, file->private_data, return -ENXIO);
+ data = file->private_data;
entry = data->entry;
switch (entry->content) {
case SNDRV_INFO_CONTENT_TEXT:
break;
}
module_put(entry->module);
- snd_magic_kfree(data);
+ kfree(data);
return 0;
}
struct snd_info_entry *entry;
unsigned int mask;
- data = snd_magic_cast(snd_info_private_data_t, file->private_data, return -ENXIO);
+ data = file->private_data;
if (data == NULL)
return 0;
entry = data->entry;
return mask;
}
-static int snd_info_entry_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, unsigned long arg)
+static inline int _snd_info_entry_ioctl(struct inode *inode, struct file *file,
+ unsigned int cmd, unsigned long arg)
{
snd_info_private_data_t *data;
struct snd_info_entry *entry;
- data = snd_magic_cast(snd_info_private_data_t, file->private_data, return -ENXIO);
+ data = file->private_data;
if (data == NULL)
return 0;
entry = data->entry;
return -ENOTTY;
}
+/* FIXME: need to unlock BKL to allow preemption */
+static int snd_info_entry_ioctl(struct inode *inode, struct file *file,
+ unsigned int cmd, unsigned long arg)
+{
+ int err;
+ unlock_kernel();
+ err = _snd_info_entry_ioctl(inode, file, cmd, arg);
+ lock_kernel();
+ return err;
+}
+
static int snd_info_entry_mmap(struct file *file, struct vm_area_struct *vma)
{
struct inode *inode = file->f_dentry->d_inode;
snd_info_private_data_t *data;
struct snd_info_entry *entry;
- data = snd_magic_cast(snd_info_private_data_t, file->private_data, return -ENXIO);
+ data = file->private_data;
if (data == NULL)
return 0;
entry = data->entry;
static snd_info_entry_t *snd_info_create_entry(const char *name)
{
snd_info_entry_t *entry;
- entry = snd_magic_kcalloc(snd_info_entry_t, 0, GFP_KERNEL);
+ entry = kcalloc(1, sizeof(*entry), GFP_KERNEL);
if (entry == NULL)
return NULL;
entry->name = snd_kmalloc_strdup(name, GFP_KERNEL);
if (entry->name == NULL) {
- snd_magic_kfree(entry);
+ kfree(entry);
return NULL;
}
entry->mode = S_IFREG | S_IRUGO;
static int snd_info_dev_free_entry(snd_device_t *device)
{
- snd_info_entry_t *entry = snd_magic_cast(snd_info_entry_t, device->device_data, return -ENXIO);
+ snd_info_entry_t *entry = device->device_data;
snd_info_free_entry(entry);
return 0;
}
static int snd_info_dev_register_entry(snd_device_t *device)
{
- snd_info_entry_t *entry = snd_magic_cast(snd_info_entry_t, device->device_data, return -ENXIO);
+ snd_info_entry_t *entry = device->device_data;
return snd_info_register(entry);
}
static int snd_info_dev_disconnect_entry(snd_device_t *device)
{
- snd_info_entry_t *entry = snd_magic_cast(snd_info_entry_t, device->device_data, return -ENXIO);
+ snd_info_entry_t *entry = device->device_data;
entry->disconnected = 1;
return 0;
}
static int snd_info_dev_unregister_entry(snd_device_t *device)
{
- snd_info_entry_t *entry = snd_magic_cast(snd_info_entry_t, device->device_data, return -ENXIO);
+ snd_info_entry_t *entry = device->device_data;
return snd_info_unregister(entry);
}
kfree((char *)entry->name);
if (entry->private_free)
entry->private_free(entry);
- snd_magic_kfree(entry);
+ kfree(entry);
}
/**