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; }
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; }