Commit 117494a1 authored by Linus Torvalds's avatar Linus Torvalds

Merge master.kernel.org:/pub/scm/linux/kernel/git/gregkh/usb-2.6

* master.kernel.org:/pub/scm/linux/kernel/git/gregkh/usb-2.6: (142 commits)
  USB: fix race in autosuspend reschedule
  atmel_usba_udc: Keep track of the device status
  USB: Nikon D40X unusual_devs entry
  USB: serial core should respect driver requirements
  USB: documentation for USB power management
  USB: skip autosuspended devices during system resume
  USB: mutual exclusion for EHCI init and port resets
  USB: allow usbstorage to have LUNS greater than 2Tb
  USB: Adding support for SHARP WS011SH to ipaq.c
  USB: add atmel_usba_udc driver
  USB: ohci SSB bus glue
  USB: ehci build fixes on au1xxx, ppc-soc
  USB: add runtime frame_no quirk for big-endian OHCI
  USB: funsoft: Fix termios
  USB: visor: termios bits
  USB: unusual_devs entry for Nikon DSC D2Xs
  USB: re-remove <linux/usb_sl811.h>
  USB: move <linux/usb_gadget.h> to <linux/usb/gadget.h>
  USB: Export URB statistics for powertop
  USB: serial gadget: Disable endpoints on unload
  ...
