48bit and 28bit ATA commands with ioctl - c

During sending ATA commands I found several classifications. For example, first one - we can divide the commands to Data-In, Data-Out and Non-Data commands. Another classification can be that there are 48bit commands and 28bit comands. First ones are for the disks, which are larger that 120Gb.
The question is: do I need to set up some values that the disk will know that it get the 48bit command or not? For example, if I send SCSI command with ATA through SATL or ATA PASS THROUGH command through the controller.

During the research it was found that every controller has its own specificities depending on the driver. That is why implementation of ATA PASS THROUGH commands are so difficult work.
Through reading the Linux driver and checking what structures are sent with ioctl it is possible to figure out if it is 28 or 48 bit command.
Moreover, it is also quite important to check how new is the software, because 48-bit Logical Block Addressing (LBA) was introduced in 2006 in ATA-6 standard. Most probably nowadays all the controllers supports 48-bit command set, but still you should check if the controller supports it.
So, the answer to this question strongly depends on the using controller.

Related

What is the difference between reboot arguments RB_HALT_SYSTEM and RB_POWER_OFF?

What is the real difference between the LINUX_REBOOT_CMD_HALT and LINUX_REBOOT_CMD_POWER_OFF arguments to the reboot() system call (resp. the RB_HALT_SYSTEM and RB_POWER_OFF arguments given to its wrapper function)?
The reboot(2) manual page has the following descriptions (differences emphasized):
RB_HALT_SYSTEM
LINUX_REBOOT_CMD_HALT
(RB_HALT_SYSTEM, 0xcdef0123; since Linux 1.1.76). The message "System halted." is printed, and the system is halted. Control is given to the ROM monitor, if there is one. If not preceded by a sync(2), data will be lost.
LINUX_REBOOT_CMD_POWER_OFF
(RB_POWER_OFF, 0x4321fedc; since Linux 2.1.30).
The message "Power down." is printed, the system is stopped, and all power is removed from the system, if possible. If not preceded by a sync(2), data will be lost.
Reading the descriptions, a few questions come up:
What is the difference between halted and stopped?
Would a reboot(RB_HALT_SYSTEM) call not remove power from the
system?
Where would the "System halted." and "Power down." messages be printed?
I don't think there is a difference; those words are synonyms in common English and I think this documentation is just using their English meaning, not as specific technical terms.
correct, that's exactly what the docs are trying to tell you.
on the console and/or kernel log, duh. Where kernel messages are normally printed, like during bootup.
You can easily try these for yourself to see what they do; the user-space shutdown(8) command has -H (halt) and -P / -h (poweroff) options, as well as -r. Read the man page. I assume it eventually makes a reboot(2) system call, or causes init to make one, after a sync.
And yes, the traditional shutdown -h command is halt + power off, i.e. POWER_OFF. Back in the old days, computers didn't used to be able to power themselves off, but these days that's usually what people think of as a non-reboot shutdown. Especially on systems where the kernel can't "return" to a BIOS / firmware command interface.
On a PC, one of the few use-cases I could imagine for halt without poweroff would be to insert a USB drive or CD before pressing the reset button (or ctrl+alt+delete). But maybe you don't want the currently-booted Linux kernel to react to the new hardware at all, so you want to halt Linux first.
You could poweroff to do this, but you don't need to and there's no need to start/stop your rotating disks and put extra wear on their motors.

Create UDP-like library in C

I am looking to implement some kind of transmission protocol in C, to use on a custom hardware. I have the ability to send and receive through RF, but I need to rely in some protocol that validates the package integrity sent/received, so I though it would be a good idea to implement some kind of UDP library.
Of course, if there is any way that I can modify the existing implementations for UDP or TCP so it works over my RF device it would be of great help. The only thing that I think it needs to be changed is the way that a single bit is sent, if I could change that on the UDP library (sys/socket.h) it would save me a lot of time.
UDP does not exist in standard C99 or C11.
It is generally part of some Internet Protocol layer. These are very complex software (as soon as you want some performance).
I would suggest to use some existing operating system kernel (e.g. Linux) and to write a network driver (e.g. for the Linux kernel) for your device. Life is too short to write a competitive UDP like layer (that could take you dozens of years).
addenda
Apparently, the mention of UDP in the question is confusing. Per your comments (which should go inside the question) you just want some serial protocol on a small 8 bits PIC 18F4550 microcontroller (32Kbytes ROM + 2Kbytes RAM). Without knowing additional constraints, I would suggest a tiny "textual" like protocol (e.g. in ASCII lines, no more than 128 bytes per line, \n terminated ....) and I would put some simple hex checksum inside it. In the 1980s Hayes modems had such things.
What you should then do is define and document the protocol first (e.g. as BNF syntax of the message lines), then implement it (probably with buffering and finite state automaton techniques). You might invent some message format like e.g. DOFOO?123,456%BE53 followed by a newline, meaning do the command DOFOO with arguments 123 then 456 and hex checksum BE53

Implementation of linux char driver with multiple parameters to access

