Ejemplo n.º 1
0
static void * CDCEther_probe( struct usb_device *usb, unsigned int ifnum,
			     const struct usb_device_id *id)
{
	struct net_device	*net;
	ether_dev_t		*ether_dev;
	int 			rc;

	// First we should check the active configuration to see if 
	// any other driver has claimed any of the interfaces.
	if ( check_for_claimed_interfaces( usb->actconfig ) ) {
		// Someone has already put there grubby paws on this device.
		// We don't want it now...
		return NULL;
	}

	// We might be finding a device we can use.
	// We all go ahead and allocate our storage space.
	// We need to because we have to start filling in the data that
	// we are going to need later.
	if(!(ether_dev = kmalloc(sizeof(ether_dev_t), GFP_KERNEL))) {
		err("out of memory allocating device structure");
		return NULL;
	}

	// Zero everything out.
	memset(ether_dev, 0, sizeof(ether_dev_t));

	// Let's see if we can find a configuration we can use.
	rc = find_valid_configuration( usb, ether_dev );
	if (rc)	{
		// Nope we couldn't find one we liked.
		// This device was not meant for us to control.
		kfree( ether_dev );
		return	NULL;
	}

	// Now that we FOUND a configuration. let's try to make the 
	// device go into it.
	if ( usb_set_configuration( usb, ether_dev->bConfigurationValue ) ) {
		err("usb_set_configuration() failed");
		kfree( ether_dev );
		return NULL;
	}

	// Now set the communication interface up as required.
	if (usb_set_interface(usb, ether_dev->comm_bInterfaceNumber, ether_dev->comm_bAlternateSetting)) {
		err("usb_set_interface() failed");
		kfree( ether_dev );
		return NULL;
	}

	// Only turn traffic on right now if we must...
	if (ether_dev->data_interface_altset_num_without_traffic >= 0)	{
		// We found an alternate setting for the data
		// interface that allows us to turn off traffic.
		// We should use it.
		if (usb_set_interface( usb, 
		                       ether_dev->data_bInterfaceNumber, 
		                       ether_dev->data_bAlternateSetting_without_traffic)) {
			err("usb_set_interface() failed");
			kfree( ether_dev );
			return NULL;
		}
	} else	{
		// We didn't find an alternate setting for the data
		// interface that would let us turn off traffic.
		// Oh well, let's go ahead and do what we must...
		if (usb_set_interface( usb, 
		                       ether_dev->data_bInterfaceNumber, 
		                       ether_dev->data_bAlternateSetting_with_traffic)) {
			err("usb_set_interface() failed");
			kfree( ether_dev );
			return NULL;
		}
	}

	// Now we need to get a kernel Ethernet interface.
	net = init_etherdev( NULL, 0 );
	if ( !net ) {
		// Hmm...  The kernel is not sharing today...
		// Fine, we didn't want it anyway...
		err( "Unable to initialize ethernet device" );
		kfree( ether_dev );
		return	NULL;
	}

	// Now that we have an ethernet device, let's set it up
	// (And I don't mean "set [it] up the bomb".)
	net->priv = ether_dev;
	net->open = CDCEther_open;
	net->stop = CDCEther_close;
	net->watchdog_timeo = CDC_ETHER_TX_TIMEOUT;
	net->tx_timeout = CDCEther_tx_timeout;   // TX timeout function
	net->do_ioctl = CDCEther_ioctl;
	net->hard_start_xmit = CDCEther_start_xmit;
	net->set_multicast_list = CDCEther_set_multicast;
	net->get_stats = CDCEther_netdev_stats;
	net->mtu = ether_dev->wMaxSegmentSize - 14;

	// We'll keep track of this information for later...
	ether_dev->usb = usb;
	ether_dev->net = net;
	
	// and don't forget the MAC address.
	set_ethernet_addr( ether_dev );

	// Send a message to syslog about what we are handling
	log_device_info( ether_dev );

	// I claim this interface to be a CDC Ethernet Networking device
	usb_driver_claim_interface( &CDCEther_driver, 
	                            &(usb->config[ether_dev->configuration_num].interface[ether_dev->comm_interface]), 
	                            ether_dev );
	// I claim this interface to be a CDC Ethernet Networking device
	usb_driver_claim_interface( &CDCEther_driver, 
	                            &(usb->config[ether_dev->configuration_num].interface[ether_dev->data_interface]), 
	                            ether_dev );

	// Does this REALLY do anything???
	usb_inc_dev_use( usb );

	// TODO - last minute HACK
	ether_dev->comm_ep_in = 5;

	// Okay, we are finally done...
	return NULL;
}
Ejemplo n.º 2
0
static void *
camera_probe (struct usb_device *dev, unsigned int ifnum, const struct usb_device_id *camera_info)
{
	int				i;
	struct usb_interface_descriptor	*interface;
	struct usb_endpoint_descriptor	*endpoint;
	int				direction, ep;
	char name[8];
	struct camera_state		*camera = NULL;


	/* these have one config, one interface */
	if (dev->descriptor.bNumConfigurations != 1
			|| dev->config[0].bNumInterfaces != 1) {
		dbg ("Bogus camera config info");
		return NULL;
	}

	/* models differ in how they report themselves */
	interface = &dev->actconfig->interface[ifnum].altsetting[0];
	if ((interface->bInterfaceClass != USB_CLASS_PER_INTERFACE
		&& interface->bInterfaceClass != USB_CLASS_VENDOR_SPEC)
			|| interface->bInterfaceSubClass != 0
			|| interface->bInterfaceProtocol != 0
			|| interface->bNumEndpoints != 2
			) {
		dbg ("Bogus camera interface info");
		return NULL;
	}


	/* select "subminor" number (part of a minor number) */
	down (&state_table_mutex);
	for (i = 0; i < MAX_CAMERAS; i++) {
		if (!minor_data [i])
			break;
	}
	if (i >= MAX_CAMERAS) {
		info ("Ignoring additional USB Camera");
		goto bye;
	}

	/* allocate & init camera state */
	camera = minor_data [i] = kmalloc (sizeof *camera, GFP_KERNEL);
	if (!camera) {
		err ("no memory!");
		goto bye;
	}

	init_MUTEX (&camera->sem);
	camera->info = camera_info;
	camera->subminor = i;
	camera->buf = NULL;
	init_waitqueue_head (&camera->wait);


	/* get input and output endpoints (either order) */
	endpoint = interface->endpoint;
	camera->outEP = camera->inEP =  -1;

	ep = endpoint [0].bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
	direction = endpoint [0].bEndpointAddress & USB_ENDPOINT_DIR_MASK;
	if (direction == USB_DIR_IN)
		camera->inEP = ep;
	else
		camera->outEP = ep;

	ep = endpoint [1].bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
	direction = endpoint [1].bEndpointAddress & USB_ENDPOINT_DIR_MASK;
	if (direction == USB_DIR_IN)
		camera->inEP = ep;
	else
		camera->outEP = ep;

	if (camera->outEP == -1 || camera->inEP == -1
			|| endpoint [0].bmAttributes != USB_ENDPOINT_XFER_BULK
			|| endpoint [1].bmAttributes != USB_ENDPOINT_XFER_BULK
			) {
		dbg ("Bogus endpoints");
		goto error;
	}

	info ("USB Camera #%d connected, major/minor %d/%d", camera->subminor,
		USB_MAJOR, USB_CAMERA_MINOR_BASE + camera->subminor);

	camera->dev = dev;
	usb_inc_dev_use (dev);

	/* If we have devfs, register the device */
	sprintf(name, "dc2xx%d", camera->subminor);
	camera->devfs = devfs_register(usb_devfs_handle, name,
				       DEVFS_FL_DEFAULT, USB_MAJOR,
				       USB_CAMERA_MINOR_BASE + camera->subminor,
				       S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP |
				       S_IWGRP, &usb_camera_fops, NULL);

	goto bye;

error:
	minor_data [camera->subminor] = NULL;
	kfree (camera);
	camera = NULL;
bye:
	up (&state_table_mutex);
	return camera;
}