Commit 686e0b75 authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman

Merge kroah.com:/home/greg/linux/BK/bleeding_edge-2.5

into kroah.com:/home/greg/linux/BK/gregkh-2.5
parents 7fb7f2ac 3b4f1bc8
...@@ -2625,7 +2625,6 @@ EXPORT_SYMBOL(usb_scan_devices); ...@@ -2625,7 +2625,6 @@ EXPORT_SYMBOL(usb_scan_devices);
EXPORT_SYMBOL(usb_alloc_dev); EXPORT_SYMBOL(usb_alloc_dev);
EXPORT_SYMBOL(usb_free_dev); EXPORT_SYMBOL(usb_free_dev);
EXPORT_SYMBOL(usb_inc_dev_use);
EXPORT_SYMBOL(usb_find_interface_driver_for_ifnum); EXPORT_SYMBOL(usb_find_interface_driver_for_ifnum);
EXPORT_SYMBOL(usb_driver_claim_interface); EXPORT_SYMBOL(usb_driver_claim_interface);
......
...@@ -91,7 +91,10 @@ ehci_hub_status_data (struct usb_hcd *hcd, char *buf) ...@@ -91,7 +91,10 @@ ehci_hub_status_data (struct usb_hcd *hcd, char *buf)
if (!(temp & PORT_CONNECT)) if (!(temp & PORT_CONNECT))
ehci->reset_done [i] = 0; ehci->reset_done [i] = 0;
if ((temp & (PORT_CSC | PORT_PEC | PORT_OCC)) != 0) { if ((temp & (PORT_CSC | PORT_PEC | PORT_OCC)) != 0) {
set_bit (i, buf); if (i < 7)
buf [0] |= 1 << (i + 1);
else
buf [1] |= 1 << (i - 7);
status = STS_PCD; status = STS_PCD;
} }
} }
...@@ -141,7 +144,7 @@ static int ehci_hub_control ( ...@@ -141,7 +144,7 @@ static int ehci_hub_control (
) { ) {
struct ehci_hcd *ehci = hcd_to_ehci (hcd); struct ehci_hcd *ehci = hcd_to_ehci (hcd);
int ports = HCS_N_PORTS (ehci->hcs_params); int ports = HCS_N_PORTS (ehci->hcs_params);
u32 temp; u32 temp, status;
unsigned long flags; unsigned long flags;
int retval = 0; int retval = 0;
...@@ -219,22 +222,22 @@ static int ehci_hub_control ( ...@@ -219,22 +222,22 @@ static int ehci_hub_control (
if (!wIndex || wIndex > ports) if (!wIndex || wIndex > ports)
goto error; goto error;
wIndex--; wIndex--;
memset (buf, 0, 4); status = 0;
temp = readl (&ehci->regs->port_status [wIndex]); temp = readl (&ehci->regs->port_status [wIndex]);
// wPortChange bits // wPortChange bits
if (temp & PORT_CSC) if (temp & PORT_CSC)
set_bit (USB_PORT_FEAT_C_CONNECTION, buf); status |= 1 << USB_PORT_FEAT_C_CONNECTION;
if (temp & PORT_PEC) if (temp & PORT_PEC)
set_bit (USB_PORT_FEAT_C_ENABLE, buf); status |= 1 << USB_PORT_FEAT_C_ENABLE;
// USB_PORT_FEAT_C_SUSPEND // USB_PORT_FEAT_C_SUSPEND
if (temp & PORT_OCC) if (temp & PORT_OCC)
set_bit (USB_PORT_FEAT_C_OVER_CURRENT, buf); status |= 1 << USB_PORT_FEAT_C_OVER_CURRENT;
/* whoever resets must GetPortStatus to complete it!! */ /* whoever resets must GetPortStatus to complete it!! */
if ((temp & PORT_RESET) if ((temp & PORT_RESET)
&& jiffies > ehci->reset_done [wIndex]) { && jiffies > ehci->reset_done [wIndex]) {
set_bit (USB_PORT_FEAT_C_RESET, buf); status |= 1 << USB_PORT_FEAT_C_RESET;
/* force reset to complete */ /* force reset to complete */
writel (temp & ~PORT_RESET, writel (temp & ~PORT_RESET,
...@@ -252,26 +255,27 @@ static int ehci_hub_control ( ...@@ -252,26 +255,27 @@ static int ehci_hub_control (
// don't show wPortStatus if it's owned by a companion hc // don't show wPortStatus if it's owned by a companion hc
if (!(temp & PORT_OWNER)) { if (!(temp & PORT_OWNER)) {
if (temp & PORT_CONNECT) { if (temp & PORT_CONNECT) {
set_bit (USB_PORT_FEAT_CONNECTION, buf); status |= 1 << USB_PORT_FEAT_CONNECTION;
set_bit (USB_PORT_FEAT_HIGHSPEED, buf); status |= 1 << USB_PORT_FEAT_HIGHSPEED;
} }
if (temp & PORT_PE) if (temp & PORT_PE)
set_bit (USB_PORT_FEAT_ENABLE, buf); status |= 1 << USB_PORT_FEAT_ENABLE;
if (temp & PORT_SUSPEND) if (temp & PORT_SUSPEND)
set_bit (USB_PORT_FEAT_SUSPEND, buf); status |= 1 << USB_PORT_FEAT_SUSPEND;
if (temp & PORT_OC) if (temp & PORT_OC)
set_bit (USB_PORT_FEAT_OVER_CURRENT, buf); status |= 1 << USB_PORT_FEAT_OVER_CURRENT;
if (temp & PORT_RESET) if (temp & PORT_RESET)
set_bit (USB_PORT_FEAT_RESET, buf); status |= 1 << USB_PORT_FEAT_RESET;
if (temp & PORT_POWER) if (temp & PORT_POWER)
set_bit (USB_PORT_FEAT_POWER, buf); status |= 1 << USB_PORT_FEAT_POWER;
} }
#ifndef EHCI_VERBOSE_DEBUG #ifndef EHCI_VERBOSE_DEBUG
if (*(u16*)(buf+2)) /* only if wPortChange is interesting */ if (status & ~0xffff) /* only if wPortChange is interesting */
#endif #endif
dbg_port (hcd, "GetStatus", wIndex + 1, temp); dbg_port (hcd, "GetStatus", wIndex + 1, temp);
cpu_to_le32s ((u32 *) buf); // we "know" this alignment is good, caller used kmalloc()...
*((u32 *) buf) = cpu_to_le32 (status);
break; break;
case SetHubFeature: case SetHubFeature:
switch (wValue) { switch (wValue) {
......
...@@ -96,7 +96,10 @@ ohci_hub_status_data (struct usb_hcd *hcd, char *buf) ...@@ -96,7 +96,10 @@ ohci_hub_status_data (struct usb_hcd *hcd, char *buf)
| RH_PS_OCIC | RH_PS_PRSC; | RH_PS_OCIC | RH_PS_PRSC;
if (status) { if (status) {
changed = 1; changed = 1;
set_bit (i + 1, buf); if (i < 7)
buf [0] |= 1 << (i + 1);
else
buf [1] |= 1 << (i - 7);
} }
} }
return changed ? length : 0; return changed ? length : 0;
......
...@@ -255,6 +255,8 @@ PEGASUS_DEV( "SMC 2206 USB Ethernet", VENDOR_SMC, 0x0201, ...@@ -255,6 +255,8 @@ PEGASUS_DEV( "SMC 2206 USB Ethernet", VENDOR_SMC, 0x0201,
DEFAULT_GPIO_RESET | PEGASUS_II) DEFAULT_GPIO_RESET | PEGASUS_II)
PEGASUS_DEV( "SOHOware NUB100 Ethernet", VENDOR_SOHOWARE, 0x9100, PEGASUS_DEV( "SOHOware NUB100 Ethernet", VENDOR_SOHOWARE, 0x9100,
DEFAULT_GPIO_RESET ) DEFAULT_GPIO_RESET )
PEGASUS_DEV( "SOHOware NUB110 Ethernet", VENDOR_SOHOWARE, 0x9110,
DEFAULT_GPIO_RESET | PEGASUS_II )
PEGASUS_DEV( "SpeedStream USB 10/100 Ethernet", VENDOR_SIEMENS, 0x1001, PEGASUS_DEV( "SpeedStream USB 10/100 Ethernet", VENDOR_SIEMENS, 0x1001,
DEFAULT_GPIO_RESET ) DEFAULT_GPIO_RESET )
......
...@@ -31,7 +31,7 @@ ...@@ -31,7 +31,7 @@
#define BRLVGER_BUZZ 4 #define BRLVGER_BUZZ 4
/* Number of supported devices, and range of covered minors */ /* Number of supported devices, and range of covered minors */
#define MAX_NR_BRLVGER_DEVS 2 #define MAX_NR_BRLVGER_DEVS 4
/* Base minor for the char devices */ /* Base minor for the char devices */
#define BRLVGER_MINOR 128 #define BRLVGER_MINOR 128
......
...@@ -317,6 +317,223 @@ int __usb_get_extra_descriptor(char *buffer, unsigned size, ...@@ -317,6 +317,223 @@ int __usb_get_extra_descriptor(char *buffer, unsigned size,
__usb_get_extra_descriptor((ifpoint)->extra,(ifpoint)->extralen,\ __usb_get_extra_descriptor((ifpoint)->extra,(ifpoint)->extralen,\
type,(void**)ptr) type,(void**)ptr)
/* -------------------------------------------------------------------------- */
/* Host Controller Driver (HCD) support */
struct usb_operations;
#define DEVNUM_ROUND_ROBIN /***** OPTION *****/
/*
* Allocated per bus we have
*/
struct usb_bus {
int busnum; /* Bus number (in order of reg) */
char *bus_name; /* stable id (PCI slot_name etc) */
#ifdef DEVNUM_ROUND_ROBIN
int devnum_next; /* Next open device number in round-robin allocation */
#endif /* DEVNUM_ROUND_ROBIN */
struct usb_devmap devmap; /* device address allocation map */
struct usb_operations *op; /* Operations (specific to the HC) */
struct usb_device *root_hub; /* Root hub */
struct list_head bus_list; /* list of busses */
void *hcpriv; /* Host Controller private data */
int bandwidth_allocated; /* on this bus: how much of the time
* reserved for periodic (intr/iso)
* requests is used, on average?
* Units: microseconds/frame.
* Limits: Full/low speed reserve 90%,
* while high speed reserves 80%.
*/
int bandwidth_int_reqs; /* number of Interrupt requests */
int bandwidth_isoc_reqs; /* number of Isoc. requests */
struct dentry *dentry; /* usbfs dentry entry for the bus */
atomic_t refcnt;
};
// FIXME: root_hub_string vanishes when "usb_hcd" conversion is done,
// along with pre-hcd versions of the OHCI and UHCI drivers.
extern int usb_root_hub_string(int id, int serial,
char *type, __u8 *data, int len);
/*
* As of USB 2.0, full/low speed devices are segregated into trees.
* One type grows from USB 1.1 host controllers (OHCI, UHCI etc).
* The other type grows from high speed hubs when they connect to
* full/low speed devices using "Transaction Translators" (TTs).
*
* TTs should only be known to the hub driver, and high speed bus
* drivers (only EHCI for now). They affect periodic scheduling and
* sometimes control/bulk error recovery.
*/
struct usb_tt {
struct usb_device *hub; /* upstream highspeed hub */
int multi; /* true means one TT per port */
};
/* -------------------------------------------------------------------------- */
/* This is arbitrary.
* From USB 2.0 spec Table 11-13, offset 7, a hub can
* have up to 255 ports. The most yet reported is 10.
*/
#define USB_MAXCHILDREN (16)
struct usb_device {
int devnum; /* Address on USB bus */
char devpath [16]; /* Use in messages: /port/port/... */
enum {
USB_SPEED_UNKNOWN = 0, /* enumerating */
USB_SPEED_LOW, USB_SPEED_FULL, /* usb 1.1 */
USB_SPEED_HIGH /* usb 2.0 */
} speed;
struct usb_tt *tt; /* low/full speed dev, highspeed hub */
int ttport; /* device port on that tt hub */
atomic_t refcnt; /* Reference count */
struct semaphore serialize;
unsigned int toggle[2]; /* one bit for each endpoint ([0] = IN, [1] = OUT) */
unsigned int halted[2]; /* endpoint halts; one bit per endpoint # & direction; */
/* [0] = IN, [1] = OUT */
int epmaxpacketin[16]; /* INput endpoint specific maximums */
int epmaxpacketout[16]; /* OUTput endpoint specific maximums */
struct usb_device *parent; /* our hub, unless we're the root */
struct usb_bus *bus; /* Bus we're part of */
struct device dev; /* Generic device interface */
struct usb_device_descriptor descriptor;/* Descriptor */
struct usb_config_descriptor *config; /* All of the configs */
struct usb_config_descriptor *actconfig;/* the active configuration */
char **rawdescriptors; /* Raw descriptors for each config */
int have_langid; /* whether string_langid is valid yet */
int string_langid; /* language ID for strings */
void *hcpriv; /* Host Controller private data */
struct list_head filelist;
struct dentry *dentry; /* usbfs dentry entry for the device */
/*
* Child devices - these can be either new devices
* (if this is a hub device), or different instances
* of this same device.
*
* Each instance needs its own set of data structures.
*/
int maxchild; /* Number of ports if hub */
struct usb_device *children[USB_MAXCHILDREN];
};
/* for when layers above USB add new non-USB drivers */
extern void usb_scan_devices(void);
/* mostly for devices emulating SCSI over USB */
extern int usb_reset_device(struct usb_device *dev);
/* for drivers using iso endpoints */
extern int usb_get_current_frame_number (struct usb_device *usb_dev);
/**
* usb_inc_dev_use - record another reference to a device
* @dev: the device being referenced
*
* Each live reference to a device should be refcounted.
*
* Drivers for USB interfaces should normally record such references in
* their probe() methods, when they bind to an interface, and release
* them usb_dec_dev_use(), in their disconnect() methods.
*/
static inline void usb_inc_dev_use (struct usb_device *dev)
{
atomic_inc (&dev->refcnt);
}
/**
* usb_dec_dev_use - drop a reference to a device
* @dev: the device no longer being referenced
*
* Each live reference to a device should be refcounted.
*
* Drivers for USB interfaces should normally release such references in
* their disconnect() methods, and record them in probe().
*
* Note that driver disconnect() methods must guarantee that when they
* return, all of their outstanding references to the device (and its
* interfaces) are cleaned up. That means that all pending URBs from
* this driver must have completed, and that no more copies of the device
* handle are saved in driver records (including other kernel threads).
*/
static inline void usb_dec_dev_use (struct usb_device *dev)
{
if (atomic_dec_and_test (&dev->refcnt)) {
/* May only go to zero when usbcore finishes
* usb_disconnect() processing: khubd or HCDs.
*
* If you hit this BUG() it's likely a problem
* with some driver's disconnect() routine.
*/
BUG ();
}
}
/* used these for multi-interface device registration */
extern int usb_find_interface_driver_for_ifnum(struct usb_device *dev, unsigned int ifnum);
extern void usb_driver_claim_interface(struct usb_driver *driver,
struct usb_interface *iface, void* priv);
extern int usb_interface_claimed(struct usb_interface *iface);
extern void usb_driver_release_interface(struct usb_driver *driver,
struct usb_interface *iface);
const struct usb_device_id *usb_match_id(struct usb_device *dev,
struct usb_interface *interface,
const struct usb_device_id *id);
/**
* usb_make_path - returns stable device path in the usb tree
* @dev: the device whose path is being constructed
* @buf: where to put the string
* @size: how big is "buf"?
*
* Returns length of the string (> 0) or negative if size was too small.
*
* This identifier is intended to be "stable", reflecting physical paths in
* hardware such as physical bus addresses for host controllers or ports on
* USB hubs. That makes it stay the same until systems are physically
* reconfigured, by re-cabling a tree of USB devices or by moving USB host
* controllers. Adding and removing devices, including virtual root hubs
* in host controller driver modules, does not change these path identifers;
* neither does rebooting or re-enumerating. These are more useful identifiers
* than changeable ("unstable") ones like bus numbers or device addresses.
*
* With a partial exception for devices connected to USB 2.0 root hubs, these
* identifiers are also predictable: so long as the device tree isn't changed,
* plugging any USB device into a given hub port always gives it the same path.
* Because of the use of "companion" controllers, devices connected to ports on
* 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)
{
int actual;
actual = snprintf (buf, size, "usb-%s-%s", dev->bus->bus_name, dev->devpath);
return (actual >= size) ? -1 : actual;
}
/*-------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------*/
/* /*
...@@ -826,10 +1043,14 @@ static inline void usb_fill_bulk_urb (struct urb *urb, ...@@ -826,10 +1043,14 @@ static inline void usb_fill_bulk_urb (struct urb *urb,
* @buffer_length: length of the transfer buffer * @buffer_length: length of the transfer buffer
* @complete: pointer to the usb_complete_t function * @complete: pointer to the usb_complete_t function
* @context: what to set the urb context to. * @context: what to set the urb context to.
* @interval: what to set the urb interval to. * @interval: what to set the urb interval to, encoded like
* the endpoint descriptor's bInterval value.
* *
* Initializes a interrupt urb with the proper information needed to submit * Initializes a interrupt urb with the proper information needed to submit
* it to a device. * it to a device.
* Note that high speed interrupt endpoints use a logarithmic encoding of
* the endpoint interval, and express polling intervals in microframes
* (eight per millisecond) rather than in frames (one per millisecond).
*/ */
static inline void usb_fill_int_urb (struct urb *urb, static inline void usb_fill_int_urb (struct urb *urb,
struct usb_device *dev, struct usb_device *dev,
...@@ -847,6 +1068,9 @@ static inline void usb_fill_int_urb (struct urb *urb, ...@@ -847,6 +1068,9 @@ static inline void usb_fill_int_urb (struct urb *urb,
urb->transfer_buffer_length = buffer_length; urb->transfer_buffer_length = buffer_length;
urb->complete = complete; urb->complete = complete;
urb->context = context; urb->context = context;
if (dev->speed == USB_SPEED_HIGH)
urb->interval = 1 << (interval - 1);
else
urb->interval = interval; urb->interval = interval;
urb->start_frame = -1; urb->start_frame = -1;
} }
...@@ -908,221 +1132,6 @@ extern int usb_set_interface(struct usb_device *dev, int ifnum, int alternate); ...@@ -908,221 +1132,6 @@ extern int usb_set_interface(struct usb_device *dev, int ifnum, int alternate);
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
/* Host Controller Driver (HCD) support */
struct usb_operations;
#define DEVNUM_ROUND_ROBIN /***** OPTION *****/
/*
* Allocated per bus we have
*/
struct usb_bus {
int busnum; /* Bus number (in order of reg) */
char *bus_name; /* stable id (PCI slot_name etc) */
#ifdef DEVNUM_ROUND_ROBIN
int devnum_next; /* Next open device number in round-robin allocation */
#endif /* DEVNUM_ROUND_ROBIN */
struct usb_devmap devmap; /* Device map */
struct usb_operations *op; /* Operations (specific to the HC) */
struct usb_device *root_hub; /* Root hub */
struct list_head bus_list;
void *hcpriv; /* Host Controller private data */
int bandwidth_allocated; /* on this Host Controller; */
/* applies to Int. and Isoc. pipes; */
/* measured in microseconds/frame; */
/* range is 0..900, where 900 = */
/* 90% of a 1-millisecond frame */
int bandwidth_int_reqs; /* number of Interrupt requesters */
int bandwidth_isoc_reqs; /* number of Isoc. requesters */
struct dentry *dentry; /* usbfs dentry entry for the bus */
atomic_t refcnt;
};
// FIXME: root_hub_string vanishes when "usb_hcd" conversion is done,
// along with pre-hcd versions of the OHCI and UHCI drivers.
extern int usb_root_hub_string(int id, int serial,
char *type, __u8 *data, int len);
/*
* As of USB 2.0, full/low speed devices are segregated into trees.
* One type grows from USB 1.1 host controllers (OHCI, UHCI etc).
* The other type grows from high speed hubs when they connect to
* full/low speed devices using "Transaction Translators" (TTs).
*
* TTs should only be known to the hub driver, and high speed bus
* drivers (only EHCI for now). They affect periodic scheduling and
* sometimes control/bulk error recovery.
*/
struct usb_tt {
struct usb_device *hub; /* upstream highspeed hub */
int multi; /* true means one TT per port */
};
/* -------------------------------------------------------------------------- */
/* This is arbitrary.
* From USB 2.0 spec Table 11-13, offset 7, a hub can
* have up to 255 ports. The most yet reported is 10.
*/
#define USB_MAXCHILDREN (16)
struct usb_device {
int devnum; /* Address on USB bus */
char devpath [16]; /* Use in messages: /port/port/... */
enum {
USB_SPEED_UNKNOWN = 0, /* enumerating */
USB_SPEED_LOW, USB_SPEED_FULL, /* usb 1.1 */
USB_SPEED_HIGH /* usb 2.0 */
} speed;
struct usb_tt *tt; /* low/full speed dev, highspeed hub */
int ttport; /* device port on that tt hub */
atomic_t refcnt; /* Reference count */
struct semaphore serialize;
unsigned int toggle[2]; /* one bit for each endpoint ([0] = IN, [1] = OUT) */
unsigned int halted[2]; /* endpoint halts; one bit per endpoint # & direction; */
/* [0] = IN, [1] = OUT */
int epmaxpacketin[16]; /* INput endpoint specific maximums */
int epmaxpacketout[16]; /* OUTput endpoint specific maximums */
struct usb_device *parent;
struct usb_bus *bus; /* Bus we're part of */
struct device dev; /* Generic device interface */
struct usb_device_descriptor descriptor;/* Descriptor */
struct usb_config_descriptor *config; /* All of the configs */
struct usb_config_descriptor *actconfig;/* the active configuration */
char **rawdescriptors; /* Raw descriptors for each config */
int have_langid; /* whether string_langid is valid yet */
int string_langid; /* language ID for strings */
void *hcpriv; /* Host Controller private data */
struct list_head filelist;
struct dentry *dentry; /* usbfs dentry entry for the device */
/*
* Child devices - these can be either new devices
* (if this is a hub device), or different instances
* of this same device.
*
* Each instance needs its own set of data structures.
*/
int maxchild; /* Number of ports if hub */
struct usb_device *children[USB_MAXCHILDREN];
};
/* for when layers above USB add new non-USB drivers */
extern void usb_scan_devices(void);
/* mostly for devices emulating SCSI over USB */
extern int usb_reset_device(struct usb_device *dev);
/* for drivers using iso endpoints */
extern int usb_get_current_frame_number (struct usb_device *usb_dev);
/**
* usb_inc_dev_use - record another reference to a device
* @dev: the device being referenced
*
* Each live reference to a device should be refcounted.
*
* Drivers for USB interfaces should normally record such references in
* their probe() methods, when they bind to an interface, and release
* them usb_dec_dev_use(), in their disconnect() methods.
*/
static inline void usb_inc_dev_use (struct usb_device *dev)
{
atomic_inc (&dev->refcnt);
}
/**
* usb_dec_dev_use - drop a reference to a device
* @dev: the device no longer being referenced
*
* Each live reference to a device should be refcounted.
*
* Drivers for USB interfaces should normally release such references in
* their disconnect() methods, and record them in probe().
*
* Note that driver disconnect() methods must guarantee that when they
* return, all of their outstanding references to the device (and its
* interfaces) are cleaned up. That means that all pending URBs from
* this driver must have completed, and that no more copies of the device
* handle are saved in driver records (including other kernel threads).
*/
static inline void usb_dec_dev_use (struct usb_device *dev)
{
if (atomic_dec_and_test (&dev->refcnt)) {
/* May only go to zero when usbcore finishes
* usb_disconnect() processing: khubd or HCDs.
*
* If you hit this BUG() it's likely a problem
* with some driver's disconnect() routine.
*/
BUG ();
}
}
/* used these for multi-interface device registration */
extern int usb_find_interface_driver_for_ifnum(struct usb_device *dev, unsigned int ifnum);
extern void usb_driver_claim_interface(struct usb_driver *driver,
struct usb_interface *iface, void* priv);
extern int usb_interface_claimed(struct usb_interface *iface);
extern void usb_driver_release_interface(struct usb_driver *driver,
struct usb_interface *iface);
const struct usb_device_id *usb_match_id(struct usb_device *dev,
struct usb_interface *interface,
const struct usb_device_id *id);
/**
* usb_make_path - returns stable device path in the usb tree
* @dev: the device whose path is being constructed
* @buf: where to put the string
* @size: how big is "buf"?
*
* Returns length of the string (> 0) or negative if size was too small.
*
* This identifier is intended to be "stable", reflecting physical paths in
* hardware such as physical bus addresses for host controllers or ports on
* USB hubs. That makes it stay the same until systems are physically
* reconfigured, by re-cabling a tree of USB devices or by moving USB host
* controllers. Adding and removing devices, including virtual root hubs
* in host controller driver modules, does not change these path identifers;
* neither does rebooting or re-enumerating. These are more useful identifiers
* than changeable ("unstable") ones like bus numbers or device addresses.
*
* With a partial exception for devices connected to USB 2.0 root hubs, these
* identifiers are also predictable: so long as the device tree isn't changed,
* plugging any USB device into a given hub port always gives it the same path.
* Because of the use of "companion" controllers, devices connected to ports on
* 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)
{
int actual;
actual = snprintf (buf, size, "usb-%s-%s", dev->bus->bus_name, dev->devpath);
return (actual >= size) ? -1 : actual;
}
/* -------------------------------------------------------------------------- */
/* /*
* Calling this entity a "pipe" is glorifying it. A USB pipe * Calling this entity a "pipe" is glorifying it. A USB pipe
* is something embarrassingly simple: it basically consists * is something embarrassingly simple: it basically consists
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment