* @urb_list: urbs queued to this endpoint; maintained by usbcore
* @hcpriv: for use by HCD; typically holds hardware dma queue head (QH)
* with one or more transfer descriptors (TDs) per urb
+ * @kobj: kobject for sysfs info
* @extra: descriptors following this endpoint in the configuration
* @extralen: how many bytes of "extra" are valid
*
struct usb_endpoint_descriptor desc;
struct list_head urb_list;
void *hcpriv;
- char *attr_name;
- struct attribute_group *attr_group;
- struct attribute **attrs;
- int num_attrs;
+ struct kobject *kobj; /* For sysfs info */
unsigned char *extra; /* Extra descriptors */
int extralen;
* active alternate setting */
unsigned num_altsetting; /* number of alternate settings */
- int minor; /* minor number this interface is bound to */
+ int minor; /* minor number this interface is
+ * bound to */
enum usb_interface_condition condition; /* state of binding */
struct device dev; /* interface specific device info */
struct class_device *class_dev;
* Device drivers should not attempt to activate configurations. The choice
* of which configuration to install is a policy decision based on such
* considerations as available power, functionality provided, and the user's
- * desires (expressed through hotplug scripts). However, drivers can call
+ * desires (expressed through userspace tools). However, drivers can call
* usb_reset_configuration() to reinitialize the current configuration and
* all its interfaces.
*/
struct usb_host_config {
struct usb_config_descriptor desc;
- char *string;
+ char *string; /* iConfiguration string, if present */
/* the interfaces associated with this configuration,
* stored in no particular order */
struct usb_interface *interface[USB_MAXINTERFACES];
__usb_get_extra_descriptor((ifpoint)->extra,(ifpoint)->extralen,\
type,(void**)ptr)
-/* -------------------------------------------------------------------------- */
+/* ----------------------------------------------------------------------- */
struct usb_operations;
unsigned is_b_host:1; /* true during some HNP roleswitches */
unsigned b_hnp_enable:1; /* OTG: did A-Host enable HNP? */
- int devnum_next; /* Next open device number in round-robin allocation */
+ int devnum_next; /* Next open device number in
+ * round-robin allocation */
struct usb_devmap devmap; /* device address allocation map */
struct usb_operations *op; /* Operations (specific to the HC) */
struct dentry *usbfs_dentry; /* usbfs dentry entry for the bus */
struct class_device *class_dev; /* class device for this bus */
- struct kref kref; /* handles reference counting this bus */
- void (*release)(struct usb_bus *bus); /* function to destroy this bus's memory */
+ struct kref kref; /* reference counting for this bus */
+ void (*release)(struct usb_bus *bus);
+
#if defined(CONFIG_USB_MON)
struct mon_bus *mon_bus; /* non-null when associated */
int monitored; /* non-zero when monitored */
#endif
};
-/* -------------------------------------------------------------------------- */
+/* ----------------------------------------------------------------------- */
/* This is arbitrary.
* From USB 2.0 spec Table 11-13, offset 7, a hub can
struct usb_tt *tt; /* low/full speed dev, highspeed hub */
int ttport; /* device port on that tt hub */
- struct semaphore serialize;
-
- unsigned int toggle[2]; /* one bit for each endpoint ([0] = IN, [1] = OUT) */
+ unsigned int toggle[2]; /* one bit for each endpoint
+ * ([0] = IN, [1] = OUT) */
struct usb_device *parent; /* our hub, unless we're the root */
struct usb_bus *bus; /* Bus we're part of */
char **rawdescriptors; /* Raw descriptors for each config */
- int have_langid; /* whether string_langid is valid yet */
+ unsigned short bus_mA; /* Current available from the bus */
+ u8 portnum; /* Parent port number (origin 1) */
+
+ int have_langid; /* whether string_langid is valid */
int string_langid; /* language ID for strings */
- char *product;
- char *manufacturer;
- char *serial; /* static strings from the device */
+ /* static strings from the device */
+ char *product; /* iProduct string, if present */
+ char *manufacturer; /* iManufacturer string, if present */
+ char *serial; /* iSerialNumber string, if present */
+
struct list_head filelist;
struct class_device *class_dev;
struct dentry *usbfs_dentry; /* usbfs dentry entry for the device */
extern struct usb_device *usb_get_dev(struct usb_device *dev);
extern void usb_put_dev(struct usb_device *dev);
-extern void usb_lock_device(struct usb_device *udev);
-extern int usb_trylock_device(struct usb_device *udev);
+/* USB device locking */
+#define usb_lock_device(udev) down(&(udev)->dev.sem)
+#define usb_unlock_device(udev) up(&(udev)->dev.sem)
+#define usb_trylock_device(udev) down_trylock(&(udev)->dev.sem)
extern int usb_lock_device_for_reset(struct usb_device *udev,
struct usb_interface *iface);
-extern void usb_unlock_device(struct usb_device *udev);
/* USB port reset for device reinitialization */
extern int usb_reset_device(struct usb_device *dev);
* USB 2.0 root hubs (EHCI host controllers) will get one path ID if they are
* high speed, and a different one if they are full or low speed.
*/
-static inline int usb_make_path (struct usb_device *dev, char *buf, size_t size)
+static inline int usb_make_path (struct usb_device *dev, char *buf,
+ size_t size)
{
int actual;
- actual = snprintf (buf, size, "usb-%s-%s", dev->bus->bus_name, dev->devpath);
+ actual = snprintf (buf, size, "usb-%s-%s", dev->bus->bus_name,
+ dev->devpath);
return (actual >= (int)size) ? -1 : actual;
}
/*-------------------------------------------------------------------------*/
-#define USB_DEVICE_ID_MATCH_DEVICE (USB_DEVICE_ID_MATCH_VENDOR | USB_DEVICE_ID_MATCH_PRODUCT)
-#define USB_DEVICE_ID_MATCH_DEV_RANGE (USB_DEVICE_ID_MATCH_DEV_LO | USB_DEVICE_ID_MATCH_DEV_HI)
-#define USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION (USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_DEV_RANGE)
+#define USB_DEVICE_ID_MATCH_DEVICE \
+ (USB_DEVICE_ID_MATCH_VENDOR | USB_DEVICE_ID_MATCH_PRODUCT)
+#define USB_DEVICE_ID_MATCH_DEV_RANGE \
+ (USB_DEVICE_ID_MATCH_DEV_LO | USB_DEVICE_ID_MATCH_DEV_HI)
+#define USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION \
+ (USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_DEV_RANGE)
#define USB_DEVICE_ID_MATCH_DEV_INFO \
- (USB_DEVICE_ID_MATCH_DEV_CLASS | USB_DEVICE_ID_MATCH_DEV_SUBCLASS | USB_DEVICE_ID_MATCH_DEV_PROTOCOL)
+ (USB_DEVICE_ID_MATCH_DEV_CLASS | \
+ USB_DEVICE_ID_MATCH_DEV_SUBCLASS | \
+ USB_DEVICE_ID_MATCH_DEV_PROTOCOL)
#define USB_DEVICE_ID_MATCH_INT_INFO \
- (USB_DEVICE_ID_MATCH_INT_CLASS | USB_DEVICE_ID_MATCH_INT_SUBCLASS | USB_DEVICE_ID_MATCH_INT_PROTOCOL)
+ (USB_DEVICE_ID_MATCH_INT_CLASS | \
+ USB_DEVICE_ID_MATCH_INT_SUBCLASS | \
+ USB_DEVICE_ID_MATCH_INT_PROTOCOL)
/**
* USB_DEVICE - macro used to describe a specific usb device
* specific device.
*/
#define USB_DEVICE(vend,prod) \
- .match_flags = USB_DEVICE_ID_MATCH_DEVICE, .idVendor = (vend), .idProduct = (prod)
+ .match_flags = USB_DEVICE_ID_MATCH_DEVICE, .idVendor = (vend), \
+ .idProduct = (prod)
/**
- * USB_DEVICE_VER - macro used to describe a specific usb device with a version range
+ * USB_DEVICE_VER - macro used to describe a specific usb device with a
+ * version range
* @vend: the 16 bit USB Vendor ID
* @prod: the 16 bit USB Product ID
* @lo: the bcdDevice_lo value
* specific device, with a version range.
*/
#define USB_DEVICE_VER(vend,prod,lo,hi) \
- .match_flags = USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION, .idVendor = (vend), .idProduct = (prod), .bcdDevice_lo = (lo), .bcdDevice_hi = (hi)
+ .match_flags = USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION, \
+ .idVendor = (vend), .idProduct = (prod), \
+ .bcdDevice_lo = (lo), .bcdDevice_hi = (hi)
/**
* USB_DEVICE_INFO - macro used to describe a class of usb devices
* specific class of devices.
*/
#define USB_DEVICE_INFO(cl,sc,pr) \
- .match_flags = USB_DEVICE_ID_MATCH_DEV_INFO, .bDeviceClass = (cl), .bDeviceSubClass = (sc), .bDeviceProtocol = (pr)
+ .match_flags = USB_DEVICE_ID_MATCH_DEV_INFO, .bDeviceClass = (cl), \
+ .bDeviceSubClass = (sc), .bDeviceProtocol = (pr)
/**
* USB_INTERFACE_INFO - macro used to describe a class of usb interfaces
* specific class of interfaces.
*/
#define USB_INTERFACE_INFO(cl,sc,pr) \
- .match_flags = USB_DEVICE_ID_MATCH_INT_INFO, .bInterfaceClass = (cl), .bInterfaceSubClass = (sc), .bInterfaceProtocol = (pr)
+ .match_flags = USB_DEVICE_ID_MATCH_INT_INFO, .bInterfaceClass = (cl), \
+ .bInterfaceSubClass = (sc), .bInterfaceProtocol = (pr)
+
+/* ----------------------------------------------------------------------- */
-/* -------------------------------------------------------------------------- */
+struct usb_dynids {
+ spinlock_t lock;
+ struct list_head list;
+};
/**
* struct usb_driver - identifies USB driver to usbcore
- * @owner: Pointer to the module owner of this driver; initialize
- * it using THIS_MODULE.
* @name: The driver name should be unique among USB drivers,
* and should normally be the same as the module name.
* @probe: Called to see if the driver is willing to manage a particular
* @id_table: USB drivers use ID table to support hotplugging.
* Export this with MODULE_DEVICE_TABLE(usb,...). This must be set
* or your driver's probe function will never get called.
+ * @dynids: used internally to hold the list of dynamically added device
+ * ids for this driver.
* @driver: the driver model core driver structure.
+ * @no_dynamic_id: if set to 1, the USB core will not allow dynamic ids to be
+ * added to this driver by preventing the sysfs file from being created.
*
* USB drivers must provide a name, probe() and disconnect() methods,
* and an id_table. Other driver fields are optional.
* them as necessary, and blocking until the unlinks complete).
*/
struct usb_driver {
- struct module *owner;
-
const char *name;
int (*probe) (struct usb_interface *intf,
void (*disconnect) (struct usb_interface *intf);
- int (*ioctl) (struct usb_interface *intf, unsigned int code, void *buf);
+ int (*ioctl) (struct usb_interface *intf, unsigned int code,
+ void *buf);
int (*suspend) (struct usb_interface *intf, pm_message_t message);
int (*resume) (struct usb_interface *intf);
const struct usb_device_id *id_table;
+ struct usb_dynids dynids;
struct device_driver driver;
+ unsigned int no_dynamic_id:1;
};
#define to_usb_driver(d) container_of(d, struct usb_driver, driver)
/**
* struct usb_class_driver - identifies a USB driver that wants to use the USB major number
- * @name: devfs name for this driver. Will also be used by the driver
- * class code to create a usb class device.
+ * @name: the usb class device name for this driver. Will show up in sysfs.
* @fops: pointer to the struct file_operations of this driver.
- * @mode: the mode for the devfs file to be created for this driver.
* @minor_base: the start of the minor range for this driver.
*
* This structure is used for the usb_register_dev() and
struct usb_class_driver {
char *name;
struct file_operations *fops;
- mode_t mode;
- int minor_base;
+ int minor_base;
};
/*
* use these in module_init()/module_exit()
* and don't forget MODULE_DEVICE_TABLE(usb, ...)
*/
-extern int usb_register(struct usb_driver *);
+int usb_register_driver(struct usb_driver *, struct module *);
+static inline int usb_register(struct usb_driver *driver)
+{
+ return usb_register_driver(driver, THIS_MODULE);
+}
extern void usb_deregister(struct usb_driver *);
extern int usb_register_dev(struct usb_interface *intf,
extern int usb_disabled(void);
-/* -------------------------------------------------------------------------- */
+/* ----------------------------------------------------------------------- */
/*
* URB support, for asynchronous request completions
* urb->transfer_flags:
*/
#define URB_SHORT_NOT_OK 0x0001 /* report short reads as errors */
-#define URB_ISO_ASAP 0x0002 /* iso-only, urb->start_frame ignored */
+#define URB_ISO_ASAP 0x0002 /* iso-only, urb->start_frame
+ * ignored */
#define URB_NO_TRANSFER_DMA_MAP 0x0004 /* urb->transfer_dma valid on submit */
#define URB_NO_SETUP_DMA_MAP 0x0008 /* urb->setup_dma valid on submit */
#define URB_NO_FSBR 0x0020 /* UHCI-specific */
-#define URB_ZERO_PACKET 0x0040 /* Finish bulk OUTs with short packet */
-#define URB_NO_INTERRUPT 0x0080 /* HINT: no non-error interrupt needed */
+#define URB_ZERO_PACKET 0x0040 /* Finish bulk OUT with short packet */
+#define URB_NO_INTERRUPT 0x0080 /* HINT: no non-error interrupt
+ * needed */
struct usb_iso_packet_descriptor {
unsigned int offset;
*/
struct urb
{
- /* private, usb core and host controller only fields in the urb */
+ /* private: usb core and host controller only fields in the urb */
struct kref kref; /* reference count of the URB */
spinlock_t lock; /* lock for the URB */
void *hcpriv; /* private data for host controller */
atomic_t use_count; /* concurrent submissions counter */
u8 reject; /* submissions will fail */
- /* public, documented fields in the urb that can be used by drivers */
- struct list_head urb_list; /* list head for use by the urb owner */
+ /* public: documented fields in the urb that can be used by drivers */
+ struct list_head urb_list; /* list head for use by the urb's
+ * current owner */
struct usb_device *dev; /* (in) pointer to associated device */
unsigned int pipe; /* (in) pipe information */
int status; /* (return) non-ISO status */
dma_addr_t setup_dma; /* (in) dma addr for setup_packet */
int start_frame; /* (modify) start frame (ISO) */
int number_of_packets; /* (in) number of ISO packets */
- int interval; /* (modify) transfer interval (INT/ISO) */
+ int interval; /* (modify) transfer interval
+ * (INT/ISO) */
int error_count; /* (return) number of ISO errors */
void *context; /* (in) context for completion */
usb_complete_t complete; /* (in) completion routine */
- struct usb_iso_packet_descriptor iso_frame_desc[0]; /* (in) ISO ONLY */
+ struct usb_iso_packet_descriptor iso_frame_desc[0];
+ /* (in) ISO ONLY */
};
-/* -------------------------------------------------------------------------- */
+/* ----------------------------------------------------------------------- */
/**
* usb_fill_control_urb - initializes a control urb
void *data, int len, int *actual_length,
int timeout);
-/* selective suspend/resume */
-extern int usb_suspend_device(struct usb_device *dev, pm_message_t message);
-extern int usb_resume_device(struct usb_device *dev);
-
-
/* wrappers around usb_control_msg() for the most common standard requests */
extern int usb_get_descriptor(struct usb_device *dev, unsigned char desctype,
unsigned char descindex, void *buf, int size);
extern int usb_get_status(struct usb_device *dev,
int type, int target, void *data);
-extern int usb_get_string(struct usb_device *dev,
- unsigned short langid, unsigned char index, void *buf, int size);
extern int usb_string(struct usb_device *dev, int index,
char *buf, size_t size);
size_t bytes;
/*
- * members below are private to usbcore,
+ * members below are private: to usbcore,
* and are not provided for driver access!
*/
spinlock_t lock;
void usb_sg_wait (struct usb_sg_request *io);
-/* -------------------------------------------------------------------------- */
+/* ----------------------------------------------------------------------- */
/*
* For various legacy reasons, Linux has a small cookie that's paired with
/* The D0/D1 toggle bits ... USE WITH CAUTION (they're almost hcd-internal) */
#define usb_gettoggle(dev, ep, out) (((dev)->toggle[out] >> (ep)) & 1)
#define usb_dotoggle(dev, ep, out) ((dev)->toggle[out] ^= (1 << (ep)))
-#define usb_settoggle(dev, ep, out, bit) ((dev)->toggle[out] = ((dev)->toggle[out] & ~(1 << (ep))) | ((bit) << (ep)))
+#define usb_settoggle(dev, ep, out, bit) \
+ ((dev)->toggle[out] = ((dev)->toggle[out] & ~(1 << (ep))) | \
+ ((bit) << (ep)))
-static inline unsigned int __create_pipe(struct usb_device *dev, unsigned int endpoint)
+static inline unsigned int __create_pipe(struct usb_device *dev,
+ unsigned int endpoint)
{
return (dev->devnum << 8) | (endpoint << 15);
}
/* Create various pipes... */
-#define usb_sndctrlpipe(dev,endpoint) ((PIPE_CONTROL << 30) | __create_pipe(dev,endpoint))
-#define usb_rcvctrlpipe(dev,endpoint) ((PIPE_CONTROL << 30) | __create_pipe(dev,endpoint) | USB_DIR_IN)
-#define usb_sndisocpipe(dev,endpoint) ((PIPE_ISOCHRONOUS << 30) | __create_pipe(dev,endpoint))
-#define usb_rcvisocpipe(dev,endpoint) ((PIPE_ISOCHRONOUS << 30) | __create_pipe(dev,endpoint) | USB_DIR_IN)
-#define usb_sndbulkpipe(dev,endpoint) ((PIPE_BULK << 30) | __create_pipe(dev,endpoint))
-#define usb_rcvbulkpipe(dev,endpoint) ((PIPE_BULK << 30) | __create_pipe(dev,endpoint) | USB_DIR_IN)
-#define usb_sndintpipe(dev,endpoint) ((PIPE_INTERRUPT << 30) | __create_pipe(dev,endpoint))
-#define usb_rcvintpipe(dev,endpoint) ((PIPE_INTERRUPT << 30) | __create_pipe(dev,endpoint) | USB_DIR_IN)
+#define usb_sndctrlpipe(dev,endpoint) \
+ ((PIPE_CONTROL << 30) | __create_pipe(dev,endpoint))
+#define usb_rcvctrlpipe(dev,endpoint) \
+ ((PIPE_CONTROL << 30) | __create_pipe(dev,endpoint) | USB_DIR_IN)
+#define usb_sndisocpipe(dev,endpoint) \
+ ((PIPE_ISOCHRONOUS << 30) | __create_pipe(dev,endpoint))
+#define usb_rcvisocpipe(dev,endpoint) \
+ ((PIPE_ISOCHRONOUS << 30) | __create_pipe(dev,endpoint) | USB_DIR_IN)
+#define usb_sndbulkpipe(dev,endpoint) \
+ ((PIPE_BULK << 30) | __create_pipe(dev,endpoint))
+#define usb_rcvbulkpipe(dev,endpoint) \
+ ((PIPE_BULK << 30) | __create_pipe(dev,endpoint) | USB_DIR_IN)
+#define usb_sndintpipe(dev,endpoint) \
+ ((PIPE_INTERRUPT << 30) | __create_pipe(dev,endpoint))
+#define usb_rcvintpipe(dev,endpoint) \
+ ((PIPE_INTERRUPT << 30) | __create_pipe(dev,endpoint) | USB_DIR_IN)
/*-------------------------------------------------------------------------*/
return le16_to_cpu(ep->desc.wMaxPacketSize);
}
-/* -------------------------------------------------------------------------- */
+/* ----------------------------------------------------------------------- */
+
+/* Events from the usb core */
+#define USB_DEVICE_ADD 0x0001
+#define USB_DEVICE_REMOVE 0x0002
+#define USB_BUS_ADD 0x0003
+#define USB_BUS_REMOVE 0x0004
+extern void usb_register_notify(struct notifier_block *nb);
+extern void usb_unregister_notify(struct notifier_block *nb);
#ifdef DEBUG
-#define dbg(format, arg...) printk(KERN_DEBUG "%s: " format "\n" , __FILE__ , ## arg)
+#define dbg(format, arg...) printk(KERN_DEBUG "%s: " format "\n" , \
+ __FILE__ , ## arg)
#else
#define dbg(format, arg...) do {} while (0)
#endif
-#define err(format, arg...) printk(KERN_ERR "%s: " format "\n" , __FILE__ , ## arg)
-#define info(format, arg...) printk(KERN_INFO "%s: " format "\n" , __FILE__ , ## arg)
-#define warn(format, arg...) printk(KERN_WARNING "%s: " format "\n" , __FILE__ , ## arg)
+#define err(format, arg...) printk(KERN_ERR "%s: " format "\n" , \
+ __FILE__ , ## arg)
+#define info(format, arg...) printk(KERN_INFO "%s: " format "\n" , \
+ __FILE__ , ## arg)
+#define warn(format, arg...) printk(KERN_WARNING "%s: " format "\n" , \
+ __FILE__ , ## arg)
#endif /* __KERNEL__ */