In a project of mine, I noticed that passing the specific integer '2' as a command to a device driver I was working on caused it to return -1 without even entering my ioctl_handle function or giving a reason. After doing a bit of reading I learned that these command numbers are shared across the system and you can get some weird behavior using the same numbers for different drivers.
Being in a hurry, I chose an arbitrary integer above 200 as an offset for all my commands knowing in the back of my mind that I'd need to find the 'proper' solution. Now that I have some spare time, I google'd around a bit and found there are some macros for just this purpose:
_IO is used for generating a simple command integer that needs to define a command and (optionally) get an integer return value. int type is an arbitrarily chosen number unique to this device driver. int number is the number you wish to assign to the command (often in a range beginning with 0 or 1).
A simple example using this macro is as follows:
There are three more that are similar but used if you are generating a command that will be passing a pointer to a data-structure in the call to IOCTL in user-space.
Each takes a third parameter data_type which is the data-structure type that you intend to send/receive. _IOR for example is used if you intend to have the kernel code fill your struct with some data, hence the notion of a READ. _IOW and _IORW are similar but for writing and read/writing respectively.