patch-2.3.18 linux/drivers/usb/uhci.c

Next file: linux/drivers/usb/usb.c
Previous file: linux/drivers/usb/proc_usb.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.3.17/linux/drivers/usb/uhci.c linux/drivers/usb/uhci.c
@@ -41,9 +41,9 @@
 #include <linux/smp_lock.h>
 #include <linux/errno.h>
 #include <linux/unistd.h>
+#include <linux/spinlock.h>
 
 #include <asm/uaccess.h>
-#include <asm/spinlock.h>
 #include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/system.h>
@@ -589,28 +589,33 @@
 /*
  * Request a interrupt handler..
  *
- * Returns: a "handle pointer" that release_irq can use to stop this
+ * Returns 0 (success) or negative (failure).
+ * Also returns/sets a "handle pointer" that release_irq can use to stop this
  * interrupt.  (It's really a pointer to the TD).
  */
-static void *uhci_request_irq(struct usb_device *usb_dev, unsigned int pipe, usb_device_irq handler, int period, void *dev_id)
+static int uhci_request_irq(struct usb_device *usb_dev, unsigned int pipe, usb_device_irq handler, int period, void *dev_id, void **handle)
 {
 	struct uhci_device *dev = usb_to_uhci(usb_dev);
 	struct uhci_td *td = uhci_td_alloc(dev);
 	struct uhci_qh *qh = uhci_qh_alloc(dev);
 	unsigned int destination, status;
 
-	if (!td || !qh)
-		return NULL;
+	if (!td || !qh) {
+		if (td)
+			uhci_td_free(td);
+		if (qh)
+			uhci_qh_free(qh);
+		return (-ENOMEM);
+	}
 
 	/* Destination: pipe destination with INPUT */
 	destination = (pipe & PIPE_DEVEP_MASK) | usb_packetid(pipe);
 
 	/* Infinite errors is 0, so no bits */
-	status = (pipe & TD_CTRL_LS) | TD_CTRL_IOC | TD_CTRL_ACTIVE |
-			TD_CTRL_SPD;
+	status = (pipe & TD_CTRL_LS) | TD_CTRL_IOC | TD_CTRL_ACTIVE | TD_CTRL_SPD;
 
 	td->link = UHCI_PTR_TERM;		/* Terminate */
-	td->status = status;			/* In */
+	td->status = status;
 	td->info = destination | ((usb_maxpacket(usb_dev, pipe, usb_pipeout(pipe)) - 1) << 21) |
 		(usb_gettoggle(usb_dev, usb_pipeendpoint(pipe), usb_pipeout(pipe)) << TD_TOKEN_TOGGLE);
 
@@ -632,7 +637,8 @@
 	/* Add it into the skeleton */
 	uhci_insert_qh(qh->skel, qh);
 
-	return (void *)td;
+	*handle = (void *)td;
+	return 0;
 }
 
 /*
@@ -684,7 +690,6 @@
 /*
  * uhci_init_isoc()
  *
- * Checks bus bandwidth allocation for this USB bus.
  * Allocates some data structures.
  * Initializes parts of them from the function parameters.
  *
@@ -705,11 +710,6 @@
 	struct usb_isoc_desc *id;
 	int i;
 
-#ifdef BANDWIDTH_ALLOCATION
-	/* TBD: add bandwidth allocation/checking/management HERE. */
-	/* TBD: some way to factor in frame_spacing ??? */
-#endif
-
 	*isocdesc = NULL;
 
 	/* Check some parameters. */
@@ -860,24 +860,13 @@
 			if (ix < START_FRAME_FUDGE || /* too small */
 			    ix > CAN_SCHEDULE_FRAMES) { /* too large */
 #ifdef CONFIG_USB_DEBUG_ISOC
-					printk (KERN_DEBUG "uhci_init_isoc: bad start_frame value (%d)\n",
-						isocdesc->start_frame);
+					printk (KERN_DEBUG "uhci_init_isoc: bad start_frame value (%d,%d)\n",
+						isocdesc->start_frame, cur_frame);
 #endif
 					return -EINVAL;
-				}
-			}
-			else /* start_frame <= cur_frame */ {
-				if ((isocdesc->start_frame + UHCI_MAX_SOF_NUMBER + 1
-				    - cur_frame) > CAN_SCHEDULE_FRAMES) {
-#ifdef CONFIG_USB_DEBUG_ISOC
-					printk (KERN_DEBUG "uhci_init_isoc: bad start_frame value (%d)\n",
-						isocdesc->start_frame);
-#endif
-					return -EINVAL;
-				}
 			}
 		} /* end START_ABSOLUTE */
-	}
+	} /* end not pr_isocdesc */
 
 	/*
 	 * Set the start/end frame numbers.
@@ -1395,7 +1384,7 @@
 		if (pktsze > maxsze)
 			pktsze = maxsze;
 
-		td->status = status;                                    /* Status */
+		td->status = status;
 		td->info = destination | ((pktsze-1) << 21) |
 			(usb_gettoggle(usb_dev, usb_pipeendpoint(pipe), usb_pipeout(pipe)) << TD_TOKEN_TOGGLE); /* pktsze bytes of data */
 		td->buffer = virt_to_bus(data);
@@ -1726,6 +1715,8 @@
 	 * interrupt cause
 	 */
 	status = inw(io_addr + USBSTS);
+	if (!status)	/* shared interrupt, not mine */
+		return;
 	outw(status, io_addr + USBSTS);
 
 	/* Walk the list of pending TD's to see which ones completed.. */

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)