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: (35 commits)
  usb: add PRODUCT, TYPE to usb-interface events
  USB: resubmission unusual_devs modification for Nikon D80
  usb quirks: Add Canon EOS 5D (PC Connection mode) to the autosuspend blacklist
  USB: make EHCI initialize properly on PPC SOCs
  UEAGLE: Remove sysfs files on error case
  USB: fsl_usb2_udc: fix bug in processing setup requests
  USB: g_file_storage: fix bug in DMA buffer handling
  USB: update last_busy field correctly
  USB: fix DoS in pwc USB video driver
  USB: allow retry on descriptor fetch errors
  USB: unkill cxacru atm driver
  USB: Adding support for HTC Smartphones to ipaq
  USB: another quirky device
  USB: quirky mass storage device
  USB: ohci, fix oddball gcc warning
  usb-storage: fix bugs in the disconnect pathway
  usb: typo in usb R8A66597 HCD config
  USB: accept 1-byte Device Status replies, fixing some b0rken devices
  USB: blacklist Samsung ML-2010 printer
  usb-serial: fix oti6858.c segfault in termios handling
  ...
  • Loading branch information
Linus Torvalds committed Aug 24, 2007
2 parents de80af4 + d65cc1b commit 9e1a3e3
Show file tree
Hide file tree
Showing 35 changed files with 255 additions and 172 deletions.
1 change: 1 addition & 0 deletions drivers/media/video/em28xx/em28xx-video.c
Original file line number Diff line number Diff line change
Expand Up @@ -1772,6 +1772,7 @@ static int em28xx_usb_probe(struct usb_interface *interface,
if (dev->alt_max_pkt_size == NULL) {
em28xx_errdev("out of memory!\n");
em28xx_devused&=~(1<<nr);
kfree(dev);
return -ENOMEM;
}

Expand Down
52 changes: 35 additions & 17 deletions drivers/media/video/pwc/pwc-if.c
Original file line number Diff line number Diff line change
Expand Up @@ -1196,12 +1196,19 @@ static int pwc_video_open(struct inode *inode, struct file *file)
return 0;
}


static void pwc_cleanup(struct pwc_device *pdev)
{
pwc_remove_sysfs_files(pdev->vdev);
video_unregister_device(pdev->vdev);
}

/* Note that all cleanup is done in the reverse order as in _open */
static int pwc_video_close(struct inode *inode, struct file *file)
{
struct video_device *vdev = file->private_data;
struct pwc_device *pdev;
int i;
int i, hint;

PWC_DEBUG_OPEN(">> video_close called(vdev = 0x%p).\n", vdev);

Expand All @@ -1224,8 +1231,9 @@ static int pwc_video_close(struct inode *inode, struct file *file)
pwc_isoc_cleanup(pdev);
pwc_free_buffers(pdev);

lock_kernel();
/* Turn off LEDS and power down camera, but only when not unplugged */
if (pdev->error_status != EPIPE) {
if (!pdev->unplugged) {
/* Turn LEDs off */
if (pwc_set_leds(pdev, 0, 0) < 0)
PWC_DEBUG_MODULE("Failed to set LED on/off time.\n");
Expand All @@ -1234,9 +1242,19 @@ static int pwc_video_close(struct inode *inode, struct file *file)
if (i < 0)
PWC_ERROR("Failed to power down camera (%d)\n", i);
}
pdev->vopen--;
PWC_DEBUG_OPEN("<< video_close() vopen=%d\n", i);
} else {
pwc_cleanup(pdev);
/* Free memory (don't set pdev to 0 just yet) */
kfree(pdev);
/* search device_hint[] table if we occupy a slot, by any chance */
for (hint = 0; hint < MAX_DEV_HINTS; hint++)
if (device_hint[hint].pdev == pdev)
device_hint[hint].pdev = NULL;
}
pdev->vopen--;
PWC_DEBUG_OPEN("<< video_close() vopen=%d\n", pdev->vopen);
unlock_kernel();

return 0;
}

