Commit ba9d306a authored by Linus Torvalds's avatar Linus Torvalds

Merge bk://kernel.bkbits.net/gregkh/linux/usb-2.6

into home.osdl.org:/home/torvalds/v2.5/linux
parents 3ee9f3e6 e03f0410
......@@ -465,7 +465,7 @@ show_periodic (struct class_device *class_dev, char *buf)
spin_lock_irqsave (&ehci->lock, flags);
for (i = 0; i < ehci->periodic_size; i++) {
p = ehci->pshadow [i];
if (!p.ptr)
if (likely (!p.ptr))
continue;
tag = Q_NEXT_TYPE (ehci->periodic [i]);
......@@ -495,7 +495,7 @@ show_periodic (struct class_device *class_dev, char *buf)
break;
}
/* show more info the first time around */
if (temp == seen_count) {
if (temp == seen_count && p.ptr) {
u32 scratch = cpu_to_le32p (
&p.qh->hw_info1);
struct ehci_qtd *qtd;
......@@ -528,8 +528,10 @@ show_periodic (struct class_device *class_dev, char *buf)
seen [seen_count++].qh = p.qh;
} else
temp = 0;
tag = Q_NEXT_TYPE (p.qh->hw_next);
p = p.qh->qh_next;
if (p.qh) {
tag = Q_NEXT_TYPE (p.qh->hw_next);
p = p.qh->qh_next;
}
break;
case Q_TYPE_FSTN:
temp = snprintf (next, size,
......
......@@ -184,7 +184,7 @@ ehci_urb_done (struct ehci_hcd *ehci, struct urb *urb, struct pt_regs *regs)
struct ehci_qh *qh = (struct ehci_qh *) urb->hcpriv;
/* S-mask in a QH means it's an interrupt urb */
if ((qh->hw_info2 & cpu_to_le32 (0x00ff)) != 0) {
if ((qh->hw_info2 & __constant_cpu_to_le32 (0x00ff)) != 0) {
/* ... update hc-wide periodic stats (for usbfs) */
hcd_to_bus (&ehci->hcd)->bandwidth_int_reqs--;
......@@ -224,7 +224,7 @@ ehci_urb_done (struct ehci_hcd *ehci, struct urb *urb, struct pt_regs *regs)
* Chases up to qh->hw_current. Returns number of completions called,
* indicating how much "real" work we did.
*/
#define HALT_BIT cpu_to_le32(QTD_STS_HALT)
#define HALT_BIT __constant_cpu_to_le32(QTD_STS_HALT)
static unsigned
qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh, struct pt_regs *regs)
{
......@@ -377,10 +377,14 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh, struct pt_regs *regs)
return count;
}
#undef HALT_BIT
/*-------------------------------------------------------------------------*/
// high bandwidth multiplier, as encoded in highspeed endpoint descriptors
#define hb_mult(wMaxPacketSize) (1 + (((wMaxPacketSize) >> 11) & 0x03))
// ... and packet size, for any kind of endpoint descriptor
#define max_packet(wMaxPacketSize) ((wMaxPacketSize) & 0x07ff)
/*
* reverse of qh_urb_transaction: free a list of TDs.
* used for cleanup after errors, before HC sees an URB's TDs.
......@@ -461,7 +465,7 @@ qh_urb_transaction (
token |= (1 /* "in" */ << 8);
/* else it's already initted to "out" pid (0 << 8) */
maxpacket = usb_maxpacket (urb->dev, urb->pipe, !is_input) & 0x03ff;
maxpacket = max_packet(usb_maxpacket(urb->dev, urb->pipe, !is_input));
/*
* buffer gets wrapped in one or more qtds;
......@@ -564,11 +568,6 @@ clear_toggle (struct usb_device *udev, int ep, int is_out, struct ehci_qh *qh)
// That'd mean updating how usbcore talks to HCDs. (2.5?)
// high bandwidth multiplier, as encoded in highspeed endpoint descriptors
#define hb_mult(wMaxPacketSize) (1 + (((wMaxPacketSize) >> 11) & 0x03))
// ... and packet size, for any kind of endpoint descriptor
#define max_packet(wMaxPacketSize) ((wMaxPacketSize) & 0x03ff)
/*
* Each QH holds a qtd list; a QH is used for everything except iso.
*
......@@ -728,7 +727,7 @@ static void qh_link_async (struct ehci_hcd *ehci, struct ehci_qh *qh)
}
}
qh->hw_token &= ~__constant_cpu_to_le32 (QTD_STS_HALT);
qh->hw_token &= ~HALT_BIT;
/* splice right after start */
qh->qh_next = head->qh_next;
......@@ -744,6 +743,8 @@ static void qh_link_async (struct ehci_hcd *ehci, struct ehci_qh *qh)
/*-------------------------------------------------------------------------*/
#define QH_ADDR_MASK __constant_le32_to_cpu(0x7f)
/*
* For control/bulk/interrupt, return QH with these TDs appended.
* Allocates and initializes the QH if necessary.
......@@ -778,12 +779,13 @@ static struct ehci_qh *qh_append_tds (
/* control qh may need patching after enumeration */
if (unlikely (epnum == 0)) {
/* set_address changes the address */
if (le32_to_cpu (qh->hw_info1 & 0x7f) == 0)
if ((qh->hw_info1 & QH_ADDR_MASK) == 0)
qh->hw_info1 |= cpu_to_le32 (
usb_pipedevice (urb->pipe));
/* for full speed, ep0 maxpacket can grow */
else if (!(qh->hw_info1 & cpu_to_le32 (0x3 << 12))) {
else if (!(qh->hw_info1
& __constant_cpu_to_le32 (0x3 << 12))) {
u32 info, max;
info = le32_to_cpu (qh->hw_info1);
......@@ -797,7 +799,7 @@ static struct ehci_qh *qh_append_tds (
/* usb_reset_device() briefly reverts to address 0 */
if (usb_pipedevice (urb->pipe) == 0)
qh->hw_info1 &= cpu_to_le32(~0x7f);
qh->hw_info1 &= ~QH_ADDR_MASK;
}
/* usb_clear_halt() means qh data toggle gets reset */
......@@ -833,7 +835,7 @@ static struct ehci_qh *qh_append_tds (
* HC is allowed to fetch the old dummy (4.10.2).
*/
token = qtd->hw_token;
qtd->hw_token = cpu_to_le32 (QTD_STS_HALT);
qtd->hw_token = HALT_BIT;
wmb ();
dummy = qh->dummy;
......
......@@ -325,6 +325,7 @@ union ehci_shadow {
struct ehci_itd *itd; /* Q_TYPE_ITD */
struct ehci_sitd *sitd; /* Q_TYPE_SITD */
struct ehci_fstn *fstn; /* Q_TYPE_FSTN */
u32 *hw_next; /* (all types) */
void *ptr;
};
......@@ -469,27 +470,12 @@ struct ehci_fstn {
/*-------------------------------------------------------------------------*/
#include <linux/version.h>
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,32)
#define SUBMIT_URB(urb,mem_flags) usb_submit_urb(urb)
#define STUB_DEBUG_FILES
static inline int hcd_register_root (struct usb_hcd *hcd)
{
return usb_new_device (hcd_to_bus (hcd)->root_hub);
}
#else /* LINUX_VERSION_CODE */
#define SUBMIT_URB(urb,mem_flags) usb_submit_urb(urb,mem_flags)
#ifndef DEBUG
#define STUB_DEBUG_FILES
#endif /* DEBUG */
#endif /* LINUX_VERSION_CODE */
/*-------------------------------------------------------------------------*/
#endif /* __LINUX_EHCI_HCD_H */
......@@ -102,14 +102,8 @@
#include <asm/unaligned.h>
#include <asm/byteorder.h>
/*
* TO DO:
*
* - "disabled" and "sleeping" should be in hcd->state
* - lots more testing!!
*/
#define DRIVER_VERSION "2003 Feb 24"
#define DRIVER_VERSION "2003 Oct 13"
#define DRIVER_AUTHOR "Roman Weissgaerber, David Brownell"
#define DRIVER_DESC "USB 1.1 'Open' Host Controller (OHCI) Driver"
......@@ -131,7 +125,6 @@ static const char hcd_name [] = "ohci_hcd";
static inline void disable (struct ohci_hcd *ohci)
{
ohci->disabled = 1;
ohci->hcd.state = USB_STATE_HALT;
}
......@@ -222,7 +215,7 @@ static int ohci_urb_enqueue (
spin_lock_irqsave (&ohci->lock, flags);
/* don't submit to a dead HC */
if (ohci->disabled || ohci->sleeping) {
if (!HCD_IS_RUNNING(ohci->hcd.state)) {
retval = -ENODEV;
goto fail;
}
......@@ -278,7 +271,7 @@ static int ohci_urb_dequeue (struct usb_hcd *hcd, struct urb *urb)
#endif
spin_lock_irqsave (&ohci->lock, flags);
if (!ohci->disabled) {
if (HCD_IS_RUNNING(ohci->hcd.state)) {
urb_priv_t *urb_priv;
/* Unless an IRQ completed the unlink while it was being
......@@ -287,7 +280,6 @@ static int ohci_urb_dequeue (struct usb_hcd *hcd, struct urb *urb)
*/
urb_priv = urb->hcpriv;
if (urb_priv) {
urb_priv->state = URB_DEL;
if (urb_priv->ed->state == ED_OPER)
start_urb_unlink (ohci, urb_priv->ed);
}
......@@ -334,7 +326,7 @@ ohci_endpoint_disable (struct usb_hcd *hcd, struct hcd_dev *dev, int ep)
if (!ed)
goto done;
if (!HCD_IS_RUNNING (ohci->hcd.state) || ohci->disabled)
if (!HCD_IS_RUNNING (ohci->hcd.state))
ed->state = ED_IDLE;
switch (ed->state) {
case ED_UNLINK: /* wait for hw to finish? */
......@@ -355,9 +347,9 @@ ohci_endpoint_disable (struct usb_hcd *hcd, struct hcd_dev *dev, int ep)
/* caller was supposed to have unlinked any requests;
* that's not our job. can't recover; must leak ed.
*/
ohci_err (ohci, "ed %p (#%d) state %d%s\n",
ohci_err (ohci, "leak ed %p (#%d) state %d%s\n",
ed, epnum, ed->state,
list_empty (&ed->td_list) ? "" : "(has tds)");
list_empty (&ed->td_list) ? "" : " (has tds)");
td_free (ohci, ed->dummy);
break;
}
......@@ -466,8 +458,7 @@ static int hc_start (struct ohci_hcd *ohci)
struct usb_bus *bus;
spin_lock_init (&ohci->lock);
ohci->disabled = 1;
ohci->sleeping = 0;
disable (ohci);
/* Tell the controller where the control and bulk lists are
* The lists are empty now. */
......@@ -496,8 +487,8 @@ static int hc_start (struct ohci_hcd *ohci)
/* start controller operations */
ohci->hc_control &= OHCI_CTRL_RWC;
ohci->hc_control |= OHCI_CONTROL_INIT | OHCI_USB_OPER;
ohci->disabled = 0;
writel (ohci->hc_control, &ohci->regs->control);
ohci->hcd.state = USB_STATE_RUNNING;
/* Choose the interrupts we care about now, others later on demand */
mask = OHCI_INTR_MIE | OHCI_INTR_UE | OHCI_INTR_WDH;
......@@ -586,9 +577,11 @@ static void ohci_irq (struct usb_hcd *hcd, struct pt_regs *ptregs)
}
if (ints & OHCI_INTR_WDH) {
writel (OHCI_INTR_WDH, &regs->intrdisable);
if (HCD_IS_RUNNING(hcd->state))
writel (OHCI_INTR_WDH, &regs->intrdisable);
dl_done_list (ohci, dl_reverse_done_list (ohci), ptregs);
writel (OHCI_INTR_WDH, &regs->intrenable);
if (HCD_IS_RUNNING(hcd->state))
writel (OHCI_INTR_WDH, &regs->intrenable);
}
/* could track INTR_SO to reduce available PCI/... bandwidth */
......@@ -600,14 +593,17 @@ static void ohci_irq (struct usb_hcd *hcd, struct pt_regs *ptregs)
if (ohci->ed_rm_list)
finish_unlinks (ohci, le16_to_cpu (ohci->hcca->frame_no),
ptregs);
if ((ints & OHCI_INTR_SF) != 0 && !ohci->ed_rm_list)
if ((ints & OHCI_INTR_SF) != 0 && !ohci->ed_rm_list
&& HCD_IS_RUNNING(ohci->hcd.state))
writel (OHCI_INTR_SF, &regs->intrdisable);
spin_unlock (&ohci->lock);
writel (ints, &regs->intrstatus);
writel (OHCI_INTR_MIE, &regs->intrenable);
// flush those pci writes
(void) readl (&ohci->regs->control);
if (HCD_IS_RUNNING(ohci->hcd.state)) {
writel (ints, &regs->intrstatus);
writel (OHCI_INTR_MIE, &regs->intrenable);
// flush those pci writes
(void) readl (&ohci->regs->control);
}
}
/*-------------------------------------------------------------------------*/
......@@ -616,13 +612,12 @@ static void ohci_stop (struct usb_hcd *hcd)
{
struct ohci_hcd *ohci = hcd_to_ohci (hcd);
ohci_dbg (ohci, "stop %s controller%s\n",
ohci_dbg (ohci, "stop %s controller (state 0x%02x)\n",
hcfs2string (ohci->hc_control & OHCI_CTRL_HCFS),
ohci->disabled ? " (disabled)" : ""
);
ohci->hcd.state);
ohci_dump (ohci, 1);
if (!ohci->disabled)
if (HCD_IS_RUNNING(ohci->hcd.state))
hc_reset (ohci);
remove_debug_files (ohci);
......@@ -649,8 +644,7 @@ static int hc_restart (struct ohci_hcd *ohci)
int temp;
int i;
ohci->disabled = 1;
ohci->sleeping = 0;
disable (ohci);
if (hcd_to_bus (&ohci->hcd)->root_hub)
usb_disconnect (&hcd_to_bus (&ohci->hcd)->root_hub);
......
......@@ -73,7 +73,7 @@ ohci_hub_status_data (struct usb_hcd *hcd, char *buf)
ports = roothub_a (ohci) & RH_A_NDP;
if (ports > MAX_ROOT_PORTS) {
if (ohci->disabled)
if (!HCD_IS_RUNNING(ohci->hcd.state))
return -ESHUTDOWN;
ohci_err (ohci, "bogus NDP=%d, rereads as NDP=%d\n",
ports, readl (&ohci->regs->roothub.a) & RH_A_NDP);
......
......@@ -117,7 +117,6 @@ ohci_pci_start (struct usb_hcd *hcd)
static int ohci_pci_suspend (struct usb_hcd *hcd, u32 state)
{
struct ohci_hcd *ohci = hcd_to_ohci (hcd);
unsigned long flags;
u16 cmd;
u32 tmp;
......@@ -129,16 +128,15 @@ static int ohci_pci_suspend (struct usb_hcd *hcd, u32 state)
/* act as if usb suspend can always be used */
ohci_dbg (ohci, "suspend to %d\n", state);
ohci->sleeping = 1;
/* First stop processing */
spin_lock_irqsave (&ohci->lock, flags);
spin_lock_irq (&ohci->lock);
ohci->hc_control &=
~(OHCI_CTRL_PLE|OHCI_CTRL_CLE|OHCI_CTRL_BLE|OHCI_CTRL_IE);
writel (ohci->hc_control, &ohci->regs->control);
writel (OHCI_INTR_SF, &ohci->regs->intrstatus);
(void) readl (&ohci->regs->intrstatus);
spin_unlock_irqrestore (&ohci->lock, flags);
spin_unlock_irq (&ohci->lock);
/* Wait a frame or two */
mdelay (1);
......@@ -156,10 +154,14 @@ static int ohci_pci_suspend (struct usb_hcd *hcd, u32 state)
&ohci->regs->intrenable);
/* Suspend chip and let things settle down a bit */
spin_lock_irq (&ohci->lock);
ohci->hc_control = OHCI_USB_SUSPEND;
writel (ohci->hc_control, &ohci->regs->control);
(void) readl (&ohci->regs->control);
mdelay (500); /* No schedule here ! */
spin_unlock_irq (&ohci->lock);
set_current_state (TASK_UNINTERRUPTIBLE);
schedule_timeout (HZ/2);
tmp = readl (&ohci->regs->control) | OHCI_CTRL_HCFS;
switch (tmp) {
......@@ -199,7 +201,6 @@ static int ohci_pci_resume (struct usb_hcd *hcd)
struct ohci_hcd *ohci = hcd_to_ohci (hcd);
int temp;
int retval = 0;
unsigned long flags;
#ifdef CONFIG_PMAC_PBOOK
{
......@@ -226,6 +227,7 @@ static int ohci_pci_resume (struct usb_hcd *hcd)
switch (temp) {
case OHCI_USB_RESET: // lost power
restart:
ohci_info (ohci, "USB restart\n");
retval = hc_restart (ohci);
break;
......@@ -235,31 +237,28 @@ static int ohci_pci_resume (struct usb_hcd *hcd)
ohci_info (ohci, "USB continue from %s wakeup\n",
(temp == OHCI_USB_SUSPEND)
? "host" : "remote");
/* we "should" only need RESUME if we're SUSPENDed ... */
ohci->hc_control = OHCI_USB_RESUME;
writel (ohci->hc_control, &ohci->regs->control);
(void) readl (&ohci->regs->control);
mdelay (20); /* no schedule here ! */
/* Some controllers (lucent) need a longer delay here */
mdelay (15);
/* Some controllers (lucent) need extra-long delays */
mdelay (35); /* no schedule here ! */
temp = readl (&ohci->regs->control);
temp = ohci->hc_control & OHCI_CTRL_HCFS;
if (temp != OHCI_USB_RESUME) {
ohci_err (ohci, "controller won't resume\n");
ohci->disabled = 1;
retval = -EIO;
break;
/* maybe we can reset */
goto restart;
}
/* Some chips likes being resumed first */
/* Then re-enable operations */
writel (OHCI_USB_OPER, &ohci->regs->control);
(void) readl (&ohci->regs->control);
mdelay (3);
/* Then re-enable operations */
spin_lock_irqsave (&ohci->lock, flags);
ohci->disabled = 0;
ohci->sleeping = 0;
spin_lock_irq (&ohci->lock);
ohci->hc_control = OHCI_CONTROL_INIT | OHCI_USB_OPER;
if (!ohci->ed_rm_list) {
if (ohci->ed_controltail)
......@@ -274,25 +273,22 @@ static int ohci_pci_resume (struct usb_hcd *hcd)
writel (OHCI_INTR_SF, &ohci->regs->intrstatus);
writel (OHCI_INTR_SF, &ohci->regs->intrenable);
/* Check for a pending done list */
writel (OHCI_INTR_WDH, &ohci->regs->intrdisable);
(void) readl (&ohci->regs->intrdisable);
spin_unlock_irqrestore (&ohci->lock, flags);
spin_unlock_irq (&ohci->lock);
#ifdef CONFIG_PMAC_PBOOK
if (_machine == _MACH_Pmac)
enable_irq (hcd->pdev->irq);
#endif
/* Check for a pending done list */
if (ohci->hcca->done_head)
dl_done_list (ohci, dl_reverse_done_list (ohci), NULL);
writel (OHCI_INTR_WDH, &ohci->regs->intrenable);
/* assume there are TDs on the bulk and control lists */
writel (OHCI_BLF | OHCI_CLF, &ohci->regs->cmdstatus);
// ohci_dump_status (ohci);
ohci_dbg (ohci, "sleeping = %d, disabled = %d\n",
ohci->sleeping, ohci->disabled);
break;
default:
......
......@@ -449,7 +449,7 @@ static void start_urb_unlink (struct ohci_hcd *ohci, struct ed *ed)
ohci->ed_rm_list = ed;
/* enable SOF interrupt */
if (!ohci->sleeping) {
if (HCD_IS_RUNNING (ohci->hcd.state)) {
writel (OHCI_INTR_SF, &ohci->regs->intrstatus);
writel (OHCI_INTR_SF, &ohci->regs->intrenable);
// flush those pci writes
......@@ -794,7 +794,16 @@ ed_halted (struct ohci_hcd *ohci, struct td *td, int cc, struct td *rev)
* looks odd ... that doesn't include protocol stalls
* (or maybe some other things)
*/
if (cc != TD_CC_STALL || !usb_pipecontrol (urb->pipe))
switch (cc) {
case TD_DATAUNDERRUN:
if ((urb->transfer_flags & URB_SHORT_NOT_OK) == 0)
break;
/* fallthrough */
case TD_CC_STALL:
if (usb_pipecontrol (urb->pipe))
break;
/* fallthrough */
default:
ohci_dbg (ohci,
"urb %p path %s ep%d%s %08x cc %d --> status %d\n",
urb, urb->dev->devpath,
......@@ -802,6 +811,7 @@ ed_halted (struct ohci_hcd *ohci, struct td *td, int cc, struct td *rev)
usb_pipein (urb->pipe) ? "in" : "out",
le32_to_cpu (td->hwINFO),
cc, cc_to_error [cc]);
}
return rev;
}
......@@ -871,7 +881,8 @@ finish_unlinks (struct ohci_hcd *ohci, u16 tick, struct pt_regs *regs)
/* only take off EDs that the HC isn't using, accounting for
* frame counter wraps.
*/
if (tick_before (tick, ed->tick) && !ohci->disabled) {
if (tick_before (tick, ed->tick)
&& HCD_IS_RUNNING(ohci->hcd.state)) {
last = &ed->ed_next;
continue;
}
......@@ -901,7 +912,7 @@ finish_unlinks (struct ohci_hcd *ohci, u16 tick, struct pt_regs *regs)
urb = td->urb;
urb_priv = td->urb->hcpriv;
if (urb_priv->state != URB_DEL) {
if (urb->status == -EINPROGRESS) {
prev = &td->hwNextTD;
continue;
}
......@@ -938,7 +949,7 @@ finish_unlinks (struct ohci_hcd *ohci, u16 tick, struct pt_regs *regs)
/* but if there's work queued, reschedule */
if (!list_empty (&ed->td_list)) {
if (!ohci->disabled && !ohci->sleeping)
if (HCD_IS_RUNNING(ohci->hcd.state))
ed_schedule (ohci, ed);
}
......@@ -947,7 +958,7 @@ finish_unlinks (struct ohci_hcd *ohci, u16 tick, struct pt_regs *regs)
}
/* maybe reenable control and bulk lists */
if (!ohci->disabled && !ohci->ed_rm_list) {
if (HCD_IS_RUNNING(ohci->hcd.state) && !ohci->ed_rm_list) {
u32 command = 0, control = 0;
if (ohci->ed_controltail) {
......
......@@ -314,13 +314,10 @@ typedef struct urb_priv {
struct ed *ed;
__u16 length; // # tds in this request
__u16 td_cnt; // tds already serviced
int state;
struct td *td [0]; // all TDs in this request
} urb_priv_t;
#define URB_DEL 1
#define TD_HASH_SIZE 64 /* power'o'two */
// sizeof (struct td) ~= 64 == 2^6 ...
#define TD_HASH_FUNC(td_dma) ((td_dma ^ (td_dma >> 6)) % TD_HASH_SIZE)
......@@ -365,8 +362,6 @@ struct ohci_hcd {
/*
* driver state
*/
int disabled; /* e.g. got a UE, we're hung */
int sleeping;
int load [NUM_INTS];
u32 hc_control; /* copy of hc control reg */
......
......@@ -28,6 +28,7 @@ comment "Input core support is needed for USB HID input layer or HIDBP support"
config USB_HIDINPUT
bool "HID input layer support"
default y
depends on INPUT && USB_HID
help
Say Y here if you want to use a USB keyboard, mouse or joystick,
......
......@@ -182,14 +182,14 @@ struct keyspan_usa90_portStatusMessage
// MSR bits
#define MSR_dCTS 0x01 // CTS has changed since last report
#define MSR_dDSR 0x02
#define MSR_dRI 0x04
#define MSR_dDCD 0x08
#define MSR_CTS 0x10 // current state of CTS
#define MSR_DSR 0x20
#define MSR_RI 0x40
#define USA_MSR_dCTS 0x01 // CTS has changed since last report
#define USA_MSR_dDSR 0x02
#define USA_MSR_dRI 0x04
#define USA_MSR_dDCD 0x08
#define USA_MSR_CTS 0x10 // current state of CTS
#define USA_MSR_DSR 0x20
#define USA_USA_MSR_RI 0x40
#define MSR_DCD 0x80
// ie: the maximum length of an endpoint buffer
......
......@@ -778,9 +778,6 @@ static int visor_probe (struct usb_serial *serial, const struct usb_device_id *i
serial->dev->actconfig->desc.bConfigurationValue);
return -ENODEV;
}
dbg("%s - reset config", __FUNCTION__);
retval = usb_reset_configuration (serial->dev);
if (id->driver_info) {
startup = (void *)id->driver_info;
......
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