Commit 7fcc2c87 authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman

Merge kroah.com:/home/greg/linux/BK/bleeding_edge-2.5

into kroah.com:/home/greg/linux/BK/gregkh-2.5
parents 94eda096 9c5e6f5a
......@@ -41,17 +41,13 @@ SPECIFIC DEVICES SUPPORTED
ConnectTech WhiteHEAT 4 port converter
ConnectTech has been very forthcoming with information about their
device, including providing a unit to test with. This driver will end up
being fully supported.
device, including providing a unit to test with.
Current status:
The device's firmware is downloaded on connection, the new firmware
runs properly and all four ports are successfully recognized and connected.
Data can be sent and received through the device on all ports.
Hardware flow control needs to be implemented.
The driver is officially supported by Connect Tech Inc.
http://www.connecttech.com
For any questions or problems with this driver, please contact Greg
Kroah-Hartman at greg@kroah.com
For any questions or problems with this driver, please contact
Stuart MacDonald at stuartm@connecttech.com
HandSpring Visor, Palm USB, and Clié USB driver
......
......@@ -1830,6 +1830,14 @@ L: linux-usb-devel@lists.sourceforge.net
W: http://www.kroah.com/linux/
S: Maintained
USB SERIAL WHITEHEAT DRIVER
P: Stuart MacDonald
M: stuartm@connecttech.com
L: linux-usb-users@lists.sourceforge.net
L: linux-usb-devel@lists.sourceforge.net
W: http://www.connecttech.com
S: Supported
USB SUBSYSTEM
P: Greg Kroah-Hartman
M: greg@kroah.com
......
......@@ -1142,6 +1142,7 @@ int usb_new_device(struct usb_device *dev, struct device *parent)
struct usb_interface_descriptor *desc = interface->altsetting;
interface->dev.parent = &dev->dev;
interface->dev.driver = NULL;
interface->dev.bus = &usb_bus_type;
sprintf (&interface->dev.bus_id[0], "%d-%s:%d",
dev->bus->busnum, dev->devpath,
......
......@@ -79,7 +79,7 @@ static void dbg_hcc_params (struct ehci_hcd *ehci, char *label)
if (HCC_EXT_CAPS (params)) {
// EHCI 0.96 ... could interpret these (legacy?)
dbg ("%s extended capabilities at pci %d",
dbg ("%s extended capabilities at pci %2x",
label, HCC_EXT_CAPS (params));
}
if (HCC_ISOC_CACHE (params)) {
......@@ -546,6 +546,18 @@ show_registers (struct device *dev, char *buf, size_t count, loff_t off)
next += temp;
}
#ifdef EHCI_STATS
temp = snprintf (next, size, "irq normal %ld err %ld reclaim %ld\n",
ehci->stats.normal, ehci->stats.error, ehci->stats.reclaim);
size -= temp;
next += temp;
temp = snprintf (next, size, "complete %ld unlink %ld qpatch %ld\n",
ehci->stats.complete, ehci->stats.unlink, ehci->stats.qpatch);
size -= temp;
next += temp;
#endif
spin_unlock_irqrestore (&ehci->lock, flags);
return count - size;
......
......@@ -63,8 +63,7 @@
* First was PCMCIA, like ISA; then CardBus, which is PCI.
* Next comes "CardBay", using USB 2.0 signals.
*
* Contains additional contributions by: Brad Hards, Rory Bolt, ...
*
* Contains additional contributions by Brad Hards, Rory Bolt, and others.
* Special thanks to Intel and VIA for providing host controllers to
* test this driver on, and Cypress (including In-System Design) for
* providing early devices for those host controllers to talk to!
......@@ -93,14 +92,20 @@
* 2001-June Works with usb-storage and NEC EHCI on 2.4
*/
#define DRIVER_VERSION "2002-Aug-28"
#define DRIVER_VERSION "2002-Sep-23"
#define DRIVER_AUTHOR "David Brownell"
#define DRIVER_DESC "USB 2.0 'Enhanced' Host Controller (EHCI) Driver"
static const char hcd_name [] = "ehci-hcd";
// #define EHCI_VERBOSE_DEBUG
// #define have_split_iso
#ifdef DEBUG
#define EHCI_STATS
#endif
#define INTR_AUTOMAGIC /* to be removed later in 2.5 */
/* magic numbers that can affect system performance */
......@@ -118,6 +123,12 @@ static int log2_irq_thresh = 0; // 0 to 6
MODULE_PARM (log2_irq_thresh, "i");
MODULE_PARM_DESC (log2_irq_thresh, "log2 IRQ latency, 1-64 microframes");
/* allow irqs at least every N URB completions */
static int max_completions = 16;
MODULE_PARM (max_completions, "i");
MODULE_PARM_DESC (max_completions,
"limit for urb completions called with irqs disenabled");
#define INTR_MASK (STS_IAA | STS_FATAL | STS_ERR | STS_INT)
/*-------------------------------------------------------------------------*/
......@@ -426,11 +437,10 @@ static int ehci_start (struct usb_hcd *hcd)
/* PCI Serial Bus Release Number is at 0x60 offset */
pci_read_config_byte (hcd->pdev, 0x60, &tempbyte);
temp = readw (&ehci->caps->hci_version);
info ("USB %x.%x support enabled, EHCI rev %x.%02x",
((tempbyte & 0xf0)>>4),
(tempbyte & 0x0f),
temp >> 8,
temp & 0xff);
info ("USB %x.%x support enabled, EHCI rev %x.%02x, %s %s",
((tempbyte & 0xf0)>>4), (tempbyte & 0x0f),
temp >> 8, temp & 0xff,
hcd_name, DRIVER_VERSION);
/*
* From here on, khubd concurrently accesses the root
......@@ -441,11 +451,7 @@ static int ehci_start (struct usb_hcd *hcd)
*/
usb_connect (udev);
udev->speed = USB_SPEED_HIGH;
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,32)
if (usb_new_device (udev) != 0) {
#else
if (usb_register_root_hub (udev, &ehci->hcd.pdev->dev) != 0) {
#endif
if (hcd_register_root (hcd) != 0) {
if (hcd->state == USB_STATE_RUNNING)
ehci_ready (ehci);
ehci_reset (ehci);
......@@ -487,6 +493,13 @@ static void ehci_stop (struct usb_hcd *hcd)
ehci_tasklet ((unsigned long) ehci);
ehci_mem_cleanup (ehci);
#ifdef EHCI_STATS
dbg ("irq normal %ld err %ld reclaim %ld",
ehci->stats.normal, ehci->stats.error, ehci->stats.reclaim);
dbg ("complete %ld unlink %ld qpatch %ld",
ehci->stats.complete, ehci->stats.unlink, ehci->stats.qpatch);
#endif
dbg_status (ehci, "ehci_stop completed", readl (&ehci->regs->status));
}
......@@ -591,21 +604,16 @@ dbg ("%s: resume port %d", hcd_to_bus (hcd)->bus_name, i);
static void ehci_tasklet (unsigned long param)
{
struct ehci_hcd *ehci = (struct ehci_hcd *) param;
unsigned long flags;
// FIXME don't pass flags; on sparc they aren't really flags.
// qh_completions can just leave irqs blocked,
// then have scan_async() allow IRQs if it's very busy
spin_lock_irqsave (&ehci->lock, flags);
spin_lock_irq (&ehci->lock);
if (ehci->reclaim_ready)
flags = end_unlink_async (ehci, flags);
flags = scan_async (ehci, flags);
end_unlink_async (ehci);
scan_async (ehci);
if (ehci->next_uframe != -1)
flags = scan_periodic (ehci, flags);
scan_periodic (ehci);
spin_unlock_irqrestore (&ehci->lock, flags);
spin_unlock_irq (&ehci->lock);
}
/*-------------------------------------------------------------------------*/
......@@ -639,11 +647,17 @@ static void ehci_irq (struct usb_hcd *hcd)
/* INT, ERR, and IAA interrupt rates can be throttled */
/* normal [4.15.1.2] or error [4.15.1.1] completion */
if (likely ((status & (STS_INT|STS_ERR)) != 0))
if (likely ((status & (STS_INT|STS_ERR)) != 0)) {
if (likely ((status & STS_ERR) == 0))
COUNT (ehci->stats.normal);
else
COUNT (ehci->stats.error);
bh = 1;
}
/* complete the unlinking of some qh [4.15.2.3] */
if (status & STS_IAA) {
COUNT (ehci->stats.reclaim);
ehci->reclaim_ready = 1;
bh = 1;
}
......@@ -765,10 +779,10 @@ static int ehci_urb_dequeue (struct usb_hcd *hcd, struct urb *urb)
spin_lock_irqsave (&ehci->lock, flags);
if (qh->qh_state == QH_STATE_LINKED) {
/* messy, can spin or block a microframe ... */
flags = intr_deschedule (ehci, qh, 1, flags);
intr_deschedule (ehci, qh, 1);
/* qh_state == IDLE */
}
flags = qh_completions (ehci, qh, flags);
qh_completions (ehci, qh);
/* reschedule QH iff another request is queued */
if (!list_empty (&qh->qtd_list)
......@@ -881,8 +895,6 @@ static void ehci_free_config (struct usb_hcd *hcd, struct usb_device *udev)
/*-------------------------------------------------------------------------*/
static const char hcd_name [] = "ehci-hcd";
static const struct hc_driver ehci_driver = {
.description = hcd_name,
......
......@@ -239,7 +239,8 @@ static int ehci_hub_control (
/* whoever resets must GetPortStatus to complete it!! */
if ((temp & PORT_RESET)
&& jiffies > ehci->reset_done [wIndex]) {
&& time_after (jiffies,
ehci->reset_done [wIndex])) {
status |= 1 << USB_PORT_FEAT_C_RESET;
/* force reset to complete */
......
......@@ -158,16 +158,13 @@ static inline void qtd_copy_status (struct urb *urb, size_t length, u32 token)
}
}
/* urb->lock ignored from here on (hcd is done with urb) */
static unsigned long ehci_urb_done (
struct ehci_hcd *ehci,
struct urb *urb,
unsigned long flags
) {
static void ehci_urb_done (struct ehci_hcd *ehci, struct urb *urb)
{
#ifdef INTR_AUTOMAGIC
struct urb *resubmit = 0;
struct usb_device *dev = 0;
static int ehci_urb_enqueue (struct usb_hcd *, struct urb *, int);
#endif
if (likely (urb->hcpriv != 0)) {
......@@ -199,8 +196,15 @@ static unsigned long ehci_urb_done (
urb->status = 0;
}
if (likely (urb->status == 0))
COUNT (ehci->stats.complete);
else if (urb->status == -ECONNRESET || urb->status == -ENOENT)
COUNT (ehci->stats.unlink);
else
COUNT (ehci->stats.error);
/* complete() can reenter this HCD */
spin_unlock_irqrestore (&ehci->lock, flags);
spin_unlock (&ehci->lock);
usb_hcd_giveback_urb (&ehci->hcd, urb);
#ifdef INTR_AUTOMAGIC
......@@ -222,24 +226,25 @@ static unsigned long ehci_urb_done (
}
#endif
spin_lock_irqsave (&ehci->lock, flags);
return flags;
spin_lock (&ehci->lock);
}
/*
* Process and free completed qtds for a qh, returning URBs to drivers.
* Chases up to qh->hw_current, returns irqsave flags (maybe modified).
* Chases up to qh->hw_current. Returns number of completions called,
* indicating how much "real" work we did.
*/
static unsigned long
qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh, unsigned long flags)
static unsigned
qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh)
{
struct ehci_qtd *qtd, *last;
struct list_head *next, *qtd_list = &qh->qtd_list;
int unlink = 0, halted = 0;
unsigned count = 0;
if (unlikely (list_empty (qtd_list)))
return flags;
return count;
/* scan QTDs till end of list, or we reach an active one */
for (qtd = list_entry (qtd_list->next, struct ehci_qtd, qtd_list),
......@@ -252,8 +257,10 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh, unsigned long flags)
/* clean up any state from previous QTD ...*/
if (last) {
if (likely (last->urb != urb))
flags = ehci_urb_done (ehci, last->urb, flags);
if (likely (last->urb != urb)) {
ehci_urb_done (ehci, last->urb);
count++;
}
/* qh overlays can have HC's old cached copies of
* next qtd ptrs, if an URB was queued afterwards.
......@@ -262,6 +269,7 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh, unsigned long flags)
&& last->hw_next != qh->hw_qtd_next) {
qh->hw_alt_next = last->hw_alt_next;
qh->hw_qtd_next = last->hw_next;
COUNT (ehci->stats.qpatch);
}
ehci_qtd_free (ehci, last);
......@@ -347,7 +355,8 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh, unsigned long flags)
/* last urb's completion might still need calling */
if (likely (last != 0)) {
flags = ehci_urb_done (ehci, last->urb, flags);
ehci_urb_done (ehci, last->urb);
count++;
ehci_qtd_free (ehci, last);
}
......@@ -357,7 +366,7 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh, unsigned long flags)
struct ehci_qtd, qtd_list));
}
return flags;
return count;
}
/*-------------------------------------------------------------------------*/
......@@ -890,8 +899,7 @@ submit_async (
/* the async qh for the qtds being reclaimed are now unlinked from the HC */
/* caller must not own ehci->lock */
static unsigned long
end_unlink_async (struct ehci_hcd *ehci, unsigned long flags)
static void end_unlink_async (struct ehci_hcd *ehci)
{
struct ehci_qh *qh = ehci->reclaim;
......@@ -903,18 +911,15 @@ end_unlink_async (struct ehci_hcd *ehci, unsigned long flags)
ehci->reclaim = 0;
ehci->reclaim_ready = 0;
flags = qh_completions (ehci, qh, flags);
qh_completions (ehci, qh);
if (!list_empty (&qh->qtd_list)
&& HCD_IS_RUNNING (ehci->hcd.state))
qh_link_async (ehci, qh);
else
qh_put (ehci, qh); // refcount from async list
return flags;
}
/* makes sure the async qh will become idle */
/* caller must own ehci->lock */
......@@ -944,12 +949,14 @@ static void start_unlink_async (struct ehci_hcd *ehci, struct ehci_qh *qh)
if (unlikely (qh == ehci->async && qh->qh_next.qh == qh)) {
/* can't get here without STS_ASS set */
if (ehci->hcd.state != USB_STATE_HALT) {
if (cmd & CMD_PSE) {
writel (cmd & ~CMD_ASE, &ehci->regs->command);
(void) handshake (&ehci->regs->status,
STS_ASS, 0, 150);
} else
ehci_ready (ehci);
writel (cmd & ~CMD_ASE, &ehci->regs->command);
(void) handshake (&ehci->regs->status, STS_ASS, 0, 150);
#if 0
// one VT8235 system wants to die with STS_FATAL
// unless this qh is leaked here. others seem ok...
qh = qh_get (qh);
dbg_qh ("async/off", ehci, qh);
#endif
}
qh->qh_next.qh = ehci->async = 0;
......@@ -986,13 +993,15 @@ static void start_unlink_async (struct ehci_hcd *ehci, struct ehci_qh *qh)
/*-------------------------------------------------------------------------*/
static unsigned long
scan_async (struct ehci_hcd *ehci, unsigned long flags)
static void
scan_async (struct ehci_hcd *ehci)
{
struct ehci_qh *qh;
unsigned count;
rescan:
qh = ehci->async;
count = 0;
if (likely (qh != 0)) {
do {
/* clean any finished work for this qh */
......@@ -1001,13 +1010,16 @@ scan_async (struct ehci_hcd *ehci, unsigned long flags)
qh = qh_get (qh);
/* concurrent unlink could happen here */
flags = qh_completions (ehci, qh, flags);
count += qh_completions (ehci, qh);
qh_put (ehci, qh);
}
/* unlink idle entries, reducing HC PCI usage as
* well as HCD schedule-scanning costs. removing
* the last qh is deferred, since it's costly.
*
* FIXME don't unlink idle entries so quickly; it
* can penalize (common) half duplex protocols.
*/
if (list_empty (&qh->qtd_list) && !ehci->reclaim) {
if (qh->qh_next.qh != qh) {
......@@ -1020,10 +1032,18 @@ scan_async (struct ehci_hcd *ehci, unsigned long flags)
jiffies + EHCI_ASYNC_JIFFIES);
}
}
/* keep latencies down: let any irqs in */
if (count > max_completions) {
spin_unlock_irq (&ehci->lock);
cpu_relax ();
spin_lock_irq (&ehci->lock);
goto rescan;
}
qh = qh->qh_next.qh;
if (!qh) /* unlinked? */
goto rescan;
} while (qh != ehci->async);
}
return flags;
}
......@@ -222,11 +222,10 @@ static int disable_periodic (struct ehci_hcd *ehci)
// FIXME microframe periods not yet handled
static unsigned long intr_deschedule (
static void intr_deschedule (
struct ehci_hcd *ehci,
struct ehci_qh *qh,
int wait,
unsigned long flags
int wait
) {
int status;
unsigned frame = qh->start;
......@@ -256,10 +255,8 @@ static unsigned long intr_deschedule (
*/
if (((ehci_get_frame (&ehci->hcd) - frame) % qh->period) == 0) {
if (wait) {
spin_unlock_irqrestore (&ehci->lock, flags);
udelay (125);
qh->hw_next = EHCI_LIST_END;
spin_lock_irqsave (&ehci->lock, flags);
} else {
/* we may not be IDLE yet, but if the qh is empty
* the race is very short. then if qh also isn't
......@@ -276,10 +273,9 @@ static unsigned long intr_deschedule (
hcd_to_bus (&ehci->hcd)->bandwidth_allocated -=
(qh->usecs + qh->c_usecs) / qh->period;
vdbg ("descheduled qh %p, per = %d frame = %d count = %d, urbs = %d",
dbg ("descheduled qh %p, period = %d frame = %d count = %d, urbs = %d",
qh, qh->period, frame,
atomic_read (&qh->refcount), ehci->periodic_sched);
return flags;
}
static int check_period (
......@@ -414,7 +410,7 @@ static int qh_schedule (struct ehci_hcd *ehci, struct ehci_qh *qh)
/* stuff into the periodic schedule */
qh->qh_state = QH_STATE_LINKED;
dbg ("qh %p usecs %d/%d period %d.0 starting %d.%d (gap %d)",
dbg ("scheduled qh %p usecs %d/%d period %d.0 starting %d.%d (gap %d)",
qh, qh->usecs, qh->c_usecs,
qh->period, frame, uframe, qh->gap_uf);
do {
......@@ -495,29 +491,30 @@ static int intr_submit (
return status;
}
static unsigned long
static unsigned
intr_complete (
struct ehci_hcd *ehci,
unsigned frame,
struct ehci_qh *qh,
unsigned long flags /* caller owns ehci->lock ... */
struct ehci_qh *qh
) {
unsigned count;
/* nothing to report? */
if (likely ((qh->hw_token & __constant_cpu_to_le32 (QTD_STS_ACTIVE))
!= 0))
return flags;
return 0;
if (unlikely (list_empty (&qh->qtd_list))) {
dbg ("intr qh %p no TDs?", qh);
return flags;
return 0;
}
/* handle any completions */
flags = qh_completions (ehci, qh, flags);
count = qh_completions (ehci, qh);
if (unlikely (list_empty (&qh->qtd_list)))
flags = intr_deschedule (ehci, qh, 0, flags);
intr_deschedule (ehci, qh, 0);
return flags;
return count;
}
/*-------------------------------------------------------------------------*/
......@@ -866,12 +863,11 @@ itd_schedule (struct ehci_hcd *ehci, struct urb *urb)
#define ISO_ERRS (EHCI_ISOC_BUF_ERR | EHCI_ISOC_BABBLE | EHCI_ISOC_XACTERR)
static unsigned long
static unsigned
itd_complete (
struct ehci_hcd *ehci,
struct ehci_itd *itd,
unsigned uframe,
unsigned long flags
unsigned uframe
) {
struct urb *urb = itd->urb;
struct usb_iso_packet_descriptor *desc;
......@@ -909,7 +905,7 @@ itd_complete (
/* handle completion now? */
if ((itd->index + 1) != urb->number_of_packets)
return flags;
return 0;
/*
* Always give the urb back to the driver ... expect it to submit
......@@ -924,16 +920,17 @@ itd_complete (
if (urb->status == -EINPROGRESS)
urb->status = 0;
spin_unlock_irqrestore (&ehci->lock, flags);
/* complete() can reenter this HCD */
spin_unlock (&ehci->lock);
usb_hcd_giveback_urb (&ehci->hcd, urb);
spin_lock_irqsave (&ehci->lock, flags);
spin_lock (&ehci->lock);
/* defer stopping schedule; completion can submit */
ehci->periodic_sched--;
if (!ehci->periodic_sched)
(void) disable_periodic (ehci);
return flags;
return 1;
}
/*-------------------------------------------------------------------------*/
......@@ -945,10 +942,6 @@ static int itd_submit (struct ehci_hcd *ehci, struct urb *urb, int mem_flags)
dbg ("itd_submit urb %p", urb);
/* NOTE DMA mapping assumes this ... */
if (urb->iso_frame_desc [0].offset != 0)
return -EINVAL;
/* allocate ITDs w/o locking anything */
status = itd_urb_transaction (ehci, urb, mem_flags);
if (status < 0)
......@@ -979,10 +972,11 @@ static int itd_submit (struct ehci_hcd *ehci, struct urb *urb, int mem_flags)
/*-------------------------------------------------------------------------*/
static unsigned long
scan_periodic (struct ehci_hcd *ehci, unsigned long flags)
static void
scan_periodic (struct ehci_hcd *ehci)
{
unsigned frame, clock, now_uframe, mod;
unsigned count = 0;
mod = ehci->periodic_size << 3;
......@@ -1005,6 +999,14 @@ scan_periodic (struct ehci_hcd *ehci, unsigned long flags)
u32 type, *hw_p;
unsigned uframes;
/* keep latencies down: let any irqs in */
if (count > max_completions) {
spin_unlock_irq (&ehci->lock);
cpu_relax ();
count = 0;
spin_lock_irq (&ehci->lock);
}
restart:
/* scan schedule to _before_ current frame index */
if (frame == clock)
......@@ -1028,8 +1030,8 @@ scan_periodic (struct ehci_hcd *ehci, unsigned long flags)
last = (q.qh->hw_next == EHCI_LIST_END);
temp = q.qh->qh_next;
type = Q_NEXT_TYPE (q.qh->hw_next);
flags = intr_complete (ehci, frame,
qh_get (q.qh), flags);
count += intr_complete (ehci, frame,
qh_get (q.qh));
qh_put (ehci, q.qh);
q = temp;
break;
......@@ -1061,8 +1063,8 @@ scan_periodic (struct ehci_hcd *ehci, unsigned long flags)
type = Q_NEXT_TYPE (*hw_p);
/* might free q.itd ... */
flags = itd_complete (ehci,
temp.itd, uf, flags);
count += itd_complete (ehci,
temp.itd, uf);
break;
}
}
......@@ -1078,7 +1080,7 @@ scan_periodic (struct ehci_hcd *ehci, unsigned long flags)
#ifdef have_split_iso
case Q_TYPE_SITD:
last = (q.sitd->hw_next == EHCI_LIST_END);
flags = sitd_complete (ehci, q.sitd, flags);
sitd_complete (ehci, q.sitd);
type = Q_NEXT_TYPE (q.sitd->hw_next);
// FIXME unlink SITD after split completes
......@@ -1124,5 +1126,4 @@ scan_periodic (struct ehci_hcd *ehci, unsigned long flags)
} else
frame = (frame + 1) % ehci->periodic_size;
}
return flags;
}
......@@ -21,6 +21,23 @@
/* definitions used for the EHCI driver */
/* statistics can be kept for for tuning/monitoring */
struct ehci_stats {
/* irq usage */
unsigned long normal;
unsigned long error;
unsigned long reclaim;
/* termination of urbs from core */
unsigned long complete;
unsigned long unlink;
/* qhs patched to recover from td queueing race
* (can avoid by using 'dummy td', allowing fewer irqs)
*/
unsigned long qpatch;
};
/* ehci_hcd->lock guards shared data against other CPUs:
* ehci_hcd: async, reclaim, periodic (and shadow), ...
* hcd_dev: ep[]
......@@ -72,6 +89,13 @@ struct ehci_hcd { /* one per controller */
struct pci_pool *sitd_pool; /* sitd per split iso urb */
struct timer_list watchdog;
#ifdef EHCI_STATS
struct ehci_stats stats;
# define COUNT(x) do { (x)++; } while (0)
#else
# define COUNT(x) do {} while (0)
#endif
};
/* unwrap an HCD pointer to get an EHCI_HCD pointer */
......@@ -400,10 +424,22 @@ struct ehci_fstn {
#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 */
// hcd_to_bus() eventually moves to hcd.h on 2.5 too
static inline struct usb_bus *hcd_to_bus (struct usb_hcd *hcd)
{ return &hcd->self; }
// ... as does hcd_register_root()
static inline int hcd_register_root (struct usb_hcd *hcd)
{
return usb_register_root_hub (
hcd_to_bus (hcd)->root_hub, &hcd->pdev->dev);
}
#define SUBMIT_URB(urb,mem_flags) usb_submit_urb(urb,mem_flags)
......
......@@ -92,6 +92,7 @@
#endif
#include <linux/usb.h>
#include <linux/version.h>
#include "../core/hcd.h"
#include <asm/io.h>
......@@ -108,7 +109,7 @@
* - lots more testing!!
*/
#define DRIVER_VERSION "2002-Sep-03"
#define DRIVER_VERSION "2002-Sep-17"
#define DRIVER_AUTHOR "Roman Weissgaerber, David Brownell"
#define DRIVER_DESC "USB 1.1 'Open' Host Controller (OHCI) Driver"
......@@ -318,9 +319,6 @@ ohci_free_config (struct usb_hcd *hcd, struct usb_device *udev)
struct hcd_dev *dev = (struct hcd_dev *) udev->hcpriv;
int i;
unsigned long flags;
#ifdef DEBUG
int rescans = 0;
#endif
rescan:
/* free any eds, and dummy tds, still hanging around */
......@@ -340,16 +338,18 @@ ohci_free_config (struct usb_hcd *hcd, struct usb_device *udev)
td_free (ohci, ed->dummy);
break;
default:
#ifdef DEBUG
err ("illegal ED %d state in free_config, %d",
err ("%s-%s ed %p (#%d) not unlinked; disconnect() bug? %d",
ohci->hcd.self.bus_name, udev->devpath, ed,
i, ed->state);
#endif
/* ED_OPER: some driver disconnect() is broken,
* it didn't even start its unlinks much less wait
* for their completions.
* OTHERWISE: hcd bug, ed is garbage
*
* ... we can't recycle this memory in either case,
* so just leak it to avoid oopsing.
*/
BUG ();
continue;
}
ed_free (ohci, ed);
}
......@@ -360,13 +360,9 @@ ohci_free_config (struct usb_hcd *hcd, struct usb_device *udev)
#ifdef DEBUG
/* a driver->disconnect() returned before its unlinks completed? */
if (in_interrupt ()) {
dbg ("WARNING: spin in interrupt; driver->disconnect() bug");
dbg ("dev usb-%s-%s ep 0x%x",
warn ("disconnect() bug for dev usb-%s-%s ep 0x%x",
ohci->hcd.self.bus_name, udev->devpath, i);
}
BUG_ON (!(readl (&ohci->regs->intrenable) & OHCI_INTR_SF));
BUG_ON (rescans >= 2); /* HWBUG */
rescans++;
#endif
spin_unlock_irqrestore (&ohci->lock, flags);
......
This diff is collapsed.
......@@ -112,3 +112,13 @@ CONFIG_USB_SPEEDTCH
For more information, see Johan Verrept's webpages at
<http://linux-usb.sourceforge.net/SpeedTouch/>.
CONFIG_USB_LCD
Say Y here if you want to connect an USBLCD to your computer's
USB port. The USBLCD is a small USB interface board for
alphanumeric LCD modules. See <http://www.usblcd.de> for more
information.
This code is also available as a module ( = code which can be
inserted in and removed from the running kernel whenever you want).
The module will be called usblcd.o. If you want to compile it as
a module, say M here and read <file:Documentation/modules.txt>.
/*****************************************************************************
* USBLCD Kernel Driver *
* See http://www.usblcd.de for Hardware and Documentation. *
* Version 1.01 *
* Version 1.03 *
* (C) 2002 Adams IT Services <info@usblcd.de> *
* *
* This file is licensed under the GPL. See COPYING in the package. *
......@@ -18,7 +18,7 @@
#include <asm/uaccess.h>
#include <linux/usb.h>
#define DRIVER_VERSION "USBLCD Driver Version 1.01"
#define DRIVER_VERSION "USBLCD Driver Version 1.03"
#define USBLCD_MINOR 144
......@@ -26,7 +26,7 @@
#define IOCTL_GET_DRV_VERSION 2
/* stall/wait timeout for USBLCD */
#define NAK_TIMEOUT (HZ)
#define NAK_TIMEOUT (10*HZ)
#define IBUF_SIZE 0x1000
#define OBUF_SIZE 0x10000
......@@ -318,7 +318,7 @@ static void disconnect_lcd(struct usb_interface *intf)
}
static struct usb_device_id id_table [] = {
{ .idVendor = 0x1212, .match_flags = USB_DEVICE_ID_MATCH_VENDOR, },
{ .idVendor = 0x10D2, .match_flags = USB_DEVICE_ID_MATCH_VENDOR, },
{},
};
......
......@@ -232,6 +232,7 @@ struct usb_serial_device_type {
extern int usb_serial_register(struct usb_serial_device_type *new_device);
extern void usb_serial_deregister(struct usb_serial_device_type *device);
extern void usb_serial_port_softint(void *private);
extern int usb_serial_probe(struct usb_interface *iface, const struct usb_device_id *id);
extern void usb_serial_disconnect(struct usb_interface *iface);
......
......@@ -498,7 +498,7 @@ int ezusb_writememory (struct usb_serial *serial, int address, unsigned char *da
return -ENOMEM;
}
memcpy (transfer_buffer, data, length);
result = usb_control_msg (serial->dev, usb_sndctrlpipe(serial->dev, 0), bRequest, 0x40, address, 0, transfer_buffer, length, 300);
result = usb_control_msg (serial->dev, usb_sndctrlpipe(serial->dev, 0), bRequest, 0x40, address, 0, transfer_buffer, length, 3*HZ);
kfree (transfer_buffer);
return result;
}
......@@ -557,12 +557,11 @@ static int serial_open (struct tty_struct *tty, struct file * filp)
retval = serial->type->open(port, filp);
else
retval = generic_open(port, filp);
}
if (retval) {
port->open_count = 0;
if (serial->type->owner)
__MOD_DEC_USE_COUNT(serial->type->owner);
if (retval) {
port->open_count = 0;
if (serial->type->owner)
__MOD_DEC_USE_COUNT(serial->type->owner);
}
}
up (&port->sem);
......@@ -1091,6 +1090,8 @@ static void generic_write_bulk_callback (struct urb *urb)
return;
}
usb_serial_port_softint((void *)port);
queue_task(&port->tqueue, &tq_immediate);
mark_bh(IMMEDIATE_BH);
......@@ -1109,14 +1110,18 @@ static void generic_shutdown (struct usb_serial *serial)
}
}
static void port_softint(void *private)
void usb_serial_port_softint(void *private)
{
struct usb_serial_port *port = (struct usb_serial_port *)private;
struct usb_serial *serial = get_usb_serial (port, __FUNCTION__);
struct usb_serial *serial;
struct tty_struct *tty;
dbg("%s - port %d", __FUNCTION__, port->number);
if (!port)
return;
serial = get_usb_serial (port, __FUNCTION__);
if (!serial)
return;
......@@ -1400,7 +1405,7 @@ int usb_serial_probe(struct usb_interface *interface,
port->number = i + serial->minor;
port->serial = serial;
port->magic = USB_SERIAL_PORT_MAGIC;
port->tqueue.routine = port_softint;
port->tqueue.routine = usb_serial_port_softint;
port->tqueue.data = port;
init_MUTEX (&port->sem);
}
......@@ -1690,6 +1695,7 @@ EXPORT_SYMBOL(usb_serial_register);
EXPORT_SYMBOL(usb_serial_deregister);
EXPORT_SYMBOL(usb_serial_probe);
EXPORT_SYMBOL(usb_serial_disconnect);
EXPORT_SYMBOL(usb_serial_port_softint);
#ifdef USES_EZUSB_FUNCTIONS
EXPORT_SYMBOL(ezusb_writememory);
EXPORT_SYMBOL(ezusb_set_reset);
......
This diff is collapsed.
This diff is collapsed.
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -70,7 +70,7 @@ datafab_bulk_read(struct us_data *us, unsigned char *data, unsigned int len) {
unsigned int act_len; /* ignored */
if (len == 0)
return USB_STOR_TRANSPORT_GOOD;
return USB_STOR_XFER_GOOD;
US_DEBUGP("datafab_bulk_read: len = %d\n", len);
return usb_storage_raw_bulk(us, SCSI_DATA_READ, data, len, &act_len);
......@@ -82,7 +82,7 @@ datafab_bulk_write(struct us_data *us, unsigned char *data, unsigned int len) {
unsigned int act_len; /* ignored */
if (len == 0)
return USB_STOR_TRANSPORT_GOOD;
return USB_STOR_XFER_GOOD;
US_DEBUGP("datafab_bulk_write: len = %d\n", len);
return usb_storage_raw_bulk(us, SCSI_DATA_WRITE, data, len, &act_len);
......@@ -144,12 +144,12 @@ static int datafab_read_data(struct us_data *us,
// send the read command
result = datafab_bulk_write(us, command, sizeof(command));
if (result != USB_STOR_TRANSPORT_GOOD)
if (result != USB_STOR_XFER_GOOD)
goto leave;
// read the result
result = datafab_bulk_read(us, ptr, len);
if (result != USB_STOR_TRANSPORT_GOOD)
if (result != USB_STOR_XFER_GOOD)
goto leave;
sectors -= thistime;
......@@ -171,7 +171,7 @@ static int datafab_read_data(struct us_data *us,
leave:
if (use_sg)
kfree(buffer);
return result;
return USB_STOR_TRANSPORT_ERROR;
}
......@@ -243,17 +243,17 @@ static int datafab_write_data(struct us_data *us,
// send the command
result = datafab_bulk_write(us, command, sizeof(command));
if (result != USB_STOR_TRANSPORT_GOOD)
if (result != USB_STOR_XFER_GOOD)
goto leave;
// send the data
result = datafab_bulk_write(us, ptr, len);
if (result != USB_STOR_TRANSPORT_GOOD)
if (result != USB_STOR_XFER_GOOD)
goto leave;
// read the result
result = datafab_bulk_read(us, reply, sizeof(reply));
if (result != USB_STOR_TRANSPORT_GOOD)
if (result != USB_STOR_XFER_GOOD)
goto leave;
if (reply[0] != 0x50 && reply[1] != 0) {
......@@ -280,7 +280,7 @@ static int datafab_write_data(struct us_data *us,
leave:
if (use_sg)
kfree(buffer);
return result;
return USB_STOR_TRANSPORT_ERROR;
}
......@@ -308,11 +308,11 @@ static int datafab_determine_lun(struct us_data *us,
command[5] = 0xa0;
rc = datafab_bulk_write(us, command, 8);
if (rc != USB_STOR_TRANSPORT_GOOD)
return rc;
if (rc != USB_STOR_XFER_GOOD)
return USB_STOR_TRANSPORT_ERROR;
rc = datafab_bulk_read(us, buf, sizeof(buf));
if (rc == USB_STOR_TRANSPORT_GOOD) {
if (rc == USB_STOR_XFER_GOOD) {
info->lun = 0;
return USB_STOR_TRANSPORT_GOOD;
}
......@@ -320,11 +320,11 @@ static int datafab_determine_lun(struct us_data *us,
command[5] = 0xb0;
rc = datafab_bulk_write(us, command, 8);
if (rc != USB_STOR_TRANSPORT_GOOD)
return rc;
if (rc != USB_STOR_XFER_GOOD)
return USB_STOR_TRANSPORT_ERROR;
rc = datafab_bulk_read(us, buf, sizeof(buf));
if (rc == USB_STOR_TRANSPORT_GOOD) {
if (rc == USB_STOR_XFER_GOOD) {
info->lun = 1;
return USB_STOR_TRANSPORT_GOOD;
}
......@@ -332,7 +332,7 @@ static int datafab_determine_lun(struct us_data *us,
wait_ms(20);
}
return USB_STOR_TRANSPORT_FAILED;
return USB_STOR_TRANSPORT_ERROR;
}
static int datafab_id_device(struct us_data *us,
......@@ -358,22 +358,23 @@ static int datafab_id_device(struct us_data *us,
command[5] += (info->lun << 4);
rc = datafab_bulk_write(us, command, 8);
if (rc != USB_STOR_TRANSPORT_GOOD)
return rc;
if (rc != USB_STOR_XFER_GOOD)
return USB_STOR_TRANSPORT_ERROR;
// we'll go ahead and extract the media capacity while we're here...
//
rc = datafab_bulk_read(us, reply, sizeof(reply));
if (rc == USB_STOR_TRANSPORT_GOOD) {
if (rc == USB_STOR_XFER_GOOD) {
// capacity is at word offset 57-58
//
info->sectors = ((u32)(reply[117]) << 24) |
((u32)(reply[116]) << 16) |
((u32)(reply[115]) << 8) |
((u32)(reply[114]) );
return USB_STOR_TRANSPORT_GOOD;
}
return rc;
return USB_STOR_TRANSPORT_ERROR;
}
......
......@@ -197,7 +197,7 @@ freecom_readdata (Scsi_Cmnd *srb, struct us_data *us,
/* has the current command been aborted? */
if (atomic_read(&us->sm_state) == US_STATE_ABORTING) {
US_DEBUGP("freecom_readdata(): transfer aborted\n");
return US_BULK_TRANSFER_ABORTED;
return USB_STOR_TRANSPORT_ABORTED;
}
return USB_STOR_TRANSPORT_ERROR;
......@@ -238,7 +238,7 @@ freecom_writedata (Scsi_Cmnd *srb, struct us_data *us,
/* has the current command been aborted? */
if (atomic_read(&us->sm_state) == US_STATE_ABORTING) {
US_DEBUGP("freecom_writedata(): transfer aborted\n");
return US_BULK_TRANSFER_ABORTED;
return USB_STOR_TRANSPORT_ABORTED;
}
return USB_STOR_TRANSPORT_ERROR;
......@@ -301,7 +301,7 @@ int freecom_transport(Scsi_Cmnd *srb, struct us_data *us)
/* we canceled this transfer */
if (atomic_read(&us->sm_state) == US_STATE_ABORTING) {
US_DEBUGP("freecom_transport(): transfer aborted\n");
return US_BULK_TRANSFER_ABORTED;
return USB_STOR_TRANSPORT_ABORTED;
}
return USB_STOR_TRANSPORT_ERROR;
......@@ -316,7 +316,7 @@ int freecom_transport(Scsi_Cmnd *srb, struct us_data *us)
/* we canceled this transfer */
if (atomic_read(&us->sm_state) == US_STATE_ABORTING) {
US_DEBUGP("freecom_transport(): transfer aborted\n");
return US_BULK_TRANSFER_ABORTED;
return USB_STOR_TRANSPORT_ABORTED;
}
US_DEBUG(pdump ((void *) fst, partial));
......@@ -354,7 +354,7 @@ int freecom_transport(Scsi_Cmnd *srb, struct us_data *us)
/* we canceled this transfer */
if (atomic_read(&us->sm_state) == US_STATE_ABORTING) {
US_DEBUGP("freecom_transport(): transfer aborted\n");
return US_BULK_TRANSFER_ABORTED;
return USB_STOR_TRANSPORT_ABORTED;
}
return USB_STOR_TRANSPORT_ERROR;
......@@ -369,7 +369,7 @@ int freecom_transport(Scsi_Cmnd *srb, struct us_data *us)
/* we canceled this transfer */
if (atomic_read(&us->sm_state) == US_STATE_ABORTING) {
US_DEBUGP("freecom_transport(): transfer aborted\n");
return US_BULK_TRANSFER_ABORTED;
return USB_STOR_TRANSPORT_ABORTED;
}
US_DEBUG(pdump ((void *) fst, partial));
......@@ -430,7 +430,7 @@ int freecom_transport(Scsi_Cmnd *srb, struct us_data *us)
if (atomic_read(&us->sm_state) == US_STATE_ABORTING) {
US_DEBUGP ("freecom_transport: transfer aborted\n");
return US_BULK_TRANSFER_ABORTED;
return USB_STOR_TRANSPORT_ABORTED;
}
if (partial != 4 || result != 0)
return USB_STOR_TRANSPORT_ERROR;
......@@ -459,7 +459,7 @@ int freecom_transport(Scsi_Cmnd *srb, struct us_data *us)
if (atomic_read(&us->sm_state) == US_STATE_ABORTING) {
US_DEBUGP ("freecom_transport: transfer aborted\n");
return US_BULK_TRANSFER_ABORTED;
return USB_STOR_TRANSPORT_ABORTED;
}
if (partial != 4 || result != 0)
return USB_STOR_TRANSPORT_ERROR;
......
......@@ -65,7 +65,7 @@ static inline int jumpshot_bulk_read(struct us_data *us,
unsigned int act_len; /* ignored */
if (len == 0)
return USB_STOR_TRANSPORT_GOOD;
return USB_STOR_XFER_GOOD;
US_DEBUGP("jumpshot_bulk_read: len = %d\n", len);
return usb_storage_raw_bulk(us, SCSI_DATA_READ, data, len, &act_len);
......@@ -79,7 +79,7 @@ static inline int jumpshot_bulk_write(struct us_data *us,
unsigned int act_len; /* ignored */
if (len == 0)
return USB_STOR_TRANSPORT_GOOD;
return USB_STOR_XFER_GOOD;
US_DEBUGP("jumpshot_bulk_write: len = %d\n", len);
return usb_storage_raw_bulk(us, SCSI_DATA_WRITE, data, len, &act_len);
......@@ -168,7 +168,7 @@ static int jumpshot_read_data(struct us_data *us,
// read the result
result = jumpshot_bulk_read(us, ptr, len);
if (result != USB_STOR_TRANSPORT_GOOD)
if (result != USB_STOR_XFER_GOOD)
goto leave;
US_DEBUGP("jumpshot_read_data: %d bytes\n", len);
......@@ -192,7 +192,7 @@ static int jumpshot_read_data(struct us_data *us,
leave:
if (use_sg)
kfree(buffer);
return result;
return USB_STOR_TRANSPORT_ERROR;
}
......@@ -253,7 +253,7 @@ static int jumpshot_write_data(struct us_data *us,
// send the data
result = jumpshot_bulk_write(us, ptr, len);
if (result != USB_STOR_TRANSPORT_GOOD)
if (result != USB_STOR_XFER_GOOD)
goto leave;
// read the result. apparently the bulk write can complete
......@@ -288,7 +288,7 @@ static int jumpshot_write_data(struct us_data *us,
leave:
if (use_sg)
kfree(buffer);
return result;
return USB_STOR_TRANSPORT_ERROR;
}
static int jumpshot_id_device(struct us_data *us,
......@@ -314,8 +314,8 @@ static int jumpshot_id_device(struct us_data *us,
// read the reply
rc = jumpshot_bulk_read(us, reply, sizeof(reply));
if (rc != USB_STOR_TRANSPORT_GOOD)
return rc;
if (rc != USB_STOR_XFER_GOOD)
return USB_STOR_TRANSPORT_ERROR;
info->sectors = ((u32)(reply[117]) << 24) |
((u32)(reply[116]) << 16) |
......
......@@ -61,7 +61,7 @@ usb_storage_send_control(struct us_data *us,
/* did we abort this command? */
if (atomic_read(&us->sm_state) == US_STATE_ABORTING) {
US_DEBUGP("usb_stor_send_control(): transfer aborted\n");
return US_BULK_TRANSFER_ABORTED;
return USB_STOR_TRANSPORT_ABORTED;
}
// Check the return code for the command.
......@@ -70,7 +70,7 @@ usb_storage_send_control(struct us_data *us,
/* a stall indicates a protocol error */
if (result == -EPIPE) {
US_DEBUGP("-- Stall on control pipe\n");
return USB_STOR_TRANSPORT_FAILED;
return USB_STOR_TRANSPORT_ERROR;
}
/* Uh oh... serious problem here */
......@@ -100,14 +100,14 @@ usb_storage_raw_bulk(struct us_data *us, int direction, unsigned char *data,
" pipe 0x%x, stalled at %d bytes\n",
pipe, *act_len);
if (usb_stor_clear_halt(us, pipe) < 0)
return US_BULK_TRANSFER_FAILED;
/* return US_BULK_TRANSFER_SHORT; */
return USB_STOR_XFER_ERROR;
return USB_STOR_XFER_STALLED;
}
/* did we abort this command? */
if (atomic_read(&us->sm_state) == US_STATE_ABORTING) {
US_DEBUGP("usb_storage_raw_bulk(): transfer aborted\n");
return US_BULK_TRANSFER_ABORTED;
return USB_STOR_XFER_ABORTED;
}
if (result) {
......@@ -122,13 +122,13 @@ usb_storage_raw_bulk(struct us_data *us, int direction, unsigned char *data,
US_DEBUGP("raw_bulk(): unknown error %d\n",
result);
return US_BULK_TRANSFER_FAILED;
return USB_STOR_XFER_ERROR;
}
if (*act_len != len) {
US_DEBUGP("Warning: Transferred only %d of %d bytes\n",
*act_len, len);
return US_BULK_TRANSFER_SHORT;
return USB_STOR_XFER_SHORT;
}
#if 0
......@@ -137,7 +137,7 @@ usb_storage_raw_bulk(struct us_data *us, int direction, unsigned char *data,
*act_len, len);
#endif
return US_BULK_TRANSFER_GOOD;
return USB_STOR_XFER_GOOD;
}
int
......@@ -145,14 +145,14 @@ usb_storage_bulk_transport(struct us_data *us, int direction,
unsigned char *data, unsigned int len,
int use_sg) {
int result = USB_STOR_TRANSPORT_GOOD;
int result = USB_STOR_XFER_ERROR;
int transferred = 0;
int i;
struct scatterlist *sg;
unsigned int act_len;
if (len == 0)
return USB_STOR_TRANSPORT_GOOD;
return USB_STOR_XFER_GOOD;
#if DEBUG_PRCT
......@@ -196,7 +196,7 @@ usb_storage_bulk_transport(struct us_data *us, int direction,
result = usb_storage_raw_bulk(us, direction,
buf, length, &act_len);
if (result != US_BULK_TRANSFER_GOOD)
if (result != USB_STOR_XFER_GOOD)
break;
transferred += length;
}
......
......@@ -285,12 +285,14 @@ sddr09_request_sense(struct us_data *us, unsigned char *sensebuf, int buflen) {
}
result = usb_storage_raw_bulk(us, SCSI_DATA_READ, sensebuf, buflen, &act_len);
if (result != USB_STOR_TRANSPORT_GOOD)
if (result != USB_STOR_XFER_GOOD) {
US_DEBUGP("request sense bulk in failed\n");
else
return USB_STOR_TRANSPORT_ERROR;
}
else {
US_DEBUGP("request sense worked\n");
return result;
return USB_STOR_TRANSPORT_GOOD;
}
}
/*
......@@ -344,11 +346,12 @@ sddr09_readX(struct us_data *us, int x, unsigned long fromaddress,
result = usb_storage_bulk_transport(us, SCSI_DATA_READ,
buf, bulklen, use_sg);
if (result != USB_STOR_TRANSPORT_GOOD)
if (result != USB_STOR_XFER_GOOD) {
US_DEBUGP("Result for bulk_transport in sddr09_read2%d %d\n",
x, result);
return result;
return USB_STOR_TRANSPORT_ERROR;
}
return USB_STOR_TRANSPORT_GOOD;
}
/*
......@@ -510,11 +513,12 @@ sddr09_writeX(struct us_data *us,
result = usb_storage_bulk_transport(us, SCSI_DATA_WRITE,
buf, bulklen, use_sg);
if (result != USB_STOR_TRANSPORT_GOOD)
if (result != USB_STOR_XFER_GOOD) {
US_DEBUGP("Result for bulk_transport in sddr09_writeX %d\n",
result);
return result;
return USB_STOR_TRANSPORT_ERROR;
}
return USB_STOR_TRANSPORT_GOOD;
}
/* erase address, write same address */
......@@ -590,13 +594,14 @@ sddr09_read_sg_test_only(struct us_data *us) {
result = usb_storage_bulk_transport(us, SCSI_DATA_READ,
buf, bulklen, 0);
if (result != USB_STOR_TRANSPORT_GOOD)
kfree(buf);
if (result != USB_STOR_XFER_GOOD) {
US_DEBUGP("Result for bulk_transport in sddr09_read_sg %d\n",
result);
return USB_STOR_TRANSPORT_ERROR;
}
kfree(buf);
return result;
return USB_STOR_TRANSPORT_GOOD;
}
#endif
......@@ -629,7 +634,8 @@ sddr09_read_status(struct us_data *us, unsigned char *status) {
result = usb_storage_bulk_transport(us, SCSI_DATA_READ,
data, sizeof(data), 0);
*status = data[0];
return result;
return (result == USB_STOR_XFER_GOOD ?
USB_STOR_TRANSPORT_GOOD : USB_STOR_TRANSPORT_ERROR);
}
static int
......@@ -953,7 +959,8 @@ sddr09_read_deviceID(struct us_data *us, unsigned char *deviceID) {
for (i = 0; i < 4; i++)
deviceID[i] = content[i];
return result;
return (result == USB_STOR_XFER_GOOD ?
USB_STOR_TRANSPORT_GOOD : USB_STOR_TRANSPORT_ERROR);
}
static int
......@@ -1549,7 +1556,8 @@ int sddr09_transport(Scsi_Cmnd *srb, struct us_data *us)
srb->request_bufflen,
srb->use_sg);
return result;
return (result == USB_STOR_XFER_GOOD ?
USB_STOR_TRANSPORT_GOOD : USB_STOR_TRANSPORT_ERROR);
}
return USB_STOR_TRANSPORT_GOOD;
......
......@@ -101,16 +101,16 @@ static int sddr55_status(struct us_data *us)
US_DEBUGP("Result for send_command in status %d\n",
result);
if (result != US_BULK_TRANSFER_GOOD) {
if (result != USB_STOR_XFER_GOOD) {
set_sense_info (4, 0, 0); /* hardware error */
return result;
return USB_STOR_TRANSPORT_ERROR;
}
result = sddr55_bulk_transport(us,
SCSI_DATA_READ, status, 4);
/* expect to get short transfer if no card fitted */
if (result == US_BULK_TRANSFER_SHORT) {
if (result == USB_STOR_XFER_SHORT || result == USB_STOR_XFER_STALLED) {
/* had a short transfer, no card inserted, free map memory */
if (info->lba_to_pba)
kfree(info->lba_to_pba);
......@@ -123,12 +123,12 @@ static int sddr55_status(struct us_data *us)
info->force_read_only = 0;
set_sense_info (2, 0x3a, 0); /* not ready, medium not present */
return result;
return USB_STOR_TRANSPORT_FAILED;
}
if (result != US_BULK_TRANSFER_GOOD) {
if (result != USB_STOR_XFER_GOOD) {
set_sense_info (4, 0, 0); /* hardware error */
return result;
return USB_STOR_TRANSPORT_FAILED;
}
/* check write protect status */
......@@ -138,11 +138,12 @@ static int sddr55_status(struct us_data *us)
result = sddr55_bulk_transport(us,
SCSI_DATA_READ, status, 2);
if (result != US_BULK_TRANSFER_GOOD) {
if (result != USB_STOR_XFER_GOOD) {
set_sense_info (4, 0, 0); /* hardware error */
}
return result;
return (result == USB_STOR_XFER_GOOD ?
USB_STOR_TRANSPORT_GOOD : USB_STOR_TRANSPORT_FAILED);
}
......@@ -214,23 +215,29 @@ static int sddr55_read_data(struct us_data *us,
US_DEBUGP("Result for send_command in read_data %d\n",
result);
if (result != US_BULK_TRANSFER_GOOD)
if (result != USB_STOR_XFER_GOOD) {
result = USB_STOR_TRANSPORT_ERROR;
goto leave;
}
/* read data */
result = sddr55_bulk_transport(us,
SCSI_DATA_READ, ptr,
pages<<info->pageshift);
if (result != US_BULK_TRANSFER_GOOD)
if (result != USB_STOR_XFER_GOOD) {
result = USB_STOR_TRANSPORT_ERROR;
goto leave;
}
/* now read status */
result = sddr55_bulk_transport(us,
SCSI_DATA_READ, status, 2);
if (result != US_BULK_TRANSFER_GOOD)
if (result != USB_STOR_XFER_GOOD) {
result = USB_STOR_TRANSPORT_ERROR;
goto leave;
}
/* check status for error */
if (status[0] == 0xff && status[1] == 0x4) {
......@@ -247,6 +254,7 @@ static int sddr55_read_data(struct us_data *us,
}
us_copy_to_sgbuf_all(buffer, len, content, use_sg);
result = USB_STOR_TRANSPORT_GOOD;
leave:
if (use_sg)
......@@ -374,12 +382,13 @@ static int sddr55_write_data(struct us_data *us,
result = sddr55_bulk_transport(us,
SCSI_DATA_WRITE, command, 8);
if (result != US_BULK_TRANSFER_GOOD) {
if (result != USB_STOR_XFER_GOOD) {
US_DEBUGP("Result for send_command in write_data %d\n",
result);
/* set_sense_info is superfluous here? */
set_sense_info (3, 0x3, 0);/* peripheral write error */
result = USB_STOR_TRANSPORT_FAILED;
goto leave;
}
......@@ -388,24 +397,26 @@ static int sddr55_write_data(struct us_data *us,
SCSI_DATA_WRITE, ptr,
pages<<info->pageshift);
if (result != US_BULK_TRANSFER_GOOD) {
if (result != USB_STOR_XFER_GOOD) {
US_DEBUGP("Result for send_data in write_data %d\n",
result);
/* set_sense_info is superfluous here? */
set_sense_info (3, 0x3, 0);/* peripheral write error */
result = USB_STOR_TRANSPORT_FAILED;
goto leave;
}
/* now read status */
result = sddr55_bulk_transport(us, SCSI_DATA_READ, status, 6);
if (result != US_BULK_TRANSFER_GOOD) {
if (result != USB_STOR_XFER_GOOD) {
US_DEBUGP("Result for get_status in write_data %d\n",
result);
/* set_sense_info is superfluous here? */
set_sense_info (3, 0x3, 0);/* peripheral write error */
result = USB_STOR_TRANSPORT_FAILED;
goto leave;
}
......@@ -446,6 +457,7 @@ static int sddr55_write_data(struct us_data *us,
sectors -= pages >> info->smallpageshift;
ptr += (pages << info->pageshift);
}
result = USB_STOR_TRANSPORT_GOOD;
leave:
if (use_sg)
......@@ -468,14 +480,14 @@ static int sddr55_read_deviceID(struct us_data *us,
US_DEBUGP("Result of send_control for device ID is %d\n",
result);
if (result != US_BULK_TRANSFER_GOOD)
return result;
if (result != USB_STOR_XFER_GOOD)
return USB_STOR_TRANSPORT_ERROR;
result = sddr55_bulk_transport(us,
SCSI_DATA_READ, content, 4);
if (result != US_BULK_TRANSFER_GOOD)
return result;
if (result != USB_STOR_XFER_GOOD)
return USB_STOR_TRANSPORT_ERROR;
*manufacturerID = content[0];
*deviceID = content[1];
......@@ -485,7 +497,7 @@ static int sddr55_read_deviceID(struct us_data *us,
SCSI_DATA_READ, content, 2);
}
return result;
return USB_STOR_TRANSPORT_GOOD;
}
......@@ -510,7 +522,7 @@ static unsigned long sddr55_get_capacity(struct us_data *us) {
US_DEBUGP("Result of read_deviceID is %d\n",
result);
if (result != US_BULK_TRANSFER_GOOD)
if (result != USB_STOR_XFER_GOOD)
return 0;
US_DEBUGP("Device ID = %02X\n", deviceID);
......@@ -603,21 +615,21 @@ static int sddr55_read_map(struct us_data *us) {
result = sddr55_bulk_transport(us, SCSI_DATA_WRITE, command, 8);
if ( result != US_BULK_TRANSFER_GOOD) {
if ( result != USB_STOR_XFER_GOOD) {
kfree (buffer);
return -1;
}
result = sddr55_bulk_transport(us, SCSI_DATA_READ, buffer, numblocks * 2);
if ( result != US_BULK_TRANSFER_GOOD) {
if ( result != USB_STOR_XFER_GOOD) {
kfree (buffer);
return -1;
}
result = sddr55_bulk_transport(us, SCSI_DATA_READ, command, 2);
if ( result != US_BULK_TRANSFER_GOOD) {
if ( result != USB_STOR_XFER_GOOD) {
kfree (buffer);
return -1;
}
......
......@@ -153,7 +153,8 @@ int usbat_read_block(struct us_data *us,
result = usb_storage_bulk_transport(us, SCSI_DATA_READ, content, len, use_sg);
return result;
return (result == USB_STOR_XFER_GOOD ?
USB_STOR_TRANSPORT_GOOD : USB_STOR_TRANSPORT_ERROR);
}
/*
......@@ -234,8 +235,8 @@ int usbat_write_block(struct us_data *us,
result = usb_storage_bulk_transport(us, SCSI_DATA_WRITE, content, len, use_sg);
if (result != USB_STOR_TRANSPORT_GOOD)
return result;
if (result != USB_STOR_XFER_GOOD)
return USB_STOR_TRANSPORT_ERROR;
return usbat_wait_not_busy(us, minutes);
}
......@@ -309,8 +310,8 @@ int usbat_rw_block_test(struct us_data *us,
SCSI_DATA_WRITE,
data, num_registers*2, 0);
if (result!=USB_STOR_TRANSPORT_GOOD)
return result;
if (result!=USB_STOR_XFER_GOOD)
return USB_STOR_TRANSPORT_ERROR;
}
......@@ -341,7 +342,8 @@ int usbat_rw_block_test(struct us_data *us,
* transferred.
*/
if (result == US_BULK_TRANSFER_SHORT) {
if (result == USB_STOR_XFER_SHORT ||
result == USB_STOR_XFER_STALLED) {
/*
* If we're reading and we stalled, then clear
......@@ -373,8 +375,8 @@ int usbat_rw_block_test(struct us_data *us,
US_DEBUGP("Redoing %s\n",
direction==SCSI_DATA_WRITE ? "write" : "read");
} else if (result != US_BULK_TRANSFER_GOOD)
return result;
} else if (result != USB_STOR_XFER_GOOD)
return USB_STOR_TRANSPORT_ERROR;
else
return usbat_wait_not_busy(us, minutes);
......@@ -425,8 +427,8 @@ int usbat_multiple_write(struct us_data *us,
result = usb_storage_bulk_transport(us,
SCSI_DATA_WRITE, data, num_registers*2, 0);
if (result != USB_STOR_TRANSPORT_GOOD)
return result;
if (result != USB_STOR_XFER_GOOD)
return USB_STOR_TRANSPORT_ERROR;
return usbat_wait_not_busy(us, 0);
}
......
......@@ -572,36 +572,37 @@ int usb_stor_transfer_partial(struct us_data *us, char *buf, int length)
if (result == -EPIPE) {
US_DEBUGP("clearing endpoint halt for pipe 0x%x\n", pipe);
if (usb_stor_clear_halt(us, pipe) < 0)
return US_BULK_TRANSFER_FAILED;
return USB_STOR_XFER_ERROR;
return USB_STOR_XFER_STALLED;
}
/* did we abort this command? */
if (atomic_read(&us->sm_state) == US_STATE_ABORTING) {
US_DEBUGP("usb_stor_transfer_partial(): transfer aborted\n");
return US_BULK_TRANSFER_ABORTED;
}
/* did we send all the data? */
if (partial == length) {
US_DEBUGP("usb_stor_transfer_partial(): transfer complete\n");
return US_BULK_TRANSFER_GOOD;
return USB_STOR_XFER_ABORTED;
}
/* NAK - that means we've retried a few times already */
if (result == -ETIMEDOUT) {
US_DEBUGP("usb_stor_transfer_partial(): device NAKed\n");
return US_BULK_TRANSFER_FAILED;
return USB_STOR_XFER_ERROR;
}
/* the catch-all error case */
if (result) {
US_DEBUGP("usb_stor_transfer_partial(): unknown error\n");
return US_BULK_TRANSFER_FAILED;
return USB_STOR_XFER_ERROR;
}
/* did we send all the data? */
if (partial == length) {
US_DEBUGP("usb_stor_transfer_partial(): transfer complete\n");
return USB_STOR_XFER_GOOD;
}
/* no error code, so we must have transferred some data,
* just not all of it */
return US_BULK_TRANSFER_SHORT;
return USB_STOR_XFER_SHORT;
}
/*
......@@ -739,7 +740,7 @@ void usb_stor_invoke_transport(Scsi_Cmnd *srb, struct us_data *us)
* Also, if we have a short transfer on a command that can't have
* a short transfer, we're going to do this.
*/
if ((srb->result == US_BULK_TRANSFER_SHORT) &&
if ((srb->result == USB_STOR_XFER_SHORT) &&
!((srb->cmnd[0] == REQUEST_SENSE) ||
(srb->cmnd[0] == INQUIRY) ||
(srb->cmnd[0] == MODE_SENSE) ||
......@@ -995,13 +996,13 @@ int usb_stor_CBI_transport(Scsi_Cmnd *srb, struct us_data *us)
/* did we abort this command? */
if (atomic_read(&us->sm_state) == US_STATE_ABORTING) {
US_DEBUGP("usb_stor_control_msg(): transfer aborted\n");
return US_BULK_TRANSFER_ABORTED;
return USB_STOR_TRANSPORT_ABORTED;
}
/* a stall indicates a protocol error */
if (result == -EPIPE) {
US_DEBUGP("-- Stall on control pipe\n");
return USB_STOR_TRANSPORT_FAILED;
return USB_STOR_TRANSPORT_ERROR;
}
if (result < 0) {
......@@ -1017,13 +1018,13 @@ int usb_stor_CBI_transport(Scsi_Cmnd *srb, struct us_data *us)
US_DEBUGP("CBI data stage result is 0x%x\n", result);
/* report any errors */
if (result == US_BULK_TRANSFER_ABORTED) {
if (result == USB_STOR_XFER_ABORTED) {
clear_bit(US_FLIDX_IP_WANTED, &us->flags);
return USB_STOR_TRANSPORT_ABORTED;
}
if (result == US_BULK_TRANSFER_FAILED) {
if (result == USB_STOR_XFER_ERROR) {
clear_bit(US_FLIDX_IP_WANTED, &us->flags);
return USB_STOR_TRANSPORT_FAILED;
return USB_STOR_TRANSPORT_ERROR;
}
}
......@@ -1103,13 +1104,13 @@ int usb_stor_CB_transport(Scsi_Cmnd *srb, struct us_data *us)
/* did we abort this command? */
if (atomic_read(&us->sm_state) == US_STATE_ABORTING) {
US_DEBUGP("usb_stor_CB_transport(): transfer aborted\n");
return US_BULK_TRANSFER_ABORTED;
return USB_STOR_TRANSPORT_ABORTED;
}
/* a stall indicates a protocol error */
if (result == -EPIPE) {
US_DEBUGP("-- Stall on control pipe\n");
return USB_STOR_TRANSPORT_FAILED;
return USB_STOR_TRANSPORT_ERROR;
}
/* Uh oh... serious problem here */
......@@ -1124,11 +1125,11 @@ int usb_stor_CB_transport(Scsi_Cmnd *srb, struct us_data *us)
US_DEBUGP("CB data stage result is 0x%x\n", result);
/* report any errors */
if (result == US_BULK_TRANSFER_ABORTED) {
if (result == USB_STOR_XFER_ABORTED) {
return USB_STOR_TRANSPORT_ABORTED;
}
if (result == US_BULK_TRANSFER_FAILED) {
return USB_STOR_TRANSPORT_FAILED;
if (result == USB_STOR_XFER_ERROR) {
return USB_STOR_TRANSPORT_ERROR;
}
}
......@@ -1207,7 +1208,7 @@ int usb_stor_Bulk_transport(Scsi_Cmnd *srb, struct us_data *us)
/* did we abort this command? */
if (atomic_read(&us->sm_state) == US_STATE_ABORTING) {
US_DEBUGP("usb_stor_Bulk_transport(): transfer aborted\n");
return US_BULK_TRANSFER_ABORTED;
return USB_STOR_TRANSPORT_ABORTED;
}
/* if we stall, we need to clear it before we go on */
......@@ -1218,7 +1219,7 @@ int usb_stor_Bulk_transport(Scsi_Cmnd *srb, struct us_data *us)
/* did we abort this command? */
if (atomic_read(&us->sm_state) == US_STATE_ABORTING) {
US_DEBUGP("usb_stor_Bulk_transport(): transfer aborted\n");
return US_BULK_TRANSFER_ABORTED;
return USB_STOR_TRANSPORT_ABORTED;
}
if (result < 0)
return USB_STOR_TRANSPORT_ERROR;
......@@ -1237,7 +1238,7 @@ int usb_stor_Bulk_transport(Scsi_Cmnd *srb, struct us_data *us)
US_DEBUGP("Bulk data transfer result 0x%x\n", result);
/* if it was aborted, we need to indicate that */
if (result == US_BULK_TRANSFER_ABORTED)
if (result == USB_STOR_XFER_ABORTED)
return USB_STOR_TRANSPORT_ABORTED;
}
}
......@@ -1257,7 +1258,7 @@ int usb_stor_Bulk_transport(Scsi_Cmnd *srb, struct us_data *us)
/* did we abort this command? */
if (atomic_read(&us->sm_state) == US_STATE_ABORTING) {
US_DEBUGP("usb_stor_Bulk_transport(): transfer aborted\n");
return US_BULK_TRANSFER_ABORTED;
return USB_STOR_TRANSPORT_ABORTED;
}
/* did the attempt to read the CSW fail? */
......@@ -1268,7 +1269,7 @@ int usb_stor_Bulk_transport(Scsi_Cmnd *srb, struct us_data *us)
/* did we abort this command? */
if (atomic_read(&us->sm_state) == US_STATE_ABORTING) {
US_DEBUGP("usb_stor_Bulk_transport(): transfer aborted\n");
return US_BULK_TRANSFER_ABORTED;
return USB_STOR_TRANSPORT_ABORTED;
}
if (result < 0)
return USB_STOR_TRANSPORT_ERROR;
......@@ -1281,7 +1282,7 @@ int usb_stor_Bulk_transport(Scsi_Cmnd *srb, struct us_data *us)
/* did we abort this command? */
if (atomic_read(&us->sm_state) == US_STATE_ABORTING) {
US_DEBUGP("usb_stor_Bulk_transport(): transfer aborted\n");
return US_BULK_TRANSFER_ABORTED;
return USB_STOR_TRANSPORT_ABORTED;
}
/* if it fails again, we need a reset and return an error*/
......@@ -1292,7 +1293,7 @@ int usb_stor_Bulk_transport(Scsi_Cmnd *srb, struct us_data *us)
/* did we abort this command? */
if (atomic_read(&us->sm_state) == US_STATE_ABORTING) {
US_DEBUGP("usb_stor_Bulk_transport(): transfer aborted\n");
return US_BULK_TRANSFER_ABORTED;
return USB_STOR_TRANSPORT_ABORTED;
}
return USB_STOR_TRANSPORT_ERROR;
}
......
......@@ -115,12 +115,13 @@ struct bulk_cs_wrap {
#define US_BULK_GET_MAX_LUN 0xfe
/*
* usb_stor_transfer() return codes
* usb_stor_transfer() return codes, in order of severity
*/
#define US_BULK_TRANSFER_GOOD 0 /* good transfer */
#define US_BULK_TRANSFER_SHORT 1 /* transfered less than expected */
#define US_BULK_TRANSFER_FAILED 2 /* transfer died in the middle */
#define US_BULK_TRANSFER_ABORTED 3 /* transfer canceled */
#define USB_STOR_XFER_GOOD 0 /* good transfer */
#define USB_STOR_XFER_SHORT 1 /* transfered less than expected */
#define USB_STOR_XFER_STALLED 2 /* endpoint stalled */
#define USB_STOR_XFER_ERROR 3 /* transfer died in the middle */
#define USB_STOR_XFER_ABORTED 4 /* transfer canceled */
/*
* Transport return codes
......
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