Ejemplo n.º 1
0
ssize_t
nidas_circbuf_read_nowait(struct file *filp, char __user* buf, size_t count,
                struct dsm_sample_circ_buf* cbuf, struct sample_read_state* state)
{
        size_t countreq = count;
        struct dsm_sample* insamp;
        size_t bytesLeft = state->bytesLeft;
        char* samplePtr = state->samplePtr;
        size_t n;

        for ( ; count; ) {
                if ((n = min(bytesLeft,count)) > 0) {
                        if (copy_to_user(buf,samplePtr,n)) return -EFAULT;
                        bytesLeft -= n;
                        count -= n;
                        samplePtr += n;
                        buf += n;
                        if (bytesLeft > 0) break;   // user buffer filled
                        samplePtr = 0;
                        INCREMENT_TAIL(*cbuf,cbuf->size);
                }
                insamp = GET_TAIL(*cbuf,cbuf->size);
                if (!insamp) break;    // no more samples
                samplePtr = (char*)insamp;
                bytesLeft = insamp->length + SIZEOF_DSM_SAMPLE_HEADER;
                KLOG_DEBUG("bytes left=%zd\n",bytesLeft);
        }
        state->samplePtr = samplePtr;
        state->bytesLeft = bytesLeft;
        KLOG_DEBUG("read return = %u\n",countreq - count);
        return countreq - count;
}
Ejemplo n.º 2
0
/*
 * The proc filesystem: function to read
 */
static int pcmcom8_read_procmem(char *buf, char **start, off_t offset,
                   int count, int *eof, void *data)
{
        int i, j, len = 0;
        int limit = count - 80; /* Don't print more than this */
        int result = 0;
        KLOG_DEBUG("read_proc, count=%d\n",count);
                                                                                    
        for (i = 0; i < pcmcom8_nr_ok && len <= limit; i++) {
                pcmcom8_board *brd = pcmcom8_boards + i;
                KLOG_DEBUG("read_proc, i=%d, device=0x%lx\n",i,(unsigned long)brd);
                if ((result = PCMCOM8_LOCK(&brd->mutex))) return result;
                pcmcom8_read_config(brd);
                len += sprintf(buf+len,"\nWinSystems PCMCOM8 board %i: ioport %x\n",
                               i, brd->ioport);
                /* loop over serial ports */
                for (j = 0; len <= limit && j < PCMCOM8_NR_PORTS; j++) {
                    len += sprintf(buf+len, "  port %d, ioport=%x,irq=%d\n",
                        j,brd->config.ports[j].ioport,brd->config.ports[j].irq);
                }
                PCMCOM8_UNLOCK(&brd->mutex);
        }
        *eof = 1;
        return len;
}
Ejemplo n.º 3
0
ssize_t
nidas_circbuf_read(struct file *filp, char __user* buf, size_t count,
                struct dsm_sample_circ_buf* cbuf, struct sample_read_state* state,
                wait_queue_head_t* readq)
{
        while(state->bytesLeft == 0 && ACCESS_ONCE(cbuf->head) == cbuf->tail) {
                if (filp->f_flags & O_NONBLOCK) return -EAGAIN;
                KLOG_DEBUG("waiting for data,head=%d,tail=%d\n",cbuf->head,cbuf->tail);
                if (wait_event_interruptible(*readq,(ACCESS_ONCE(cbuf->head) != cbuf->tail)))
                        return -ERESTARTSYS;
                KLOG_DEBUG("woken\n");
        }
        return nidas_circbuf_read_nowait(filp,buf,count,cbuf,state);
}
Ejemplo n.º 4
0
static void pcmcom8_create_proc(void)
{
        KLOG_DEBUG("within pcmcom8_create_proc\n");
        create_proc_read_entry(DRIVER_NAME, 0644 /* default mode */,
                           NULL /* parent dir */, pcmcom8_read_procmem,
                           NULL /* client data */);
}
Ejemplo n.º 5
0
static void klog_file_log(void)
{
    klog_file_level = LOG_INFO;
    int result = klog_init_file(LOG_PATH, strlen(LOG_PATH), 256, 1);
    TEST_ASSERT_EQUAL_INT(result, 0);

    KLOG_INFO("test", "123:%d", 456);
    KLOG_WARN("logger", "hi");
    KLOG_ERR("o", "error");
    KLOG_DEBUG("b", "debug");
    klog_cleanup();

    FILE *log_file = fopen(LOG_PATH ".000", "r");
    TEST_ASSERT_NOT_NULL(log_file);

    char buffer[256];
    char lines[4][64];
    int i = 0;
    fread(buffer, 1, 256, log_file);

    for (char *token = strtok(buffer, "\n");
         token;
         token = strtok(NULL, "\n"), i++) {

        strcpy(lines[i], token);
    }

    ASSERT_STRING_STARTS_WITH(&lines[0][14], " test:I 123:456");
    ASSERT_STRING_STARTS_WITH(&lines[1][14], " logger:W hi");
    ASSERT_STRING_STARTS_WITH(&lines[2][14], " o:E error");
    TEST_ASSERT_EQUAL_INT(i, 4);
}
Ejemplo n.º 6
0
static int pcmcom8_wait_eedone(pcmcom8_board* brd)
{
        int cnt;
        unsigned char status;

        cnt = 10;
        while (--cnt) {
                set_current_state(TASK_INTERRUPTIBLE);
                schedule_timeout(1);
                status = inb(brd->addr + PCMCOM8_STA);
                if ((status & 0xc0) == 0x80) break;
        }
        KLOG_DEBUG("read EEPROM cnt=%d\n",cnt);
        if (cnt == 0) {
            KLOG_ERR("read EEPROM timeout\n");
            return -ETIMEDOUT;
        }
        return 0;
}
Ejemplo n.º 7
0
/* Don't add __exit macro to the declaration of this cleanup function
 * since it is also called at init time, if init fails. */
