Skip to content

Commit c377d91

Browse files
authored
update eq3_char_loop to v1.3 (#568)
* apply relevant changes from 0002-version1_2.patch (cf. https://github.com/OpenCCU/OpenCCU/blob/master/buildroot-external/package/eq3_char_loop/0002-version1_2.patch) * apply 0003-Fix-eq3_char_loop-driver-build-on-Linux-6.4.patch (cf. https://github.com/OpenCCU/OpenCCU/blob/master/buildroot-external/package/eq3_char_loop/0003-Fix-eq3_char_loop-driver-build-on-Linux-6.4.patch) * apply 0005-eq3_char_loop-termios2.patch (cf. https://github.com/OpenCCU/OpenCCU/blob/master/buildroot-external/package/eq3_char_loop/0005-eq3_char_loop-termios2.patch) * remove class_create define as 0003-Fix-eq3_char_loop-driver-build-on-Linux-6.4.patch already introduces kernel 6.4+ compatibility.
1 parent e1a8cc8 commit c377d91

1 file changed

Lines changed: 80 additions & 11 deletions

File tree

kernel/eq3_char_loop.c

Lines changed: 80 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
#include <asm/termbits.h>
4141
#include <asm/termios.h>
4242
#include <asm/ioctls.h>
43+
#include <linux/serial.h>
4344
#include <linux/version.h>
4445

4546
#include "stack_protector.include"
@@ -70,10 +71,6 @@
7071
#define _access_ok(__type, __addr, __size) access_ok(__type, __addr, __size)
7172
#endif
7273

73-
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6,4,0))
74-
#define class_create(__owner, __class) class_create(__class)
75-
#endif
76-
7774
struct eq3loop_channel_data
7875
{
7976
struct circ_buf master2slave_buf;
@@ -365,7 +362,7 @@ static ssize_t eq3loop_write_master(struct eq3loop_channel_data* channel, struct
365362
{
366363
ret=-EFAULT;
367364
count_to_end = CIRC_SPACE( head, channel->master2slave_buf.tail, BUFSIZE);
368-
printk( KERN_ERR EQ3LOOP_DRIVER_NAME ": eq3loop_write_master() %s: not enought space in the buffers. free space = %zu, required space = %zu", channel->name,count_to_end,count );
365+
printk( KERN_ERR EQ3LOOP_DRIVER_NAME ": eq3loop_write_master() %s: not enough space in buffers. free space = %zu, required space = %zu", channel->name,count_to_end,count );
369366
goto out;
370367
}
371368
/* ok, space is free, write something */
@@ -401,7 +398,7 @@ static ssize_t eq3loop_write_master(struct eq3loop_channel_data* channel, struct
401398
up (&channel->sem);
402399
if(ret < 0)
403400
{
404-
printk( KERN_INFO EQ3LOOP_DRIVER_NAME ": eq3loop_write_master() retrun error:");
401+
printk( KERN_INFO EQ3LOOP_DRIVER_NAME ": eq3loop_write_master() return error: %zd", ret);
405402
}
406403
if( ret > 0 || CIRC_CNT(channel->master2slave_buf.head,channel->master2slave_buf.tail,BUFSIZE) )
407404
{
@@ -512,21 +509,76 @@ static long eq3loop_ioctl_slave(struct eq3loop_channel_data* channel, struct fil
512509
switch(cmd) {
513510

514511
case TCGETS:
515-
if( _access_ok(VERIFY_READ, (void *)arg, sizeof(struct termios) ) )
512+
if( _access_ok(VERIFY_WRITE, (void *)arg, sizeof(struct termios) ) )
516513
{
517514
ret = copy_to_user( (void*)arg, &channel->termios, sizeof(struct termios) );
518515
} else {
519516
ret = -EFAULT;
520517
}
521518
break;
522519
case TCSETS:
523-
if( _access_ok(VERIFY_WRITE, (void *)arg, sizeof(struct termios) ) )
520+
case TCSETSW:
521+
case TCSETSF:
522+
if( _access_ok(VERIFY_READ, (void *)arg, sizeof(struct termios) ) )
524523
{
525524
ret = copy_from_user( &channel->termios, (void*)arg, sizeof(struct termios) );
526525
} else {
527526
ret = -EFAULT;
528527
}
529528
break;
529+
#ifdef TCGETS2
530+
case TCGETS2:
531+
{
532+
struct termios2 t2;
533+
534+
memset(&t2, 0, sizeof(t2));
535+
t2.c_iflag = channel->termios.c_iflag;
536+
t2.c_oflag = channel->termios.c_oflag;
537+
t2.c_cflag = channel->termios.c_cflag;
538+
t2.c_lflag = channel->termios.c_lflag;
539+
t2.c_line = channel->termios.c_line;
540+
memcpy(t2.c_cc, channel->termios.c_cc, NCCS);
541+
t2.c_ispeed = 0;
542+
t2.c_ospeed = 0;
543+
544+
if( _access_ok(VERIFY_WRITE, (void *)arg, sizeof(struct termios2) ) )
545+
{
546+
ret = copy_to_user( (void*)arg, &t2, sizeof(struct termios2) );
547+
} else {
548+
ret = -EFAULT;
549+
}
550+
break;
551+
}
552+
#endif
553+
#ifdef TCSETS2
554+
case TCSETS2:
555+
#ifdef TCSETSW2
556+
case TCSETSW2:
557+
#endif
558+
#ifdef TCSETSF2
559+
case TCSETSF2:
560+
#endif
561+
{
562+
struct termios2 t2;
563+
564+
if( _access_ok(VERIFY_READ, (void *)arg, sizeof(struct termios2) ) )
565+
{
566+
ret = copy_from_user( &t2, (void*)arg, sizeof(struct termios2) );
567+
if( !ret )
568+
{
569+
channel->termios.c_iflag = t2.c_iflag;
570+
channel->termios.c_oflag = t2.c_oflag;
571+
channel->termios.c_cflag = t2.c_cflag;
572+
channel->termios.c_lflag = t2.c_lflag;
573+
channel->termios.c_line = t2.c_line;
574+
memcpy(channel->termios.c_cc, t2.c_cc, NCCS);
575+
}
576+
} else {
577+
ret = -EFAULT;
578+
}
579+
break;
580+
}
581+
#endif
530582
case TIOCINQ:
531583
temp = CIRC_CNT( channel->master2slave_buf.head, channel->master2slave_buf.tail, BUFSIZE);
532584
ret = __put_user( temp, (int*)arg );
@@ -546,10 +598,20 @@ static long eq3loop_ioctl_slave(struct eq3loop_channel_data* channel, struct fil
546598
case TIOCMSET:
547599
break;
548600
case TIOCSERGETLSR:
549-
ret = -ENOIOCTLCMD;
601+
temp = TIOCSER_TEMT;
602+
ret = __put_user( temp, (int*)arg );
550603
break;
551604
case TIOCGICOUNT:
552-
ret = -ENOIOCTLCMD;
605+
{
606+
struct serial_icounter_struct icount;
607+
memset(&icount, 0, sizeof(icount));
608+
if( _access_ok(VERIFY_WRITE, (void *)arg, sizeof(struct serial_icounter_struct) ) )
609+
{
610+
ret = copy_to_user( (void*)arg, &icount, sizeof(struct serial_icounter_struct) );
611+
} else {
612+
ret = -EFAULT;
613+
}
614+
}
553615
break;
554616
default:
555617
ret = -ENOTTY;
@@ -559,7 +621,6 @@ static long eq3loop_ioctl_slave(struct eq3loop_channel_data* channel, struct fil
559621
if( ret == -ENOTTY )
560622
{
561623
printk( KERN_NOTICE EQ3LOOP_DRIVER_NAME ": eq3loop_ioctl_slave() %s: unhandled ioctl 0x%04X\n", channel->name, cmd );
562-
ret = -ENOIOCTLCMD;
563624
}
564625
return ret;
565626
}
@@ -960,7 +1021,14 @@ static int __init eq3loop_init(void)
9601021
printk(KERN_ERR EQ3LOOP_DRIVER_NAME ": Unable to add driver\n");
9611022
goto out_unregister_chrdev_region;
9621023
}
1024+
/* Linux changed signature of class_create in 6.4+
1025+
* see: https://lore.kernel.org/all/20230324100132.1633647-1-gregkh@linuxfoundation.org/
1026+
*/
1027+
#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 4, 0)
9631028
control_data->class=class_create(THIS_MODULE, EQ3LOOP_DRIVER_NAME);
1029+
#else
1030+
control_data->class=class_create(EQ3LOOP_DRIVER_NAME);
1031+
#endif
9641032
if(IS_ERR(control_data->class)){
9651033
ret = -EIO;
9661034
printk(KERN_ERR EQ3LOOP_DRIVER_NAME ": Unable to register driver class\n");
@@ -1003,3 +1071,4 @@ module_init(eq3loop_init);
10031071
module_exit(eq3loop_exit);
10041072
MODULE_DESCRIPTION("eQ-3 IPC loopback char driver");
10051073
MODULE_LICENSE("GPL");
1074+
MODULE_VERSION("1.3");

0 commit comments

Comments
 (0)