patch-2.3.16 linux/drivers/usb/uhci.c
Next file: linux/drivers/usb/uhci.h
Previous file: linux/drivers/usb/proc_usb.c
Back to the patch index
Back to the overall index
- Lines: 168
- Date:
Fri Aug 27 15:03:07 1999
- Orig file:
v2.3.15/linux/drivers/usb/uhci.c
- Orig date:
Thu Aug 26 13:05:39 1999
diff -u --recursive --new-file v2.3.15/linux/drivers/usb/uhci.c linux/drivers/usb/uhci.c
@@ -192,7 +192,7 @@
if ((status == TD_CTRL_ACTIVE) && (!rval))
return USB_ST_DATAUNDERRUN;
- return uhci_map_status(status, usb_pipeout(tmp->info) ^ 1);
+ return uhci_map_status(status, uhci_packetout(tmp->info));
}
/*
@@ -593,7 +593,7 @@
*/
static int uhci_get_current_frame_number(struct usb_device *usb_dev)
{
- return inw (usb_to_uhci(usb_dev)->uhci->io_addr + USBFRNUM) & 0x3ff;
+ return inw (usb_to_uhci(usb_dev)->uhci->io_addr + USBFRNUM);
}
@@ -747,26 +747,52 @@
return -EINVAL;
}
+ /*
+ * Check start_frame for inside a valid range.
+ * Only allow transfer requests to be made 1.000 second
+ * into the future.
+ */
+ cur_frame = uhci_get_current_frame_number (isocdesc->usb_dev);
+
/* if not START_ASAP (i.e., RELATIVE or ABSOLUTE): */
- if (!pr_isocdesc && (isocdesc->start_type != START_ASAP))
- if ((isocdesc->start_frame < 0) || (isocdesc->start_frame > 1000)) {
+ if (!pr_isocdesc)
+ if (isocdesc->start_type == START_RELATIVE) {
+ if ((isocdesc->start_frame < 0) || (isocdesc->start_frame > CAN_SCHEDULE_FRAMES)) {
#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)\n",
+ isocdesc->start_frame);
#endif
- return -EINVAL;
- }
+ return -EINVAL;
+ }
+ } /* end START_RELATIVE */
+ else
+ if (isocdesc->start_type == START_ABSOLUTE) {
+ if (isocdesc->start_frame > cur_frame) {
+ if ((isocdesc->start_frame - 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;
+ }
+ }
+ 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 */
/*
* Set the start/end frame numbers.
*/
- if (!pr_isocdesc)
- cur_frame = uhci_get_current_frame_number (isocdesc->usb_dev);
-
if (pr_isocdesc) {
isocdesc->start_frame = pr_isocdesc->end_frame + 1;
- } else if (isocdesc->start_type == START_ABSOLUTE) {
- /* Use start_frame as is. */
} else if (isocdesc->start_type == START_RELATIVE) {
if (isocdesc->start_frame < START_FRAME_FUDGE)
isocdesc->start_frame = START_FRAME_FUDGE;
@@ -774,15 +800,16 @@
} else if (isocdesc->start_type == START_ASAP) {
isocdesc->start_frame = cur_frame + START_FRAME_FUDGE;
}
+ /* else for start_type == START_ABSOLUTE, use start_frame as is. */
/* and see if start_frame needs any correction */
- if (isocdesc->start_frame >= 1000)
- isocdesc->start_frame -= 1000;
+ if (isocdesc->start_frame >= UHCI_NUMFRAMES)
+ isocdesc->start_frame -= UHCI_NUMFRAMES;
/* and fix the end_frame value */
isocdesc->end_frame = isocdesc->start_frame + isocdesc->frame_count - 1;
- if (isocdesc->end_frame >= 1000)
- isocdesc->end_frame -= 1000;
+ if (isocdesc->end_frame >= UHCI_NUMFRAMES)
+ isocdesc->end_frame -= UHCI_NUMFRAMES;
isocdesc->prev_completed_frame = -1;
isocdesc->cur_completed_frame = -1;
@@ -807,7 +834,7 @@
isocdesc->frame_spacing = 1;
for (ix = 0, td = isocdesc->td, fd = isocdesc->frames;
- ix < isocdesc->frame_count; ix++, td++, fd++, cur_frame++) {
+ ix < isocdesc->frame_count; ix++, td++, fd++) {
frlen = fd->frame_length;
if (frlen > isocdesc->frame_size)
frlen = isocdesc->frame_size;
@@ -823,7 +850,7 @@
td->info = destination | ((frlen - 1) << 21);
td->buffer = virt_to_bus (bufptr);
td->dev = dev;
- td->isoc_td_number = ix; /* 0-based; does not wrap 999 -> 0 */
+ td->isoc_td_number = ix; /* 0-based; does not wrap/overflow back to 0 */
if (isocdesc->callback_frames &&
(++cb_frames >= isocdesc->callback_frames)) {
@@ -841,8 +868,8 @@
td->link = uhci->fl->frame [cur_frame];
uhci->fl->frame [cur_frame] = virt_to_bus (td);
- if (cur_frame >= 999)
- cur_frame = -1;
+ if (++cur_frame >= UHCI_NUMFRAMES)
+ cur_frame = 0;
} /* end for ix */
/*
@@ -872,7 +899,7 @@
struct uhci_td *td;
int ix, cur_frame;
- if ((isocdesc->start_frame < 0) || (isocdesc->start_frame >= 1000)) {
+ if ((isocdesc->start_frame < 0) || (isocdesc->start_frame >= UHCI_NUMFRAMES)) {
#ifdef CONFIG_USB_DEBUG_ISOC
printk (KERN_DEBUG "uhci_kill_isoc: invalid start_frame (%d)\n",
isocdesc->start_frame);
@@ -885,7 +912,7 @@
td->status &= ~(TD_CTRL_ACTIVE | TD_CTRL_IOC);
uhci->fl->frame [cur_frame] = td->link;
- if (++cur_frame >= 1000)
+ if (++cur_frame >= UHCI_NUMFRAMES)
cur_frame = 0;
} /* end for ix */
@@ -1551,7 +1578,7 @@
usb_dotoggle(usb_dev, usb_pipeendpoint(td->info), usb_pipeout(td->info) ^ 1);
td->info &= ~(1 << 19); /* clear data toggle */
td->info |= usb_gettoggle(usb_dev, usb_pipeendpoint(td->info),
- usb_pipeout(td->info) ^ 1) << 19; /* toggle between data0 and data1 */
+ uhci_packetout(td->info)) << 19; /* toggle between data0 and data1 */
td->status = (td->status & 0x2F000000) | TD_CTRL_ACTIVE | TD_CTRL_IOC;
/* The HC only removes it when it completed */
/* successfully, so force remove and readd it */
@@ -1562,7 +1589,7 @@
/* marked for removal */
td->flags &= ~UHCI_TD_REMOVE;
- usb_dotoggle(usb_dev, usb_pipeendpoint(td->info), usb_pipeout(td->info) ^ 1);
+ usb_dotoggle(usb_dev, usb_pipeendpoint(td->info), uhci_packetout(td->info));
uhci_remove_qh(td->qh->skel, td->qh);
uhci_qh_free(td->qh);
uhci_td_free(td);
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)