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
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,
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
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
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.