kern/104675: Apparently there is a clash between two ioctls

Jukka A. Ukkonen jau at iki.fi
Sun Oct 22 05:00:34 PDT 2006


>Number:         104675
>Category:       kern
>Synopsis:       Apparently there is a clash between two ioctls
>Confidential:   no
>Severity:       serious
>Priority:       high
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Sun Oct 22 12:00:32 GMT 2006
>Closed-Date:
>Last-Modified:
>Originator:     Jukka A. Ukkonen
>Release:        FreeBSD 6.2-PRERELEASE i386
>Organization:
Private person
>Environment:
System: FreeBSD mjolnir 6.2-PRERELEASE FreeBSD 6.2-PRERELEASE #1: Wed Oct 18 08:04:30 EEST 2006 root at mjolnir:/usr/obj/usr/src/sys/Mjolnir i386


>Description:
	It seems that the bktr driver cannot change the input connector
	used when using a card with multiple connectors.
	When I used ktrace to see what happens at the kernel API level
	I got somewhat disturbing output...

 56314 try      CALL  ioctl(0x3,METEORGINPUT,0xbfbfed24)
 56314 try      RET   ioctl 0
 56314 try      CALL  ioctl(0x3,SERIAL_SETINVCLK,0xbfbfed20)
 56314 try      RET   ioctl 0
 56314 try      CALL  ioctl(0x3,METEORGINPUT,0xbfbfed20)
 56314 try      RET   ioctl 0

      It seems that METEORGINPUT is recognized properly but its
      complement METEORSINPUT is not. Instead METEORSINPUT gets
      mapped to something completely unrelated (SERIAL_SETINVCLK).

      This make multiconnector BT cards completely useless, because
      only one connector can be used.
      Multiconnector cards would be the device of choice for purposes
      like video surveilance with motion capture etc. when one needs
      only one or two frames per camera per second.

      Because this makes a full class of devices useless and seriously
      harms every application which benefits from capturing a single
      frame now and then from multiple cameras, I classify this as
      a serious bug with high priority.
      Currently the only way to monitor multiple cameras is using
      multiple cards with a single functional connector per card.
      This is wasting card slots all too quickly when multiple cameras
      are needed.

>How-To-Repeat:

	Try the following snippet. On my system there is no change.
	As a second test do the same attempts to change the input
	connector using ktrace to monitor the kernel API. The outcome
	should be like shown above, METEORSINPUT gets mixed with
	SERIAL_SETINVCLK.

#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <sys/ioctl.h>
#include <errno.h>

#include <dev/bktr/ioctl_bt848.h>
#include <dev/bktr/ioctl_meteor.h>

static const char	bktr[] = "/dev/bktr";

int
main (ac, av)
	int	ac;
	char	*av[];
{
	unsigned long	oldval;
	unsigned long	iocval;
	int		iocret;
	int		fd;
	char		*endp;

	fd = open (bktr, O_RDWR, 0);

	if (fd < 0) {
		perror (bktr);
		exit (-1);
	}

	printf ("fd = %d\n", fd);

	if (ac > 1) {
		iocval = strtoul (av[1], &endp, 0);

		if ((endp <= av[1]) || (*endp && ! isspace (*endp))) {
			errno = EINVAL;

			fprintf (stderr, "%s: %s %s\r\n",
				 av[0], av[1], strerror (errno));
			exit (-1);
		}

#if 0
#define METEOR_INPUT_DEV0       0x01000 /* camera input 0 -- default */
#define METEOR_INPUT_DEV_RCA    METEOR_INPUT_DEV0
#define METEOR_INPUT_DEV1       0x02000 /* camera input 1 */
#define METEOR_INPUT_DEV2       0x04000 /* camera input 2 */
#define METEOR_INPUT_DEV3       0x08000 /* camera input 3 */
#define METEOR_INPUT_DEV_RGB    0x0a000 /* for rgb version of meteor */
#define METEOR_INPUT_DEV_SVIDEO 0x06000 /* S-video input port */
#endif

		iocval &= 0xf;
		switch (iocval) {
		case	0x1:
		case	0x2:
		case	0x4:
		case	0x6:
		case	0x8:
		case	0xa:
			break;

		default:
			errno = EINVAL;
			fprintf (stderr, "%s: %s %s\r\n",
				 av[0], av[1], strerror (errno));
			exit (-1);
			break;
		}

		iocval << 12;

		if ((iocret = ioctl (fd, METEORGINPUT, &oldval)) < 0) {
			fprintf (stderr, "%s: %s\r\n", 
				 bktr, strerror (errno));
			exit (-1);
		}

		oldval &= ~0xf000;
		iocval |= oldval;

		if ((iocret = ioctl (fd, METEORSINPUT, &iocval)) < 0) {
			fprintf (stderr, "%s: %s\r\n", 
				 bktr, strerror (errno));
			exit (-1);
		}
	}

	if ((iocret = ioctl (fd, METEORGINPUT, &iocval)) < 0) {
		fprintf (stderr, "%s: %s\r\n", 
			 bktr, strerror (errno));
		exit (-1);
	}

	printf ("input channel = %d %lx %lu\n", 
		iocret, iocval, (iocval >> 12));

	exit (0);
}


>Fix:
	None yet. Supposedly requires a change in the kernel ioctl
	mappings.

>Release-Note:
>Audit-Trail:
>Unformatted:


More information about the freebsd-bugs mailing list