Menu

#27 Scramdisk 4 Linux 2.1 can't compile driver with 3.12 kernel

v1.0 (example)
open
nobody
None
5
2015-04-26
2014-04-01
No

Trying to compile Scramdisk 4 Linux on kernel 3.12.15, getting

make -C /lib/modules/3.12.15-pclos1/build SUBDIRS=/home/jcet/ScramDisk-2.1/driver modules
make[1]: Entering directory '/usr/src/kernel-devel-3.12.15-pclos1'
CC [M] /home/jcet/ScramDisk-2.1/driver/sddriver.o
/home/jcet/ScramDisk-2.1/driver/sddriver.c:254:3: warning: initialization from incompatible pointer type [enabled by default]
/home/jcet/ScramDisk-2.1/driver/sddriver.c:254:3: warning: (near initialization for ‘scramdisk_bdops.release’) [enabled by default]
/home/jcet/ScramDisk-2.1/driver/sddriver.c: In function ‘scramdisk_thread’:
/home/jcet/ScramDisk-2.1/driver/sddriver.c:1307:3: error: implicit declaration of function ‘daemonize’ [-Werror=implicit-function-declaration]
/home/jcet/ScramDisk-2.1/driver/sddriver.c: In function ‘scramdisk_splice_actor’:
/home/jcet/ScramDisk-2.1/driver/sddriver.c:1470:38: error: ‘KM_USER0’ undeclared (first use in this function)
/home/jcet/ScramDisk-2.1/driver/sddriver.c:1470:38: note: each undeclared identifier is reported only once for each function it appears in
/home/jcet/ScramDisk-2.1/driver/sddriver.c:1470:3: error: too many arguments to function ‘kmap_atomic’
In file included from include/linux/highmem.h:34:0,
from include/linux/pagemap.h:10,
from include/linux/buffer_head.h:13,
from /home/jcet/ScramDisk-2.1/driver/sddriver.c:212:
/usr/src/kernel-devel-3.12.15-pclos1/arch/x86/include/asm/highmem.h:64:7: note: declared here
/home/jcet/ScramDisk-2.1/driver/sddriver.c:1471:38: error: ‘KM_USER1’ undeclared (first use in this function)
/home/jcet/ScramDisk-2.1/driver/sddriver.c:1471:3: error: too many arguments to function ‘kmap_atomic’
In file included from include/linux/highmem.h:34:0,
from include/linux/pagemap.h:10,
from include/linux/buffer_head.h:13,
from /home/jcet/ScramDisk-2.1/driver/sddriver.c:212:
/usr/src/kernel-devel-3.12.15-pclos1/arch/x86/include/asm/highmem.h:64:7: note: declared here
/home/jcet/ScramDisk-2.1/driver/sddriver.c:1479:33: error: macro "kunmap_atomic" passed 2 arguments, but takes just 1
/home/jcet/ScramDisk-2.1/driver/sddriver.c:1479:3: error: ‘kunmap_atomic’ undeclared (first use in this function)
/home/jcet/ScramDisk-2.1/driver/sddriver.c:1480:34: error: macro "kunmap_atomic" passed 2 arguments, but takes just 1
/home/jcet/ScramDisk-2.1/driver/sddriver.c: In function ‘scramdisk_send’:
/home/jcet/ScramDisk-2.1/driver/sddriver.c:1596:40: error: ‘KM_USER0’ undeclared (first use in this function)
/home/jcet/ScramDisk-2.1/driver/sddriver.c:1596:5: error: too many arguments to function ‘kmap_atomic’
In file included from include/linux/highmem.h:34:0,
from include/linux/pagemap.h:10,
from include/linux/buffer_head.h:13,
from /home/jcet/ScramDisk-2.1/driver/sddriver.c:212:
/usr/src/kernel-devel-3.12.15-pclos1/arch/x86/include/asm/highmem.h:64:7: note: declared here
/home/jcet/ScramDisk-2.1/driver/sddriver.c:1597:32: error: ‘KM_USER1’ undeclared (first use in this function)
/home/jcet/ScramDisk-2.1/driver/sddriver.c:1597:5: error: too many arguments to function ‘kmap_atomic’
In file included from include/linux/highmem.h:34:0,
from include/linux/pagemap.h:10,
from include/linux/buffer_head.h:13,
from /home/jcet/ScramDisk-2.1/driver/sddriver.c:212:
/usr/src/kernel-devel-3.12.15-pclos1/arch/x86/include/asm/highmem.h:64:7: note: declared here
/home/jcet/ScramDisk-2.1/driver/sddriver.c:1614:35: error: macro "kunmap_atomic" passed 2 arguments, but takes just 1
/home/jcet/ScramDisk-2.1/driver/sddriver.c:1614:5: error: ‘kunmap_atomic’ undeclared (first use in this function)
/home/jcet/ScramDisk-2.1/driver/sddriver.c:1615:36: error: macro "kunmap_atomic" passed 2 arguments, but takes just 1
/home/jcet/ScramDisk-2.1/driver/sddriver.c: In function ‘scramdisk_init’:
/home/jcet/ScramDisk-2.1/driver/sddriver.c:1829:5: warning: passing argument 2 of ‘blk_queue_make_request’ from incompatible pointer type [enabled by default]
In file included from /home/jcet/ScramDisk-2.1/driver/sddriver.h:77:0,
from /home/jcet/ScramDisk-2.1/driver/sddriver.c:217:
include/linux/blkdev.h:923:13: note: expected ‘void ()(struct request_queue , struct bio )’ but argument is of type ‘int ()(struct request_queue , struct bio )’
cc1: some warnings being treated as errors
scripts/Makefile.build:308: recipe for target '/home/jcet/ScramDisk-2.1/driver/sddriver.o' failed
make[2]: [/home/jcet/ScramDisk-2.1/driver/sddriver.o] Error 1
Makefile:1221: recipe for target 'module/home/jcet/ScramDisk-2.1/driver' failed
make[1]:
[module/home/jcet/ScramDisk-2.1/driver] Error 2
make[1]: Leaving directory '/usr/src/kernel-devel-3.12.15-pclos1'
Makefile:97: recipe for target 'all' failed
make: *** [all] Error 2

