Commit 9e1a3e31 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: (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
  ...
parents de80af4c d65cc1b4
......@@ -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;
}
......
......@@ -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);
......@@ -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");
......@@ -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;
}
......@@ -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();
}
......
......@@ -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];
......
......@@ -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
......
......@@ -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);
......@@ -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,
......
......@@ -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;
......
......@@ -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");
......@@ -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);
......
......@@ -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);
......@@ -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);
......@@ -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);
}
}
......
......@@ -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) {
......
......@@ -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;
......@@ -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",
......
......@@ -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 */
......@@ -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) */
......@@ -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 },
......
......@@ -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>
......
......@@ -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;
......@@ -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)
......@@ -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;
}
......@@ -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;
}
......@@ -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;
}
......@@ -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);
......@@ -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;
......
......@@ -1277,31 +1277,32 @@ static void setup_received_irq(struct fsl_udc *udc,
udc_reset_ep_queue(udc, 0);
/* We process some stardard setup requests here */
switch (setup->bRequest) {
/* Request that need Data+Status phase from udc */
case USB_REQ_GET_STATUS:
if ((setup->bRequestType & (USB_DIR_IN | USB_TYPE_STANDARD))
/* Data+Status phase from udc */
if ((setup->bRequestType & (USB_DIR_IN | USB_TYPE_MASK))
!= (USB_DIR_IN | USB_TYPE_STANDARD))
break;
ch9getstatus(udc, setup->bRequestType, wValue, wIndex, wLength);
break;
return;
/* Requests that need Status phase from udc */
case USB_REQ_SET_ADDRESS:
/* Status phase from udc */
if (setup->bRequestType != (USB_DIR_OUT | USB_TYPE_STANDARD
| USB_RECIP_DEVICE))
break;
ch9setaddress(udc, wValue, wIndex, wLength);
break;
return;
/* Handled by udc, no data, status by udc */
case USB_REQ_CLEAR_FEATURE:
case USB_REQ_SET_FEATURE:
{ /* status transaction */
/* Status phase from udc */
{
int rc = -EOPNOTSUPP;
if ((setup->bRequestType & USB_RECIP_MASK)
== USB_RECIP_ENDPOINT) {
if ((setup->bRequestType & (USB_RECIP_MASK | USB_TYPE_MASK))
== (USB_RECIP_ENDPOINT | USB_TYPE_STANDARD)) {
int pipe = get_pipe_by_windex(wIndex);
struct fsl_ep *ep;
......@@ -1315,8 +1316,9 @@ static void setup_received_irq(struct fsl_udc *udc,
? 1 : 0);
spin_lock(&udc->lock);
} else if ((setup->bRequestType & USB_RECIP_MASK)
== USB_RECIP_DEVICE) {
} else if ((setup->bRequestType & (USB_RECIP_MASK
| USB_TYPE_MASK)) == (USB_RECIP_DEVICE
| USB_TYPE_STANDARD)) {
/* Note: The driver has not include OTG support yet.
* This will be set when OTG support is added */
if (!udc->gadget.is_otg)
......@@ -1329,39 +1331,42 @@ static void setup_received_irq(struct fsl_udc *udc,
USB_DEVICE_A_ALT_HNP_SUPPORT)
udc->gadget.a_alt_hnp_support = 1;
rc = 0;
}
} else
break;
if (rc == 0) {
if (ep0_prime_status(udc, EP_DIR_IN))
ep0stall(udc);
}
break;
return;
}
/* Requests handled by gadget */
default:
if (wLength) {
/* Data phase from gadget, status phase from udc */
udc->ep0_dir = (setup->bRequestType & USB_DIR_IN)
? USB_DIR_IN : USB_DIR_OUT;
spin_unlock(&udc->lock);
if (udc->driver->setup(&udc->gadget,
&udc->local_setup_buff) < 0)
ep0stall(udc);
spin_lock(&udc->lock);
udc->ep0_state = (setup->bRequestType & USB_DIR_IN)
? DATA_STATE_XMIT : DATA_STATE_RECV;
} else {
/* No data phase, IN status from gadget */
udc->ep0_dir = USB_DIR_IN;
spin_unlock(&udc->lock);
if (udc->driver->setup(&udc->gadget,
&udc->local_setup_buff) < 0)
ep0stall(udc);
spin_lock(&udc->lock);
udc->ep0_state = WAIT_FOR_OUT_STATUS;
}
default:
break;
}
/* Requests handled by gadget */
if (wLength) {
/* Data phase from gadget, status phase from udc */
udc->ep0_dir = (setup->bRequestType & USB_DIR_IN)
? USB_DIR_IN : USB_DIR_OUT;
spin_unlock(&udc->lock);
if (udc->driver->setup(&udc->gadget,
&udc->local_setup_buff) < 0)
ep0stall(udc);
spin_lock(&udc->lock);
udc->ep0_state = (setup->bRequestType & USB_DIR_IN)
? DATA_STATE_XMIT : DATA_STATE_RECV;
} else {
/* No data phase, IN status from gadget */
udc->ep0_dir = USB_DIR_IN;
spin_unlock(&udc->lock);
if (udc->driver->setup(&udc->gadget,
&udc->local_setup_buff) < 0)
ep0stall(udc);
spin_lock(&udc->lock);
udc->ep0_state = WAIT_FOR_OUT_STATUS;
}
}
/* Process request for Data or Status phase of ep0
......
......@@ -967,7 +967,7 @@ static int pxa2xx_udc_pullup(struct usb_gadget *_gadget, int is_active)
udc = container_of(_gadget, struct pxa2xx_udc, gadget);
/* not all boards support pullup control */
if (!udc->mach->udc_command)
if (!udc->mach->gpio_pullup && !udc->mach->udc_command)
return -EOPNOTSUPP;
is_active = (is_active != 0);
......@@ -2309,7 +2309,7 @@ static int pxa2xx_udc_suspend(struct platform_device *dev, pm_message_t state)
{
struct pxa2xx_udc *udc = platform_get_drvdata(dev);
if (!udc->mach->udc_command)
if (!udc->mach->gpio_pullup && !udc->mach->udc_command)
WARN("USB host won't detect disconnect!\n");
pullup(udc, 0);
......
......@@ -237,7 +237,7 @@ config USB_SL811_CS
module will be called "sl811_cs".
config USB_R8A66597_HCD
tristate "R8A66597 HCD suppoort"
tristate "R8A66597 HCD support"
depends on USB
help
The R8A66597 is a USB 2.0 host and peripheral controller.
......
/*
* EHCI HCD (Host Controller Driver) for USB.
*
* (C) Copyright 2000-2004 David Brownell <dbrownell@users.sourceforge.net>
*
* Bus Glue for AMD Alchemy Au1xxx
*
* Based on "ohci-au1xxx.c" by Matt Porter <mporter@kernel.crashing.org>
......@@ -196,6 +194,9 @@ static const struct hc_driver ehci_au1xxx_hc_driver = {
/*
* basic lifecycle operations
*
* FIXME -- ehci_init() doesn't do enough here.
* See ehci-ppc-soc for a complete implementation.
*/
.reset = ehci_init,
.start = ehci_run,
......
......@@ -6,7 +6,7 @@
* Bus Glue for PPC On-Chip EHCI driver
* Tested on AMCC 440EPx
*
* Based on "ehci-au12xx.c" by David Brownell <dbrownell@users.sourceforge.net>
* Based on "ehci-au1xxx.c" by K.Boge <karsten.boge@amd.com>
*
* This file is licenced under the GPL.
*/
......@@ -15,6 +15,24 @@
extern int usb_disabled(void);
/* called during probe() after chip reset completes */
static int ehci_ppc_soc_setup(struct usb_hcd *hcd)
{
struct ehci_hcd *ehci = hcd_to_ehci(hcd);
int retval;
retval = ehci_halt(ehci);
if (retval)
return retval;
retval = ehci_init(hcd);
if (retval)
return retval;
ehci->sbrn = 0x20;
return ehci_reset(ehci);
}
/**
* usb_ehci_ppc_soc_probe - initialize PPC-SoC-based HCDs
* Context: !in_interrupt()
......@@ -120,7 +138,7 @@ static const struct hc_driver ehci_ppc_soc_hc_driver = {
/*
* basic lifecycle operations
*/
.reset = ehci_init,
.reset = ehci_ppc_soc_setup,
.start = ehci_run,
.stop = ehci_stop,
.shutdown = ehci_shutdown,
......
......@@ -74,7 +74,7 @@ urb_print (struct urb * urb, char * str, int small)
#define ohci_dbg_sw(ohci, next, size, format, arg...) \
do { \
if (next) { \
if (next != NULL) { \
unsigned s_len; \
s_len = scnprintf (*next, *size, format, ## arg ); \
*size -= s_len; *next += s_len; \
......
......@@ -2208,8 +2208,6 @@ static int __init r8a66597_probe(struct platform_device *pdev)
clean_up:
if (reg)
iounmap(reg);
if (res)
release_mem_region(res->start, 1);
return ret;
}
......
......@@ -1520,12 +1520,15 @@ static void u132_hcd_endp_work_scheduler(struct work_struct *work)
}
}
}
#ifdef CONFIG_PM
static void port_power(struct u132 *u132, int pn, int is_on)
{
u132->port[pn].power = is_on;
}
#endif
static void u132_power(struct u132 *u132, int is_on)
{
struct usb_hcd *hcd = u132_to_hcd(u132)
......
......@@ -18,7 +18,6 @@
static struct usb_device_id id_table [] = {
{ USB_DEVICE(0x0c88, 0x17da) }, /* Kyocera Wireless KPC650/Passport */
{ USB_DEVICE(0x413c, 0x8115) }, /* Dell Wireless HSDPA 5500 */
{ },
};
MODULE_DEVICE_TABLE(usb, id_table);
......
......@@ -383,6 +383,10 @@ static void belkin_sa_set_termios (struct usb_serial_port *port, struct ktermios
}
baud = tty_get_baud_rate(port->tty);
if (baud == 0) {
dbg("%s - tty_get_baud_rate says 0 baud", __FUNCTION__);
return;
}
urb_value = BELKIN_SA_BAUD(baud);
/* Clip to maximum speed */
if (urb_value == 0)
......
......@@ -538,6 +538,8 @@ static struct usb_device_id id_table_combined [] = {
{ USB_DEVICE(FTDI_VID, FTDI_TERATRONIK_VCP_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_TERATRONIK_D2XX_PID) },
{ USB_DEVICE(EVOLUTION_VID, EVOLUTION_ER1_PID) },
{ USB_DEVICE(EVOLUTION_VID, EVO_HYBRID_PID) },
{ USB_DEVICE(EVOLUTION_VID, EVO_RCM4_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_ARTEMIS_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_ATIK_ATK16_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_ATIK_ATK16C_PID) },
......
......@@ -430,6 +430,9 @@
*/
#define EVOLUTION_VID 0xDEEE /* Vendor ID */
#define EVOLUTION_ER1_PID 0x0300 /* ER1 Control Module */
#define EVO_8U232AM_PID 0x02FF /* Evolution robotics RCM2 (FT232AM)*/
#define EVO_HYBRID_PID 0x0302 /* Evolution robotics RCM4 PID (FT232BM)*/
#define EVO_RCM4_PID 0x0303 /* Evolution robotics RCM4 PID */
/* Pyramid Computer GmbH */
#define FTDI_PYRAMID_PID 0xE6C8 /* Pyramid Appliance Display */
......
/*
* Garmin GPS driver
*
* Copyright (C) 2006 Hermann Kneissel herkne@users.sourceforge.net
* Copyright (C) 2006,2007 Hermann Kneissel herkne@users.sourceforge.net
*
* The latest version of the driver can be found at
* http://sourceforge.net/projects/garmin-gps/
......@@ -34,6 +34,7 @@
#include <linux/module.h>
#include <linux/spinlock.h>
#include <asm/uaccess.h>
#include <asm/atomic.h>
#include <linux/usb.h>
#include <linux/usb/serial.h>
......@@ -52,7 +53,7 @@ static int debug = 0;
*/
#define VERSION_MAJOR 0
#define VERSION_MINOR 28
#define VERSION_MINOR 31
#define _STR(s) #s
#define _DRIVER_VERSION(a,b) "v" _STR(a) "." _STR(b)
......@@ -141,6 +142,8 @@ struct garmin_data {
__u8 inbuffer [GPS_IN_BUFSIZ]; /* tty -> usb */
__u8 outbuffer[GPS_OUT_BUFSIZ]; /* usb -> tty */
__u8 privpkt[4*6];
atomic_t req_count;
atomic_t resp_count;
spinlock_t lock;
struct list_head pktlist;
};
......@@ -171,8 +174,6 @@ struct garmin_data {
#define CLEAR_HALT_REQUIRED 0x0001
#define FLAGS_QUEUING 0x0100
#define FLAGS_APP_RESP_SEEN 0x0200
#define FLAGS_APP_REQ_SEEN 0x0400
#define FLAGS_DROP_DATA 0x0800
#define FLAGS_GSP_SKIP 0x1000
......@@ -186,7 +187,8 @@ struct garmin_data {
/* function prototypes */
static void gsp_next_packet(struct garmin_data * garmin_data_p);
static int garmin_write_bulk(struct usb_serial_port *port,
const unsigned char *buf, int count);
const unsigned char *buf, int count,
int dismiss_ack);
/* some special packets to be send or received */
static unsigned char const GARMIN_START_SESSION_REQ[]
......@@ -233,9 +235,7 @@ static struct usb_driver garmin_driver = {
static inline int noResponseFromAppLayer(struct garmin_data * garmin_data_p)
{
return ((garmin_data_p->flags
& (FLAGS_APP_REQ_SEEN|FLAGS_APP_RESP_SEEN))
== FLAGS_APP_REQ_SEEN);
return atomic_read(&garmin_data_p->req_count) == atomic_read(&garmin_data_p->resp_count);
}
......@@ -463,7 +463,7 @@ static int gsp_rec_packet(struct garmin_data * garmin_data_p, int count)
usbdata[2] = __cpu_to_le32(size);
garmin_write_bulk (garmin_data_p->port, garmin_data_p->inbuffer,
GARMIN_PKTHDR_LENGTH+size);
GARMIN_PKTHDR_LENGTH+size, 0);
/* if this was an abort-transfer command, flush all
queued data. */
......@@ -818,7 +818,7 @@ static int nat_receive(struct garmin_data * garmin_data_p,
if (garmin_data_p->insize >= len) {
garmin_write_bulk (garmin_data_p->port,
garmin_data_p->inbuffer,
len);
len, 0);
garmin_data_p->insize = 0;
/* if this was an abort-transfer command,
......@@ -893,10 +893,11 @@ static int garmin_clear(struct garmin_data * garmin_data_p)
struct usb_serial_port *port = garmin_data_p->port;
if (port != NULL && garmin_data_p->flags & FLAGS_APP_RESP_SEEN) {
if (port != NULL && atomic_read(&garmin_data_p->resp_count)) {
/* send a terminate command */
status = garmin_write_bulk(port, GARMIN_STOP_TRANSFER_REQ,
sizeof(GARMIN_STOP_TRANSFER_REQ));
sizeof(GARMIN_STOP_TRANSFER_REQ),
1);
}
/* flush all queued data */
......@@ -939,7 +940,8 @@ static int garmin_init_session(struct usb_serial_port *port)
dbg("%s - starting session ...", __FUNCTION__);
garmin_data_p->state = STATE_ACTIVE;
status = garmin_write_bulk(port, GARMIN_START_SESSION_REQ,
sizeof(GARMIN_START_SESSION_REQ));
sizeof(GARMIN_START_SESSION_REQ),
0);
if (status >= 0) {
......@@ -950,7 +952,8 @@ static int garmin_init_session(struct usb_serial_port *port)
/* not needed, but the win32 driver does it too ... */
status = garmin_write_bulk(port,
GARMIN_START_SESSION_REQ2,
sizeof(GARMIN_START_SESSION_REQ2));
sizeof(GARMIN_START_SESSION_REQ2),
0);
if (status >= 0) {
status = 0;
spin_lock_irqsave(&garmin_data_p->lock, flags);
......@@ -987,6 +990,8 @@ static int garmin_open (struct usb_serial_port *port, struct file *filp)
garmin_data_p->mode = initial_mode;
garmin_data_p->count = 0;
garmin_data_p->flags = 0;
atomic_set(&garmin_data_p->req_count, 0);
atomic_set(&garmin_data_p->resp_count, 0);
spin_unlock_irqrestore(&garmin_data_p->lock, flags);
/* shutdown any bulk reads that might be going on */
......@@ -1035,28 +1040,39 @@ static void garmin_write_bulk_callback (struct urb *urb)
{
unsigned long flags;
struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
struct garmin_data * garmin_data_p = usb_get_serial_port_data(port);
int status = urb->status;
/* free up the transfer buffer, as usb_free_urb() does not do this */
kfree (urb->transfer_buffer);
if (port) {
struct garmin_data * garmin_data_p = usb_get_serial_port_data(port);
dbg("%s - port %d", __FUNCTION__, port->number);
dbg("%s - port %d", __FUNCTION__, port->number);
if (status) {
dbg("%s - nonzero write bulk status received: %d",
__FUNCTION__, status);
spin_lock_irqsave(&garmin_data_p->lock, flags);
garmin_data_p->flags |= CLEAR_HALT_REQUIRED;
spin_unlock_irqrestore(&garmin_data_p->lock, flags);
if (GARMIN_LAYERID_APPL == getLayerId(urb->transfer_buffer)
&& (garmin_data_p->mode == MODE_GARMIN_SERIAL)) {
gsp_send_ack(garmin_data_p, ((__u8 *)urb->transfer_buffer)[4]);
}
if (status) {
dbg("%s - nonzero write bulk status received: %d",
__FUNCTION__, urb->status);
spin_lock_irqsave(&garmin_data_p->lock, flags);
garmin_data_p->flags |= CLEAR_HALT_REQUIRED;
spin_unlock_irqrestore(&garmin_data_p->lock, flags);
}
usb_serial_port_softint(port);
}
usb_serial_port_softint(port);
/* Ignore errors that resulted from garmin_write_bulk with dismiss_ack=1 */
/* free up the transfer buffer, as usb_free_urb() does not do this */
kfree (urb->transfer_buffer);
}
static int garmin_write_bulk (struct usb_serial_port *port,
const unsigned char *buf, int count)
const unsigned char *buf, int count,
int dismiss_ack)
{
unsigned long flags;
struct usb_serial *serial = port->serial;
......@@ -1093,13 +1109,12 @@ static int garmin_write_bulk (struct usb_serial_port *port,
usb_sndbulkpipe (serial->dev,
port->bulk_out_endpointAddress),
buffer, count,
garmin_write_bulk_callback, port);
garmin_write_bulk_callback,
dismiss_ack ? NULL : port);
urb->transfer_flags |= URB_ZERO_PACKET;
if (GARMIN_LAYERID_APPL == getLayerId(buffer)) {
spin_lock_irqsave(&garmin_data_p->lock, flags);
garmin_data_p->flags |= FLAGS_APP_REQ_SEEN;
spin_unlock_irqrestore(&garmin_data_p->lock, flags);
atomic_inc(&garmin_data_p->req_count);
if (garmin_data_p->mode == MODE_GARMIN_SERIAL) {
pkt_clear(garmin_data_p);
garmin_data_p->state = STATE_GSP_WAIT_DATA;
......@@ -1114,13 +1129,6 @@ static int garmin_write_bulk (struct usb_serial_port *port,
"failed with status = %d\n",
__FUNCTION__, status);
count = status;
} else {
if (GARMIN_LAYERID_APPL == getLayerId(buffer)
&& (garmin_data_p->mode == MODE_GARMIN_SERIAL)) {
gsp_send_ack(garmin_data_p, buffer[4]);
}
}
/* we are done with this urb, so let the host driver
......@@ -1135,7 +1143,6 @@ static int garmin_write_bulk (struct usb_serial_port *port,
static int garmin_write (struct usb_serial_port *port,
const unsigned char *buf, int count)
{
unsigned long flags;
int pktid, pktsiz, len;
struct garmin_data * garmin_data_p = usb_get_serial_port_data(port);
__le32 *privpkt = (__le32 *)garmin_data_p->privpkt;
......@@ -1186,9 +1193,7 @@ static int garmin_write (struct usb_serial_port *port,
break;
case PRIV_PKTID_RESET_REQ:
spin_lock_irqsave(&garmin_data_p->lock, flags);
garmin_data_p->flags |= FLAGS_APP_REQ_SEEN;
spin_unlock_irqrestore(&garmin_data_p->lock, flags);
atomic_inc(&garmin_data_p->req_count);
break;
case PRIV_PKTID_SET_DEF_MODE:
......@@ -1241,8 +1246,6 @@ static int garmin_chars_in_buffer (struct usb_serial_port *port)
static void garmin_read_process(struct garmin_data * garmin_data_p,
unsigned char *data, unsigned data_length)
{
unsigned long flags;
if (garmin_data_p->flags & FLAGS_DROP_DATA) {
/* abort-transfer cmd is actice */
dbg("%s - pkt dropped", __FUNCTION__);
......@@ -1254,9 +1257,7 @@ static void garmin_read_process(struct garmin_data * garmin_data_p,
the device */
if (0 == memcmp(data, GARMIN_APP_LAYER_REPLY,
sizeof(GARMIN_APP_LAYER_REPLY))) {
spin_lock_irqsave(&garmin_data_p->lock, flags);
garmin_data_p->flags |= FLAGS_APP_RESP_SEEN;
spin_unlock_irqrestore(&garmin_data_p->lock, flags);
atomic_inc(&garmin_data_p->resp_count);
}
/* if throttling is active or postprecessing is required
......
......@@ -545,6 +545,7 @@ static struct usb_device_id ipaq_id_table [] = {
{ USB_DEVICE(0x413C, 0x4009) }, /* Dell Axim USB Sync */
{ USB_DEVICE(0x4505, 0x0010) }, /* Smartphone */
{ USB_DEVICE(0x5E04, 0xCE00) }, /* SAGEM Wireless Assistant */
{ USB_DEVICE(0x0BB4, 0x00CF) }, /* HTC smartphone modems */
{ } /* Terminating entry */
};
......
......@@ -110,6 +110,7 @@ static int option_send_setup(struct usb_serial_port *port);
#define HUAWEI_PRODUCT_E220 0x1003
#define NOVATELWIRELESS_VENDOR_ID 0x1410
#define DELL_VENDOR_ID 0x413C
#define ANYDATA_VENDOR_ID 0x16d5
#define ANYDATA_PRODUCT_ADU_E100A 0x6501
......@@ -119,8 +120,6 @@ static int option_send_setup(struct usb_serial_port *port);
#define BANDRICH_PRODUCT_C100_1 0x1002
#define BANDRICH_PRODUCT_C100_2 0x1003
#define DELL_VENDOR_ID 0x413C
static struct usb_device_id option_ids[] = {
{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) },
{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA) },
......@@ -171,11 +170,16 @@ static struct usb_device_id option_ids[] = {
{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x2110) }, /* Novatel Merlin ES620 / Merlin ES720 / Ovation U720 */
{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x2130) }, /* Novatel Merlin ES620 SM Bus */
{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x2410) }, /* Novatel EU740 */
{ USB_DEVICE(DELL_VENDOR_ID, 0x8114) }, /* Dell Wireless 5700 Mobile Broadband CDMA/EVDO Mini-Card == Novatel Expedite EV620 CDMA/EV-DO */
{ USB_DEVICE(DELL_VENDOR_ID, 0x8115) }, /* Dell Wireless 5500 Mobile Broadband HSDPA Mini-Card == Novatel Expedite EU740 HSDPA/3G */
{ USB_DEVICE(DELL_VENDOR_ID, 0x8116) }, /* Dell Wireless 5505 Mobile Broadband HSDPA Mini-Card == Novatel Expedite EU740 HSDPA/3G */
{ USB_DEVICE(DELL_VENDOR_ID, 0x8117) }, /* Dell Wireless 5700 Mobile Broadband CDMA/EVDO ExpressCard == Novatel Merlin XV620 CDMA/EV-DO */
{ USB_DEVICE(DELL_VENDOR_ID, 0x8118) }, /* Dell Wireless 5510 Mobile Broadband HSDPA ExpressCard == Novatel Merlin XU870 HSDPA/3G */
{ USB_DEVICE(DELL_VENDOR_ID, 0x8128) }, /* Dell Wireless 5700 Mobile Broadband CDMA/EVDO Mini-Card == Novatel Expedite E720 CDMA/EV-DO */
{ USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_E100A) },
{ USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_500A) },
{ USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_C100_1) },
{ USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_C100_2) },
{ USB_DEVICE(DELL_VENDOR_ID, 0x8118) }, /* Dell Wireless 5510 Mobile Broadband HSDPA ExpressCard */
{ } /* Terminating entry */
};
MODULE_DEVICE_TABLE(usb, option_ids);
......
......@@ -818,19 +818,17 @@ static int oti6858_ioctl(struct usb_serial_port *port, struct file *file,
switch (cmd) {
case TCGETS:
if (copy_to_user(user_arg, port->tty->termios,
sizeof(struct ktermios))) {
if (kernel_termios_to_user_termios((struct ktermios __user *)arg,
port->tty->termios))
return -EFAULT;
}
return 0;
case TCSETS:
case TCSETSW: /* FIXME: this is not the same! */
case TCSETSF: /* FIXME: this is not the same! */
if (copy_from_user(port->tty->termios, user_arg,
sizeof(struct ktermios))) {
if (user_termios_to_kernel_termios(port->tty->termios,
(struct ktermios __user *)arg))
return -EFAULT;
}
oti6858_set_termios(port, NULL);
return 0;
......
......@@ -74,13 +74,13 @@
#include <linux/usb/serial.h>
#ifndef CONFIG_USB_SAFE_PADDED
#define CONFIG_USB_SAFE_PADDED 0
#ifndef CONFIG_USB_SERIAL_SAFE_PADDED
#define CONFIG_USB_SERIAL_SAFE_PADDED 0
#endif
static int debug;
static int safe = 1;
static int padded = CONFIG_USB_SAFE_PADDED;
static int padded = CONFIG_USB_SERIAL_SAFE_PADDED;
#define DRIVER_VERSION "v0.0b"
#define DRIVER_AUTHOR "sl@lineo.com, tbr@lineo.com"
......
......@@ -104,6 +104,8 @@ static struct usb_device_id id_table [] = {
.driver_info = (kernel_ulong_t)&palm_os_4_probe },
{ USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_TJ25_ID),
.driver_info = (kernel_ulong_t)&palm_os_4_probe },
{ USB_DEVICE(ACER_VENDOR_ID, ACER_S10_ID),
.driver_info = (kernel_ulong_t)&palm_os_4_probe },
{ USB_DEVICE(SAMSUNG_VENDOR_ID, SAMSUNG_SCH_I330_ID),
.driver_info = (kernel_ulong_t)&palm_os_4_probe },
{ USB_DEVICE(SAMSUNG_VENDOR_ID, SAMSUNG_SPH_I500_ID),
......
......@@ -48,6 +48,9 @@
#define SONY_CLIE_UX50_ID 0x0144
#define SONY_CLIE_TJ25_ID 0x0169
#define ACER_VENDOR_ID 0x0502
#define ACER_S10_ID 0x0001
#define SAMSUNG_VENDOR_ID 0x04E8
#define SAMSUNG_SCH_I330_ID 0x8001
#define SAMSUNG_SPH_I500_ID 0x6601
......
......@@ -342,7 +342,7 @@ UNUSUAL_DEV( 0x04b0, 0x040d, 0x0100, 0x0100,
US_FL_FIX_CAPACITY),
/* Reported by Emil Larsson <emil@swip.net> */
UNUSUAL_DEV( 0x04b0, 0x0411, 0x0100, 0x0100,
UNUSUAL_DEV( 0x04b0, 0x0411, 0x0100, 0x0101,
"NIKON",
"NIKON DSC D80",
US_SC_DEVICE, US_PR_DEVICE, NULL,
......
......@@ -112,13 +112,6 @@ module_param(delay_use, uint, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(delay_use, "seconds to delay before using a new device");
/* These are used to make sure the module doesn't unload before all the
* threads have exited.
*/
static atomic_t total_threads = ATOMIC_INIT(0);
static DECLARE_COMPLETION(threads_gone);
/*
* The entries in this table correspond, line for line,
* with the entries of us_unusual_dev_list[].
......@@ -879,9 +872,6 @@ static void quiesce_and_remove_host(struct us_data *us)
usb_stor_stop_transport(us);
wake_up(&us->delay_wait);
/* It doesn't matter if the SCSI-scanning thread is still running.
* The thread will exit when it sees the DISCONNECTING flag. */
/* queuecommand won't accept any new commands and the control
* thread won't execute a previously-queued command. If there
* is such a command pending, complete it with an error. */
......@@ -891,12 +881,16 @@ static void quiesce_and_remove_host(struct us_data *us)
scsi_lock(host);
us->srb->scsi_done(us->srb);
us->srb = NULL;
complete(&us->notify); /* in case of an abort */
scsi_unlock(host);
}
mutex_unlock(&us->dev_mutex);
/* Now we own no commands so it's safe to remove the SCSI host */
scsi_remove_host(host);
/* Wait for the SCSI-scanning thread to stop */
wait_for_completion(&us->scanning_done);
}
/* Second stage of disconnect processing: deallocate all resources */
......@@ -947,9 +941,8 @@ static int usb_stor_scan_thread(void * __us)
/* Should we unbind if no devices were detected? */
}
scsi_host_put(us_to_host(us));
usb_autopm_put_interface(us->pusb_intf);
complete_and_exit(&threads_gone, 0);
complete_and_exit(&us->scanning_done, 0);
}
......@@ -984,6 +977,7 @@ static int storage_probe(struct usb_interface *intf,
init_MUTEX_LOCKED(&(us->sema));
init_completion(&(us->notify));
init_waitqueue_head(&us->delay_wait);
init_completion(&us->scanning_done);
/* Associate the us_data structure with the USB device */
result = associate_dev(us, intf);
......@@ -1033,11 +1027,6 @@ static int storage_probe(struct usb_interface *intf,
goto BadDevice;
}
/* Take a reference to the host for the scanning thread and
* count it among all the threads we have launched. Then
* start it up. */
scsi_host_get(us_to_host(us));
atomic_inc(&total_threads);
usb_autopm_get_interface(intf); /* dropped in the scanning thread */
wake_up_process(th);
......@@ -1104,16 +1093,6 @@ static void __exit usb_stor_exit(void)
US_DEBUGP("-- calling usb_deregister()\n");
usb_deregister(&usb_storage_driver) ;
/* Don't return until all of our control and scanning threads
* have exited. Since each thread signals threads_gone as its
* last act, we have to call wait_for_completion the right number
* of times.
*/
while (atomic_read(&total_threads) > 0) {
wait_for_completion(&threads_gone);
atomic_dec(&total_threads);
}
usb_usual_clear_present(USB_US_TYPE_STOR);
}
......
......@@ -150,6 +150,7 @@ struct us_data {
struct semaphore sema; /* to sleep thread on */
struct completion notify; /* thread begin/end */
wait_queue_head_t delay_wait; /* wait during scan, reset */
struct completion scanning_done; /* wait for scan thread */
/* subdriver information */
void *extra; /* Any extra data */
......
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