Two parameters? (I take it, syscall number and a pointer to data.)
ioctl can do the same. It takes a number and an unsigned long
(sufficent for a pointer) to data. I could do the same over a cdev, a
32-bit quantity serving as a number and a 64-bit quantity as a
pointer. The same holds for netlink. There are endless ways to pass
on bits into the kernel, and be it an ICMP packet. Once you have the
addresses, you can use copy_from_user(), and be done. That still
does not say why syscalls are better than ioctl or netlink.
Well, nl and cdevs become especially handy when passing on more data
than just a pointer... usually you can do away with the pointer
indirection, e.g.
struct timespec n;
syscall(123, &n);
vs ioctl(somefd, 123, &n);
vs write(cdevfd, &n, sizeof(n));
vs nlmsg_write(it's not so easy in NL after all);
hooray. Win = 0.
It is not. The reiser4() system call was just as heavily debated
because it just did not seem to fit.
It does not make any sense to discuss here. Each task to achieve has
a specific preferred method (syscalls, cdev, libnl, ioctl) to do it
over.
Maybe syscalls have been ok 20+ years ago. Maybe people still don't
know cdevs or netlink because they are submerged in teaching DOS
semantics only.
If syscalls were so übergreat, then /dev would be a lot less populated:
Where's my nvidiactl() syscall?
--