Expand Down Expand Up @@ -1791,21 +1809,21 @@ static void usb_pwc_disconnect(struct usb_interface *intf)
/* Alert waiting processes */
wake_up_interruptible(&pdev->frameq);
/* Wait until device is closed */
while (pdev->vopen)
schedule();
/* Device is now closed, so we can safely unregister it */
PWC_DEBUG_PROBE("Unregistering video device in disconnect().\n");
pwc_remove_sysfs_files(pdev->vdev);
video_unregister_device(pdev->vdev);

/* Free memory (don't set pdev to 0 just yet) */
kfree(pdev);
if(pdev->vopen) {
pdev->unplugged = 1;
} else {
/* Device is closed, so we can safely unregister it */
PWC_DEBUG_PROBE("Unregistering video device in disconnect().\n");
pwc_cleanup(pdev);
/* Free memory (don't set pdev to 0 just yet) */
kfree(pdev);

disconnect_out:
/* search device_hint[] table if we occupy a slot, by any chance */
for (hint = 0; hint < MAX_DEV_HINTS; hint++)
if (device_hint[hint].pdev == pdev)
device_hint[hint].pdev = NULL;
/* search device_hint[] table if we occupy a slot, by any chance */
for (hint = 0; hint < MAX_DEV_HINTS; hint++)
if (device_hint[hint].pdev == pdev)
device_hint[hint].pdev = NULL;
}

unlock_kernel();
}
Expand Down
1 change: 1 addition & 0 deletions drivers/media/video/pwc/pwc.h
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,7 @@ struct pwc_device
char vsnapshot; /* snapshot mode */
char vsync; /* used by isoc handler */
char vmirror; /* for ToUCaM series */
char unplugged;

int cmd_len;
unsigned char cmd_buf[13];
Expand Down
1 change: 1 addition & 0 deletions drivers/usb/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ config USB_ARCH_HAS_HCD
default y if USB_ARCH_HAS_EHCI
default y if PCMCIA && !M32R # sl811_cs
default y if ARM # SL-811
default y if SUPERH # r8a66597-hcd
default PCI

