Greg:

This patch adds a bit-array to the hub driver's private data structure, 
used for storing the contents of the hub's interrupt status message.  That 
message indicates which ports have events pending (and whether the hub 
itself has events pending).  By only polling the status of the ports 
listed in the bit-array we can save a fair amount of overhead in hub 
communication.

(The #error test added to hub.h is a little awkward, but it's purely 
precautionary -- it won't matter until someone decides to support hubs 
with more than 31 ports!)

Also included in the patch, since this seemed the perfect opportunity for 
it, is Byron's suggestion for handling hub events in the order in which 
they were received.

Please apply.

Alan Stern



Signed-off-by: Alan Stern <[EMAIL PROTECTED]>

===== drivers/usb/core/hub.c 1.171 vs edited =====
--- 1.171/drivers/usb/core/hub.c        Mon Jun 14 06:59:02 2004
+++ edited/drivers/usb/core/hub.c       Tue Jun 15 16:11:37 2004
@@ -231,6 +231,8 @@
 {
        struct usb_hub *hub = (struct usb_hub *)urb->context;
        int status;
+       int i;
+       unsigned long bits;
 
        spin_lock(&hub_event_lock);
        hub->urb_active = 0;
@@ -255,6 +257,11 @@
        
        /* let khubd handle things */
        case 0:                 /* we got data:  port status changed */
+               bits = 0;
+               for (i = 0; i < urb->actual_length; ++i)
+                       bits |= ((unsigned long) ((*hub->buffer)[i]))
+                                       << (i*8);
+               hub->event_bits[0] = bits;
                break;
        }
 
@@ -262,7 +269,7 @@
 
        /* Something happened, let khubd figure it out */
        if (list_empty(&hub->event_list)) {
-               list_add(&hub->event_list, &hub_event_list);
+               list_add_tail(&hub->event_list, &hub_event_list);
                wake_up(&khubd_wait);
        }
 
@@ -1776,7 +1783,10 @@
                        hub->error = 0;
                }
 
+               /* deal with port status changes */
                for (i = 0; i < hub->descriptor->bNbrPorts; i++) {
+                       if (!test_and_clear_bit(i+1, hub->event_bits))
+                               continue;
                        ret = hub_port_status(hdev, i, &portstatus, &portchange);
                        if (ret < 0)
                                continue;
@@ -1846,7 +1856,9 @@
                } /* end for i */
 
                /* deal with hub status changes */
-               if (hub_hub_status(hub, &hubstatus, &hubchange) < 0)
+               if (test_and_clear_bit(0, hub->event_bits) == 0)
+                       ;       /* do nothing */
+               else if (hub_hub_status(hub, &hubstatus, &hubchange) < 0)
                        dev_err (hub_dev, "get_hub_status failed\n");
                else {
                        if (hubchange & HUB_CHANGE_LOCAL_POWER) {
===== drivers/usb/core/hub.h 1.29 vs edited =====
--- 1.29/drivers/usb/core/hub.h Mon Jun 14 06:33:06 2004
+++ edited/drivers/usb/core/hub.h       Tue Jun 15 16:10:57 2004
@@ -203,6 +203,10 @@
        int                     nerrors;        /* track consecutive errors */
 
        struct list_head        event_list;     /* hubs w/data or errs ready */
+       unsigned long           event_bits[1];  /* status change bitmask */
+#if USB_MAXCHILDREN > 31 /* 8*sizeof(unsigned long) - 1 */
+#error event_bits[] is too short!
+#endif
 
        struct usb_hub_descriptor *descriptor;  /* class descriptor */
        struct usb_tt           tt;             /* Transaction Translator */




-------------------------------------------------------
This SF.Net email is sponsored by The 2004 JavaOne(SM) Conference
Learn from the experts at JavaOne(SM), Sun's Worldwide Java Developer
Conference, June 28 - July 1 at the Moscone Center in San Francisco, CA
REGISTER AND SAVE! http://java.sun.com/javaone/sf Priority Code NWMGYKND
_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to