patch-2.4.3 linux/drivers/usb/usb-ohci.c
Next file: linux/drivers/usb/usb-ohci.h
Previous file: linux/drivers/usb/uhci.h
Back to the patch index
Back to the overall index
- Lines: 215
- Date:
Fri Mar 23 11:50:01 2001
- Orig file:
v2.4.2/linux/drivers/usb/usb-ohci.c
- Orig date:
Wed Feb 21 18:20:36 2001
diff -u --recursive --new-file v2.4.2/linux/drivers/usb/usb-ohci.c linux/drivers/usb/usb-ohci.c
@@ -12,6 +12,7 @@
*
* History:
*
+ * 2001/03/07 hcca allocation uses pci_alloc_consistent (Steve Longerbeam)
* 2000/09/26 fixed races in removing the private portion of the urb
* 2000/09/07 disable bulk and control lists when unlinking the last
* endpoint descriptor in order to avoid unrecoverable errors on
@@ -208,7 +209,7 @@
__u32 * ed_p;
for (i= 0; i < 32; i++) {
j = 5;
- ed_p = &(ohci->hcca.int_table [i]);
+ ed_p = &(ohci->hcca->int_table [i]);
if (*ed_p == 0)
continue;
printk (KERN_DEBUG __FILE__ ": %s branch int %2d(%2x):", str, i, i);
@@ -371,7 +372,7 @@
ohci_dump_status (controller);
if (verbose)
ep_print_int_eds (controller, "hcca");
- dbg ("hcca frame #%04x", controller->hcca.frame_no);
+ dbg ("hcca frame #%04x", controller->hcca->frame_no);
ohci_dump_roothub (controller, 1);
}
@@ -555,7 +556,7 @@
if (urb->transfer_flags & USB_ISO_ASAP) {
urb->start_frame = ((ed->state == ED_OPER)
? (ed->last_iso + 1)
- : (le16_to_cpu (ohci->hcca.frame_no) + 10)) & 0xffff;
+ : (le16_to_cpu (ohci->hcca->frame_no) + 10)) & 0xffff;
}
/* FALLTHROUGH */
case PIPE_INTERRUPT:
@@ -751,7 +752,7 @@
* the controller won't ever be touching
* these lists again!!
dl_del_list (ohci,
- le16_to_cpu (ohci->hcca.frame_no) & 1);
+ le16_to_cpu (ohci->hcca->frame_no) & 1);
*/
warn ("TD leak, %d", cnt);
@@ -795,7 +796,7 @@
{
ohci_t * ohci = usb_dev->bus->hcpriv;
- return le16_to_cpu (ohci->hcca.frame_no);
+ return le16_to_cpu (ohci->hcca->frame_no);
}
/*-------------------------------------------------------------------------*/
@@ -914,7 +915,7 @@
for (i = 0; i < ep_rev (6, interval); i += inter) {
inter = 1;
- for (ed_p = &(ohci->hcca.int_table[ep_rev (5, i) + int_branch]);
+ for (ed_p = &(ohci->hcca->int_table[ep_rev (5, i) + int_branch]);
(*ed_p != 0) && (((ed_t *) bus_to_virt (le32_to_cpup (ed_p)))->int_interval >= interval);
ed_p = &(((ed_t *) bus_to_virt (le32_to_cpup (ed_p)))->hwNextED))
inter = ep_rev (6, ((ed_t *) bus_to_virt (le32_to_cpup (ed_p)))->int_interval);
@@ -935,7 +936,7 @@
} else {
for ( i = 0; i < 32; i += inter) {
inter = 1;
- for (ed_p = &(ohci->hcca.int_table[ep_rev (5, i)]);
+ for (ed_p = &(ohci->hcca->int_table[ep_rev (5, i)]);
*ed_p != 0;
ed_p = &(((ed_t *) bus_to_virt (le32_to_cpup (ed_p)))->hwNextED))
inter = ep_rev (6, ((ed_t *) bus_to_virt (le32_to_cpup (ed_p)))->int_interval);
@@ -1009,7 +1010,7 @@
interval = ed->int_interval;
for (i = 0; i < ep_rev (6, interval); i += inter) {
- for (ed_p = &(ohci->hcca.int_table[ep_rev (5, i) + int_branch]), inter = 1;
+ for (ed_p = &(ohci->hcca->int_table[ep_rev (5, i) + int_branch]), inter = 1;
(*ed_p != 0) && (*ed_p != ed->hwNextED);
ed_p = &(((ed_t *) bus_to_virt (le32_to_cpup (ed_p)))->hwNextED),
inter = ep_rev (6, ((ed_t *) bus_to_virt (le32_to_cpup (ed_p)))->int_interval)) {
@@ -1036,7 +1037,7 @@
ed->ed_prev->hwNextED = ed->hwNextED;
} else {
for (i = 0; i < 32; i++) {
- for (ed_p = &(ohci->hcca.int_table[ep_rev (5, i)]);
+ for (ed_p = &(ohci->hcca->int_table[ep_rev (5, i)]);
*ed_p != 0;
ed_p = &(((ed_t *) bus_to_virt (le32_to_cpup (ed_p)))->hwNextED)) {
// inter = ep_rev (6, ((ed_t *) bus_to_virt (le32_to_cpup (ed_p)))->int_interval);
@@ -1148,7 +1149,7 @@
}
}
- frame = le16_to_cpu (ohci->hcca.frame_no) & 0x1;
+ frame = le16_to_cpu (ohci->hcca->frame_no) & 0x1;
ed->ed_rm_list = ohci->ed_rm_list[frame];
ohci->ed_rm_list[frame] = ed;
@@ -1361,8 +1362,8 @@
spin_lock_irqsave (&usb_ed_lock, flags);
- td_list_hc = le32_to_cpup (&ohci->hcca.done_head) & 0xfffffff0;
- ohci->hcca.done_head = 0;
+ td_list_hc = le32_to_cpup (&ohci->hcca->done_head) & 0xfffffff0;
+ ohci->hcca->done_head = 0;
while (td_list_hc) {
td_list = (td_t *) bus_to_virt (td_list_hc);
@@ -2018,7 +2019,7 @@
writel (0, &ohci->regs->ed_controlhead);
writel (0, &ohci->regs->ed_bulkhead);
- writel (virt_to_bus (&ohci->hcca), &ohci->regs->hcca); /* a reset clears this */
+ writel (ohci->hcca_dma, &ohci->regs->hcca); /* a reset clears this */
fminterval = 0x2edf;
writel ((fminterval * 9) / 10, &ohci->regs->periodicstart);
@@ -2075,13 +2076,13 @@
struct ohci_regs * regs = ohci->regs;
int ints;
- if ((ohci->hcca.done_head != 0) && !(le32_to_cpup (&ohci->hcca.done_head) & 0x01)) {
+ if ((ohci->hcca->done_head != 0) && !(le32_to_cpup (&ohci->hcca->done_head) & 0x01)) {
ints = OHCI_INTR_WDH;
} else if ((ints = (readl (®s->intrstatus) & readl (®s->intrenable))) == 0) {
return;
}
- // dbg("Interrupt: %x frame: %x", ints, le16_to_cpu (ohci->hcca.frame_no));
+ // dbg("Interrupt: %x frame: %x", ints, le16_to_cpu (ohci->hcca->frame_no));
if (ints & OHCI_INTR_UE) {
ohci->disabled++;
@@ -2111,7 +2112,7 @@
}
if (ints & OHCI_INTR_SF) {
- unsigned int frame = le16_to_cpu (ohci->hcca.frame_no) & 1;
+ unsigned int frame = le16_to_cpu (ohci->hcca->frame_no) & 1;
writel (OHCI_INTR_SF, ®s->intrdisable);
if (ohci->ed_rm_list[!frame] != NULL) {
dl_del_list (ohci, !frame);
@@ -2139,7 +2140,15 @@
return NULL;
memset (ohci, 0, sizeof (ohci_t));
-
+
+ ohci->hcca = pci_alloc_consistent (dev, sizeof *ohci->hcca,
+ &ohci->hcca_dma);
+ if (!ohci->hcca) {
+ kfree (ohci);
+ return NULL;
+ }
+ memset (ohci->hcca, 0, sizeof (struct ohci_hcca));
+
ohci->disabled = 1;
ohci->irq = -1;
ohci->regs = mem_base;
@@ -2192,7 +2201,9 @@
/* unmap the IO address space */
iounmap (ohci->regs);
-
+
+ pci_free_consistent (ohci->ohci_dev, sizeof *ohci->hcca,
+ ohci->hcca, ohci->hcca_dma);
kfree (ohci);
}
@@ -2290,7 +2301,7 @@
/* empty the interrupt branches */
for (i = 0; i < NUM_INTS; i++) ohci->ohci_int_load[i] = 0;
- for (i = 0; i < NUM_INTS; i++) ohci->hcca.int_table[i] = 0;
+ for (i = 0; i < NUM_INTS; i++) ohci->hcca->int_table[i] = 0;
/* no EDs to remove */
ohci->ed_rm_list [0] = NULL;
@@ -2320,6 +2331,13 @@
unsigned long mem_resource, mem_len;
void *mem_base;
+ /* blacklisted hardware? */
+ if (id->driver_data) {
+ info ("%s (%s): %s", dev->slot_name,
+ dev->name, (char *) id->driver_data);
+ return -ENODEV;
+ }
+
if (pci_enable_device(dev) < 0)
return -ENODEV;
@@ -2484,6 +2502,20 @@
/*-------------------------------------------------------------------------*/
static const struct pci_device_id __devinitdata ohci_pci_ids [] = { {
+
+ /*
+ * AMD-756 [Viper] USB has a serious erratum when used with
+ * lowspeed devices like mice; oopses have been seen. The
+ * vendor workaround needs an NDA ... for now, blacklist it.
+ */
+ vendor: 0x1022,
+ device: 0x740c,
+ subvendor: PCI_ANY_ID,
+ subdevice: PCI_ANY_ID,
+
+ driver_data: (unsigned long) "blacklisted, erratum #4",
+
+} , {
/* handle any USB OHCI controller */
class: ((PCI_CLASS_SERIAL_USB << 8) | 0x10),
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)