I am writing a simple char driver which accesses a PCI card. It is registered to sysfs with the help of a new class and accessible under /dev/foodev. Using standard file operations I can perform simple read and write operations to the device.
My problem: I have multiple parameters stored at different addresses on the card (version, status, control, ...) which I would like access independently. Currently having only one read and one write function I therefore have to change the address every time again in the driver code.
Obviously there is a more convenient way to implement this. I stumbled about the two following approaches and was wondering which is the better one in terms of sustainability and user accessibility:
Using ioctl commands setting the address/parameter before an
access.
Having the device already nicely set up in udev using multiple attributes
(device_create_file()) of which the user than just can write/read from
different "files":
/dev/foodev
../version
../status
../control
I think you should take a look at the PCI framework to implement your driver.
Don't (mis)use ioctls; you'll have race conditions. Use the attributes as files. That scheme is already used in sysfs. E.G. look at GPIO LEDs and keys. – sawdust

sysfs, ifreq, IOCTL or ??? to programatically monitor network status

We have an embedded SoC running BusyBox Linux (kernel 2.6.x), and we have a need to monitor or at least notice in a timely manner when the network connection goes down or comes up (catching other events would be good but not essential).
I've spent a long time googling & reading SO threads and there seems to be a ton of different answers depending on the exact task at hand on the particular OS and the phases of the moon etc.
Our specific criteria are:
We are looking from inside a C program, so C code is preferable to command line calls.
Although the interface is always there, we can't guarantee it is or has ever been up (I have seen comments on some examples that only work when the interface is up even if the link is down)
It would be nice not to have to poll, but rather to send/catch status change messages as and when they happen. I believe the kernel may already get such messages from the driver, but I'm not sure if there's anything we can hook into?
I've narrowed the likely seeming answers down to a few candidates but can't work out which is the nicest (least overhead, most reliable, least likely to break in future versions):
cat sys/class/net/eth0/operstate
cat sys/class/net/eth0/carrier (I can find no good explanation of the difference between these two)
Using ifreq or various sequences of ioctl calls to read the socket status (looks kinda messy to me) as per answers here and here (more tidy looking).
Somehow catch status change messages???
You can use inotify to keep check on the /sys/class/net/eth0/operstate. Inotify allows different events to be watched on specified file or directory e.g. CREATE, MODIFY, WRITE etc.
You can seen the working example here

C Linux Device Programming - Reading Straight from /Dev

I have been playing with creating sounds using mathematical wave functions in C. The next step in my project is getting user input from a MIDI keyboard controller in order to modulate the waves to different pitches.
My first notion was that this would be relatively simple and that Linux, being Linux, would allow me to read the raw data stream from my device like I would any other file.
However, research overwhelmingly advises that I write a device driver for the MIDI controller. The general idea is that even though the device file may be present, the kernel will not know what system calls to execute when my application calls functions like read() and write().
Despite these warnings, I did an experiment. I plugged in the MIDI controller and cat'ed the "/dev/midi1" device file. A steady stream of null characters appeared, and when I pressed a key on the MIDI controller several bytes appeared corresponding to the expected Message Chunks that a MIDI device should output. MIDI Protocol Info
So my questions are:
Why does the cat'ed stream behave this way?
Does this mean that there is a plug and play device driver already installed on my system?
Should I still go ahead and write a device driver, or can I get away with reading it like a file?
Thank you in advanced for sharing your wisdom in these areas.
Why does the cat'ed stream behave this way?
Because that is presumably the raw MIDI data that is being received by the controller. The null bytes are probably some sort of sync tick.
Does this mean that there is a plug and play device driver already installed on my system?
Yes.
However, research overwhelmingly advises that I write a device driver for the MIDI controller. The general idea is that even though the device file may be present, the kernel will not know what system calls to execute when my application calls functions like read() and write().
<...>
Should I still go ahead and write a device driver, or can I get away with reading it like a file?
I'm not sure what you're reading or how you're coming to this conclusion, but it's wrong. :) You've already got a perfectly good driver installed for your MIDI controller -- go ahead and use it!
Are you sure you are reading NUL bytes? And not 0xf8 bytes? Because 0xf8 is the MIDI time tick status and is usually sent periodically to keep the instruments in sync. Try reading the device using od:
od -vtx1 /dev/midi1
If you're seeing a bunch of 0xf8, it's okay. If you don't need the tempo information sent by your MIDI controller, either disable it on your controller or ignore those 0xf8 status bytes.
Also, for MIDI, keep in mind that the current MIDI status is usually sent once (to save on bytes) and then the payload bytes follow for as long as needed. For example, the pitch bend status is byte 0xeK (where K is the channel number, i.e. 0 to 15) and its payload is 7 bits of the least significant byte followed by 7 bits of the most significant bytes. Thus, maybe you got a weird controller and you're seeing only repeated payloads of some status, but any controller that's not stupid won't repeat what it doesn't need to.
Now for the driver: have a look at dmesg when you plug in your MIDI controller. Now if your OSS /dev/midi1 appears when you plug in your device (udev is doing this job), and dmesg doesn't shoot any error, you don't need anything else. The MIDI protocol is yet-another-serial-protocol that has a fixed baudrate and transmits/receives bytes. There's nothing complicated about that... just read from or write to the device and you're done.
The only issue is that queuing at some place could result in bad audio latency (if you're using the MIDI commands to control live audio, which I believe is what you're doing). It seems like those devices are mostly made for system exclusive messages, that is, for example, downloading some patch/preset for a synthesizer online and uploading it to the device using MIDI. Latency doesn't really matter in this situation.
Also have a look at the ALSA way of playing with MIDI on Linux.
If you are not developing a new MIDI controller hardware, you shouldn't worry about writing a driver for it. It's the user's concern installing their hardware, and the vendor's obligation to supply the drivers.
Under Linux, you just read the file. Now to interpret and make useful things with the data.

Resources