Beispiel #1
1
static void drv_arithmetic_routine(struct work_struct* ws) {
    struct DataIn opData;
    int ans = 0;
    opData.a = myinb(DMAOPCODEADDR);
    opData.b = myinl(DMAOPERANDBADDR);
    opData.c = myinw(DMAOPERANDCADDR);
    if (opData.a == '+') {
        ans = opData.b + opData.c;
    } else if (opData.a == '-') {
        ans = opData.b - opData.c;
    } else if (opData.a == '*') {
        ans = opData.b * opData.c;
    } else if (opData.a == '/') {
        ans = opData.b / opData.c;
    } else if (opData.a == 'p') {
        ans = prime(opData.b, opData.c);
    } else {
        ans = 0;
    }
    printk("%s:%s():%d %c %d = %d\n", PREFIX_TITLE, __func__, opData.b, opData.a, opData.c, ans);
    myoutl(ans, DMAANSADDR);
    if(myinl(DMABLOCKADDR == FALSE)) {
        myoutl(TRUE, DMAREADABLEADDR);
    }
}
Beispiel #2
0
static int drv_read(struct file *filp, char __user *buffer, size_t ss, loff_t* lo) {
    printk("%s:%s(): ans = %d\n", PREFIX_TITLE, __func__, myinl(DMAANSADDR));
    *(int *)buffer = myinl(DMAANSADDR);
    // Clean answer & set readable to false
    myoutl(INITIANL_VALUE, DMAANSADDR);
    myoutl(FALSE, DMAREADABLEADDR);
    return 0;
}
Beispiel #3
0
static int drv_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) {
    int value = 1;
    unsigned int studentID = 101062124;
    switch(cmd){
    case HW5_IOCSETSTUID:
        // Copy data from user
        get_user(value, (int *)arg);
        myoutl(studentID, DMASTUIDADDR);
        printk("%s:%s(): My STUID is = %d\n", PREFIX_TITLE, __func__, myinl(DMASTUIDADDR));
        break;
    case HW5_IOCSETRWOK:
        // Copy data from user
        get_user(value, (int *)arg);
        myoutl(value, DMARWOKADDR);
        printk("%s:%s(): RW OK\n", PREFIX_TITLE, __func__);
        break;
    case HW5_IOCSETIOCOK:
        // Copy data from user
        get_user(value, (int *)arg);
        myoutl(value, DMAIOCOKADDR);
        printk("%s:%s(): IOC OK\n", PREFIX_TITLE, __func__);
        break;
    case HW5_IOCSETIRQOK:
        // Copy data from user
        get_user(value, (int *)arg);
        myoutl(value, DMAIRQOKADDR);
        printk("%s:%s(): IRC OK\n", PREFIX_TITLE, __func__);
        break;
    case HW5_IOCSETBLOCK:
        // Copy data from user
        get_user(value, (int *)arg);
        myoutl(value, DMABLOCKADDR);
        if(value) {
            printk("%s:%s(): Blocking IO\n", PREFIX_TITLE, __func__);
        } else {
            printk("%s:%s(): Non-Blocking IO\n", PREFIX_TITLE, __func__);
        }
        break;
    case HW5_IOCWAITREADABLE:
        while(myinl(DMAREADABLEADDR) != TRUE)
            msleep(TIMEPERIOD);
        // Copy data to user
        put_user(TRUE, (int *)arg);
        printk("%s:%s(): wait readable 1\n", PREFIX_TITLE, __func__);
        break;
    default:
        return -1;
    }
    return 0;
}
Beispiel #4
0
static void
l_write(int p, const void *buff, int size)
{
	int i;
    _Cli();

    for(i = 0; i < size; i++) {
    	myoutl( p , ( (int *) buff )[i] );
    }
    _Sti();
}
Beispiel #5
0
static int drv_write(struct file *filp, const char __user *buffer, size_t ss, loff_t* lo) {
    // Get IO mode
    int IOMode = myinl(DMABLOCKADDR);
    printk("%s:%s(): queue work\n", PREFIX_TITLE, __func__);
    INIT_WORK(work_routine, drv_arithmetic_routine);

    // Get data
    dataIn = (struct DataIn *)buffer;
    myoutb(dataIn->a, DMAOPCODEADDR);
    myoutl(dataIn->b, DMAOPERANDBADDR);
    myoutw(dataIn->c, DMAOPERANDCADDR);

    // Decide io mode
    if(IOMode) {
        // Blocking IO
        printk("%s:%s(): block\n", PREFIX_TITLE, __func__);
	schedule_work(work_routine);
        flush_scheduled_work();
    } else {
        // Non-locking IO
	schedule_work(work_routine);
    }
    return 0;
}