parents 4d5709a7 d1aa3e6a
Authorizing (or not) your USB devices to connect to the system
(C) 2007 Inaky Perez-Gonzalez <inaky@linux.intel.com> Intel Corporation
This feature allows you to control if a USB device can be used (or
not) in a system. This feature will allow you to implement a lock-down
of USB devices, fully controlled by user space.
As of now, when a USB device is connected it is configured and
it's interfaces inmediately made available to the users. With this
modification, only if root authorizes the device to be configured will
then it be possible to use it.
Usage:
Authorize a device to connect:
$ echo 1 > /sys/usb/devices/DEVICE/authorized
Deauthorize a device:
$ echo 0 > /sys/usb/devices/DEVICE/authorized
Set new devices connected to hostX to be deauthorized by default (ie:
lock down):
$ echo 0 > /sys/bus/devices/usbX/authorized_default
Remove the lock down:
$ echo 1 > /sys/bus/devices/usbX/authorized_default
By default, Wired USB devices are authorized by default to
connect. Wireless USB hosts deauthorize by default all new connected
devices (this is so because we need to do an authentication phase
before authorizing).
Example system lockdown (lame)
-----------------------
Imagine you want to implement a lockdown so only devices of type XYZ
can be connected (for example, it is a kiosk machine with a visible
USB port):
boot up
rc.local ->
for host in /sys/bus/devices/usb*
do
echo 0 > $host/authorized_default
done
Hookup an script to udev, for new USB devices
if device_is_my_type $DEV
then
echo 1 > $device_path/authorized
done
Now, device_is_my_type() is where the juice for a lockdown is. Just
checking if the class, type and protocol match something is the worse
security verification you can make (or the best, for someone willing
to break it). If you need something secure, use crypto and Certificate
Authentication or stuff like that. Something simple for an storage key
could be:
function device_is_my_type()
{
echo 1 > authorized # temporarily authorize it
# FIXME: make sure none can mount it
mount DEVICENODE /mntpoint
sum=$(md5sum /mntpoint/.signature)
if [ $sum = $(cat /etc/lockdown/keysum) ]
then
echo "We are good, connected"
umount /mntpoint
# Other stuff so others can use it
else
echo 0 > authorized
fi
}
Of course, this is lame, you'd want to do a real certificate
verification stuff with PKI, so you don't depend on a shared secret,
etc, but you get the idea. Anybody with access to a device gadget kit
can fake descriptors and device info. Don't trust that. You are
welcome.
This diff is collapsed.
......@@ -428,6 +428,17 @@ Options supported:
See http://www.uuhaus.de/linux/palmconnect.html for up-to-date
information on this driver.
Winchiphead CH341 Driver
This driver is for the Winchiphead CH341 USB-RS232 Converter. This chip
also implements an IEEE 1284 parallel port, I2C and SPI, but that is not
supported by the driver. The protocol was analyzed from the behaviour
of the Windows driver, no datasheet is available at present.
The manufacturer's website: http://www.winchiphead.com/.
For any questions or problems with this driver, please contact
frank@kingswood-consulting.co.uk.
Generic Serial driver
If your device is not one of the above listed devices, compatible with
......
......@@ -34,9 +34,12 @@ if usbmon is built into the kernel.
Verify that bus sockets are present.
# ls /sys/kernel/debug/usbmon
1s 1t 1u 2s 2t 2u 3s 3t 3u 4s 4t 4u
0s 0t 0u 1s 1t 1u 2s 2t 2u 3s 3t 3u 4s 4t 4u
#
Now you can choose to either use the sockets numbered '0' (to capture packets on
all buses), and skip to step #3, or find the bus used by your device with step #2.
2. Find which bus connects to the desired device
Run "cat /proc/bus/usb/devices", and find the T-line which corresponds to
......@@ -56,6 +59,10 @@ Bus=03 means it's bus 3.
# cat /sys/kernel/debug/usbmon/3u > /tmp/1.mon.out
to listen on a single bus, otherwise, to listen on all buses, type:
# cat /sys/kernel/debug/usbmon/0u > /tmp/1.mon.out
This process will be reading until killed. Naturally, the output can be
redirected to a desirable location. This is preferred, because it is going
to be quite long.
......
......@@ -677,6 +677,13 @@ P: Haavard Skinnemoen
M: hskinnemoen@atmel.com
S: Supported
ATMEL USBA UDC DRIVER
P: Haavard Skinnemoen
M: hskinnemoen@atmel.com
L: kernel@avr32linux.org
W: http://avr32linux.org/twiki/bin/view/Main/AtmelUsbDeviceDriver
S: Supported
ATMEL WIRELESS DRIVER
P: Simon Kelley
M: simon@thekelleys.org.uk
......
......@@ -40,7 +40,7 @@
#include <linux/pata_platform.h>
#include <linux/irq.h>
#include <linux/interrupt.h>
#include <linux/usb_sl811.h>
#include <linux/usb/sl811.h>
#include <asm/dma.h>
#include <asm/bfin5xx_spi.h>
#include <asm/reboot.h>
......
......@@ -40,7 +40,7 @@
#include <linux/irq.h>
#include <asm/dma.h>
#include <asm/bfin5xx_spi.h>
#include <linux/usb_sl811.h>
#include <linux/usb/sl811.h>
#include <linux/spi/ad7877.h>
......
......@@ -40,7 +40,7 @@
#include <linux/pata_platform.h>
#include <linux/irq.h>
#include <linux/interrupt.h>
#include <linux/usb_sl811.h>
#include <linux/usb/sl811.h>
#include <asm/dma.h>
#include <asm/bfin5xx_spi.h>
#include <asm/reboot.h>
......
......@@ -28,27 +28,7 @@ obj-$(CONFIG_USB_MICROTEK) += image/
obj-$(CONFIG_USB_SERIAL) += serial/
obj-$(CONFIG_USB_ADUTUX) += misc/
obj-$(CONFIG_USB_APPLEDISPLAY) += misc/
obj-$(CONFIG_USB_AUERSWALD) += misc/
obj-$(CONFIG_USB_BERRY_CHARGE) += misc/
obj-$(CONFIG_USB_CYPRESS_CY7C63)+= misc/
obj-$(CONFIG_USB_CYTHERM) += misc/
obj-$(CONFIG_USB_EMI26) += misc/
obj-$(CONFIG_USB_EMI62) += misc/
obj-$(CONFIG_USB_FTDI_ELAN) += misc/
obj-$(CONFIG_USB_IDMOUSE) += misc/
obj-$(CONFIG_USB_LCD) += misc/
obj-$(CONFIG_USB_LD) += misc/
obj-$(CONFIG_USB_LED) += misc/
obj-$(CONFIG_USB_LEGOTOWER) += misc/
obj-$(CONFIG_USB_PHIDGETSERVO) += misc/
obj-$(CONFIG_USB_RIO500) += misc/
obj-$(CONFIG_USB_SISUSBVGA) += misc/
obj-$(CONFIG_USB_TEST) += misc/
obj-$(CONFIG_USB_TRANCEVIBRATOR)+= misc/
obj-$(CONFIG_USB_USS720) += misc/
obj-$(CONFIG_USB_IOWARRIOR) += misc/
obj-$(CONFIG_USB) += misc/
obj-$(CONFIG_USB_ATM) += atm/
obj-$(CONFIG_USB_SPEEDTOUCH) += atm/
......@@ -482,7 +482,9 @@ static int cxacru_cm(struct cxacru_data *instance, enum cxacru_cm_request cm,
int rbuflen = ((rsize - 1) / stride + 1) * CMD_PACKET_SIZE;
if (wbuflen > PAGE_SIZE || rbuflen > PAGE_SIZE) {
dbg("too big transfer requested");
if (printk_ratelimit())
usb_err(instance->usbatm, "requested transfer size too large (%d, %d)\n",
wbuflen, rbuflen);
ret = -ENOMEM;
goto fail;
}
......@@ -493,8 +495,9 @@ static int cxacru_cm(struct cxacru_data *instance, enum cxacru_cm_request cm,
init_completion(&instance->rcv_done);
ret = usb_submit_urb(instance->rcv_urb, GFP_KERNEL);
if (ret < 0) {
dbg("submitting read urb for cm %#x failed", cm);
ret = ret;
if (printk_ratelimit())
usb_err(instance->usbatm, "submit of read urb for cm %#x failed (%d)\n",
cm, ret);
goto fail;
}
......@@ -510,27 +513,29 @@ static int cxacru_cm(struct cxacru_data *instance, enum cxacru_cm_request cm,
init_completion(&instance->snd_done);
ret = usb_submit_urb(instance->snd_urb, GFP_KERNEL);
if (ret < 0) {
dbg("submitting write urb for cm %#x failed", cm);
ret = ret;
if (printk_ratelimit())
usb_err(instance->usbatm, "submit of write urb for cm %#x failed (%d)\n",
cm, ret);
goto fail;
}
ret = cxacru_start_wait_urb(instance->snd_urb, &instance->snd_done, NULL);
if (ret < 0) {
dbg("sending cm %#x failed", cm);
ret = ret;
if (printk_ratelimit())
usb_err(instance->usbatm, "send of cm %#x failed (%d)\n", cm, ret);
goto fail;
}
ret = cxacru_start_wait_urb(instance->rcv_urb, &instance->rcv_done, &actlen);
if (ret < 0) {
dbg("receiving cm %#x failed", cm);
ret = ret;
if (printk_ratelimit())
usb_err(instance->usbatm, "receive of cm %#x failed (%d)\n", cm, ret);
goto fail;
}
if (actlen % CMD_PACKET_SIZE || !actlen) {
dbg("response is not a positive multiple of %d: %#x",
CMD_PACKET_SIZE, actlen);
if (printk_ratelimit())
usb_err(instance->usbatm, "invalid response length to cm %#x: %d\n",
cm, actlen);
ret = -EIO;
goto fail;
}
......@@ -538,12 +543,16 @@ static int cxacru_cm(struct cxacru_data *instance, enum cxacru_cm_request cm,
/* check the return status and copy the data to the output buffer, if needed */
for (offb = offd = 0; offd < rsize && offb < actlen; offb += CMD_PACKET_SIZE) {
if (rbuf[offb] != cm) {
dbg("wrong cm %#x in response", rbuf[offb]);
if (printk_ratelimit())
usb_err(instance->usbatm, "wrong cm %#x in response to cm %#x\n",
rbuf[offb], cm);
ret = -EIO;
goto fail;
}
if (rbuf[offb + 1] != CM_STATUS_SUCCESS) {
dbg("response failed: %#x", rbuf[offb + 1]);
if (printk_ratelimit())
usb_err(instance->usbatm, "response to cm %#x failed: %#x\n",
cm, rbuf[offb + 1]);
ret = -EIO;
goto fail;
}
......@@ -582,14 +591,18 @@ static int cxacru_cm_get_array(struct cxacru_data *instance, enum cxacru_cm_requ
for (offb = 0; offb < len; ) {
int l = le32_to_cpu(buf[offb++]);
if (l > stride || l > (len - offb) / 2) {
dbg("wrong data length %#x in response", l);
if (printk_ratelimit())
usb_err(instance->usbatm, "invalid data length from cm %#x: %d\n",
cm, l);
ret = -EIO;
goto cleanup;
}
while (l--) {
offd = le32_to_cpu(buf[offb++]);
if (offd >= size) {
dbg("wrong index %#x in response", offd);
if (printk_ratelimit())
usb_err(instance->usbatm, "wrong index #%x in response to cm #%x\n",
offd, cm);
ret = -EIO;
goto cleanup;
}
......
......@@ -251,7 +251,6 @@ static int speedtch_upload_firmware(struct speedtch_instance_data *instance,
{
unsigned char *buffer;
struct usbatm_data *usbatm = instance->usbatm;
struct usb_interface *intf;
struct usb_device *usb_dev = usbatm->usb_dev;
int actual_length;
int ret = 0;
......@@ -265,7 +264,7 @@ static int speedtch_upload_firmware(struct speedtch_instance_data *instance,
goto out;
}
if (!(intf = usb_ifnum_to_if(usb_dev, 2))) {
if (!usb_ifnum_to_if(usb_dev, 2)) {
ret = -ENODEV;
usb_dbg(usbatm, "%s: interface not found!\n", __func__);
goto out_free;
......
This diff is collapsed.
......@@ -28,6 +28,7 @@
* v0.12 - add hpoj.sourceforge.net ioctls (David Paschal)
* v0.13 - alloc space for statusbuf (<status> not on stack);
* use usb_buffer_alloc() for read buf & write buf;
* none - Maintained in Linux kernel after v0.13
*/
/*
......@@ -69,7 +70,6 @@
#define USBLP_DEVICE_ID_SIZE 1024
/* ioctls: */
#define LPGETSTATUS 0x060b /* same as in drivers/char/lp.c */
#define IOCNR_GET_DEVICE_ID 1
#define IOCNR_GET_PROTOCOLS 2
#define IOCNR_SET_PROTOCOL 3
......@@ -115,7 +115,7 @@ MFG:HEWLETT-PACKARD;MDL:DESKJET 970C;CMD:MLC,PCL,PML;CLASS:PRINTER;DESCRIPTION:H
#define USBLP_MINORS 16
#define USBLP_MINOR_BASE 0
#define USBLP_WRITE_TIMEOUT (5000) /* 5 seconds */
#define USBLP_CTL_TIMEOUT 5000 /* 5 seconds */
#define USBLP_FIRST_PROTOCOL 1
#define USBLP_LAST_PROTOCOL 3
......@@ -159,10 +159,12 @@ struct usblp {
int wstatus; /* bytes written or error */
int rstatus; /* bytes ready or error */
unsigned int quirks; /* quirks flags */
unsigned int flags; /* mode flags */
unsigned char used; /* True if open */
unsigned char present; /* True if not disconnected */
unsigned char bidir; /* interface is bidirectional */
unsigned char sleeping; /* interface is suspended */
unsigned char no_paper; /* Paper Out happened */
unsigned char *device_id_string; /* IEEE 1284 DEVICE ID string (ptr) */
/* first 2 bytes are (big-endian) length */
};
......@@ -259,7 +261,7 @@ static int usblp_ctrl_msg(struct usblp *usblp, int request, int type, int dir, i
retval = usb_control_msg(usblp->dev,
dir ? usb_rcvctrlpipe(usblp->dev, 0) : usb_sndctrlpipe(usblp->dev, 0),
request, type | dir | recip, value, index, buf, len, USBLP_WRITE_TIMEOUT);
request, type | dir | recip, value, index, buf, len, USBLP_CTL_TIMEOUT);
dbg("usblp_control_msg: rq: 0x%02x dir: %d recip: %d value: %d idx: %d len: %#x result: %d",
request, !!dir, recip, value, index, len, retval);
return retval < 0 ? retval : 0;
......@@ -325,13 +327,11 @@ static void usblp_bulk_write(struct urb *urb)
usblp->wstatus = status;
else
usblp->wstatus = urb->actual_length;
usblp->no_paper = 0;
usblp->wcomplete = 1;
wake_up(&usblp->wwait);
spin_unlock(&usblp->lock);
/* XXX Use usb_setup_bulk_urb when available. Talk to Marcel. */
kfree(urb->transfer_buffer);
urb->transfer_buffer = NULL; /* Not refcounted, so to be safe... */
usb_free_urb(urb);
}
......@@ -346,16 +346,17 @@ static int usblp_check_status(struct usblp *usblp, int err)
unsigned char status, newerr = 0;
int error;
error = usblp_read_status (usblp, usblp->statusbuf);
if (error < 0) {
mutex_lock(&usblp->mut);
if ((error = usblp_read_status(usblp, usblp->statusbuf)) < 0) {
mutex_unlock(&usblp->mut);
if (printk_ratelimit())
printk(KERN_ERR
"usblp%d: error %d reading printer status\n",
usblp->minor, error);
return 0;
}
status = *usblp->statusbuf;
mutex_unlock(&usblp->mut);
if (~status & LP_PERRORP)
newerr = 3;
......@@ -411,18 +412,10 @@ static int usblp_open(struct inode *inode, struct file *file)
goto out;
/*
* TODO: need to implement LP_ABORTOPEN + O_NONBLOCK as in drivers/char/lp.c ???
* This is #if 0-ed because we *don't* want to fail an open
* just because the printer is off-line.
* We do not implement LP_ABORTOPEN/LPABORTOPEN for two reasons:
* - We do not want persistent state which close(2) does not clear
* - It is not used anyway, according to CUPS people
*/
#if 0
if ((retval = usblp_check_status(usblp, 0))) {
retval = retval > 1 ? -EIO : -ENOSPC;
goto out;
}
#else
retval = 0;
#endif
retval = usb_autopm_get_interface(intf);
if (retval < 0)
......@@ -463,6 +456,8 @@ static int usblp_release(struct inode *inode, struct file *file)
{
struct usblp *usblp = file->private_data;
usblp->flags &= ~LP_ABORT;
mutex_lock (&usblp_mutex);
usblp->used = 0;
if (usblp->present) {
......@@ -485,8 +480,8 @@ static unsigned int usblp_poll(struct file *file, struct poll_table_struct *wait
poll_wait(file, &usblp->rwait, wait);
poll_wait(file, &usblp->wwait, wait);
spin_lock_irqsave(&usblp->lock, flags);
ret = ((!usblp->bidir || !usblp->rcomplete) ? 0 : POLLIN | POLLRDNORM)
| (!usblp->wcomplete ? 0 : POLLOUT | POLLWRNORM);
ret = ((usblp->bidir && usblp->rcomplete) ? POLLIN | POLLRDNORM : 0) |
((usblp->no_paper || usblp->wcomplete) ? POLLOUT | POLLWRNORM : 0);
spin_unlock_irqrestore(&usblp->lock, flags);
return ret;
}
......@@ -675,6 +670,13 @@ static long usblp_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
retval = -EFAULT;
break;
case LPABORT:
if (arg)
usblp->flags |= LP_ABORT;
else
usblp->flags &= ~LP_ABORT;
break;
default:
retval = -ENOTTY;
}
......@@ -684,10 +686,30 @@ done:
return retval;
}
static struct urb *usblp_new_writeurb(struct usblp *usblp, int transfer_length)
{
struct urb *urb;
char *writebuf;
if ((writebuf = kmalloc(transfer_length, GFP_KERNEL)) == NULL)
return NULL;
if ((urb = usb_alloc_urb(0, GFP_KERNEL)) == NULL) {
kfree(writebuf);
return NULL;
}
usb_fill_bulk_urb(urb, usblp->dev,
usb_sndbulkpipe(usblp->dev,
usblp->protocol[usblp->current_protocol].epwrite->bEndpointAddress),
writebuf, transfer_length, usblp_bulk_write, usblp);
urb->transfer_flags |= URB_FREE_BUFFER;
return urb;
}
static ssize_t usblp_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos)
{
struct usblp *usblp = file->private_data;
char *writebuf;
struct urb *writeurb;
int rv;
int transfer_length;
......@@ -708,17 +730,11 @@ static ssize_t usblp_write(struct file *file, const char __user *buffer, size_t
transfer_length = USBLP_BUF_SIZE;
rv = -ENOMEM;
if ((writebuf = kmalloc(USBLP_BUF_SIZE, GFP_KERNEL)) == NULL)
goto raise_buf;
if ((writeurb = usb_alloc_urb(0, GFP_KERNEL)) == NULL)
if ((writeurb = usblp_new_writeurb(usblp, transfer_length)) == NULL)
goto raise_urb;
usb_fill_bulk_urb(writeurb, usblp->dev,
usb_sndbulkpipe(usblp->dev,
usblp->protocol[usblp->current_protocol].epwrite->bEndpointAddress),
writebuf, transfer_length, usblp_bulk_write, usblp);
usb_anchor_urb(writeurb, &usblp->urbs);
if (copy_from_user(writebuf,
if (copy_from_user(writeurb->transfer_buffer,
buffer + writecount, transfer_length)) {
rv = -EFAULT;
goto raise_badaddr;
......@@ -730,6 +746,7 @@ static ssize_t usblp_write(struct file *file, const char __user *buffer, size_t
if ((rv = usb_submit_urb(writeurb, GFP_KERNEL)) < 0) {
usblp->wstatus = 0;
spin_lock_irq(&usblp->lock);
usblp->no_paper = 0;
usblp->wcomplete = 1;
wake_up(&usblp->wwait);
spin_unlock_irq(&usblp->lock);
......@@ -747,12 +764,17 @@ static ssize_t usblp_write(struct file *file, const char __user *buffer, size_t
/* Presume that it's going to complete well. */
writecount += transfer_length;
}
if (rv == -ENOSPC) {
spin_lock_irq(&usblp->lock);
usblp->no_paper = 1; /* Mark for poll(2) */
spin_unlock_irq(&usblp->lock);
writecount += transfer_length;
}
/* Leave URB dangling, to be cleaned on close. */
goto collect_error;
}
if (usblp->wstatus < 0) {
usblp_check_status(usblp, 0);
rv = -EIO;
goto collect_error;
}
......@@ -771,8 +793,6 @@ raise_badaddr:
usb_unanchor_urb(writeurb);
usb_free_urb(writeurb);
raise_urb:
kfree(writebuf);
raise_buf:
raise_wait:
collect_error: /* Out of raise sequence */
mutex_unlock(&usblp->wmut);
......@@ -838,32 +858,36 @@ done:
* when O_NONBLOCK is set. So, applications setting O_NONBLOCK must use
* select(2) or poll(2) to wait for the buffer to drain before closing.
* Alternatively, set blocking mode with fcntl and issue a zero-size write.
*
* Old v0.13 code had a non-functional timeout for wait_event(). Someone forgot
* to check the return code for timeout expiration, so it had no effect.
* Apparently, it was intended to check for error conditons, such as out
* of paper. It is going to return when we settle things with CUPS. XXX
*/
static int usblp_wwait(struct usblp *usblp, int nonblock)
{
DECLARE_WAITQUEUE(waita, current);
int rc;
int err = 0;
add_wait_queue(&usblp->wwait, &waita);
for (;;) {
set_current_state(TASK_INTERRUPTIBLE);
if (mutex_lock_interruptible(&usblp->mut)) {
rc = -EINTR;
break;
}
set_current_state(TASK_INTERRUPTIBLE);
if ((rc = usblp_wtest(usblp, nonblock)) < 0) {
mutex_unlock(&usblp->mut);
break;
}
rc = usblp_wtest(usblp, nonblock);
mutex_unlock(&usblp->mut);
if (rc == 0)
if (rc <= 0)