static void viper_dio_cleanup(void)
{
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35)
        int i;
        for (i = 0; i < _ngpio; i++)
                gpio_free(VIPER_PL9_OUT0 + i);
#endif

        if (viper_dio.vclass && !IS_ERR(viper_dio.vclass)) {
                if (viper_dio.device && !IS_ERR(viper_dio.device))
                        device_destroy(viper_dio.vclass, viper_dio.cdev.dev);
                class_destroy(viper_dio.vclass);
        }

        if (MAJOR(viper_dio.cdev.dev) != 0) {
                cdev_del(&viper_dio.cdev);
                viper_dio.cdev.dev =  MKDEV(0,0);
                unregister_chrdev_region(viper_dio.cdev.dev,1);
        }

        viper_dio.vclass = 0;

        KLOG_DEBUG("complete\n");
}
Ejemplo n.º 8
0
static int __init pcmcom8_init_module(void)
{
        int result, ib,itmp;
        dev_t devno;

        KLOG_NOTICE("version: %s\n", REPO_REVISION);

        for (ib = 0; ib < PCMCOM8_MAX_NR_DEVS; ib++)
          if (ioports[ib] == 0) break;
        pcmcom8_numboards = ib;
        KLOG_DEBUG("numboards=%d\n",pcmcom8_numboards);

        /*
         * Register your major, and accept a dynamic number. This is the
         * first thing to do, in order to avoid releasing other module's
         * fops in pcmcom8_cleanup_module()
         */
        result = alloc_chrdev_region(&pcmcom8_device, 0,
            pcmcom8_numboards,DRIVER_NAME);
        if (result < 0) goto fail;

        /*
         * allocate the board structures
         */
        pcmcom8_boards = kmalloc(pcmcom8_numboards * sizeof(pcmcom8_board), GFP_KERNEL);
        if (!pcmcom8_boards) {
                result = -ENOMEM;
                goto fail;
        }
        memset(pcmcom8_boards, 0, pcmcom8_numboards * sizeof(pcmcom8_board));

        pcmcom8_class = class_create(THIS_MODULE, DRIVER_NAME);
        if (IS_ERR(pcmcom8_class)) {
                result = PTR_ERR(pcmcom8_class);
                goto fail;
        }

        for (ib = 0; ib < pcmcom8_numboards; ib++) {
                pcmcom8_board* brd = pcmcom8_boards + ib;
                if (!request_region(ioports[ib],PCMCOM8_IO_REGION_SIZE,DRIVER_NAME)) {
                    result = -ENODEV;
                    goto fail;
                }
                brd->ioport = ioports[ib];
                brd->addr = brd->ioport + ioport_base;
                brd->region_req = 1;

#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16)
                mutex_init(&brd->mutex);
#else
                init_MUTEX(&brd->mutex);
#endif
                /*
                 * Read EEPROM configuration. If it doesn't return
                 * -ETIMEDOUT then it looks like there is a board at
                 * the given address.
                 */
                if (!pcmcom8_read_eeconfig(brd,&brd->config,0)) {
                        pcmcom8_nr_ok = ib + 1;
                        itmp = pcmcom8_check_config(&brd->config);
                        KLOG_INFO("EEPROM config for board %d,ioport %#x=%s\n",
                            ib,brd->ioport,(itmp ? "OK":"looks invalid"));
                }
                else {
                        release_region(brd->ioport, PCMCOM8_IO_REGION_SIZE);
                        brd->ioport = 0;
                        brd->region_req = 0;
                        break;
                }

                cdev_init(&brd->cdev,&pcmcom8_fops);
                brd->cdev.owner = THIS_MODULE;
                devno = MKDEV(MAJOR(pcmcom8_device),ib);
                // after calling cdev_add the device is ready for operations
                result = cdev_add(&brd->cdev,devno,1);
                if (result) goto fail;

                brd->device = device_create_x(pcmcom8_class, NULL,
                         devno, DRIVER_NAME "_%d", ib);
                if (IS_ERR(brd->device)) {
                        result = PTR_ERR(brd->device);
                        goto fail;
                }

        }
        if (pcmcom8_nr_ok == 0) {
                result = -ENODEV;
                goto fail;
        }
  
#ifdef DEBUG /* only when debugging */
        KLOG_DEBUG("create_proc\n");
        pcmcom8_create_proc();
#endif
        return result; /* succeed */

fail:
        pcmcom8_cleanup_module();
        return result;
}
Ejemplo n.º 9
0
static int __init viper_dio_init(void)
{	
        int result = -EINVAL;
        int i;
        dev_t devno = MKDEV(0,0);

        KLOG_NOTICE("version: %s\n",REPO_REVISION);

#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35)
        for (i = 0; i < 8; i++) {
                result = gpio_request(VIPER_PL9_OUT0 + i, "GPIO");
                if (result) {
                        KLOG_ERR("gpio_request failed for GPIO %d\n",VIPER_PL9_OUT0 + i);
                        goto err;
                }
                _ngpio = i + 1;
                result = gpio_direction_output(VIPER_PL9_OUT0, 0);
                if (result) {
                        KLOG_ERR("gpio_direction_output failed for GPIO %d\n",VIPER_PL9_OUT0 + i);
                        goto err;
                }
        }
#endif

        result = alloc_chrdev_region(&devno,0,1,"viper_dio");
        if (result < 0) goto err;

        mutex_init(&viper_dio.reg_mutex);

        // for informational messages only at this point
        sprintf(viper_dio.deviceName,"/dev/viper_dio%d",0);

        viper_dio.vclass = class_create(THIS_MODULE, "viper_dio");
        if (IS_ERR(viper_dio.vclass)) {
                result = PTR_ERR(viper_dio.vclass);
                goto err;
        }

        cdev_init(&viper_dio.cdev,&viper_dio_fops);
        viper_dio.cdev.owner = THIS_MODULE;

        /* After calling cdev_all the device is "live"
         * and ready for user operation.
         */
        result = cdev_add(&viper_dio.cdev, devno, 1);
        if (result) goto err;

        viper_dio.device = device_create_x(viper_dio.vclass, NULL,
                        devno, "viper_dio%d", 0);
        if (IS_ERR(viper_dio.device)) {
                result = PTR_ERR(viper_dio.device);
                goto err;
        }

        KLOG_DEBUG("complete.\n");

        return 0;
err:
        viper_dio_cleanup();
        return result;
}
Ejemplo n.º 10
0
/*
 * Allocate a circular buffer of dsm_samples.  If the size of one
 * sample is less than PAGE_SIZE, they are allocated in blocks of
 * size up to PAGE_SIZE.
 * dlen: length in bytes of the data portion of each sample.
 * blen: number of samples in the circular buffer.
 */
