--- linux/drivers/usb/usb-ohci-orig	Thu Jun 15 03:26:12 2000
+++ linux/drivers/usb/usb-ohci.c	Thu Jun 15 04:44:52 2000
@@ -61,6 +61,8 @@
 #include <linux/pmu.h>
 #endif
 
+#define PARANOID
+
 
 /* For initializing controller (mask in an HCFS mode too) */
 #define	OHCI_CONTROL_INIT \
@@ -324,6 +326,25 @@
  * Interface functions (URB)
  *-------------------------------------------------------------------------*/
 
+static ohci_t *urb_to_ohci (urb_t *urb)
+{
+#ifdef PARANOID
+	// some paths are seeing bogus OHCI register pointers
+	struct list_head	*entry;
+
+	list_for_each (entry, &ohci_hcd_list) {
+	    ohci_t *next = list_entry (entry, ohci_t, ohci_hcd_list);
+	    if (next == urb->dev->bus->hcpriv) {
+		return next;
+	    }
+	}
+	err ("urb_to_ohci, bogus URB %p", urb);
+	return 0;
+#else
+	return (ohci_t *) urb->dev->bus->hcpriv;
+#endif
+}
+ 
 /* return a request to the completion handler */
  
 static int sohci_return_urb (urb_t * urb)
@@ -1392,6 +1413,12 @@
 	__u8 data[8];
 
 	num_ports = readl (&ohci->regs->roothub.a) & RH_A_NDP; 
+#ifdef PARANOID
+	if (num_ports > MAX_ROOT_PORTS) {
+	    err ("rh_send_irq given bogus controller address %p", ohci->regs);
+	    return 0;
+	}
+#endif
 	*(__u8 *) data = (readl (&ohci->regs->roothub.status) & (RH_HS_LPSC | RH_HS_OCIC))
 		? 1: 0;
 	ret = *(__u8 *) data;
@@ -1415,14 +1442,15 @@
 /*-------------------------------------------------------------------------*/
 
 /* Virtual Root Hub INTs are polled by this timer every "interval" ms */
- 
+
 static void rh_int_timer_do (unsigned long ptr)
 {
 	int len; 
-
 	urb_t * urb = (urb_t *) ptr;
-	ohci_t * ohci = urb->dev->bus->hcpriv;
+	ohci_t *ohci = urb_to_ohci (urb);
 
+	if (ohci == 0)
+	    return;
 	if (ohci->disabled)
 	    return;
 	
@@ -1445,7 +1473,14 @@
 
 static int rh_init_int_timer (urb_t * urb) 
 {
-	ohci_t * ohci = urb->dev->bus->hcpriv;
+	ohci_t * ohci = urb_to_ohci (urb);
+
+#ifdef PARANOID
+	if (!ohci) {
+	    err ("rh_init_int_timer, bogus URB");
+	    return 1;
+	}
+#endif
 
 	ohci->rh.interval = urb->interval;
 	init_timer (&ohci->rh.rh_int_timer);
@@ -1667,9 +1702,9 @@
 
 static int rh_unlink_urb (urb_t * urb)
 {
-	ohci_t * ohci = urb->dev->bus->hcpriv;
+	ohci_t * ohci = urb_to_ohci (urb);
  
-	if (ohci->rh.urb == urb) {
+	if (ohci && ohci->rh.urb == urb) {
 		ohci->rh.send = 0;
 		del_timer (&ohci->rh.rh_int_timer);
 	}

