コード例 #1
0
ファイル: lunix-chrdev.c プロジェクト: panayiotisd/ntua-oslab
/*
 * Updates the cached state of a character device
 * based on sensor data. Must be called with the
 * character device state lock held.
 */
static int lunix_chrdev_state_update(struct lunix_chrdev_state_struct *state)
{
	//struct lunix_sensor_struct *sensor;
	unsigned long flags;
	int need_refresh, n;
	long int data;
	uint32_t raw_data, raw_time;
	char c;
	
	debug("entering lunix_chrdev_state_update\n");

	/*
	 * Grab the raw data quickly, hold the
	 * spinlock for as little as possible.
	 */
	/* ? */
	/* Why use spinlocks? See LDD3, p. 119 */

	/*
	 * Any new data available?
	 */
	/* ? */
	need_refresh = lunix_chrdev_state_needs_refresh(state);
	if (need_refresh) {
		debug("Spinlock almost at hand.\n");
		spin_lock_irqsave(&(state->sensor->lock), flags);
		debug("Spinlock at hand.\n");
		raw_data = state->sensor->msr_data[state->type]->values[0];
		raw_time = state->sensor->msr_data[state->type]->last_update;
		spin_unlock_irqrestore(&(state->sensor->lock), flags);
	}
	else {
		debug("Again!\n");		
		return -EAGAIN; /* No new data */
	}
	/*
	 * Now we can take our time to format them,
	 * holding only the private state semaphore
	 */
	/* ? */
	
	switch(state->type) {
		debug("case 0\n");
		case BATT: data = lookup_voltage[raw_data]; break;
		debug("case 1\n");
		case TEMP: data = lookup_temperature[raw_data]; break;
		debug("case 2\n");
		case LIGHT: data = lookup_light[raw_data]; break;
		default: ;
		debug("case default\n");
	}
	c = (data >= 0) ? '+' : '-';
	data = (data > 0) ? data : (-data);
	n = sprintf(state->buf_data, "%c%ld.%ld\n", c, data/1000, data%1000 );
	state->buf_timestamp = raw_time;
	state->buf_lim = n;
	
	debug("leaving\n");
	return 0;
}
コード例 #2
0
ファイル: lunix-chrdev.c プロジェクト: panayiotisd/ntua-oslab
static ssize_t lunix_chrdev_read(struct file *filp, char __user *usrbuf, size_t cnt, loff_t *f_pos)
{
	ssize_t ret;
	struct lunix_sensor_struct *sensor;
	struct lunix_chrdev_state_struct *state;
	
	int di,bytes;
	
	debug("entering\n");
	
	state = filp->private_data;
	WARN_ON(!state);

	sensor = state->sensor;
	WARN_ON(!sensor);

	/* Lock? */
	di = down_interruptible(&(state->lock));
	if (di) {
		/* Failed to V */
		debug("failed down_interruptible\n");
		ret = -EINTR;
		goto out;
	}
	
	/*
	 * If the cached character device state needs to be
	 * updated by actual sensor data (i.e. we need to report
	 * on a "fresh" measurement, do so
	 */
	if (*f_pos == 0) {
		while (lunix_chrdev_state_update(state) == -EAGAIN) {
			/* ? */
			/* The process needs to sleep */
			/* See LDD3, page 153 for a hint */
			
			up(&(state->lock));
			if (wait_event_interruptible(sensor->wq, lunix_chrdev_state_needs_refresh(state)))
				return -ERESTARTSYS; /* signal: tell the fs layer to handle it */
			di = down_interruptible(&(state->lock));
			if (di) {
				/* Failed to V */
				debug("failed down_interruptible\n");
				ret = -EINTR;
				goto out;
			}
		}
	}

	debug("ready to copy_to_user\n");

	bytes = (cnt < state->buf_lim - *f_pos) ? cnt : state->buf_lim-*f_pos;

  	ret = copy_to_user(usrbuf, state->buf_data + *f_pos, bytes);
	if (ret) {
		/* Failed to copy */
		debug("copy_to_user failed\n");
	}
	
	/* Auto-rewind on EOF mode? */
	/* ? */
	
	(*f_pos)+=bytes;
	if(*f_pos >= state->buf_lim) *f_pos=0;
	ret = bytes;
	
out:
	/* Unlock? */
	up(&(state->lock));
	return ret;
}
コード例 #3
0
ファイル: lunix-chrdev.c プロジェクト: spirosmastorakis/OSlab
/*
 * Updates the cached state of a character device
 * based on sensor data. Must be called with the
 * character device state lock held.
 */
static int lunix_chrdev_state_update(struct lunix_chrdev_state_struct *state)
{
	struct lunix_sensor_struct *sensor;
    unsigned long flags;
    int new_data;
    uint16_t portion; /* fract_portion; */
    long res ; /* res_fract */
    uint32_t temp, temp1 ;
    unsigned char temp_buf[20];
	/*
	 * Grab the raw data quickly, hold the
	 * spinlock for as little as possible.
	 */
	/* ? */
	/* Why use spinlocks? See LDD3, p. 119 */
    
    debug("going into lunix_chrdev_state_update \n ");
    spin_lock_irqsave(&sensor->lock, flags );
    
	/*
	 * Any new data available?
	 */
	/* ? */
    
    new_data = lunix_chrdev_state_needs_refresh(&state);
    spin_unlock_irqrestore(&sensor->lock, flags);
    
	/*
	 * Now we can take our time to format them,
	 * holding only the private state semaphore
	 */
    /* ? */
    
    if (down_interruptible(&state->lock)) {
        debug("Could not acquire lock\n");
        return -ERESTARTSYS;
    }
    if ((new_data) == 1) {
        debug("there is new data")
        memcpy(&temp1,((sensor->msr_data[state->type])->values[0]), 4);
        temp = cpu_to_le32(temp1);
        memcpy(&portion,&temp,2);
       /* temp = temp >> 16; */
       /* memcpy(&integ_portion,&temp,2); */
        if ((state->type) == 0 ) {
            res = uint16_to_batt(portion);
            /* res_fract = uint16_to_batt(fract_portion); */
        }
        if ((state->type) == 1 ){
            res = uint16_to_temp(portion);
            /* res_fract = uint16_to_temp(fract_portion); */
        }
        if ((state->type) == 2 ){
            res = uint16_to_light(portion);
            /* res_fract = uint16_to_light(fract_portion); */
        }
        up(&state->lock);
        sprintf(temp_buf, "%ld" , res);
        (state->buf_lim) = strlen(temp_buf);
        memcpy((state->buf_data), &temp_buf, (state->buf_lim));
        return 0;
        
    }
    
    else {
        up(&state->lock);
        return -EAGAIN;
    }
	debug("leaving\n");
	return 0;
}