/* * drivers/usb/usb.c * * (C) Copyright Linus Torvalds 1999 * (C) Copyright Johannes Erdfelt 1999-2001 * (C) Copyright Andreas Gal 1999 * (C) Copyright Gregory P. Smith 1999 * (C) Copyright Deti Fliegl 1999 (new USB architecture) * (C) Copyright Randy Dunlap 2000 * (C) Copyright David Brownell 2000 (kernel hotplug, usb_device_id) * (C) Copyright Yggdrasil Computing, Inc. 2000 * (usb_device_id matching changes by Adam J. Richter) * * NOTE! This is not actually a driver at all, rather this is * just a collection of helper routines that implement the * generic USB things that the real drivers can use.. * * Think of this as a "USB library" rather than anything else. * It should be considered a slave, with no callbacks. Callbacks * are evil. */ #include #include #include #include #include #include /* for in_interrupt() */ #include #include #include #include #ifdef CONFIG_USB_DEBUG #define DEBUG #else #undef DEBUG #endif #include static const int usb_bandwidth_option = #ifdef CONFIG_USB_BANDWIDTH 1; #else 0; #endif extern int usb_hub_init(void); extern void usb_hub_cleanup(void); /* * Prototypes for the device driver probing/loading functions */ static void usb_find_drivers(struct usb_device *); static int usb_find_interface_driver(struct usb_device *, unsigned int); static void usb_check_support(struct usb_device *); /* * We have a per-interface "registered driver" list. */ LIST_HEAD(usb_driver_list); LIST_HEAD(usb_bus_list); struct semaphore usb_bus_list_lock; devfs_handle_t usb_devfs_handle; /* /dev/usb dir. */ static struct usb_busmap busmap; static struct usb_driver *usb_minors[16]; /** * usb_register - register a USB driver * @new_driver: USB operations for the driver * * Registers a USB driver with the USB core. The list of unattached * interfaces will be rescanned whenever a new driver is added, allowing * the new driver to attach to any recognized devices. * Returns a negative error code on failure and 0 on success. */ int usb_register(struct usb_driver *new_driver) { if (new_driver->fops != NULL) { if (usb_minors[new_driver->minor/16]) { err("error registering %s driver", new_driver->name); return -EINVAL; } usb_minors[new_driver->minor/16] = new_driver; } info("registered new driver %s", new_driver->name); init_MUTEX(&new_driver->serialize); /* Add it to the list of known drivers */ list_add_tail(&new_driver->driver_list, &usb_driver_list); usb_scan_devices(); return 0; } /** * usb_scan_devices - scans all unclaimed USB interfaces * * Goes through all unclaimed USB interfaces, and offers them to all * registered USB drivers through the 'probe' function. * This will automatically be called after usb_register is called. * It is called by some of the USB subsystems after one of their subdrivers * are registered. */ void usb_scan_devices(void) { struct list_head *tmp; down (&usb_bus_list_lock); tmp = usb_bus_list.next; while (tmp != &usb_bus_list) { struct usb_bus *bus = list_entry(tmp,struct usb_bus, bus_list); tmp = tmp->next; usb_check_support(bus->root_hub); } up (&usb_bus_list_lock); } /* * This function is part of a depth-first search down the device tree, * removing any instances of a device driver. */ static void usb_drivers_purge(struct usb_driver *driver,struct usb_device *dev) { int i; if (!dev) { err("null device being purged!!!"); return; } for (i=0; ichildren[i]) usb_drivers_purge(driver, dev->children[i]); if (!dev->actconfig) return; for (i = 0; i < dev->actconfig->bNumInterfaces; i++) { struct usb_interface *interface = &dev->actconfig->interface[i]; if (interface->driver == driver) { down(&driver->serialize); driver->disconnect(dev, interface->private_data); up(&driver->serialize); /* if driver->disconnect didn't release the interface */ if (interface->driver) usb_driver_release_interface(driver, interface); /* * This will go through the list looking for another * driver that can handle the device */ usb_find_interface_driver(dev, i); } } } /** * usb_deregister - unregister a USB driver * @driver: USB operations of the driver to unregister * * Unlinks the specified driver from the internal USB driver list. */ void usb_deregister(struct usb_driver *driver) { struct list_head *tmp; info("deregistering driver %s", driver->name); if (driver->fops != NULL) usb_minors[driver->minor/16] = NULL; /* * first we remove the driver, to be sure it doesn't get used by * another thread while we are stepping through removing entries */ list_del(&driver->driver_list); down (&usb_bus_list_lock); tmp = usb_bus_list.next; while (tmp != &usb_bus_list) { struct usb_bus *bus = list_entry(tmp,struct usb_bus,bus_list); tmp = tmp->next; usb_drivers_purge(driver, bus->root_hub); } up (&usb_bus_list_lock); } struct usb_interface *usb_ifnum_to_if(struct usb_device *dev, unsigned ifnum) { int i; for (i = 0; i < dev->actconfig->bNumInterfaces; i++) if (dev->actconfig->interface[i].altsetting[0].bInterfaceNumber == ifnum) return &dev->actconfig->interface[i]; return NULL; } struct usb_endpoint_descriptor *usb_epnum_to_ep_desc(struct usb_device *dev, unsigned epnum) { int i, j, k; for (i = 0; i < dev->actconfig->bNumInterfaces; i++) for (j = 0; j < dev->actconfig->interface[i].num_altsetting; j++) for (k = 0; k < dev->actconfig->interface[i].altsetting[j].bNumEndpoints; k++) if (epnum == dev->actconfig->interface[i].altsetting[j].endpoint[k].bEndpointAddress) return &dev->actconfig->interface[i].altsetting[j].endpoint[k]; return NULL; } /* * usb_calc_bus_time: * * returns (approximate) USB bus time in nanoseconds for a USB transaction. */ static long usb_calc_bus_time (int low_speed, int input_dir, int isoc, int bytecount) { unsigned long tmp; if (low_speed) /* no isoc. here */ { if (input_dir) { tmp = (67667L * (31L + 10L * BitTime (bytecount))) / 1000L; return (64060L + (2 * BW_HUB_LS_SETUP) + BW_HOST_DELAY + tmp); } else { tmp = (66700L * (31L + 10L * BitTime (bytecount))) / 1000L; return (64107L + (2 * BW_HUB_LS_SETUP) + BW_HOST_DELAY + tmp); } } /* for full-speed: */ if (!isoc) /* Input or Output */ { tmp = (8354L * (31L + 10L * BitTime (bytecount))) / 1000L; return (9107L + BW_HOST_DELAY + tmp); } /* end not Isoc */ /* for isoc: */ tmp = (8354L * (31L + 10L * BitTime (bytecount))) / 1000L; return (((input_dir) ? 7268L : 6265L) + BW_HOST_DELAY + tmp); } /* * usb_check_bandwidth(): * * old_alloc is from host_controller->bandwidth_allocated in microseconds; * bustime is from calc_bus_time(), but converted to microseconds. * * returns if successful, * or USB_ST_BANDWIDTH_ERROR if bandwidth request fails. * * FIXME: * This initial implementation does not use Endpoint.bInterval * in managing bandwidth allocation. * It probably needs to be expanded to use Endpoint.bInterval. * This can be done as a later enhancement (correction). * This will also probably require some kind of * frame allocation tracking...meaning, for example, * that if multiple drivers request interrupts every 10 USB frames, * they don't all have to be allocated at * frame numbers N, N+10, N+20, etc. Some of them could be at * N+11, N+21, N+31, etc., and others at * N+12, N+22, N+32, etc. * However, this first cut at USB bandwidth allocation does not * contain any frame allocation tracking. */ int usb_check_bandwidth (struct usb_device *dev, struct urb *urb) { int new_alloc; int old_alloc = dev->bus->bandwidth_allocated; unsigned int pipe = urb->pipe; long bustime; bustime = usb_calc_bus_time (usb_pipeslow(pipe), usb_pipein(pipe), usb_pipeisoc(pipe), usb_maxpacket(dev, pipe, usb_pipeout(pipe))); if (usb_pipeisoc(pipe)) bustime = NS_TO_US(bustime) / urb->number_of_packets; else bustime = NS_TO_US(bustime); new_alloc = old_alloc + (int)bustime; /* what new total allocated bus time would be */ if (new_alloc > FRAME_TIME_MAX_USECS_ALLOC) dbg("usb-check-bandwidth %sFAILED: was %u, would be %u, bustime = %ld us", usb_bandwidth_option ? "" : "would have ", old_alloc, new_alloc, bustime); if (!usb_bandwidth_option) /* don't enforce it */ return (bustime); return (new_alloc <= FRAME_TIME_MAX_USECS_ALLOC) ? bustime : USB_ST_BANDWIDTH_ERROR; } void usb_claim_bandwidth (struct usb_device *dev, struct urb *urb, int bustime, int isoc) { dev->bus->bandwidth_allocated += bustime; if (isoc) dev->bus->bandwidth_isoc_reqs++; else dev->bus->bandwidth_int_reqs++; urb->bandwidth = bustime; #ifdef USB_BANDWIDTH_MESSAGES dbg("bandwidth alloc increased by %d to %d for %d requesters", bustime, dev->bus->bandwidth_allocated, dev->bus->bandwidth_int_reqs + dev->bus->bandwidth_isoc_reqs); #endif } /* * usb_release_bandwidth(): * * called to release a pipe's bandwidth (in microseconds) */ void usb_release_bandwidth(struct usb_device *dev, struct urb *urb, int isoc) { dev->bus->bandwidth_allocated -= urb->bandwidth; if (isoc) dev->bus->bandwidth_isoc_reqs--; else dev->bus->bandwidth_int_reqs--; #ifdef USB_BANDWIDTH_MESSAGES dbg("bandwidth alloc reduced by %d to %d for %d requesters", urb->bandwidth, dev->bus->bandwidth_allocated, dev->bus->bandwidth_int_reqs + dev->bus->bandwidth_isoc_reqs); #endif urb->bandwidth = 0; } static void usb_bus_get(struct usb_bus *bus) { atomic_inc(&bus->refcnt); } static void usb_bus_put(struct usb_bus *bus) { if (atomic_dec_and_test(&bus->refcnt)) kfree(bus); } /** * usb_alloc_bus - creates a new USB host controller structure * @op: pointer to a struct usb_operations that this bus structure should use * * Creates a USB host controller bus structure with the specified * usb_operations and initializes all the necessary internal objects. * (For use only by USB Host Controller Drivers.) * * If no memory is available, NULL is returned. * * The caller should call usb_free_bus() when it is finished with the structure. */ struct usb_bus *usb_alloc_bus(struct usb_operations *op) { struct usb_bus *bus; bus = kmalloc(sizeof(*bus), GFP_KERNEL); if (!bus) return NULL; memset(&bus->devmap, 0, sizeof(struct usb_devmap)); #ifdef DEVNUM_ROUND_ROBIN bus->devnum_next = 1; #endif /* DEVNUM_ROUND_ROBIN */ bus->op = op; bus->root_hub = NULL; bus->hcpriv = NULL; bus->busnum = -1; bus->bandwidth_allocated = 0; bus->bandwidth_int_reqs = 0; bus->bandwidth_isoc_reqs = 0; INIT_LIST_HEAD(&bus->bus_list); INIT_LIST_HEAD(&bus->inodes); atomic_set(&bus->refcnt, 1); return bus; } /** * usb_free_bus - frees the memory used by a bus structure * @bus: pointer to the bus to free * * (For use only by USB Host Controller Drivers.) */ void usb_free_bus(struct usb_bus *bus) { if (!bus) return; usb_bus_put(bus); } /** * usb_register_bus - registers the USB host controller with the usb core * @bus: pointer to the bus to register * * (For use only by USB Host Controller Drivers.) */ void usb_register_bus(struct usb_bus *bus) { int busnum; down (&usb_bus_list_lock); busnum = find_next_zero_bit(busmap.busmap, USB_MAXBUS, 1); if (busnum < USB_MAXBUS) { set_bit(busnum, busmap.busmap); bus->busnum = busnum; } else warn("too many buses"); usb_bus_get(bus); /* Add it to the list of buses */ list_add(&bus->bus_list, &usb_bus_list); up (&usb_bus_list_lock); usbdevfs_add_bus(bus); info("new USB bus registered, assigned bus number %d", bus->busnum); } /** * usb_deregister_bus - deregisters the USB host controller * @bus: pointer to the bus to deregister * * (For use only by USB Host Controller Drivers.) */ void usb_deregister_bus(struct usb_bus *bus) { info("USB bus %d deregistered", bus->busnum); /* * NOTE: make sure that all the devices are removed by the * controller code, as well as having it call this when cleaning * itself up */ down (&usb_bus_list_lock); list_del(&bus->bus_list); up (&usb_bus_list_lock); usbdevfs_remove_bus(bus); clear_bit(bus->busnum, busmap.busmap); usb_bus_put(bus); } /* * This function is for doing a depth-first search for devices which * have support, for dynamic loading of driver modules. */ static void usb_check_support(struct usb_device *dev) { int i; if (!dev) { err("null device being checked!!!"); return; } for (i=0; ichildren[i]) usb_check_support(dev->children[i]); if (!dev->actconfig) return; /* now we check this device */ if (dev->devnum > 0) for (i = 0; i < dev->actconfig->bNumInterfaces; i++) usb_find_interface_driver(dev, i); } /* * This is intended to be used by usb device drivers that need to * claim more than one interface on a device at once when probing * (audio and acm are good examples). No device driver should have * to mess with the internal usb_interface or usb_device structure * members. */ void usb_driver_claim_interface(struct usb_driver *driver, struct usb_interface *iface, void* priv) { if (!iface || !driver) return; dbg("%s driver claimed interface %p", driver->name, iface); iface->driver = driver; iface->private_data = priv; } /* usb_driver_claim_interface() */ /* * This should be used by drivers to check other interfaces to see if * they are available or not. */ int usb_interface_claimed(struct usb_interface *iface) { if (!iface) return 0; return (iface->driver != NULL); } /* usb_interface_claimed() */ /* * This should be used by drivers to release their claimed interfaces */ void usb_driver_release_interface(struct usb_driver *driver, struct usb_interface *iface) { /* this should never happen, don't release something that's not ours */ if (!iface || iface->driver != driver) return; iface->driver = NULL; iface->private_data = NULL; } /** * usb_match_id - find first usb_device_id matching device or interface * @dev: the device whose descriptors are considered when matching * @interface: the interface of interest * @id: array of usb_device_id structures, terminated by zero entry * * usb_match_id searches an array of usb_device_id's and returns * the first one matching the device or interface, or null. * This is used when binding (or rebinding) a driver to an interface. * Most USB device drivers will use this indirectly, through the usb core, * but some layered driver frameworks use it directly. * These device tables are exported with MODULE_DEVICE_TABLE, through * modutils and "modules.usbmap", to support the driver loading * functionality of USB hotplugging. * * What Matches: * * The "match_flags" element in a usb_device_id controls which * members are used. If the corresponding bit is set, the * value in the device_id must match its corresponding member * in the device or interface descriptor, or else the device_id * does not match. * * "driver_info" is normally used only by device drivers, * but you can create a wildcard "matches anything" usb_device_id * as a driver's "modules.usbmap" entry if you provide an id with * only a nonzero "driver_info" field. If you do this, the USB device * driver's probe() routine should use additional intelligence to * decide whether to bind to the specified interface. * * What Makes Good usb_device_id Tables: * * The match algorithm is very simple, so that intelligence in * driver selection must come from smart driver id records. * Unless you have good reasons to use another selection policy, * provide match elements only in related groups, and order match * specifiers from specific to general. Use the macros provided * for that purpose if you can. * * The most specific match specifiers use device descriptor * data. These are commonly used with product-specific matches; * the USB_DEVICE macro lets you provide vendor and product IDs, * and you can also match against ranges of product revisions. * These are widely used for devices with application or vendor * specific bDeviceClass values. * * Matches based on device class/subclass/protocol specifications * are slightly more general; use the USB_DEVICE_INFO macro, or * its siblings. These are used with single-function devices * where bDeviceClass doesn't specify that each interface has * its own class. * * Matches based on interface class/subclass/protocol are the * most general; they let drivers bind to any interface on a * multiple-function device. Use the USB_INTERFACE_INFO * macro, or its siblings, to match class-per-interface style * devices (as recorded in bDeviceClass). * * Within those groups, remember that not all combinations are * meaningful. For example, don't give a product version range * without vendor and product IDs; or specify a protocol without * its associated class and subclass. */ const struct usb_device_id * usb_match_id(struct usb_device *dev, struct usb_interface *interface, const struct usb_device_id *id) { struct usb_interface_descriptor *intf = 0; /* proc_connectinfo in devio.c may call us with id == NULL. */ if (id == NULL) return NULL; /* It is important to check that id->driver_info is nonzero, since an entry that is all zeroes except for a nonzero id->driver_info is the way to create an entry that indicates that the driver want to examine every device and interface. */ for (; id->idVendor || id->bDeviceClass || id->bInterfaceClass || id->driver_info; id++) { if ((id->match_flags & USB_DEVICE_ID_MATCH_VENDOR) && id->idVendor != dev->descriptor.idVendor) continue; if ((id->match_flags & USB_DEVICE_ID_MATCH_PRODUCT) && id->idProduct != dev->descriptor.idProduct) continue; /* No need to test id->bcdDevice_lo != 0, since 0 is never greater than any unsigned number. */ if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_LO) && (id->bcdDevice_lo > dev->descriptor.bcdDevice)) continue; if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_HI) && (id->bcdDevice_hi < dev->descriptor.bcdDevice)) continue; if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_CLASS) && (id->bDeviceClass != dev->descriptor.bDeviceClass)) continue; if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_SUBCLASS) && (id->bDeviceSubClass!= dev->descriptor.bDeviceSubClass)) continue; if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_PROTOCOL) && (id->bDeviceProtocol != dev->descriptor.bDeviceProtocol)) continue; intf = &interface->altsetting [interface->act_altsetting]; if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_CLASS) && (id->bInterfaceClass != intf->bInterfaceClass)) continue; if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_SUBCLASS) && (id->bInterfaceSubClass != intf->bInterfaceSubClass)) continue; if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_PROTOCOL) && (id->bInterfaceProtocol != intf->bInterfaceProtocol)) continue; return id; } return NULL; } /* * This entrypoint gets called for each new device. * * We now walk the list of registered USB drivers, * looking for one that will accept this interface. * * "New Style" drivers use a table describing the devices and interfaces * they handle. Those tables are available to user mode tools deciding * whether to load driver modules for a new device. * * The probe return value is changed to be a private pointer. This way * the drivers don't have to dig around in our structures to set the * private pointer if they only need one interface. * * Returns: 0 if a driver accepted the interface, -1 otherwise */ static int usb_find_interface_driver(struct usb_device *dev, unsigned ifnum) { struct list_head *tmp; struct usb_interface *interface; void *private; const struct usb_device_id *id; struct usb_driver *driver; int i; if ((!dev) || (ifnum >= dev->actconfig->bNumInterfaces)) { err("bad find_interface_driver params"); return -1; } down(&dev->serialize); interface = dev->actconfig->interface + ifnum; if (usb_interface_claimed(interface)) goto out_err; private = NULL; for (tmp = usb_driver_list.next; tmp != &usb_driver_list;) { driver = list_entry(tmp, struct usb_driver, driver_list); tmp = tmp->next; id = driver->id_table; /* new style driver? */ if (id) { for (i = 0; i < interface->num_altsetting; i++) { interface->act_altsetting = i; id = usb_match_id(dev, interface, id); if (id) { down(&driver->serialize); private = driver->probe(dev,ifnum,id); up(&driver->serialize); if (private != NULL) break; } } /* if driver not bound, leave defaults unchanged */ if (private == NULL) interface->act_altsetting = 0; } else { /* "old style" driver */ down(&driver->serialize); private = driver->probe(dev, ifnum, NULL); up(&driver->serialize); } /* probe() may have changed the config on us */ interface = dev->actconfig->interface + ifnum; if (private) { usb_driver_claim_interface(driver, interface, private); up(&dev->serialize); return 0; } } out_err: up(&dev->serialize); return -1; } #ifdef CONFIG_HOTPLUG /* * USB hotplugging invokes what /proc/sys/kernel/hotplug says * (normally /sbin/hotplug) when USB devices get added or removed. * * This invokes a user mode policy agent, typically helping to load driver * or other modules, configure the device, and more. Drivers can provide * a MODULE_DEVICE_TABLE to help with module loading subtasks. * * Some synchronization is important: removes can't start processing * before the add-device processing completes, and vice versa. That keeps * a stack of USB-related identifiers stable while they're in use. If we * know that agents won't complete after they return (such as by forking * a process that completes later), it's enough to just waitpid() for the * agent -- as is currently done. * * The reason: we know we're called either from khubd (the typical case) * or from root hub initialization (init, kapmd, modprobe, etc). In both * cases, we know no other thread can recycle our address, since we must * already have been serialized enough to prevent that. */ static void call_policy (char *verb, struct usb_device *dev) { char *argv [3], **envp, *buf, *scratch; int i = 0, value; if (!hotplug_path [0]) return; if (in_interrupt ()) { dbg ("In_interrupt"); return; } if (!current->fs->root) { /* statically linked USB is initted rather early */ dbg ("call_policy %s, num %d -- no FS yet", verb, dev->devnum); return; } if (dev->devnum < 0) { dbg ("device already deleted ??"); return; } if (!(envp = (char **) kmalloc (20 * sizeof (char *), GFP_KERNEL))) { dbg ("enomem"); return; } if (!(buf = kmalloc (256, GFP_KERNEL))) { kfree (envp); dbg ("enomem2"); return; } /* only one standardized param to hotplug command: type */ argv [0] = hotplug_path; argv [1] = "usb"; argv [2] = 0; /* minimal command environment */ envp [i++] = "HOME=/"; envp [i++] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin"; #ifdef DEBUG /* hint that policy agent should enter no-stdout debug mode */ envp [i++] = "DEBUG=kernel"; #endif /* extensible set of named bus-specific parameters, * supporting multiple driver selection algorithms. */ scratch = buf; /* action: add, remove */ envp [i++] = scratch; scratch += sprintf (scratch, "ACTION=%s", verb) + 1; #ifdef CONFIG_USB_DEVICEFS /* If this is available, userspace programs can directly read * all the device descriptors we don't tell them about. Or * even act as usermode drivers. * * FIXME reduce hardwired intelligence here */ envp [i++] = "DEVFS=/proc/bus/usb"; envp [i++] = scratch; scratch += sprintf (scratch, "DEVICE=/proc/bus/usb/%03d/%03d", dev->bus->busnum, dev->devnum) + 1; #endif /* per-device configuration hacks are common */ envp [i++] = scratch; scratch += sprintf (scratch, "PRODUCT=%x/%x/%x", dev->descriptor.idVendor, dev->descriptor.idProduct, dev->descriptor.bcdDevice) + 1; /* class-based driver binding models */ envp [i++] = scratch; scratch += sprintf (scratch, "TYPE=%d/%d/%d", dev->descriptor.bDeviceClass, dev->descriptor.bDeviceSubClass, dev->descriptor.bDeviceProtocol) + 1; if (dev->descriptor.bDeviceClass == 0) { int alt = dev->actconfig->interface [0].act_altsetting; /* a simple/common case: one config, one interface, one driver * with current altsetting being a reasonable setting. * everything needs a smart agent and usbdevfs; or can rely on * device-specific binding policies. */ envp [i++] = scratch; scratch += sprintf (scratch, "INTERFACE=%d/%d/%d", dev->actconfig->interface [0].altsetting [alt].bInterfaceClass, dev->actconfig->interface [0].altsetting [alt].bInterfaceSubClass, dev->actconfig->interface [0].altsetting [alt].bInterfaceProtocol) + 1; /* INTERFACE-0, INTERFACE-1, ... ? */ } envp [i++] = 0; /* assert: (scratch - buf) < sizeof buf */ /* NOTE: user mode daemons can call the agents too */ dbg ("kusbd: %s %s %d", argv [0], verb, dev->devnum); value = call_usermodehelper (argv [0], argv, envp); kfree (buf); kfree (envp); if (value != 0) dbg ("kusbd policy returned 0x%x", value); } #else static inline void call_policy (char *verb, struct usb_device *dev) { } #endif /* CONFIG_HOTPLUG */ /* * This entrypoint gets called for each new device. * * All interfaces are scanned for matching drivers. */ static void usb_find_drivers(struct usb_device *dev) { unsigned ifnum; unsigned rejected = 0; unsigned claimed = 0; for (ifnum = 0; ifnum < dev->actconfig->bNumInterfaces; ifnum++) { /* if this interface hasn't already been claimed */ if (!usb_interface_claimed(dev->actconfig->interface + ifnum)) { if (usb_find_interface_driver(dev, ifnum)) rejected++; else claimed++; } } if (rejected) dbg("unhandled interfaces on device"); if (!claimed) { warn("USB device %d (vend/prod 0x%x/0x%x) is not claimed by any active driver.", dev->devnum, dev->descriptor.idVendor, dev->descriptor.idProduct); #ifdef DEBUG usb_show_device(dev); #endif } } /* * Only HC's should call usb_alloc_dev and usb_free_dev directly * Anybody may use usb_inc_dev_use or usb_dec_dev_use */ struct usb_device *usb_alloc_dev(struct usb_device *parent, struct usb_bus *bus) { struct usb_device *dev; dev = kmalloc(sizeof(*dev), GFP_KERNEL); if (!dev) return NULL; memset(dev, 0, sizeof(*dev)); usb_bus_get(bus); dev->bus = bus; dev->parent = parent; atomic_set(&dev->refcnt, 1); INIT_LIST_HEAD(&dev->inodes); INIT_LIST_HEAD(&dev->filelist); init_MUTEX(&dev->serialize); dev->bus->op->allocate(dev); return dev; } void usb_free_dev(struct usb_device *dev) { if (atomic_dec_and_test(&dev->refcnt)) { dev->bus->op->deallocate(dev); usb_destroy_configuration(dev); usb_bus_put(dev->bus); kfree(dev); } } void usb_inc_dev_use(struct usb_device *dev) { atomic_inc(&dev->refcnt); } /* ------------------------------------------------------------------------------------- * New USB Core Functions * -------------------------------------------------------------------------------------*/ /** * usb_alloc_urb - creates a new urb for a USB driver to use * @iso_packets: number of iso packets for this urb * * Creates an urb for the USB driver to use and returns a pointer to it. * If no memory is available, NULL is returned. * * If the driver want to use this urb for interrupt, control, or bulk * endpoints, pass '0' as the number of iso packets. * * The driver should call usb_free_urb() when it is finished with the urb. */ urb_t *usb_alloc_urb(int iso_packets) { urb_t *urb; urb = (urb_t *)kmalloc(sizeof(urb_t) + iso_packets * sizeof(iso_packet_descriptor_t), in_interrupt() ? GFP_ATOMIC : GFP_KERNEL); if (!urb) { err("alloc_urb: kmalloc failed"); return NULL; } memset(urb, 0, sizeof(*urb)); spin_lock_init(&urb->lock); return urb; } /** * usb_free_urb - frees the memory used by a urb * @urb: pointer to the urb to free * * If an urb is created with a call to usb_create_urb() it should be * cleaned up with a call to usb_free_urb() when the driver is finished * with it. */ void usb_free_urb(urb_t* urb) { if (urb) kfree(urb); } /*-------------------------------------------------------------------*/ int usb_submit_urb(urb_t *urb) { if (urb && urb->dev && urb->dev->bus && urb->dev->bus->op) return urb->dev->bus->op->submit_urb(urb); else return -ENODEV; } /*-------------------------------------------------------------------*/ int usb_unlink_urb(urb_t *urb) { if (urb && urb->dev && urb->dev->bus && urb->dev->bus->op) return urb->dev->bus->op->unlink_urb(urb); else return -ENODEV; } /*-------------------------------------------------------------------* * COMPLETION HANDLERS * *-------------------------------------------------------------------*/ /*-------------------------------------------------------------------* * completion handler for compatibility wrappers (sync control/bulk) * *-------------------------------------------------------------------*/ static void usb_api_blocking_completion(urb_t *urb) { struct usb_api_data *awd = (struct usb_api_data *)urb->context; awd->done = 1; wmb(); wake_up(&awd->wqh); } /*-------------------------------------------------------------------* * COMPATIBILITY STUFF * *-------------------------------------------------------------------*/ // Starts urb and waits for completion or timeout static int usb_start_wait_urb(urb_t *urb, int timeout, int* actual_length) { DECLARE_WAITQUEUE(wait, current); struct usb_api_data awd; int status; init_waitqueue_head(&awd.wqh); awd.done = 0; set_current_state(TASK_UNINTERRUPTIBLE); add_wait_queue(&awd.wqh, &wait); urb->context = &awd; status = usb_submit_urb(urb); if (status) { // something went wrong usb_free_urb(urb); set_current_state(TASK_RUNNING); remove_wait_queue(&awd.wqh, &wait); return status; } while (timeout && !awd.done) { timeout = schedule_timeout(timeout); set_current_state(TASK_UNINTERRUPTIBLE); rmb(); } set_current_state(TASK_RUNNING); remove_wait_queue(&awd.wqh, &wait); if (!timeout && !awd.done) { if (urb->status != -EINPROGRESS) { /* No callback?!! */ printk(KERN_ERR "usb: raced timeout, " "pipe 0x%x status %d time left %d\n", urb->pipe, urb->status, timeout); status = urb->status; } else { printk("usb_control/bulk_msg: timeout\n"); usb_unlink_urb(urb); // remove urb safely status = -ETIMEDOUT; } } else status = urb->status; if (actual_length) *actual_length = urb->actual_length; usb_free_urb(urb); return status; } /*-------------------------------------------------------------------*/ // returns status (negative) or length (positive) int usb_internal_control_msg(struct usb_device *usb_dev, unsigned int pipe, devrequest *cmd, void *data, int len, int timeout) { urb_t *urb; int retv; int length; urb = usb_alloc_urb(0); if (!urb) return -ENOMEM; FILL_CONTROL_URB(urb, usb_dev, pipe, (unsigned char*)cmd, data, len, usb_api_blocking_completion, 0); retv = usb_start_wait_urb(urb, timeout, &length); if (retv < 0) return retv; else return length; } /** * usb_control_msg - Builds a control urb, sends it off and waits for completion * @dev: pointer to the usb device to send the message to * @pipe: endpoint "pipe" to send the message to * @request: USB message request value * @requesttype: USB message request type value * @value: USB message value * @index: USB message index value * @data: pointer to the data to send * @size: length in bytes of the data to send * @timeout: time to wait for the message to complete before timing out (if 0 the wait is forever) * * This function sends a simple control message to a specified endpoint * and waits for the message to complete, or timeout. * * If successful, it returns 0, othwise a negative error number. * * Don't use this function from within an interrupt context, like a * bottom half handler. If you need a asyncronous message, or need to send * a message from within interrupt context, use usb_submit_urb() */ int usb_control_msg(struct usb_device *dev, unsigned int pipe, __u8 request, __u8 requesttype, __u16 value, __u16 index, void *data, __u16 size, int timeout) { devrequest *dr = kmalloc(sizeof(devrequest), GFP_KERNEL); int ret; if (!dr) return -ENOMEM; dr->requesttype = requesttype; dr->request = request; dr->value = cpu_to_le16p(&value); dr->index = cpu_to_le16p(&index); dr->length = cpu_to_le16p(&size); //dbg("usb_control_msg"); ret = usb_internal_control_msg(dev, pipe, dr, data, size, timeout); kfree(dr); return ret; } /** * usb_bulk_msg - Builds a bulk urb, sends it off and waits for completion * @usb_dev: pointer to the usb device to send the message to * @pipe: endpoint "pipe" to send the message to * @data: pointer to the data to send * @len: length in bytes of the data to send * @actual_length: pointer to a location to put the actual length transferred in bytes * @timeout: time to wait for the message to complete before timing out (if 0 the wait is forever) * * This function sends a simple bulk message to a specified endpoint * and waits for the message to complete, or timeout. * * If successful, it returns 0, othwise a negative error number. * The number of actual bytes transferred will be plaed in the * actual_timeout paramater. * * Don't use this function from within an interrupt context, like a * bottom half handler. If you need a asyncronous message, or need to * send a message from within interrupt context, use usb_submit_urb() */ int usb_bulk_msg(struct usb_device *usb_dev, unsigned int pipe, void *data, int len, int *actual_length, int timeout) { urb_t *urb; if (len < 0) return -EINVAL; urb=usb_alloc_urb(0); if (!urb) return -ENOMEM; FILL_BULK_URB(urb, usb_dev, pipe, data, len, usb_api_blocking_completion, 0); return usb_start_wait_urb(urb,timeout,actual_length); } /* * usb_get_current_frame_number() * * returns the current frame number for the parent USB bus/controller * of the given USB device. */ int usb_get_current_frame_number(struct usb_device *usb_dev) { return usb_dev->bus->op->get_frame_number (usb_dev); } /*-------------------------------------------------------------------*/ static int usb_parse_endpoint(struct usb_endpoint_descriptor *endpoint, unsigned char *buffer, int size) { struct usb_descriptor_header *header; unsigned char *begin; int parsed = 0, len, numskipped; header = (struct usb_descriptor_header *)buffer; /* Everything should be fine being passed into here, but we sanity */ /* check JIC */ if (header->bLength > size) { err("ran out of descriptors parsing"); return -1; } if (header->bDescriptorType != USB_DT_ENDPOINT) { warn("unexpected descriptor 0x%X, expecting endpoint descriptor, type 0x%X", endpoint->bDescriptorType, USB_DT_ENDPOINT); return parsed; } if (header->bLength == USB_DT_ENDPOINT_AUDIO_SIZE) memcpy(endpoint, buffer, USB_DT_ENDPOINT_AUDIO_SIZE); else memcpy(endpoint, buffer, USB_DT_ENDPOINT_SIZE); le16_to_cpus(&endpoint->wMaxPacketSize); buffer += header->bLength; size -= header->bLength; parsed += header->bLength; /* Skip over the rest of the Class Specific or Vendor Specific */ /* descriptors */ begin = buffer; numskipped = 0; while (size >= sizeof(struct usb_descriptor_header)) { header = (struct usb_descriptor_header *)buffer; if (header->bLength < 2) { err("invalid descriptor length of %d", header->bLength); return -1; } /* If we find another "proper" descriptor then we're done */ if ((header->bDescriptorType == USB_DT_ENDPOINT) || (header->bDescriptorType == USB_DT_INTERFACE) || (header->bDescriptorType == USB_DT_CONFIG) || (header->bDescriptorType == USB_DT_DEVICE)) break; dbg("skipping descriptor 0x%X", header->bDescriptorType); numskipped++; buffer += header->bLength; size -= header->bLength; parsed += header->bLength; } if (numskipped) dbg("skipped %d class/vendor specific endpoint descriptors", numskipped); /* Copy any unknown descriptors into a storage area for drivers */ /* to later parse */ len = (int)(buffer - begin); if (!len) { endpoint->extra = NULL; endpoint->extralen = 0; return parsed; } endpoint->extra = kmalloc(len, GFP_KERNEL); if (!endpoint->extra) { err("couldn't allocate memory for endpoint extra descriptors"); endpoint->extralen = 0; return parsed; } memcpy(endpoint->extra, begin, len); endpoint->extralen = len; return parsed; } static int usb_parse_interface(struct usb_interface *interface, unsigned char *buffer, int size) { int i, len, numskipped, retval, parsed = 0; struct usb_descriptor_header *header; struct usb_interface_descriptor *ifp; unsigned char *begin; interface->act_altsetting = 0; interface->num_altsetting = 0; interface->max_altsetting = USB_ALTSETTINGALLOC; interface->altsetting = kmalloc(sizeof(struct usb_interface_descriptor) * interface->max_altsetting, GFP_KERNEL); if (!interface->altsetting) { err("couldn't kmalloc interface->altsetting"); return -1; } while (size > 0) { if (interface->num_altsetting >= interface->max_altsetting) { void *ptr; int oldmas; oldmas = interface->max_altsetting; interface->max_altsetting += USB_ALTSETTINGALLOC; if (interface->max_altsetting > USB_MAXALTSETTING) { warn("too many alternate settings (max %d)", USB_MAXALTSETTING); return -1; } ptr = interface->altsetting; interface->altsetting = kmalloc(sizeof(struct usb_interface_descriptor) * interface->max_altsetting, GFP_KERNEL); if (!interface->altsetting) { err("couldn't kmalloc interface->altsetting"); interface->altsetting = ptr; return -1; } memcpy(interface->altsetting, ptr, sizeof(struct usb_interface_descriptor) * oldmas); kfree(ptr); } ifp = interface->altsetting + interface->num_altsetting; interface->num_altsetting++; memcpy(ifp, buffer, USB_DT_INTERFACE_SIZE); /* Skip over the interface */ buffer += ifp->bLength; parsed += ifp->bLength; size -= ifp->bLength; begin = buffer; numskipped = 0; /* Skip over any interface, class or vendor descriptors */ while (size >= sizeof(struct usb_descriptor_header)) { header = (struct usb_descriptor_header *)buffer; if (header->bLength < 2) { err("invalid descriptor length of %d", header->bLength); return -1; } /* If we find another "proper" descriptor then we're done */ if ((header->bDescriptorType == USB_DT_INTERFACE) || (header->bDescriptorType == USB_DT_ENDPOINT) || (header->bDescriptorType == USB_DT_CONFIG) || (header->bDescriptorType == USB_DT_DEVICE)) break; numskipped++; buffer += header->bLength; parsed += header->bLength; size -= header->bLength; } if (numskipped) dbg("skipped %d class/vendor specific interface descriptors", numskipped); /* Copy any unknown descriptors into a storage area for */ /* drivers to later parse */ len = (int)(buffer - begin); if (!len) { ifp->extra = NULL; ifp->extralen = 0; } else { ifp->extra = kmalloc(len, GFP_KERNEL); if (!ifp->extra) { err("couldn't allocate memory for interface extra descriptors"); ifp->extralen = 0; return -1; } memcpy(ifp->extra, begin, len); ifp->extralen = len; } /* Did we hit an unexpected descriptor? */ header = (struct usb_descriptor_header *)buffer; if ((size >= sizeof(struct usb_descriptor_header)) && ((header->bDescriptorType == USB_DT_CONFIG) || (header->bDescriptorType == USB_DT_DEVICE))) return parsed; if (ifp->bNumEndpoints > USB_MAXENDPOINTS) { warn("too many endpoints"); return -1; } ifp->endpoint = (struct usb_endpoint_descriptor *) kmalloc(ifp->bNumEndpoints * sizeof(struct usb_endpoint_descriptor), GFP_KERNEL); if (!ifp->endpoint) { err("out of memory"); return -1; } memset(ifp->endpoint, 0, ifp->bNumEndpoints * sizeof(struct usb_endpoint_descriptor)); for (i = 0; i < ifp->bNumEndpoints; i++) { header = (struct usb_descriptor_header *)buffer; if (header->bLength > size) { err("ran out of descriptors parsing"); return -1; } retval = usb_parse_endpoint(ifp->endpoint + i, buffer, size); if (retval < 0) return retval; buffer += retval; parsed += retval; size -= retval; } /* We check to see if it's an alternate to this one */ ifp = (struct usb_interface_descriptor *)buffer; if (size < USB_DT_INTERFACE_SIZE || ifp->bDescriptorType != USB_DT_INTERFACE || !ifp->bAlternateSetting) return parsed; } return parsed; } int usb_parse_configuration(struct usb_config_descriptor *config, char *buffer) { int i, retval, size; struct usb_descriptor_header *header; memcpy(config, buffer, USB_DT_CONFIG_SIZE); le16_to_cpus(&config->wTotalLength); size = config->wTotalLength; if (config->bNumInterfaces > USB_MAXINTERFACES) { warn("too many interfaces"); return -1; } config->interface = (struct usb_interface *) kmalloc(config->bNumInterfaces * sizeof(struct usb_interface), GFP_KERNEL); dbg("kmalloc IF %p, numif %i", config->interface, config->bNumInterfaces); if (!config->interface) { err("out of memory"); return -1; } memset(config->interface, 0, config->bNumInterfaces * sizeof(struct usb_interface)); buffer += config->bLength; size -= config->bLength; config->extra = NULL; config->extralen = 0; for (i = 0; i < config->bNumInterfaces; i++) { int numskipped, len; char *begin; /* Skip over the rest of the Class Specific or Vendor */ /* Specific descriptors */ begin = buffer; numskipped = 0; while (size >= sizeof(struct usb_descriptor_header)) { header = (struct usb_descriptor_header *)buffer; if ((header->bLength > size) || (header->bLength < 2)) { err("invalid descriptor length of %d", header->bLength); return -1; } /* If we find another "proper" descriptor then we're done */ if ((header->bDescriptorType == USB_DT_ENDPOINT) || (header->bDescriptorType == USB_DT_INTERFACE) || (header->bDescriptorType == USB_DT_CONFIG) || (header->bDescriptorType == USB_DT_DEVICE)) break; dbg("skipping descriptor 0x%X", header->bDescriptorType); numskipped++; buffer += header->bLength; size -= header->bLength; } if (numskipped) dbg("skipped %d class/vendor specific endpoint descriptors", numskipped); /* Copy any unknown descriptors into a storage area for */ /* drivers to later parse */ len = (int)(buffer - begin); if (len) { if (config->extralen) { warn("extra config descriptor"); } else { config->extra = kmalloc(len, GFP_KERNEL); if (!config->extra) { err("couldn't allocate memory for config extra descriptors"); config->extralen = 0; return -1; } memcpy(config->extra, begin, len); config->extralen = len; } } retval = usb_parse_interface(config->interface + i, buffer, size); if (retval < 0) return retval; buffer += retval; size -= retval; } return size; } void usb_destroy_configuration(struct usb_device *dev) { int c, i, j, k; if (!dev->config) return; if (dev->rawdescriptors) { for (i = 0; i < dev->descriptor.bNumConfigurations; i++) kfree(dev->rawdescriptors[i]); kfree(dev->rawdescriptors); } for (c = 0; c < dev->descriptor.bNumConfigurations; c++) { struct usb_config_descriptor *cf = &dev->config[c]; if (!cf->interface) break; for (i = 0; i < cf->bNumInterfaces; i++) { struct usb_interface *ifp = &cf->interface[i]; if (!ifp->altsetting) break; for (j = 0; j < ifp->num_altsetting; j++) { struct usb_interface_descriptor *as = &ifp->altsetting[j]; if(as->extra) { kfree(as->extra); } if (!as->endpoint) break; for(k = 0; k < as->bNumEndpoints; k++) { if(as->endpoint[k].extra) { kfree(as->endpoint[k].extra); } } kfree(as->endpoint); } kfree(ifp->altsetting); } kfree(cf->interface); } kfree(dev->config); } /* for returning string descriptors in UTF-16LE */ static int ascii2utf (char *ascii, __u8 *utf, int utfmax) { int retval; for (retval = 0; *ascii && utfmax > 1; utfmax -= 2, retval += 2) { *utf++ = *ascii++ & 0x7f; *utf++ = 0; } return retval; } /* * root_hub_string is used by each host controller's root hub code, * so that they're identified consistently throughout the system. */ int usb_root_hub_string (int id, int serial, char *type, __u8 *data, int len) { char buf [30]; // assert (len > (2 * (sizeof (buf) + 1))); // assert (strlen (type) <= 8); // language ids if (id == 0) { *data++ = 4; *data++ = 3; /* 4 bytes data */ *data++ = 0; *data++ = 0; /* some language id */ return 4; // serial number } else if (id == 1) { sprintf (buf, "%x", serial); // product description } else if (id == 2) { sprintf (buf, "USB %s Root Hub", type); // id 3 == vendor description // unsupported IDs --> "stall" } else return 0; data [0] = 2 + ascii2utf (buf, data + 2, len - 2); data [1] = 3; return data [0]; } /* * __usb_get_extra_descriptor() finds a descriptor of specific type in the * extra field of the interface and endpoint descriptor structs. */ int __usb_get_extra_descriptor(char *buffer, unsigned size, unsigned char type, void **ptr) { struct usb_descriptor_header *header; while (size >= sizeof(struct usb_descriptor_header)) { header = (struct usb_descriptor_header *)buffer; if (header->bLength < 2) { err("invalid descriptor length of %d", header->bLength); return -1; } if (header->bDescriptorType == type) { *ptr = header; return 0; } buffer += header->bLength; size -= header->bLength; } return -1; } /* * Something got disconnected. Get rid of it, and all of its children. */ void usb_disconnect(struct usb_device **pdev) { struct usb_device * dev = *pdev; int i; if (!dev) return; *pdev = NULL; info("USB disconnect on device %d", dev->devnum); if (dev->actconfig) { for (i = 0; i < dev->actconfig->bNumInterfaces; i++) { struct usb_interface *interface = &dev->actconfig->interface[i]; struct usb_driver *driver = interface->driver; if (driver) { down(&driver->serialize); driver->disconnect(dev, interface->private_data); up(&driver->serialize); /* if driver->disconnect didn't release the interface */ if (interface->driver) usb_driver_release_interface(driver, interface); } } } /* Free up all the children.. */ for (i = 0; i < USB_MAXCHILDREN; i++) { struct usb_device **child = dev->children + i; if (*child) usb_disconnect(child); } /* Let policy agent unload modules etc */ call_policy ("remove", dev); /* Free the device number and remove the /proc/bus/usb entry */ if (dev->devnum > 0) { clear_bit(dev->devnum, &dev->bus->devmap.devicemap); usbdevfs_remove_device(dev); } /* Free up the device itself */ usb_free_dev(dev); } /* * Connect a new USB device. This basically just initializes * the USB device information and sets up the topology - it's * up to the low-level driver to reset the port and actually * do the setup (the upper levels don't know how to do that). */ void usb_connect(struct usb_device *dev) { int devnum; // FIXME needs locking for SMP!! /* why? this is called only from the hub thread, * which hopefully doesn't run on multiple CPU's simultaneously 8-) */ dev->descriptor.bMaxPacketSize0 = 8; /* Start off at 8 bytes */ #ifndef DEVNUM_ROUND_ROBIN devnum = find_next_zero_bit(dev->bus->devmap.devicemap, 128, 1); #else /* round_robin alloc of devnums */ /* Try to allocate the next devnum beginning at bus->devnum_next. */ devnum = find_next_zero_bit(dev->bus->devmap.devicemap, 128, dev->bus->devnum_next); if (devnum >= 128) devnum = find_next_zero_bit(dev->bus->devmap.devicemap, 128, 1); dev->bus->devnum_next = ( devnum >= 127 ? 1 : devnum + 1); #endif /* round_robin alloc of devnums */ if (devnum < 128) { set_bit(devnum, dev->bus->devmap.devicemap); dev->devnum = devnum; } } /* * These are the actual routines to send * and receive control messages. */ #ifdef CONFIG_USB_LONG_TIMEOUT #define GET_TIMEOUT 4 #else #define GET_TIMEOUT 3 #endif #define SET_TIMEOUT 3 int usb_set_address(struct usb_device *dev) { return usb_control_msg(dev, usb_snddefctrl(dev), USB_REQ_SET_ADDRESS, 0, dev->devnum, 0, NULL, 0, HZ * GET_TIMEOUT); } int usb_get_descriptor(struct usb_device *dev, unsigned char type, unsigned char index, void *buf, int size) { int i = 5; int result; memset(buf,0,size); // Make sure we parse really received data while (i--) { if ((result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), USB_REQ_GET_DESCRIPTOR, USB_DIR_IN, (type << 8) + index, 0, buf, size, HZ * GET_TIMEOUT)) > 0 || result == -EPIPE) break; /* retry if the returned length was 0; flaky device */ } return result; } int usb_get_class_descriptor(struct usb_device *dev, int ifnum, unsigned char type, unsigned char id, void *buf, int size) { return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), USB_REQ_GET_DESCRIPTOR, USB_RECIP_INTERFACE | USB_DIR_IN, (type << 8) + id, ifnum, buf, size, HZ * GET_TIMEOUT); } int usb_get_string(struct usb_device *dev, unsigned short langid, unsigned char index, void *buf, int size) { return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), USB_REQ_GET_DESCRIPTOR, USB_DIR_IN, (USB_DT_STRING << 8) + index, langid, buf, size, HZ * GET_TIMEOUT); } int usb_get_device_descriptor(struct usb_device *dev) { int ret = usb_get_descriptor(dev, USB_DT_DEVICE, 0, &dev->descriptor, sizeof(dev->descriptor)); if (ret >= 0) { le16_to_cpus(&dev->descriptor.bcdUSB); le16_to_cpus(&dev->descriptor.idVendor); le16_to_cpus(&dev->descriptor.idProduct); le16_to_cpus(&dev->descriptor.bcdDevice); } return ret; } int usb_get_status(struct usb_device *dev, int type, int target, void *data) { return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), USB_REQ_GET_STATUS, USB_DIR_IN | type, 0, target, data, 2, HZ * GET_TIMEOUT); } int usb_get_protocol(struct usb_device *dev, int ifnum) { unsigned char type; int ret; if ((ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), USB_REQ_GET_PROTOCOL, USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE, 0, ifnum, &type, 1, HZ * GET_TIMEOUT)) < 0) return ret; return type; } int usb_set_protocol(struct usb_device *dev, int ifnum, int protocol) { return usb_control_msg(dev, usb_sndctrlpipe(dev, 0), USB_REQ_SET_PROTOCOL, USB_TYPE_CLASS | USB_RECIP_INTERFACE, protocol, ifnum, NULL, 0, HZ * SET_TIMEOUT); } int usb_set_idle(struct usb_device *dev, int ifnum, int duration, int report_id) { return usb_control_msg(dev, usb_sndctrlpipe(dev, 0), USB_REQ_SET_IDLE, USB_TYPE_CLASS | USB_RECIP_INTERFACE, (duration << 8) | report_id, ifnum, NULL, 0, HZ * SET_TIMEOUT); } void usb_set_maxpacket(struct usb_device *dev) { int i, b; for (i=0; iactconfig->bNumInterfaces; i++) { struct usb_interface *ifp = dev->actconfig->interface + i; struct usb_interface_descriptor *as = ifp->altsetting + ifp->act_altsetting; struct usb_endpoint_descriptor *ep = as->endpoint; int e; for (e=0; ebNumEndpoints; e++) { b = ep[e].bEndpointAddress & USB_ENDPOINT_NUMBER_MASK; if ((ep[e].bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_CONTROL) { /* Control => bidirectional */ dev->epmaxpacketout[b] = ep[e].wMaxPacketSize; dev->epmaxpacketin [b] = ep[e].wMaxPacketSize; } else if (usb_endpoint_out(ep[e].bEndpointAddress)) { if (ep[e].wMaxPacketSize > dev->epmaxpacketout[b]) dev->epmaxpacketout[b] = ep[e].wMaxPacketSize; } else { if (ep[e].wMaxPacketSize > dev->epmaxpacketin [b]) dev->epmaxpacketin [b] = ep[e].wMaxPacketSize; } } } } /* * endp: endpoint number in bits 0-3; * direction flag in bit 7 (1 = IN, 0 = OUT) */ int usb_clear_halt(struct usb_device *dev, int pipe) { int result; __u16 status; unsigned char *buffer; int endp=usb_pipeendpoint(pipe)|(usb_pipein(pipe)<<7); /* if (!usb_endpoint_halted(dev, endp & 0x0f, usb_endpoint_out(endp))) return 0; */ result = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), USB_REQ_CLEAR_FEATURE, USB_RECIP_ENDPOINT, 0, endp, NULL, 0, HZ * SET_TIMEOUT); /* don't clear if failed */ if (result < 0) return result; buffer = kmalloc(sizeof(status), GFP_KERNEL); if (!buffer) { err("unable to allocate memory for configuration descriptors"); return -ENOMEM; } result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), USB_REQ_GET_STATUS, USB_DIR_IN | USB_RECIP_ENDPOINT, 0, endp, buffer, sizeof(status), HZ * SET_TIMEOUT); memcpy(&status, buffer, sizeof(status)); kfree(buffer); if (result < 0) return result; if (le16_to_cpu(status) & 1) return -EPIPE; /* still halted */ usb_endpoint_running(dev, usb_pipeendpoint(pipe), usb_pipeout(pipe)); /* toggle is reset on clear */ usb_settoggle(dev, usb_pipeendpoint(pipe), usb_pipeout(pipe), 0); return 0; } int usb_set_interface(struct usb_device *dev, int interface, int alternate) { struct usb_interface *iface; int ret; iface = usb_ifnum_to_if(dev, interface); if (!iface) { warn("selecting invalid interface %d", interface); return -EINVAL; } /* 9.4.10 says devices don't need this, if the interface only has one alternate setting */ if (iface->num_altsetting == 1) { warn("ignoring set_interface for dev %d, iface %d, alt %d", dev->devnum, interface, alternate); return 0; } if ((ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), USB_REQ_SET_INTERFACE, USB_RECIP_INTERFACE, alternate, interface, NULL, 0, HZ * 5)) < 0) return ret; iface->act_altsetting = alternate; dev->toggle[0] = 0; /* 9.1.1.5 says to do this */ dev->toggle[1] = 0; usb_set_maxpacket(dev); return 0; } int usb_set_configuration(struct usb_device *dev, int configuration) { int i, ret; struct usb_config_descriptor *cp = NULL; for (i=0; idescriptor.bNumConfigurations; i++) { if (dev->config[i].bConfigurationValue == configuration) { cp = &dev->config[i]; break; } } if (!cp) { warn("selecting invalid configuration %d", configuration); return -EINVAL; } if ((ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), USB_REQ_SET_CONFIGURATION, 0, configuration, 0, NULL, 0, HZ * SET_TIMEOUT)) < 0) return ret; dev->actconfig = cp; dev->toggle[0] = 0; dev->toggle[1] = 0; usb_set_maxpacket(dev); return 0; } int usb_get_report(struct usb_device *dev, int ifnum, unsigned char type, unsigned char id, void *buf, int size) { return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), USB_REQ_GET_REPORT, USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE, (type << 8) + id, ifnum, buf, size, HZ * GET_TIMEOUT); } int usb_set_report(struct usb_device *dev, int ifnum, unsigned char type, unsigned char id, void *buf, int size) { return usb_control_msg(dev, usb_sndctrlpipe(dev, 0), USB_REQ_SET_REPORT, USB_TYPE_CLASS | USB_RECIP_INTERFACE, (type << 8) + id, ifnum, buf, size, HZ); } int usb_get_configuration(struct usb_device *dev) { int result; unsigned int cfgno, length; unsigned char *buffer; unsigned char *bigbuffer; struct usb_config_descriptor *desc; if (dev->descriptor.bNumConfigurations > USB_MAXCONFIG) { warn("too many configurations"); return -EINVAL; } if (dev->descriptor.bNumConfigurations < 1) { warn("not enough configurations"); return -EINVAL; } dev->config = (struct usb_config_descriptor *) kmalloc(dev->descriptor.bNumConfigurations * sizeof(struct usb_config_descriptor), GFP_KERNEL); if (!dev->config) { err("out of memory"); return -ENOMEM; } memset(dev->config, 0, dev->descriptor.bNumConfigurations * sizeof(struct usb_config_descriptor)); dev->rawdescriptors = (char **)kmalloc(sizeof(char *) * dev->descriptor.bNumConfigurations, GFP_KERNEL); if (!dev->rawdescriptors) { err("out of memory"); return -ENOMEM; } buffer = kmalloc(8, GFP_KERNEL); if (!buffer) { err("unable to allocate memory for configuration descriptors"); return -ENOMEM; } desc = (struct usb_config_descriptor *)buffer; for (cfgno = 0; cfgno < dev->descriptor.bNumConfigurations; cfgno++) { /* We grab the first 8 bytes so we know how long the whole */ /* configuration is */ result = usb_get_descriptor(dev, USB_DT_CONFIG, cfgno, buffer, 8); if (result < 8) { if (result < 0) err("unable to get descriptor"); else { err("config descriptor too short (expected %i, got %i)", 8, result); result = -EINVAL; } goto err; } /* Get the full buffer */ length = le16_to_cpu(desc->wTotalLength); bigbuffer = kmalloc(length, GFP_KERNEL); if (!bigbuffer) { err("unable to allocate memory for configuration descriptors"); result = -ENOMEM; goto err; } /* Now that we know the length, get the whole thing */ result = usb_get_descriptor(dev, USB_DT_CONFIG, cfgno, bigbuffer, length); if (result < 0) { err("couldn't get all of config descriptors"); kfree(bigbuffer); goto err; } if (result < length) { err("config descriptor too short (expected %i, got %i)", length, result); result = -EINVAL; kfree(bigbuffer); goto err; } dev->rawdescriptors[cfgno] = bigbuffer; result = usb_parse_configuration(&dev->config[cfgno], bigbuffer); if (result > 0) dbg("descriptor data left"); else if (result < 0) { result = -EINVAL; goto err; } } kfree(buffer); return 0; err: kfree(buffer); dev->descriptor.bNumConfigurations = cfgno; return result; } /* * usb_string: * returns string length (> 0) or error (< 0) */ int usb_string(struct usb_device *dev, int index, char *buf, size_t size) { unsigned char *tbuf; int err; unsigned int u, idx; if (size <= 0 || !buf || !index) return -EINVAL; buf[0] = 0; tbuf = kmalloc(256, GFP_KERNEL); if (!tbuf) return -ENOMEM; /* get langid for strings if it's not yet known */ if (!dev->have_langid) { err = usb_get_string(dev, 0, 0, tbuf, 4); if (err < 0) { err("error getting string descriptor 0 (error=%d)", err); goto errout; } else if (tbuf[0] < 4) { err("string descriptor 0 too short"); err = -EINVAL; goto errout; } else { dev->have_langid = -1; dev->string_langid = tbuf[2] | (tbuf[3]<< 8); /* always use the first langid listed */ dbg("USB device number %d default language ID 0x%x", dev->devnum, dev->string_langid); } } /* * Just ask for a maximum length string and then take the length * that was returned. */ err = usb_get_string(dev, dev->string_langid, index, tbuf, 255); if (err < 0) goto errout; size--; /* leave room for trailing NULL char in output buffer */ for (idx = 0, u = 2; u < err; u += 2) { if (idx >= size) break; if (tbuf[u+1]) /* high byte */ buf[idx++] = '?'; /* non-ASCII character */ else buf[idx++] = tbuf[u]; } buf[idx] = 0; err = idx; errout: kfree(tbuf); return err; } /* * By the time we get here, the device has gotten a new device ID * and is in the default state. We need to identify the thing and * get the ball rolling.. * * Returns 0 for success, != 0 for error. */ int usb_new_device(struct usb_device *dev) { int err; /* USB v1.1 5.5.3 */ /* We read the first 8 bytes from the device descriptor to get to */ /* the bMaxPacketSize0 field. Then we set the maximum packet size */ /* for the control pipe, and retrieve the rest */ dev->epmaxpacketin [0] = 8; dev->epmaxpacketout[0] = 8; err = usb_set_address(dev); if (err < 0) { err("USB device not accepting new address=%d (error=%d)", dev->devnum, err); clear_bit(dev->devnum, &dev->bus->devmap.devicemap); dev->devnum = -1; return 1; } wait_ms(10); /* Let the SET_ADDRESS settle */ err = usb_get_descriptor(dev, USB_DT_DEVICE, 0, &dev->descriptor, 8); if (err < 8) { if (err < 0) err("USB device not responding, giving up (error=%d)", err); else err("USB device descriptor short read (expected %i, got %i)", 8, err); clear_bit(dev->devnum, &dev->bus->devmap.devicemap); dev->devnum = -1; return 1; } dev->epmaxpacketin [0] = dev->descriptor.bMaxPacketSize0; dev->epmaxpacketout[0] = dev->descriptor.bMaxPacketSize0; err = usb_get_device_descriptor(dev); if (err < (signed)sizeof(dev->descriptor)) { if (err < 0) err("unable to get device descriptor (error=%d)", err); else err("USB device descriptor short read (expected %Zi, got %i)", sizeof(dev->descriptor), err); clear_bit(dev->devnum, &dev->bus->devmap.devicemap); dev->devnum = -1; return 1; } err = usb_get_configuration(dev); if (err < 0) { err("unable to get device %d configuration (error=%d)", dev->devnum, err); clear_bit(dev->devnum, &dev->bus->devmap.devicemap); dev->devnum = -1; return 1; } /* we set the default configuration here */ err = usb_set_configuration(dev, dev->config[0].bConfigurationValue); if (err) { err("failed to set device %d default configuration (error=%d)", dev->devnum, err); clear_bit(dev->devnum, &dev->bus->devmap.devicemap); dev->devnum = -1; return 1; } dbg("new device strings: Mfr=%d, Product=%d, SerialNumber=%d", dev->descriptor.iManufacturer, dev->descriptor.iProduct, dev->descriptor.iSerialNumber); #ifdef DEBUG if (dev->descriptor.iManufacturer) usb_show_string(dev, "Manufacturer", dev->descriptor.iManufacturer); if (dev->descriptor.iProduct) usb_show_string(dev, "Product", dev->descriptor.iProduct); if (dev->descriptor.iSerialNumber) usb_show_string(dev, "SerialNumber", dev->descriptor.iSerialNumber); #endif /* now that the basic setup is over, add a /proc/bus/usb entry */ usbdevfs_add_device(dev); /* find drivers willing to handle this device */ usb_find_drivers(dev); /* userspace may load modules and/or configure further */ call_policy ("add", dev); return 0; } static int usb_open(struct inode * inode, struct file * file) { int minor = MINOR(inode->i_rdev); struct usb_driver *c = usb_minors[minor/16]; int err = -ENODEV; struct file_operations *old_fops, *new_fops = NULL; /* * No load-on-demand? Randy, could you ACK that it's really not * supposed to be done? -- AV */ if (!c || !(new_fops = fops_get(c->fops))) return err; old_fops = file->f_op; file->f_op = new_fops; /* Curiouser and curiouser... NULL ->open() as "no device" ? */ if (file->f_op->open) err = file->f_op->open(inode,file); if (err) { fops_put(file->f_op); file->f_op = fops_get(old_fops); } fops_put(old_fops); return err; } static struct file_operations usb_fops = { owner: THIS_MODULE, open: usb_open, }; int usb_major_init(void) { if (devfs_register_chrdev(USB_MAJOR, "usb", &usb_fops)) { err("unable to get major %d for usb devices", USB_MAJOR); return -EBUSY; } usb_devfs_handle = devfs_mk_dir(NULL, "usb", NULL); return 0; } void usb_major_cleanup(void) { devfs_unregister(usb_devfs_handle); devfs_unregister_chrdev(USB_MAJOR, "usb"); } #ifdef CONFIG_PROC_FS struct list_head *usb_driver_get_list(void) { return &usb_driver_list; } struct list_head *usb_bus_get_list(void) { return &usb_bus_list; } #endif /* * Init */ static int __init usb_init(void) { init_MUTEX(&usb_bus_list_lock); usb_major_init(); usbdevfs_init(); usb_hub_init(); return 0; } /* * Cleanup */ static void __exit usb_exit(void) { usb_major_cleanup(); usbdevfs_cleanup(); usb_hub_cleanup(); } module_init(usb_init); module_exit(usb_exit); /* * USB may be built into the kernel or be built as modules. * If the USB core [and maybe a host controller driver] is built * into the kernel, and other device drivers are built as modules, * then these symbols need to be exported for the modules to use. */ EXPORT_SYMBOL(usb_ifnum_to_if); EXPORT_SYMBOL(usb_epnum_to_ep_desc); EXPORT_SYMBOL(usb_register); EXPORT_SYMBOL(usb_deregister); EXPORT_SYMBOL(usb_scan_devices); EXPORT_SYMBOL(usb_alloc_bus); EXPORT_SYMBOL(usb_free_bus); EXPORT_SYMBOL(usb_register_bus); EXPORT_SYMBOL(usb_deregister_bus); EXPORT_SYMBOL(usb_alloc_dev); EXPORT_SYMBOL(usb_free_dev); EXPORT_SYMBOL(usb_inc_dev_use); EXPORT_SYMBOL(usb_driver_claim_interface); EXPORT_SYMBOL(usb_interface_claimed); EXPORT_SYMBOL(usb_driver_release_interface); EXPORT_SYMBOL(usb_match_id); EXPORT_SYMBOL(usb_root_hub_string); EXPORT_SYMBOL(usb_new_device); EXPORT_SYMBOL(usb_reset_device); EXPORT_SYMBOL(usb_connect); EXPORT_SYMBOL(usb_disconnect); EXPORT_SYMBOL(usb_check_bandwidth); EXPORT_SYMBOL(usb_claim_bandwidth); EXPORT_SYMBOL(usb_release_bandwidth); EXPORT_SYMBOL(usb_set_address); EXPORT_SYMBOL(usb_get_descriptor); EXPORT_SYMBOL(usb_get_class_descriptor); EXPORT_SYMBOL(__usb_get_extra_descriptor); EXPORT_SYMBOL(usb_get_device_descriptor); EXPORT_SYMBOL(usb_get_string); EXPORT_SYMBOL(usb_string); EXPORT_SYMBOL(usb_get_protocol); EXPORT_SYMBOL(usb_set_protocol); EXPORT_SYMBOL(usb_get_report); EXPORT_SYMBOL(usb_set_report); EXPORT_SYMBOL(usb_set_idle); EXPORT_SYMBOL(usb_clear_halt); EXPORT_SYMBOL(usb_set_interface); EXPORT_SYMBOL(usb_get_configuration); EXPORT_SYMBOL(usb_set_configuration); EXPORT_SYMBOL(usb_get_status); EXPORT_SYMBOL(usb_get_current_frame_number); EXPORT_SYMBOL(usb_alloc_urb); EXPORT_SYMBOL(usb_free_urb); EXPORT_SYMBOL(usb_submit_urb); EXPORT_SYMBOL(usb_unlink_urb); EXPORT_SYMBOL(usb_control_msg); EXPORT_SYMBOL(usb_bulk_msg); EXPORT_SYMBOL(usb_devfs_handle); MODULE_LICENSE("GPL");