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
- Lines: 128
- Date:
Fri Sep 10 12:59:49 1999
- Orig file:
v2.3.17/linux/drivers/usb/uhci.c
- Orig date:
Tue Sep 7 12:14:07 1999
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)