# many non-PCI SOC chips embed OHCI
Expand Down
3 changes: 1 addition & 2 deletions drivers/usb/atm/cxacru.c
Original file line number Diff line number Diff line change
Expand Up @@ -456,7 +456,6 @@ static int cxacru_start_wait_urb(struct urb *urb, struct completion *done,
int* actual_length)
{
struct timer_list timer;
int status = urb->status;

init_timer(&timer);
timer.expires = jiffies + msecs_to_jiffies(CMD_TIMEOUT);
Expand All @@ -468,7 +467,7 @@ static int cxacru_start_wait_urb(struct urb *urb, struct completion *done,

if (actual_length)
*actual_length = urb->actual_length;
return status;
return urb->status; /* must read status after completion */
}

static int cxacru_cm(struct cxacru_data *instance, enum cxacru_cm_request cm,
Expand Down
5 changes: 4 additions & 1 deletion drivers/usb/atm/ueagle-atm.c
Original file line number Diff line number Diff line change
Expand Up @@ -1721,9 +1721,12 @@ static int uea_bind(struct usbatm_data *usbatm, struct usb_interface *intf,

ret = uea_boot(sc);
if (ret < 0)
goto error;
goto error_rm_grp;

return 0;

error_rm_grp:
sysfs_remove_group(&intf->dev.kobj, &attr_grp);
error:
kfree(sc);
return ret;
Expand Down
12 changes: 9 additions & 3 deletions drivers/usb/class/cdc-acm.c
Original file line number Diff line number Diff line change
Expand Up @@ -921,6 +921,10 @@ static int acm_probe (struct usb_interface *intf,
return -EINVAL;
}
}

/* Accept probe requests only for the control interface */
if (intf != control_interface)
return -ENODEV;

if (usb_interface_claimed(data_interface)) { /* valid in this context */
dev_dbg(&intf->dev,"The data interface isn't available");
Expand Down Expand Up @@ -1109,10 +1113,12 @@ static void acm_disconnect(struct usb_interface *intf)
return;
}
if (acm->country_codes){
device_remove_file(&intf->dev, &dev_attr_wCountryCodes);
device_remove_file(&intf->dev, &dev_attr_iCountryCodeRelDate);
device_remove_file(&acm->control->dev,
&dev_attr_wCountryCodes);
device_remove_file(&acm->control->dev,
&dev_attr_iCountryCodeRelDate);
}
device_remove_file(&intf->dev, &dev_attr_bmCapabilities);
device_remove_file(&acm->control->dev, &dev_attr_bmCapabilities);
acm->dev = NULL;
usb_set_intfdata(acm->control, NULL);
usb_set_intfdata(acm->data, NULL);
Expand Down
9 changes: 4 additions & 5 deletions drivers/usb/core/driver.c
Original file line number Diff line number Diff line change
Expand Up @@ -1224,6 +1224,8 @@ static int usb_autopm_do_device(struct usb_device *udev, int inc_usage_cnt)
udev->auto_pm = 1;
udev->pm_usage_cnt += inc_usage_cnt;
WARN_ON(udev->pm_usage_cnt < 0);
if (inc_usage_cnt)
udev->last_busy = jiffies;
if (inc_usage_cnt >= 0 && udev->pm_usage_cnt > 0) {
if (udev->state == USB_STATE_SUSPENDED)
status = usb_resume_both(udev);
Expand All @@ -1232,8 +1234,6 @@ static int usb_autopm_do_device(struct usb_device *udev, int inc_usage_cnt)
else if (inc_usage_cnt)
udev->last_busy = jiffies;
} else if (inc_usage_cnt <= 0 && udev->pm_usage_cnt <= 0) {
if (inc_usage_cnt)
udev->last_busy = jiffies;
status = usb_suspend_both(udev, PMSG_SUSPEND);
}
usb_pm_unlock(udev);
Expand Down Expand Up @@ -1342,16 +1342,15 @@ static int usb_autopm_do_interface(struct usb_interface *intf,
else {
udev->auto_pm = 1;
intf->pm_usage_cnt += inc_usage_cnt;
udev->last_busy = jiffies;
if (inc_usage_cnt >= 0 && intf->pm_usage_cnt > 0) {
if (udev->state == USB_STATE_SUSPENDED)
status = usb_resume_both(udev);
if (status != 0)
intf->pm_usage_cnt -= inc_usage_cnt;
else if (inc_usage_cnt)
else
udev->last_busy = jiffies;
} else if (inc_usage_cnt <= 0 && intf->pm_usage_cnt <= 0) {
if (inc_usage_cnt)
udev->last_busy = jiffies;
status = usb_suspend_both(udev, PMSG_SUSPEND);
}
}
Expand Down
3 changes: 2 additions & 1 deletion drivers/usb/core/hub.c
Original file line number Diff line number Diff line change
Expand Up @@ -1644,9 +1644,10 @@ static int finish_port_resume(struct usb_device *udev)
* and device drivers will know about any resume quirks.
*/
if (status == 0) {
devstatus = 0;
status = usb_get_status(udev, USB_RECIP_DEVICE, 0, &devstatus);
if (status >= 0)
status = (status == 2 ? 0 : -ENODEV);
status = (status > 0 ? 0 : -ENODEV);
}

if (status) {
Expand Down
28 changes: 26 additions & 2 deletions drivers/usb/core/message.c
Original file line number Diff line number Diff line change
Expand Up @@ -637,12 +637,12 @@ int usb_get_descriptor(struct usb_device *dev, unsigned char type, unsigned char
memset(buf,0,size); // Make sure we parse really received data

for (i = 0; i < 3; ++i) {
/* retry on length 0 or stall; some devices are flakey */
/* retry on length 0 or error; some devices are flakey */
result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
USB_REQ_GET_DESCRIPTOR, USB_DIR_IN,
(type << 8) + index, 0, buf, size,
USB_CTRL_GET_TIMEOUT);
if (result == 0 || result == -EPIPE)
if (result <= 0 && result != -ETIMEDOUT)
continue;
if (result > 1 && ((u8 *)buf)[1] != type) {
result = -EPROTO;
Expand Down Expand Up @@ -1358,6 +1358,30 @@ static int usb_if_uevent(struct device *dev, char **envp, int num_envp,
usb_dev = interface_to_usbdev(intf);
alt = intf->cur_altsetting;

#ifdef CONFIG_USB_DEVICEFS
if (add_uevent_var(envp, num_envp, &i,
buffer, buffer_size, &length,
"DEVICE=/proc/bus/usb/%03d/%03d",
usb_dev->bus->busnum, usb_dev->devnum))
return -ENOMEM;
#endif

if (add_uevent_var(envp, num_envp, &i,
buffer, buffer_size, &length,
"PRODUCT=%x/%x/%x",
le16_to_cpu(usb_dev->descriptor.idVendor),
le16_to_cpu(usb_dev->descriptor.idProduct),
le16_to_cpu(usb_dev->descriptor.bcdDevice)))
return -ENOMEM;

if (add_uevent_var(envp, num_envp, &i,
buffer, buffer_size, &length,
"TYPE=%d/%d/%d",
usb_dev->descriptor.bDeviceClass,
usb_dev->descriptor.bDeviceSubClass,
usb_dev->descriptor.bDeviceProtocol))
return -ENOMEM;

if (add_uevent_var(envp, num_envp, &i,
buffer, buffer_size, &length,
"INTERFACE=%d/%d/%d",
Expand Down
12 changes: 12 additions & 0 deletions drivers/usb/core/quirks.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@
static const struct usb_device_id usb_quirk_list[] = {
/* HP 5300/5370C scanner */
{ USB_DEVICE(0x03f0, 0x0701), .driver_info = USB_QUIRK_STRING_FETCH_255 },
/* Hewlett-Packard PhotoSmart 720 / PhotoSmart 935 (storage) */
{ USB_DEVICE(0x03f0, 0x4002), .driver_info = USB_QUIRK_NO_AUTOSUSPEND },
/* Acer Peripherals Inc. (now BenQ Corp.) Prisa 640BU */
{ USB_DEVICE(0x04a5, 0x207e), .driver_info = USB_QUIRK_NO_AUTOSUSPEND },
/* Benq S2W 3300U */
Expand All @@ -56,6 +58,8 @@ static const struct usb_device_id usb_quirk_list[] = {
{ USB_DEVICE(0x04b8, 0x0121), .driver_info = USB_QUIRK_NO_AUTOSUSPEND },
/* Seiko Epson Corp.*/
{ USB_DEVICE(0x04b8, 0x0122), .driver_info = USB_QUIRK_NO_AUTOSUSPEND },
/* Samsung ML-2010 printer */
{ USB_DEVICE(0x04e8, 0x326c), .driver_info = USB_QUIRK_NO_AUTOSUSPEND },
/* Samsung ML-2510 Series printer */
{ USB_DEVICE(0x04e8, 0x327e), .driver_info = USB_QUIRK_NO_AUTOSUSPEND },
/* Elsa MicroLink 56k (V.250) */
Expand All @@ -64,12 +68,20 @@ static const struct usb_device_id usb_quirk_list[] = {
{ USB_DEVICE(0x05d8, 0x4005), .driver_info = USB_QUIRK_NO_AUTOSUSPEND },
/* Agfa Snapscan1212u */
{ USB_DEVICE(0x06bd, 0x2061), .driver_info = USB_QUIRK_NO_AUTOSUSPEND },
/* Seagate RSS LLC */
{ USB_DEVICE(0x0bc2, 0x3000), .driver_info = USB_QUIRK_NO_AUTOSUSPEND },
/* Umax [hex] Astra 3400U */
{ USB_DEVICE(0x1606, 0x0060), .driver_info = USB_QUIRK_NO_AUTOSUSPEND },

/* Philips PSC805 audio device */
{ USB_DEVICE(0x0471, 0x0155), .driver_info = USB_QUIRK_RESET_RESUME },

/* Alcor multi-card reader */
{ USB_DEVICE(0x058f, 0x6366), .driver_info = USB_QUIRK_NO_AUTOSUSPEND },

/* Canon EOS 5D in PC Connection mode */
{ USB_DEVICE(0x04a9, 0x3101), .driver_info = USB_QUIRK_NO_AUTOSUSPEND },

/* RIM Blackberry */
{ USB_DEVICE(0x0fca, 0x0001), .driver_info = USB_QUIRK_NO_AUTOSUSPEND },
{ USB_DEVICE(0x0fca, 0x0004), .driver_info = USB_QUIRK_NO_AUTOSUSPEND },
Expand Down
2 changes: 0 additions & 2 deletions drivers/usb/gadget/dummy_hcd.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,6 @@
* bypassing some hardware (and driver) issues. UML could help too.
*/

#define DEBUG

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/delay.h>
Expand Down
10 changes: 4 additions & 6 deletions drivers/usb/gadget/file_storage.c
Original file line number Diff line number Diff line change
Expand Up @@ -599,7 +599,6 @@ enum fsg_buffer_state {

struct fsg_buffhd {
void *buf;
dma_addr_t dma;
enum fsg_buffer_state state;
struct fsg_buffhd *next;

Expand Down Expand Up @@ -1295,6 +1294,7 @@ static int class_setup_req(struct fsg_dev *fsg,
struct usb_request *req = fsg->ep0req;
int value = -EOPNOTSUPP;
u16 w_index = le16_to_cpu(ctrl->wIndex);
u16 w_value = le16_to_cpu(ctrl->wValue);
u16 w_length = le16_to_cpu(ctrl->wLength);

if (!fsg->config)
Expand All @@ -1308,7 +1308,7 @@ static int class_setup_req(struct fsg_dev *fsg,
if (ctrl->bRequestType != (USB_DIR_OUT |
USB_TYPE_CLASS | USB_RECIP_INTERFACE))
break;
if (w_index != 0) {
if (w_index != 0 || w_value != 0) {
value = -EDOM;
break;
}
Expand All @@ -1324,7 +1324,7 @@ static int class_setup_req(struct fsg_dev *fsg,
if (ctrl->bRequestType != (USB_DIR_IN |
USB_TYPE_CLASS | USB_RECIP_INTERFACE))
break;
if (w_index != 0) {
if (w_index != 0 || w_value != 0) {
value = -EDOM;
break;
}
Expand All @@ -1343,7 +1343,7 @@ static int class_setup_req(struct fsg_dev *fsg,
if (ctrl->bRequestType != (USB_DIR_OUT |
USB_TYPE_CLASS | USB_RECIP_INTERFACE))
break;
if (w_index != 0) {
if (w_index != 0 || w_value != 0) {
value = -EDOM;
break;
}
Expand Down Expand Up @@ -2611,7 +2611,6 @@ static int send_status(struct fsg_dev *fsg)

fsg->intr_buffhd = bh; // Point to the right buffhd
fsg->intreq->buf = bh->inreq->buf;
fsg->intreq->dma = bh->inreq->dma;
fsg->intreq->context = bh;
start_transfer(fsg, fsg->intr_in, fsg->intreq,
&fsg->intreq_busy, &bh->state);
Expand Down Expand Up @@ -3200,7 +3199,6 @@ static int do_set_interface(struct fsg_dev *fsg, int altsetting)
if ((rc = alloc_request(fsg, fsg->bulk_out, &bh->outreq)) != 0)
goto reset;
bh->inreq->buf = bh->outreq->buf = bh->buf;
bh->inreq->dma = bh->outreq->dma = bh->dma;
bh->inreq->context = bh->outreq->context = bh;
bh->inreq->complete = bulk_in_complete;
bh->outreq->complete = bulk_out_complete;
Expand Down
Loading

0 comments on commit 9e1a3e3

Please sign in to comment.