示例#1
0
文件: ide-proc.c 项目: 274914765/C
static int proc_ide_read_settings
    (char *page, char **start, off_t off, int count, int *eof, void *data)
{
    ide_drive_t    *drive = (ide_drive_t *) data;
    ide_settings_t    *setting = (ide_settings_t *) drive->settings;
    char        *out = page;
    int        len, rc, mul_factor, div_factor;

    proc_ide_settings_warn();

    mutex_lock(&ide_setting_mtx);
    out += sprintf(out, "name\t\t\tvalue\t\tmin\t\tmax\t\tmode\n");
    out += sprintf(out, "----\t\t\t-----\t\t---\t\t---\t\t----\n");
    while (setting) {
        mul_factor = setting->mul_factor;
        div_factor = setting->div_factor;
        out += sprintf(out, "%-24s", setting->name);
        rc = ide_read_setting(drive, setting);
        if (rc >= 0)
            out += sprintf(out, "%-16d", rc * mul_factor / div_factor);
        else
            out += sprintf(out, "%-16s", "write-only");
        out += sprintf(out, "%-16d%-16d", (setting->min * mul_factor + div_factor - 1) / div_factor, setting->max * mul_factor / div_factor);
        if (setting->rw & SETTING_READ)
            out += sprintf(out, "r");
        if (setting->rw & SETTING_WRITE)
            out += sprintf(out, "w");
        out += sprintf(out, "\n");
        setting = setting->next;
    }
    len = out - page;
    mutex_unlock(&ide_setting_mtx);
    PROC_IDE_READ_RETURN(page, start, off, count, eof, len);
}
示例#2
0
static int proc_ide_read_settings
(char *page, char **start, off_t off, int count, int *eof, void *data)
{
    const struct ide_proc_devset *setting, *g, *d;
    const struct ide_devset *ds;
    ide_drive_t	*drive = (ide_drive_t *) data;
    char		*out = page;
    int		len, rc, mul_factor, div_factor;

    proc_ide_settings_warn();

    mutex_lock(&ide_setting_mtx);
    g = ide_generic_settings;
    d = drive->settings;
    out += sprintf(out, "name\t\t\tvalue\t\tmin\t\tmax\t\tmode\n");
    out += sprintf(out, "----\t\t\t-----\t\t---\t\t---\t\t----\n");
    while (g->name || (d && d->name)) {
        /* read settings in the alphabetical order */
        if (g->name && d && d->name) {
            if (strcmp(d->name, g->name) < 0)
                setting = d++;
            else
                setting = g++;
        } else if (d && d->name) {
            setting = d++;
        } else
            setting = g++;
        mul_factor = setting->mulf ? setting->mulf(drive) : 1;
        div_factor = setting->divf ? setting->divf(drive) : 1;
        out += sprintf(out, "%-24s", setting->name);
        rc = ide_read_setting(drive, setting);
        if (rc >= 0)
            out += sprintf(out, "%-16d", rc * mul_factor / div_factor);
        else
            out += sprintf(out, "%-16s", "write-only");
        out += sprintf(out, "%-16d%-16d", (setting->min * mul_factor + div_factor - 1) / div_factor, setting->max * mul_factor / div_factor);
        ds = setting->setting;
        if (ds->get)
            out += sprintf(out, "r");
        if (ds->set)
            out += sprintf(out, "w");
        out += sprintf(out, "\n");
    }
    len = out - page;
    mutex_unlock(&ide_setting_mtx);
    PROC_IDE_READ_RETURN(page, start, off, count, eof, len);
}
示例#3
0
static int proc_ide_write_settings(struct file *file, const char __user *buffer,
                                   unsigned long count, void *data)
{
    ide_drive_t	*drive = (ide_drive_t *) data;
    char		name[MAX_LEN + 1];
    int		for_real = 0, mul_factor, div_factor;
    unsigned long	n;

    const struct ide_proc_devset *setting;
    char *buf, *s;

    if (!capable(CAP_SYS_ADMIN))
        return -EACCES;

    proc_ide_settings_warn();

    if (count >= PAGE_SIZE)
        return -EINVAL;

    s = buf = (char *)__get_free_page(GFP_USER);
    if (!buf)
        return -ENOMEM;

    if (copy_from_user(buf, buffer, count)) {
        free_page((unsigned long)buf);
        return -EFAULT;
    }

    buf[count] = '\0';

    /*
     * Skip over leading whitespace
     */
    while (count && isspace(*s)) {
        --count;
        ++s;
    }
    /*
     * Do one full pass to verify all parameters,
     * then do another to actually write the new settings.
     */
    do {
        char *p = s;
        n = count;
        while (n > 0) {
            unsigned val;
            char *q = p;

            while (n > 0 && *p != ':') {
                --n;
                p++;
            }
            if (*p != ':')
                goto parse_error;
            if (p - q > MAX_LEN)
                goto parse_error;
            memcpy(name, q, p - q);
            name[p - q] = 0;

            if (n > 0) {
                --n;
                p++;
            } else
                goto parse_error;

            val = simple_strtoul(p, &q, 10);
            n -= q - p;
            p = q;
            if (n > 0 && !isspace(*p))
                goto parse_error;
            while (n > 0 && isspace(*p)) {
                --n;
                ++p;
            }

            mutex_lock(&ide_setting_mtx);
            /* generic settings first, then driver specific ones */
            setting = ide_find_setting(ide_generic_settings, name);
            if (!setting) {
                if (drive->settings)
                    setting = ide_find_setting(drive->settings, name);
                if (!setting) {
                    mutex_unlock(&ide_setting_mtx);
                    goto parse_error;
                }
            }
            if (for_real) {
                mul_factor = setting->mulf ? setting->mulf(drive) : 1;
                div_factor = setting->divf ? setting->divf(drive) : 1;
                ide_write_setting(drive, setting, val * div_factor / mul_factor);
            }
            mutex_unlock(&ide_setting_mtx);
        }
    } while (!for_real++);
    free_page((unsigned long)buf);
    return count;
parse_error:
    free_page((unsigned long)buf);
    printk("proc_ide_write_settings(): parse error\n");
    return -EINVAL;
}