Worked fine with 3.4 kernel yet... Am I doing something wrong? I use this wonderful software almost daily.

Discussion

  • Mike Ritchie

    Mike Ritchie - 2014-04-09

    The following patch to sddriver.c and makefiles seems to fix it for newer kernels.
    WARNING: not extensively tested.

    diff -ru a/ScramDisk-2.1/driver/Makefile b/ScramDisk-2.1/driver/Makefile
    --- a/ScramDisk-2.1/driver/Makefile
    +++ b/ScramDisk-2.1/driver/Makefile
    @@ -78,7 +78,9 @@
     MAINHDR = $(MAINSRC:.c=.h) sdstructs.h
     HEADERS = $(SOURCES:.c=.h) sdstructs.h
    
    -ifeq ($(MINOR),6)
    +KERNEL_GE_26 = $(shell [ $(MAJOR) -ge 3 -o \( $(MAJOR) -eq 2 -a $(MINOR) -ge 6 \) ] && echo true)
    +
    +ifeq ($(KERNEL_GE_26),true)
     EXTRADIR = extra
     MODULEOBJECT = scramdisk.ko
    
    diff -ru a/ScramDisk-2.1/driver/sddriver.c b/ScramDisk-2.1/driver/sddriver.c
    --- a/ScramDisk-2.1/driver/sddriver.c
    +++ b/ScramDisk-2.1/driver/sddriver.c
    @@ -208,6 +208,7 @@
    
     #include <linux/version.h>
     #include <linux/init.h>
    +#include <linux/kthread.h>
     #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
     #include <linux/buffer_head.h>
     #endif
    @@ -463,6 +464,7 @@
       int slot = 0;
       unsigned long flags = 0ul;
       struct inode* inode;
    +  struct task_struct *task;
    
       slot = scramdisk_getfreeslot();
       if (slot == -1)
    @@ -578,16 +580,22 @@
         slots[slot].sdbh_tail = NULL;
         err = kernel_thread(scramdisk_thread, &slots[slot],
                             CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
    +    if (err < 0)
    +    {
    +      printk(KERN_ERR "scramdisk: can't start kernel thread for container\n");
    +      goto error;
    +    }
     #else
         slots[slot].sdbio_head = NULL;
         slots[slot].sdbio_tail = NULL;
    -    err = kernel_thread(scramdisk_thread, &slots[slot], CLONE_KERNEL);
    -#endif
    -    if (err < 0)
    +    task = kthread_run(scramdisk_thread, &slots[slot], "scramdisk%2.2d", slot);
    +    
    +    if (IS_ERR(task))
         {
           printk(KERN_ERR "scramdisk: can't start kernel thread for container\n");
           goto error;
         }
    +#endif
     #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
         register_disk(&sd_disk, MKDEV(MAJOR_NR, slot << SLOTDEV_SHIFT),
                       SD_PARTITIONS, &scramdisk_bdops, mount->size >> SD_BLK_SHIFT);
    @@ -1304,13 +1312,13 @@
       struct bio* bio;
       sd_slot_t* p_slot = (sd_slot_t*)data;
    
    -  daemonize("scramdisk%2.2d", p_slot->slot);
       current->flags |= PF_NOFREEZE;
    
       while (1)
       {
         int finished = 0;
         unsigned long flags = 0ul;
    +    struct task_struct *task;
    
         if (p_slot->timeout > 0)
         {
    @@ -1322,8 +1330,8 @@
             printk(KERN_INFO "scramdisk_thread: slot %d timed out\n", p_slot->slot);
             if (p_slot->mount->mnt_point[0] != '-')
             {
    -          ret = kernel_thread(sd_shutdown_thread, p_slot, CLONE_KERNEL);
    -          if (ret < 0)
    +     task = kthread_run(sd_shutdown_thread, p_slot, "sd_shutdown%2.2d", p_slot->slot);
    +     if (IS_ERR(task))
                 printk(KERN_ERR "scramdisk: can't start kernel shutdown thread\n");
             }
           }
    @@ -1396,7 +1404,6 @@
       char* envp[] = { NULL };
    
       sprintf(slotarg, "%d", p_slot->slot);
    -  daemonize("sd_shutdown%2.2d", p_slot->slot);
       current->flags |= PF_NOFREEZE;
    
       ret = call_usermodehelper(SDHELPER_PROG, argv, envp, 1);
    @@ -1429,8 +1436,8 @@
         size = desc->count;
       n_sectors = size >> SD_BLK_SHIFT;
       crypt_sector = p_data->crypt_sector;
    -  raw_buf = kmap_atomic(page, KM_USER0);
    -  sd_buf = kmap_atomic(p_data->page, KM_USER1);
    +  raw_buf = kmap_atomic(page);
    +  sd_buf = kmap_atomic(p_data->page);
       memcpy(sd_buf + p_data->offset, raw_buf + offset, size);
       if (p_data->slot->mount->format == 0 && p_data->slot->context.sd != NULL)
         sd_decrypt_sectors((sd_buf + p_data->offset),
    @@ -1438,8 +1445,8 @@
       else if (p_data->slot->context.tc != NULL)
         tc_decrypt_sectors(sd_buf + p_data->offset, p_data->slot->context.tc,
                            crypt_sector, n_sectors);
    -  kunmap_atomic(sd_buf, KM_USER1);
    -  kunmap_atomic(raw_buf, KM_USER0);
    +  kunmap_atomic(sd_buf);
    +  kunmap_atomic(raw_buf);
       desc->count -= size;
       desc->written += size;
       p_data->offset += size;
    @@ -1467,8 +1474,8 @@
         size = p_data->slot->blocksize;
       n_sectors = size >> SD_BLK_SHIFT;
       crypt_sector = p_data->crypt_sector;
    -  raw_buf = kmap_atomic(p_buf->page, KM_USER0);
    -  sd_buf = kmap_atomic(p_data->page, KM_USER1);
    +  raw_buf = kmap_atomic(p_buf->page);
    +  sd_buf = kmap_atomic(p_data->page);
       memcpy(sd_buf + p_data->offset, raw_buf + p_buf->offset, size);
       if (p_data->slot->mount->format == 0 && p_data->slot->context.sd != NULL)
         sd_decrypt_sectors((sd_buf + p_data->offset),
    @@ -1476,8 +1483,8 @@
       else if (p_data->slot->context.tc != NULL)
         tc_decrypt_sectors(sd_buf + p_data->offset, p_data->slot->context.tc,
                            crypt_sector, n_sectors);
    -  kunmap_atomic(sd_buf, KM_USER1);
    -  kunmap_atomic(raw_buf, KM_USER0);
    +  kunmap_atomic(sd_buf);
    +  kunmap_atomic(raw_buf);
       flush_dcache_page(p_data->page);
       p_data->offset += size;
       p_data->crypt_sector += n_sectors;
    @@ -1593,8 +1600,8 @@
         if (pagecache_write_begin(filp, mapping, pos, size, 0, &page, &data))
           goto fail;
     #endif
    -    raw_buf = kmap_atomic(bv->bv_page, KM_USER0);
    -    sd_buf = kmap_atomic(page, KM_USER1);
    +    raw_buf = kmap_atomic(bv->bv_page);
    +    sd_buf = kmap_atomic(page);
         memcpy(sd_buf + offset, raw_buf + bv_offs, size);
         n_sectors = size >> SD_BLK_SHIFT;
         if (p_slot->mount->format == 0 && p_slot->context.sd != NULL)
    @@ -1611,8 +1618,8 @@
           tc_encrypt_sectors(sd_buf + offset, p_slot->context.tc,
                              crypt_sector, n_sectors);
         }
    -    kunmap_atomic(sd_buf, KM_USER1);
    -    kunmap_atomic(raw_buf, KM_USER0);
    +    kunmap_atomic(sd_buf);
    +    kunmap_atomic(raw_buf);
     #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
         flush_dcache_page(page);
         if (aops->commit_write(filp, page, offset, offset + size))
    diff -ru a/ScramDisk-2.1/Makefile b/ScramDisk-2.1/Makefile
    --- a/ScramDisk-2.1/Makefile
    +++ b/ScramDisk-2.1/Makefile
    @@ -180,7 +180,7 @@
        if test "$(MINOR)" = "4"; then \
          mkdir -p $(LIBDIR) && \
          install -m 0644 driver/scramdisk.o $(LIBDIR); \
    -   elif test "$(MINOR)" = "6"; then \
    +   elif test "$(MINOR)" = "6" -o "$(MAJOR)" = "3"; then \
          mkdir -p $(LIBDIR) && \
          install -m 0644 driver/scramdisk.ko $(LIBDIR); \
        fi
    
     
  • Mike Ritchie

    Mike Ritchie - 2014-05-29

    Additionally, the following patches are needed for kernel 3.14.
    Please test.

    diff -ru a/ScramDisk-2.1/driver/sddriver.c b/ScramDisk-2.1/driver/sddriver.c
    --- a/ScramDisk-2.1/driver/sddriver.c
    +++ b/ScramDisk-2.1/driver/sddriver.c
    @@ -359,7 +359,7 @@
         if (sdinf->uid == current->uid || sdinf->uid == current->euid ||
             capable(CAP_SYS_ADMIN))
     #else
    -    if (sdinf->uid == current_uid() || sdinf->uid == current_euid() ||
    +    if (sdinf->uid == __kuid_val(current_uid()) || sdinf->uid == __kuid_val(current_euid()) ||
             capable(CAP_SYS_ADMIN))
     #endif
         {
    @@ -475,7 +475,7 @@
     #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)
         slots[slot].uid = current->uid;
     #else
    -    slots[slot].uid = current_uid();
    +    slots[slot].uid = __kuid_val(current_uid());
     #endif
         spin_lock_irqsave(&slots[slot].slot_lock, flags);
         slots[slot].state = sd_inactive;
    @@ -747,7 +747,7 @@
     #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)
       if (uid == current->uid || uid == current->euid || capable(CAP_SYS_ADMIN))
     #else
    -  if (uid == current_uid() || uid == current_euid() || capable(CAP_SYS_ADMIN))
    +  if (uid == __kuid_val(current_uid()) || uid == __kuid_val(current_euid()) || capable(CAP_SYS_ADMIN))
     #endif
       {
         int count;
    @@ -1498,7 +1498,7 @@
     }
     #endif
    
    -int scramdisk_receive(sd_slot_t* p_slot, struct bio_vec* bvec, loff_t pos)
    +int scramdisk_receive(sd_slot_t* p_slot, struct bio_vec bvec, loff_t pos)
     {
       int ret;
       struct file* filp = p_slot->filp;
    @@ -1509,15 +1509,15 @@
       struct splice_desc desc;
    
       desc.len = 0;
    -  desc.total_len = bvec->bv_len;
    +  desc.total_len = bvec.bv_len;
       desc.flags = 0;
       desc.pos = pos;
       desc.u.data = &data;
     #endif
    
       data.slot = p_slot;
    -  data.page = bvec->bv_page;
    -  data.offset = bvec->bv_offset;
    +  data.page = bvec.bv_page;
    +  data.offset = bvec.bv_offset;
       if (p_slot->mount->format == 0 && p_slot->context.sd != NULL)
         data.crypt_sector = (pos - SD_CRYPT_OFFS) >> SD_BLK_SHIFT;
       else if (p_slot->context.tc != NULL)
    @@ -1536,17 +1536,17 @@
    
     int scramdisk_read(sd_slot_t* p_slot, struct bio* bio)
     {
    -  int segnr;
    +  struct bvec_iter iter;
       int ret = 0;
    -  loff_t pos = ((loff_t)bio->bi_sector + p_slot->vol_sectoff) << SD_BLK_SHIFT;
    -  struct bio_vec* bvec;
    +  loff_t pos = ((loff_t)bio->bi_iter.bi_sector + p_slot->vol_sectoff) << SD_BLK_SHIFT;
    +  struct bio_vec bvec;
    
    -  bio_for_each_segment(bvec, bio, segnr)
    +  bio_for_each_segment(bvec, bio, iter)
       {
         ret = scramdisk_receive(p_slot, bvec, pos);
         if (unlikely(ret < 0))
           break;
    -    pos += bvec->bv_len;
    +    pos += bvec.bv_len;
       }
       if (!ret)
     #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
    @@ -1557,13 +1557,13 @@
       return ret;
     }
    
    -int scramdisk_send(sd_slot_t* p_slot, struct bio_vec* bv, loff_t pos)
    +int scramdisk_send(sd_slot_t* p_slot, struct bio_vec bv, loff_t pos)
     {
    -  int len = bv->bv_len;
    +  int len = bv.bv_len;
       int n_sectors;
       uint64 crypt_sector;
       unsigned int size;
    -  unsigned int bv_offs = bv->bv_offset;
    +  unsigned int bv_offs = bv.bv_offset;
       unsigned int offset = pos & ((pgoff_t)PAGE_CACHE_SIZE - 1);
       pgoff_t index = pos >> PAGE_CACHE_SHIFT;
       struct page* page;
    @@ -1600,7 +1600,7 @@
         if (pagecache_write_begin(filp, mapping, pos, size, 0, &page, &data))
           goto fail;
     #endif
    -    raw_buf = kmap_atomic(bv->bv_page);
    +    raw_buf = kmap_atomic(bv.bv_page);
         sd_buf = kmap_atomic(page);
         memcpy(sd_buf + offset, raw_buf + bv_offs, size);
         n_sectors = size >> SD_BLK_SHIFT;
    @@ -1660,22 +1660,22 @@
    
     int scramdisk_write(sd_slot_t* p_slot, struct bio* bio)
     {
    -  int segnr;
    +  struct bvec_iter iter;
       int ret = 0;
    -  loff_t pos = ((loff_t)bio->bi_sector + p_slot->vol_sectoff) << SD_BLK_SHIFT;
    -  struct bio_vec* bvec;
    +  loff_t pos = ((loff_t)bio->bi_iter.bi_sector + p_slot->vol_sectoff) << SD_BLK_SHIFT;
    +  struct bio_vec bvec;
    
       if (p_slot->mount->rd_only)
       {
         printk(KERN_ERR "scramdisk: attempt to write read only device\n");
         return -EACCES;
       }
    -  bio_for_each_segment(bvec, bio, segnr)
    +  bio_for_each_segment(bvec, bio, iter)
       {
         ret = scramdisk_send(p_slot, bvec, pos);
         if (unlikely(ret < 0))
           break;
    -    pos += bvec->bv_len;
    +    pos += bvec.bv_len;
       }
       if (!ret)
     #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
    @@ -1699,7 +1699,7 @@
       }
       if (p_slot == NULL || p_slot->mount == NULL)
         return -EINVAL;
    -  if (bio->bi_sector*SD_BLOCK_SIZE + bio->bi_size > p_slot->mount->size)
    +  if (bio->bi_iter.bi_sector*SD_BLOCK_SIZE + bio->bi_iter.bi_size > p_slot->mount->size)
       {
         printk(KERN_ERR "scramdisk_make_request: request past end of device\n");
     #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
    diff -ru a/ScramDisk-2.1/driver/sddriver.h b/ScramDisk-2.1/driver/sddriver.h
    --- a/ScramDisk-2.1/driver/sddriver.h
    +++ b/ScramDisk-2.1/driver/sddriver.h
    @@ -137,9 +137,9 @@
     int scramdisk_write(sd_slot_t* p_slot, struct buffer_head* bh);
     int scramdisk_make_request(request_queue_t* q, int rw, struct buffer_head* bh);
     #else
    -int scramdisk_receive(sd_slot_t* p_slot, struct bio_vec* bvec, loff_t pos);
    +int scramdisk_receive(sd_slot_t* p_slot, struct bio_vec bvec, loff_t pos);
     int scramdisk_read(sd_slot_t* p_slot, struct bio* bio);
    -int scramdisk_send(sd_slot_t* p_slot, struct bio_vec* bv, loff_t pos);
    +int scramdisk_send(sd_slot_t* p_slot, struct bio_vec bv, loff_t pos);
     int scramdisk_write(sd_slot_t* p_slot, struct bio* bio);
     int scramdisk_make_request(struct request_queue* q, struct bio* bio);
     #endif
    
     
  • Mike Ritchie

    Mike Ritchie - 2015-04-26

    Patch for 3.19 kernel:

    diff -ru a/ScramDisk-2.1/driver/sddriver.c b/ScramDisk-2.1/driver/sddriver.c
    --- a/ScramDisk-2.1/driver/sddriver.c
    +++ b/ScramDisk-2.1/driver/sddriver.c
    @@ -528,7 +528,7 @@
           slots[slot].filp = NULL;
           goto error;
         }
    -    inode = slots[slot].filp->f_dentry->d_inode;
    +    inode = slots[slot].filp->f_path.dentry->d_inode;
         if (!S_ISREG(inode->i_mode) && !S_ISBLK(inode->i_mode))
         {
           printk(KERN_ERR "scramdisk: container is neither a regular file "
    @@ -1172,7 +1172,7 @@
       unsigned long index = pos >> PAGE_CACHE_SHIFT;
       char* data = bh->b_data;
       struct page* page;
    -  struct address_space* mapping = p_slot->filp->f_dentry->d_inode->i_mapping;
    +  struct address_space* mapping = p_slot->filp->f_path.dentry->d_inode->i_mapping;
       struct address_space_operations* aops = mapping->a_ops;
    
       if (p_slot->mount->rd_only)
    diff -ru a/ScramDisk-2.1/driver/volume.c b/ScramDisk-2.1/driver/volume.c
    --- a/ScramDisk-2.1/driver/volume.c
    +++ b/ScramDisk-2.1/driver/volume.c
    @@ -266,7 +266,7 @@
             memcmp(check_blocks, check_blocks+1024, 512) == 0 ||
             memcmp(check_blocks+512, check_blocks+1024, 512) == 0)
         { /* We have found a working digest/cipher combination */
    -      struct inode* inode = filp->f_dentry->d_inode;
    +      struct inode* inode = filp->f_path.dentry->d_inode;
           unsigned int year, mon, day, hour, min, sec;
           octet* p;
           sd_slot->context.sd = ctx;
    @@ -602,7 +602,7 @@
       digest_t digest;
       mm_segment_t oldfs;
       struct file* filp = sd_slot->filp;
    -  struct inode* inode = filp->f_dentry->d_inode;
    +  struct inode* inode = filp->f_path.dentry->d_inode;
    
       sd_slot->context.tc = NULL;
    
     

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.