macOS SO_REUSEPORT of setsockopt() - macos

SO_REUSEPORT is deleted to make the example work on macOS.
Socket programming - setsockopt: Protocol not available?
But man setsockopt on macOS clearly document the option SO_REUSEPORT.
SO_REUSEPORT enables duplicate address and port bindings
Why SO_REUSEPORT has to be removed to make the example? Is there a bug in setsockopt() on macOS? Where is the source code of setsockopt() on macOS?

SO_REUSEPORT is an option for secsockopt, so the source for it is in the kernel proper. That'd be xnu's sources, specifically the sys call handler checks validity (bsd/kern/uipc_socket.c) and the IPv4/v6 stacks
(bsd/netinet/in_pcb.c and bsd/netinet6/in6_pcb.c, respectively) implement it. From it, you can see two things:
that SO_REUSEPORT and SO_REUSEADDR actually work interchangeably in many cases (e.g. multicast).
it would work in the sample you referred to when put in two setsockopt(2) calls, as well: The mistake was that the options are not bitmasks, so | and + won't work with them - even though
#define SO_REUSEADDR 0x0004 /* allow local address reuse */
#define SO_REUSEPORT 0x0200 /* allow local address & port reuse */
are used in the kernel as bit masks later on (|'ed) , the code in kernel to handle getsockopt and check for validity uses a switch statement, so it ends up that neither option is honored, because it doesn't fall in those cases. Specifically, it's bsd/kern/uipc_socket.c:
int sosetoptlock(struct socket *so, struct sockopt *sopt, int dolock)
{
. ...
switch (sopt->sopt_name) {
. ..
case SO_REUSEADDR:
case SO_REUSEPORT:
case SO_OOBINLINE:
case SO_TIMESTAMP:
case SO_TIMESTAMP_MONOTONIC:
case SO_TIMESTAMP_CONTINUOUS:
case SO_DONTTRUNC:
case SO_WANTMORE:
case SO_WANTOOBFLAG:
case SO_NOWAKEFROMSLEEP:
case SO_NOAPNFALLBK:
error = sooptcopyin(sopt, &optval, sizeof(optval),
...

Related

How does GetCommState populate the DCB struct in Windows 10 when using usbser.sys CDC ACM driver

I am building a embedded device that will communicate to the outside world by virtual COM. I have the descriptor and all the callbacks for the USB set up correctly and COM is working - well kind of. The problem is that when I issue the GetCommState command for the COM I get a semi valid struct back and when one fixes only couple of parameters (like setting the speed and 8N1) and try to reconfigure the port by calling SetCommState the actions fails with: 'A device attached to the system is not functioning.'
If one continues to use the port it just work - all writes and reads - without a problem. But the issue is that most libraries try to reconfigure the port by first issuing the GetCommState and then SetCommState - pyserial and C# both do it in this way.
My question is where do the "default" configuration for COM comes form?
In the USB ACM CDC standard there are (optional) class requests for SET and GET COMM feature but I can see (from USB sniffer) that they are never called (I tried with capabilities for USB ACM CDC set to 0x06 (that is without SET/GET COMM) and 0x07 (with SET/GET COMM) but in no case I get a class request from the driver). So the driver must take the config from somewhere else, does anybody knows from where or how?
I am using an NXP LPC and Windows 10 with usbser.sys driver on other end.
What I already checked is:
compared the USB descriptor to the working one - they are the same
checked the USB traffic - the enumeration and communication looks the same
without doing GetCommState and SetCommState the COM is working without problem
I attached the content of the DCB struct for working sample (left) and my (right). I do not understand where do the marked values come from? Who sets them?
The settings should come from the port driver - you can view and set default values in the Windows Device Manager. In your case, it would seem that flow control with RTS/CTS is enabled (left picture), which might be something that your USB adapter uses internally. If it works, then leave those settings as they were.
I'd advise to do like this:
Always check the result of each API function you call!
Call CreateFile to get the port handle.
Optionally call GetCommTimeouts and store the result in a zero-initialized struct like COMMTIMEOUTS com_timeouts = {0};. Change members of the struct as needed, then call SetCommTimeouts.
Create an (almost) zero-initialized struct DCB dcb = { .DCBlength = sizeof(DCB) }.
Call GetCommState on this struct.
Set baudrate, parity, stop bits etc as required. Leave other members as they were.
Call SetCommState.

SO_REUSEPORT on macOS with libuv

the SO_REUSEPORT option not works on macOS with libuv.
uv_loop_init
uv_tcp_init_ex
uv_fileno // get fd
int option_value = 1;
setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &option_value, sizeof (int)
uv_tcp_bind
uv_thread_create 4
I see 4 same address and port binding at 0.0.0.0:8080, but only thread1's connection_cb works, so can I use this option with my program? thx.
macOS (and other BSDs) have a different SO_REUSEPORT implementation than Linux. On (relatively) recent Linux versions it will allow you to kernel level load balancing, but on BSDs only the last socket to bind will get the connections.
Long story short, it cannot be made to work, alas.

Port B GPIO ep93xx/gpio.c interrupt issue

I am having troubles with gpio interrupt issue.
According documentation for ep93xx ports A, B, F can be configured to generate interrupts.
quote:
Any of the 19 GPIO lines maybe configured to generate interrupts
However arch/arm/march-ep93xx/gpio.c is handling only interrupts from port A. And doesn't react to port B and F.
static void ep93xx_gpio_ab_irq_handler(unsigned int irq, struct irq_desc *desc)
{
unsigned char status;
int i;
printk(KERN_INFO "ep93xx_gpio_ab_irq_handler: irq=%u", irq);
I know printk is terrible in irq_handlers.
I am configuring iterrupts via sysfs.
GPIO 0,8 are wired with Port F if it is important to issue.
Also when enabling interrupts on port B without having configured port A i get following warning:
------------[ cut here ]------------
WARNING: at drivers/gpio/gpiolib.c:103 gpio_ensure_requested+0x54/0x118()
autorequest GPIO-1
Modules linked in:
[<c002696c>] (unwind_backtrace+0x0/0xf0) from [<c00399d4>] (warn_slowpath_fmt+0x54/0x78)
[<c00399d4>] (warn_slowpath_fmt+0x54/0x78) from [<c019dd90>] (gpio_ensure_requested+0x54/0x118)
[<c019dd90>] (gpio_ensure_requested+0x54/0x118) from [<c019e05c>] (gpio_direction_input+0xb0/0x150)
[<c019e05c>] (gpio_direction_input+0xb0/0x150) from [<c002c9a8>] (ep93xx_gpio_irq_type+0x3c/0x1d8)
[<c002c9a8>] (ep93xx_gpio_irq_type+0x3c/0x1d8) from [<c0066ad8>] (__irq_set_trigger+0x38/0x9c)
[<c0066ad8>] (__irq_set_trigger+0x38/0x9c) from [<c0066e14>] (__setup_irq+0x2d8/0x354)
[<c0066e14>] (__setup_irq+0x2d8/0x354) from [<c0066f38>] (request_threaded_irq+0xa8/0x140)
[<c0066f38>] (request_threaded_irq+0xa8/0x140) from [<c019e784>] (gpio_setup_irq+0x14c/0x260)
[<c019e784>] (gpio_setup_irq+0x14c/0x260) from [<c019ec1c>] (gpio_edge_store+0x90/0xac)
[<c019ec1c>] (gpio_edge_store+0x90/0xac) from [<c01be8fc>] (dev_attr_store+0x1c/0x28)
[<c01be8fc>] (dev_attr_store+0x1c/0x28) from [<c00e8b2c>] (sysfs_write_file+0x168/0x19c)
[<c00e8b2c>] (sysfs_write_file+0x168/0x19c) from [<c009a3d4>] (vfs_write+0xa4/0x160)
[<c009a3d4>] (vfs_write+0xa4/0x160) from [<c009a6a4>] (sys_write+0x3c/0x7c)
[<c009a6a4>] (sys_write+0x3c/0x7c) from [<c0020e40>] (ret_fast_syscall+0x0/0x2c)
---[ end trace ff56c09a294dbe68 ]---
I am using kernel version 2.6.34.14 with linux-2.6.34-ts7200_matt-6.tar.gz patch (hovewer it doesn't seem contain patches for gpio.c or gpiolib.c)
cross version:
binutils-2.23.1
gcc-4.7.3
glibc-2.17
Also i crawled through change history of gpio.c and gpiolib.c and didn't find anything that can be related to this issue.
Can someone give me and advice regarding this issue? I want interrupts on all ports (A,B,F) not just A.
There are a lot of question on this issue (and ARM irq OR interrupt). Please look at them.
We can see many changes by looking at more recent Linux 3.0 gpio.c change logs versus the 2.6.34 logs and the current version. You should be able to get the current Linux stable tree and extract these patches and back port them to your kernel. For instance, there is a bug where port C and F are swapped; I don't know if this is in your ts7200_matt variant.
Some important change sets to look at,
arm: Fold irq_set_chip/irq_set_handler
arm: Cleanup the irq namespace
arm: ep93xx: Use proper irq accessor functions
arm: ep93xx: Add basic interrupt info
ARM: ep93xx: irq_data conversion.
ARM: 5954/1: ep93xx: move gpio interrupt support to gpio.c
[ARM] 5243/1: ep93xx: bugfix, GPIO ports C and F are swapped
You may have #6, but it is worth looking at as it is basically the interrupt implementation for your controller. After about linux-3.0, your SOC's GPIO controller was moved to drivers/gpio/gpio-ep93xx.c. You may wish to look at these changes, but none seem to be related to your issue. You should be aware of structural changes to Linux. Ie, overall changes to interrupt handling and/or the generic GPIO infrastructure. A good guess is that Thomas Gleixner or Russell King will make these changes.
The patches can be extracted from a particular Linux stable tree with git format-patch b685004.. b0ec5cf1 gpio.c. This will create several patch files. Move them to your tree and apply with either git am or patch -p1. You may have to massage these files to get them to apply cleanly to your tree; if you take them all, even though they are not related to interrupt handling, you will have better luck doing this automatically. You can also look at the patch set and try to manually patch the file with a text editor.
None of this addresses your specific questions. However, it gives a path to merge changes from the latest Linux versions. Also, the previous stack overflow questions give details on the structure of the GPIO interrupt handling. Coupled with your data sheet, the Linux GPIO document, and the given change sets, you should be able to fix your own problem. Otherwise, you need someone familiar with the EP93xx and the question is fairly localized.
Note: The stack trace indicates that a GPIO is being used without a corresponding gpio_request()
. This is either a bug in the machine file or in the EP93xx GPIO interrupt handling code.
I had the same warning:
------------[ cut here ]------------
WARNING: at drivers/gpio/gpiolib.c:103 gpio_ensure_requested
From my research we have to call gpio_request_one / gpio_request, before gpio_direction_input.
It fixed the problem for me.
http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=99789
http://e2e.ti.com/support/embedded/linux/f/354/p/119946/427889.aspx

first kernel space driver in -- linux

I was able to control GPIO using mmap system call to control LED operation directly from the user space. Now I want to implement driver in kernel space.
I am trying to write my first kernel space device driver for 16*2 line of LCD in Linux for ARM controller RPi.
Now i need to access the GPIO for this purpose.
In AVR i use to access the Port like this.
#define PORTA *(volatile unsigned char*)0x30
I was reading LLD it tells to use inb() & outb() function to access the i/o port.
http://www.makelinux.net/ldd3/chp-9-sect-2
1> Can we not use #define address of port to access the GPIO ?
2> What is the advantages to use use inb() & outb() functions for controlling the GPIO ?
Please suggest.
In AVR i use to access the Port like this.
#define PORTA *(volatile unsigned char*)0x30
That's an improper definition that overloads the symbol PORTA.
Besides defining the port address as 0x30, you are also dereferencing that location.
So it is actually a read operation, but there's no indication of that in the name, i.e. you have really defined a macro for READ_PORTA.
1> Can we not use #define address of port to access the GPIO ?
Of course you can (and should).
#define PORTA (unsigned char *)0x30
You'll find similar statements in header files for device registers in the Linux source tree. When developing a new device driver, I look for a header file of #defines for all of the device's registers and command codes, and start writing one if no file is already available.
2> What is the advantages to use use inb() & outb() functions for controlling the GPIO ?
The code is then an unambiguous statement that I/O is being performed, regardless of whether the architecture uses I/O ports or memory-mapped I/O.
Anyone reading the following should be able to deduce what is going on:
x = inb(PORTA);
versus the confusion when using your macro:
x = PORTA;
The above statement using an overloaded macro would not pass a code review conducted by competent coders.
You should also get familiar with and use the Linux kernel coding style.
1) the use of defines simplifies your task often. You could, of course, not use define for your port and use this construction literally everywhere you need to access the port. But then you will have to replace the 0x30 everywhere with another address if you change the design of your device, for example, if you decide to connect your LED to port B. Also, it will make your code less readable. Alternatively you could declare a function that will access your port. If such a simple function is declared inline (if your compiler supports inlines) then there is no difference in performance.
2) the advantage of using inb() and outb() is portability of your program. If this is not an issue, then it is fine to access your port directly.

How do I port a serial port device driver from Linux 2.6.21 to 2.6.36?

It appears that some time between these two kernels a lot of data structures were changed, and it breaks my driver in several places.
First, in 2.6.21 the struct uart_port had a field "struct uart_info *info" which I relied on in several places. I test several places to make sure it is non-null, and if non-null I additionally test if it's sub-field (struct tty_struct *tty) is non-null, and I uses these to check if flow control is enabled and if we are stopped transmitting.
In 2.6.36 the info back pointer has been removed and I'm not sure how to get at it, or if the semantics of what I am trying to do are even valid any more, as the only serial driver that even uses this appears to have ifdef'ed out the code dealing with it, and additionally holds all this data in its own structures (how does that work to even correctly maintain state with the kernel)???
Additionally, save_and_cli() and restore_flags() are missing. I see new functions local_irq_save() and local_irq_restore(), can I just switch to using those, or are there any gotchas?
Finally, __ioremap is missing. Looks like maybe ioremap_noncache is the replacement, but again I'm not sure if there are any semantic differences or gotchas. I would assume I don't want ioremap() since I am talking directly to hardware, but some other drivers appear to do so and I don't know why that would work.
Looking at how an in-tree driver that uses the same functionality has changed between the two versions is usually the best way to go. For example, the ioc4_serial driver uses the info member of struct uart_port in kernel 2.6.21, but has switched to using the struct uart_state *state member by kernel 2.6.36.
That driver obtains the tty_struct with:
state = the_port->state;
tty = state->port.tty;

Resources