Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I am just confused like how can I break cmd=3222823425 value into different parts to figure out what this command means actually in the Linux kernel. I know, some functions are making ioctl command with following parameters but I want to know what these parameter values mean.

fd=21, cmd=3222823425 and arg=3203118816 

I have been looking into various forums, man pages and other links to figure this out like what does it mean when a cmd in an ioctl system call has value of 3222823425. I have found that cmd is a command number which consists of type, number and data_type and first twos are 8-bit integers (0-255).

So my question is how to decode these parameter values to find out what this call is trying to do?

share|improve this question
add comment

1 Answer

up vote 4 down vote accepted

An ioctl goes to a driver, so the most important thing to figure out what an ioctl is doing is which driver is handling it.

What you've read about type, number and data_type is a convention that driver writers are supposed to use when choosing ioctl numbers. Although different drivers can use the same value to mean completely different things, it's best to avoid this, so that if an ioctl is accidentally sent to the wrong device, there is a good chance that it will return an error rather than cause some catastrophic event.

A good description of the convention is in the book Linux Device Drivers (LDD), chapter 6. The data_type is in fact (since some time early in the 2.6.x series IIRC) made of two parts, direction and size.

  • type (8 bits) is a constant that must be consistent across the ioctls implemented in a driver and should be different from ioctls of unrelated devices if possible. There is an out-of-date repository of type values in Documentation/ioctl/ioctl-number.txt.
  • number (8 bits) should be different for all the ioctls in a driver.
  • direction (2 bits) indicate the direction of data transfer (0=none, 1=write, 2=read, 3=both).
  • size is the size of the data buffer, if the ioctl argument is a pointer to a data buffer.

The ioctl number should be

 direction << 30 | size << 16 | type << 8 | number

(If you're writing a driver, use the _IOC_* macros defined in asm-generic/ioctl.h.)

For your ioctl number 3222823425 = 0xc0186201, we get type=0x62 (known as “bit3 vme host bridge” in 1999), number=1, direction=2 and size=0x18=24, so the ioctl takes a 24-byte input parameter.

This ioctl value should be defined as _IOR(0x62, 0x01, struct somestruct) or something equivalent like _IOR('b', 1, struct somestruct), where struct somestruct is a 24-byte structure. If you don't know what driver is processing the ioctl, you can search for a call like this in the kernel source to gather candidates. However, note that a simple text search often won't find the driver, because it's common for them to use a macro, e.g. #define FOOIO_TYPE 0x62 followed by #define FOOIO_SOMETHING _IOR(FOOIO_TYPE, 1, struct foobar).

An ioctl call has two parameters in addition to the file descriptor that the ioctl acts on: the ioctl number cmd, and an argument arg. The argument can be an immediate value or a pointer to a buffer. Here, if the driver writer is following the convention, arg should be a pointer to a 24-byte buffer in the application memory space.

share|improve this answer
    
An awesome explanation..One quick question: By direction=2, you mean both read and write or direction value? I assume the first one as c(Hex)= 1100 (binary) where 11 are 30th and 31st bit of cmd and 11(bin) = 3(dec). So direction= 3 would be correct. Isn't so? –  Junaid Jan 9 '13 at 6:11
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.