int alloc_dsm_circ_buf(struct dsm_sample_circ_buf* c,size_t dlen,int blen)
{
        int isamp = 0;
        int samps_per_page;
        int j,n;
        char *sp;

        /* count number of bits set, which should be one for a
         * power of 2.  Or check if first bit set
         * is the same as the last bit set: ffs(blen) == fls(blen)
         */
        if (blen == 0 || ffs(blen) != fls(blen)) {
                KLOG_ERR("circular buffer size=%d is not a power of 2\n",blen);
                return -EINVAL;
        }

        c->head = c->tail = c->size = c->npages = 0;
        c->pages = 0;

        KLOG_DEBUG("kmalloc %u bytes\n",blen * sizeof(void*));
        if (!(c->buf = kmalloc(blen * sizeof(void*),GFP_KERNEL))) return -ENOMEM;
        memset(c->buf,0,blen * sizeof(void*));

        /* Total size of a sample. Make it a multiple of sizeof(int)
         * so that samples are aligned to an int */
        dlen += SIZEOF_DSM_SAMPLE_HEADER;
        n = dlen % sizeof(int);
        if (n) dlen += sizeof(int) - n;

        samps_per_page = PAGE_SIZE / dlen;
        if (samps_per_page < 1) samps_per_page = 1;

        /* number of pages to allocate */
        n = (blen - 1) / samps_per_page + 1;
        if (!(c->pages = kmalloc(n * sizeof(void*),GFP_KERNEL))) {
                kfree(c->buf);
                c->buf = 0;
                return -ENOMEM;
        }
        memset(c->pages,0,n * sizeof(void*));
        c->npages = n;

        KLOG_INFO("sample len=%zu, buf len=%d, samps_per_page=%d, npages=%d\n",
                        dlen,blen,samps_per_page,n);

        for (n = 0; n < c->npages; n++) {
                j = blen - isamp;       /* left to allocate */
                if (j > samps_per_page) j = samps_per_page;
                sp = kmalloc(dlen * j,GFP_KERNEL);
                if (!sp) {
                        for (j = 0; j < n; j++) kfree(c->pages[j]);
                        kfree(c->pages);
                        c->pages = 0;
                        c->npages = 0;
                        kfree(c->buf);
                        c->buf = 0;
                        return -ENOMEM;
                }
                c->pages[n] = sp;

                for (j = 0; j < samps_per_page && isamp < blen; j++) {
                        c->buf[isamp++] = (struct dsm_sample*) sp;
                        sp += dlen;
                }
        }
        c->size = blen;
        smp_mb();
        return 0;
}
Ejemplo n.º 11
0
static void __exit nidas_util_cleanup(void)
{
        KLOG_DEBUG("nidas_util done\n");
        return;
}