FreeBSD/sys/dev/tdfx/tdfx_pci.c
/* Calls to ioctl(2) eventually end up here. Unhandled ioctls return an ENXIO,
 * normally, you would read in the data pointed to by data, then write your
 * output to it. The ioctl *should* normally return zero if everything is
 * alright, but 3dfx didn't make it that way...
 *
 * For all of the ioctl code, in the event of a real error,
 * we return -Exxxx rather than simply Exxxx. The reason for this
 * is that the ioctls actually RET information back to the program
 * sometimes, rather than filling it in the passed structure. We
 * want to distinguish errors from useful data, and maintain compatibility.
 *
 * There is this portion of the proc struct called p_retval[], we can store a
 * return value in td->td_retval[0] and place the return value if it is positive
 * in there, then we can return 0 (good). If the return value is negative, we
 * can return -retval and the error should be properly handled.
 */
Calls to ioctl(2) eventually end up here. Unhandled ioctls return an ENXIO,
normally, you would read in the data pointed to by data, then write your
output to it. The ioctl *should* normally return zero if everything is
alright, but 3dfx didn't make it that way

For all of the ioctl code, in the event of a real error,
we return -Exxxx rather than simply Exxxx. The reason for this
is that the ioctls actually RET information back to the program
sometimes, rather than filling it in the passed structure. We
want to distinguish errors from useful data, and maintain compatibility.

There is this portion of the proc struct called p_retval[], we can store a
return value in td->td_retval[0] and place the return value if it is positive
in there, then we can return 0 (good). If the return value is negative, we
can return -retval and the error should be properly handled.
Calls to ioctl ( 2 ) eventually end up here . Unhandled ioctls return an ENXIO normally you would read in the data pointed to by data then write your output to it . The ioctl * should * normally return zero if everything is alright but 3dfx didn ' t make it that way For all of the ioctl code in the event of a real error we return - Exxxx rather than simply Exxxx . The reason for this is that the ioctls actually RET information back to the program sometimes rather than filling it in the passed structure . We want to distinguish errors from useful data and maintain compatibility . There is this portion of the proc struct called p_retval [] we can store a return value in td - > td_retval [ 0 ] and place the return value if it is positive in there then we can return 0 ( good ) . If the return value is negative we can return - retval and the error should be properly handled .
static int
tdfx_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thread *td)
{
	int retval = 0;
	struct tdfx_pio_data *piod = (struct tdfx_pio_data*)data;
#ifdef	DEBUG
	printf("IOCTL'd by #%d, cmd: 0x%x, data: %p\n", td->td_proc->p_pid, (u_int32_t)cmd,
			piod);
#endif
	switch(_IOC_TYPE(cmd)) {
	case 0x33:
			if((retval = tdfx_do_query(cmd, piod)) > 0) td->td_retval[0] = retval;
			else return -retval;
			break;
		case 0:
			if((tdfx_do_pio(cmd, piod)) > 0) td->td_retval[0] = retval;
			else return -retval;
			break;
		default:
#ifdef DEBUG
			printf("Bad IOCTL from #%d\n", td->td_proc->p_pid);
#endif
			return ENXIO;
	}
	return 0;
}
static int tdfx_ioctl ( struct cdev * dev , u_long cmd , caddr_t data , int flag , struct thread * td ) { int retval = 0 ; struct tdfx_pio_data * piod = ( struct tdfx_pio_data * ) data ; #ifdef DEBUG printf ( " \n " , td -> td_proc -> p_pid , ( u_int32_t ) cmd , piod ) ; #endif switch ( _IOC_TYPE ( cmd ) ) { case 0x33 : if ( ( retval = tdfx_do_query ( cmd , piod ) ) > 0 ) td -> td_retval [ 0 ] = retval ; else return - retval ; break ; case 0 : if ( ( tdfx_do_pio ( cmd , piod ) ) > 0 ) td -> td_retval [ 0 ] = retval ; else return - retval ; break ; default : #ifdef DEBUG printf ( " \n " , td -> td_proc -> p_pid ) ; #endif return ENXIO ; } return 0 ; }
Calls to ioctl(2) eventually end up here.
Calls to ioctl ( 2 ) eventually end up here .
/* Return the real error if negative, or simply stick the valid return
		 * in td->td_retval */ /* The '3'(0x33) type IOCTL is for querying the installed cards */ /* The 0 type IOCTL is for programmed I/O methods */ /* Technically, we won't reach this from linux emu, but when glide
			 * finally gets ported, watch out! */