Skip to content

Commit

Permalink
Merge master.kernel.org:/pub/scm/linux/kernel/git/gregkh/usb-2.6
Browse files Browse the repository at this point in the history
* master.kernel.org:/pub/scm/linux/kernel/git/gregkh/usb-2.6:
  OHCI: Fix machine check in ohci_hub_status_data
  USB: Fix up bogus bInterval values in endpoint descriptors
  USB: cxacru: ignore error trying to start ADSL in atm_start
  USB: cxacru: create sysfs attributes in atm_start instead of bind
  USB: cxacru: add Documentation file
  USB: UNUSUAL_DEV: Sync up some reported devices from Ubuntu
  USB: usb gadgets avoid le{16,32}_to_cpup()
  usblp: Don't let suspend to kill ->used
  USB: set default y for CONFIG_USB_DEVICE_CLASS
  • Loading branch information
Linus Torvalds committed Jun 9, 2007
2 parents 837525e + 6fd75b1 commit 5b65c09
Show file tree
Hide file tree
Showing 13 changed files with 222 additions and 65 deletions.
2 changes: 2 additions & 0 deletions Documentation/networking/00-INDEX
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ cops.txt
- info on the COPS LocalTalk Linux driver
cs89x0.txt
- the Crystal LAN (CS8900/20-based) Ethernet ISA adapter driver
cxacru.txt
- Conexant AccessRunner USB ADSL Modem
de4x5.txt
- the Digital EtherWORKS DE4?? and DE5?? PCI Ethernet driver
decnet.txt
Expand Down
84 changes: 84 additions & 0 deletions Documentation/networking/cxacru.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
Firmware is required for this device: http://accessrunner.sourceforge.net/

While it is capable of managing/maintaining the ADSL connection without the
module loaded, the device will sometimes stop responding after unloading the
driver and it is necessary to unplug/remove power to the device to fix this.

Detected devices will appear as ATM devices named "cxacru". In /sys/class/atm/
these are directories named cxacruN where N is the device number. A symlink
named device points to the USB interface device's directory which contains
several sysfs attribute files for retrieving device statistics:

* adsl_controller_version

* adsl_headend
* adsl_headend_environment
Information about the remote headend.

* downstream_attenuation (dB)
* downstream_bits_per_frame
* downstream_rate (kbps)
* downstream_snr_margin (dB)
Downstream stats.

* upstream_attenuation (dB)
* upstream_bits_per_frame
* upstream_rate (kbps)
* upstream_snr_margin (dB)
* transmitter_power (dBm/Hz)
Upstream stats.

* downstream_crc_errors
* downstream_fec_errors
* downstream_hec_errors
* upstream_crc_errors
* upstream_fec_errors
* upstream_hec_errors
Error counts.

* line_startable
Indicates that ADSL support on the device
is/can be enabled, see adsl_start.

* line_status
"initialising"
"down"
"attempting to activate"
"training"
"channel analysis"
"exchange"
"waiting"
"up"

Changes between "down" and "attempting to activate"
if there is no signal.

* link_status
"not connected"
"connected"
"lost"

* mac_address

* modulation
"ANSI T1.413"
"ITU-T G.992.1 (G.DMT)"
"ITU-T G.992.2 (G.LITE)"

* startup_attempts
Count of total attempts to initialise ADSL.

To enable/disable ADSL, the following can be written to the adsl_state file:
"start"
"stop
"restart" (stops, waits 1.5s, then starts)
"poll" (used to resume status polling if it was disabled due to failure)

Changes in adsl/line state are reported via kernel log messages:
[4942145.150704] ATM dev 0: ADSL state: running
[4942243.663766] ATM dev 0: ADSL line: down
[4942249.665075] ATM dev 0: ADSL line: attempting to activate
[4942253.654954] ATM dev 0: ADSL line: training
[4942255.666387] ATM dev 0: ADSL line: channel analysis
[4942259.656262] ATM dev 0: ADSL line: exchange
[2635357.696901] ATM dev 0: ADSL line: up (8128 kb/s down | 832 kb/s up)
52 changes: 26 additions & 26 deletions drivers/usb/atm/cxacru.c
Original file line number Diff line number Diff line change
Expand Up @@ -476,8 +476,6 @@ static int cxacru_start_wait_urb(struct urb *urb, struct completion *done,
add_timer(&timer);
wait_for_completion(done);
status = urb->status;
if (status == -ECONNRESET)
status = -ETIMEDOUT;
del_timer_sync(&timer);

if (actual_length)
Expand Down Expand Up @@ -629,10 +627,22 @@ static int cxacru_card_status(struct cxacru_data *instance)
return 0;
}

