static ssize_t vme_user_read(struct file *file, char *buf, size_t count, loff_t * ppos) { unsigned int minor = MINOR(file->f_dentry->d_inode->i_rdev); ssize_t retval; size_t image_size; size_t okcount; down(&image[minor].sem); /* XXX Do we *really* want this helper - we can use vme_*_get ? */ image_size = vme_get_size(image[minor].resource); /* Ensure we are starting at a valid location */ if ((*ppos < 0) || (*ppos > (image_size - 1))) { up(&image[minor].sem); return 0; } /* Ensure not reading past end of the image */ if (*ppos + count > image_size) okcount = image_size - *ppos; else okcount = count; switch (type[minor]){ case MASTER_MINOR: retval = resource_to_user(minor, buf, okcount, ppos); break; case SLAVE_MINOR: retval = buffer_to_user(minor, buf, okcount, ppos); break; default: retval = -EINVAL; } up(&image[minor].sem); if (retval > 0) *ppos += retval; return retval; }
static loff_t vme_user_llseek(struct file *file, loff_t off, int whence) { loff_t absolute = -1; unsigned int minor = MINOR(file->f_dentry->d_inode->i_rdev); size_t image_size; down(&image[minor].sem); image_size = vme_get_size(image[minor].resource); switch (whence) { case SEEK_SET: absolute = off; break; case SEEK_CUR: absolute = file->f_pos + off; break; case SEEK_END: absolute = image_size + off; break; default: up(&image[minor].sem); return -EINVAL; break; } if ((absolute < 0) || (absolute >= image_size)) { up(&image[minor].sem); return -EINVAL; } file->f_pos = absolute; up(&image[minor].sem); return absolute; }