static void cxacru_remove_device_files(struct usbatm_data *usbatm_instance,
struct atm_dev *atm_dev)
{
struct usb_interface *intf = usbatm_instance->usb_intf;

#define CXACRU_DEVICE_REMOVE_FILE(_name) \
device_remove_file(&intf->dev, &dev_attr_##_name);
CXACRU_ALL_FILES(REMOVE);
#undef CXACRU_DEVICE_REMOVE_FILE
}

static int cxacru_atm_start(struct usbatm_data *usbatm_instance,
struct atm_dev *atm_dev)
{
struct cxacru_data *instance = usbatm_instance->driver_data;
struct usb_interface *intf = usbatm_instance->usb_intf;
/*
struct atm_dev *atm_dev = usbatm_instance->atm_dev;
*/
Expand All @@ -649,14 +659,18 @@ static int cxacru_atm_start(struct usbatm_data *usbatm_instance,
return ret;
}

#define CXACRU_DEVICE_CREATE_FILE(_name) \
ret = device_create_file(&intf->dev, &dev_attr_##_name); \
if (unlikely(ret)) \
goto fail_sysfs;
CXACRU_ALL_FILES(CREATE);
#undef CXACRU_DEVICE_CREATE_FILE

/* start ADSL */
mutex_lock(&instance->adsl_state_serialize);
ret = cxacru_cm(instance, CM_REQUEST_CHIP_ADSL_LINE_START, NULL, 0, NULL, 0);
if (ret < 0) {
if (ret < 0)
atm_err(usbatm_instance, "cxacru_atm_start: CHIP_ADSL_LINE_START returned %d\n", ret);
mutex_unlock(&instance->adsl_state_serialize);
return ret;
}

/* Start status polling */
mutex_lock(&instance->poll_state_serialize);
Expand All @@ -680,6 +694,11 @@ static int cxacru_atm_start(struct usbatm_data *usbatm_instance,
if (start_polling)
cxacru_poll_status(&instance->poll_work.work);
return 0;

fail_sysfs:
usb_err(usbatm_instance, "cxacru_atm_start: device_create_file failed (%d)\n", ret);
cxacru_remove_device_files(usbatm_instance, atm_dev);
return ret;
}

static void cxacru_poll_status(struct work_struct *work)
Expand Down Expand Up @@ -1065,13 +1084,6 @@ static int cxacru_bind(struct usbatm_data *usbatm_instance,
goto fail;
}

#define CXACRU_DEVICE_CREATE_FILE(_name) \
ret = device_create_file(&intf->dev, &dev_attr_##_name); \
if (unlikely(ret)) \
goto fail_sysfs;
CXACRU_ALL_FILES(CREATE);
#undef CXACRU_DEVICE_CREATE_FILE

usb_fill_int_urb(instance->rcv_urb,
usb_dev, usb_rcvintpipe(usb_dev, CXACRU_EP_CMD),
instance->rcv_buf, PAGE_SIZE,
Expand All @@ -1092,14 +1104,6 @@ static int cxacru_bind(struct usbatm_data *usbatm_instance,

return 0;

fail_sysfs:
dbg("cxacru_bind: device_create_file failed (%d)\n", ret);

#define CXACRU_DEVICE_REMOVE_FILE(_name) \
device_remove_file(&intf->dev, &dev_attr_##_name);
CXACRU_ALL_FILES(REMOVE);
#undef CXACRU_DEVICE_REVOVE_FILE

fail:
free_page((unsigned long) instance->snd_buf);
free_page((unsigned long) instance->rcv_buf);
Expand Down Expand Up @@ -1146,11 +1150,6 @@ static void cxacru_unbind(struct usbatm_data *usbatm_instance,
free_page((unsigned long) instance->snd_buf);
free_page((unsigned long) instance->rcv_buf);

#define CXACRU_DEVICE_REMOVE_FILE(_name) \
device_remove_file(&intf->dev, &dev_attr_##_name);
CXACRU_ALL_FILES(REMOVE);
#undef CXACRU_DEVICE_REVOVE_FILE

kfree(instance);

usbatm_instance->driver_data = NULL;
Expand Down Expand Up @@ -1231,6 +1230,7 @@ static struct usbatm_driver cxacru_driver = {
.heavy_init = cxacru_heavy_init,
.unbind = cxacru_unbind,
.atm_start = cxacru_atm_start,
.atm_stop = cxacru_remove_device_files,
.bulk_in = CXACRU_EP_DATA,
.bulk_out = CXACRU_EP_DATA,
.rx_padding = 3,
Expand Down
5 changes: 2 additions & 3 deletions drivers/usb/class/usblp.c
Original file line number Diff line number Diff line change
Expand Up @@ -347,10 +347,8 @@ static int handle_bidir (struct usblp *usblp)
if (usblp->bidir && usblp->used && !usblp->sleeping) {
usblp->readcount = 0;
usblp->readurb->dev = usblp->dev;
if (usb_submit_urb(usblp->readurb, GFP_KERNEL) < 0) {
usblp->used = 0;
if (usb_submit_urb(usblp->readurb, GFP_KERNEL) < 0)
return -EIO;
}
}

return 0;
Expand Down Expand Up @@ -412,6 +410,7 @@ static int usblp_open(struct inode *inode, struct file *file)
usblp->readurb->status = 0;

if (handle_bidir(usblp) < 0) {
usblp->used = 0;
file->private_data = NULL;
retval = -EIO;
}
Expand Down
22 changes: 13 additions & 9 deletions drivers/usb/core/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -40,21 +40,25 @@ config USB_DEVICEFS
config USB_DEVICE_CLASS
bool "USB device class-devices (DEPRECATED)"
depends on USB
default n
default y
---help---
Userspace access to USB devices is granted by device-nodes exported
directly from the usbdev in sysfs. Old versions of the driver
core and udev needed additional class devices to export device nodes.

These additional devices are difficult to handle in userspace, if
information about USB interfaces must be available. One device contains
the device node, the other device contains the interface data. Both
devices are at the same level in sysfs (siblings) and one can't access
the other. The device node created directly by the usbdev is the parent
device of the interface and therefore easily accessible from the interface
event.

This option provides backward compatibility if needed.
information about USB interfaces must be available. One device
contains the device node, the other device contains the interface
data. Both devices are at the same level in sysfs (siblings) and one
can't access the other. The device node created directly by the
usb device is the parent device of the interface and therefore
easily accessible from the interface event.

This option provides backward compatibility for libusb device
nodes (lsusb) when usbfs is not used, and the following udev rule
doesn't exist:
SUBSYSTEM=="usb", ACTION=="add", ENV{DEVTYPE}=="usb_device", \
NAME="bus/usb/$env{BUSNUM}/$env{DEVNUM}", MODE="0644"

config USB_DYNAMIC_MINORS
bool "Dynamic USB minor allocation (EXPERIMENTAL)"
Expand Down
42 changes: 41 additions & 1 deletion drivers/usb/core/config.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include <linux/usb.h>
#include <linux/usb/ch9.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
Expand Down Expand Up @@ -49,7 +50,7 @@ static int usb_parse_endpoint(struct device *ddev, int cfgno, int inum,
unsigned char *buffer0 = buffer;
struct usb_endpoint_descriptor *d;
struct usb_host_endpoint *endpoint;
int n, i;
int n, i, j;

d = (struct usb_endpoint_descriptor *) buffer;
buffer += d->bLength;
Expand Down Expand Up @@ -84,6 +85,45 @@ static int usb_parse_endpoint(struct device *ddev, int cfgno, int inum,
memcpy(&endpoint->desc, d, n);
INIT_LIST_HEAD(&endpoint->urb_list);

/* If the bInterval value is outside the legal range,
* set it to a default value: 32 ms */
i = 0; /* i = min, j = max, n = default */
j = 255;
if (usb_endpoint_xfer_int(d)) {
i = 1;
switch (to_usb_device(ddev)->speed) {
case USB_SPEED_HIGH:
n = 9; /* 32 ms = 2^(9-1) uframes */
j = 16;
break;
default: /* USB_SPEED_FULL or _LOW */
/* For low-speed, 10 ms is the official minimum.
* But some "overclocked" devices might want faster
* polling so we'll allow it. */
n = 32;
break;
}
} else if (usb_endpoint_xfer_isoc(d)) {
i = 1;
j = 16;
switch (to_usb_device(ddev)->speed) {
case USB_SPEED_HIGH:
n = 9; /* 32 ms = 2^(9-1) uframes */
break;
default: /* USB_SPEED_FULL */
n = 6; /* 32 ms = 2^(6-1) frames */
break;
}
}
if (d->bInterval < i || d->bInterval > j) {
dev_warn(ddev, "config %d interface %d altsetting %d "
"endpoint 0x%X has an invalid bInterval %d, "
"changing to %d\n",
cfgno, inum, asnum,
d->bEndpointAddress, d->bInterval, n);
endpoint->desc.bInterval = n;
}

/* Skip over any Class Specific or Vendor Specific descriptors;
* find the next endpoint or interface descriptor */
endpoint->extra = buffer;
Expand Down
2 changes: 1 addition & 1 deletion drivers/usb/gadget/epautoconf.c
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ ep_matches (
* where it's an output parameter representing the full speed limit.
* the usb spec fixes high speed bulk maxpacket at 512 bytes.
*/
max = 0x7ff & le16_to_cpup (&desc->wMaxPacketSize);
max = 0x7ff & le16_to_cpu(desc->wMaxPacketSize);
switch (type) {
case USB_ENDPOINT_XFER_INT:
/* INT: limit 64 bytes full speed, 1024 high speed */
Expand Down
8 changes: 4 additions & 4 deletions drivers/usb/gadget/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -1369,12 +1369,12 @@ config_buf (struct dev_data *dev, u8 type, unsigned index)
hs = !hs;
if (hs) {
dev->req->buf = dev->hs_config;
len = le16_to_cpup (&dev->hs_config->wTotalLength);
len = le16_to_cpu(dev->hs_config->wTotalLength);
} else
#endif
{
dev->req->buf = dev->config;
len = le16_to_cpup (&dev->config->wTotalLength);
len = le16_to_cpu(dev->config->wTotalLength);
}
((u8 *)dev->req->buf) [1] = type;
return len;
Expand Down Expand Up @@ -1885,7 +1885,7 @@ dev_config (struct file *fd, const char __user *buf, size_t len, loff_t *ptr)

/* full or low speed config */
dev->config = (void *) kbuf;
total = le16_to_cpup (&dev->config->wTotalLength);
total = le16_to_cpu(dev->config->wTotalLength);
if (!is_valid_config (dev->config) || total >= length)
goto fail;
kbuf += total;
Expand All @@ -1894,7 +1894,7 @@ dev_config (struct file *fd, const char __user *buf, size_t len, loff_t *ptr)
/* optional high speed config */
if (kbuf [1] == USB_DT_CONFIG) {
dev->hs_config = (void *) kbuf;
total = le16_to_cpup (&dev->hs_config->wTotalLength);
total = le16_to_cpu(dev->hs_config->wTotalLength);
if (!is_valid_config (dev->hs_config) || total >= length)
goto fail;
kbuf += total;
Expand Down
6 changes: 3 additions & 3 deletions drivers/usb/gadget/net2280.c
Original file line number Diff line number Diff line change
Expand Up @@ -2440,9 +2440,9 @@ static void handle_stat0_irqs (struct net2280 *dev, u32 stat)

tmp = 0;

#define w_value le16_to_cpup (&u.r.wValue)
#define w_index le16_to_cpup (&u.r.wIndex)
#define w_length le16_to_cpup (&u.r.wLength)
#define w_value le16_to_cpu(u.r.wValue)
#define w_index le16_to_cpu(u.r.wIndex)
#define w_length le16_to_cpu(u.r.wLength)

/* ack the irq */
writel (1 << SETUP_PACKET_INTERRUPT, &dev->regs->irqstat0);
Expand Down
6 changes: 3 additions & 3 deletions drivers/usb/gadget/omap_udc.c
Original file line number Diff line number Diff line change
Expand Up @@ -1651,9 +1651,9 @@ static void ep0_irq(struct omap_udc *udc, u16 irq_src)
UDC_EP_NUM_REG = 0;
} while (UDC_IRQ_SRC_REG & UDC_SETUP);

#define w_value le16_to_cpup (&u.r.wValue)
#define w_index le16_to_cpup (&u.r.wIndex)
#define w_length le16_to_cpup (&u.r.wLength)
#define w_value le16_to_cpu(u.r.wValue)
#define w_index le16_to_cpu(u.r.wIndex)
#define w_length le16_to_cpu(u.r.wLength)

/* Delegate almost all control requests to the gadget driver,
* except for a handful of ch9 status/feature requests that
Expand Down
Loading

0 comments on commit 5b65c09

Please sign in to comment.