Author: thompsa
Date: Wed Apr 22 17:07:53 2009
New Revision: 191395
URL: http://svn.freebsd.org/changeset/base/191395

Log:
  MFp4 //depot/projects/u...@160413
  
  Use direct reference to parent high-speed HUB instead of indirect, due to
  pointer clearing race at detach of parent USB HUB.
  
  Reported by:  kientzle
  Submitted by: Hans Petter Selasky
  PR:           usb/133545

Modified:
  head/sys/dev/usb/controller/ehci.c
  head/sys/dev/usb/usb_device.c
  head/sys/dev/usb/usb_device.h
  head/sys/dev/usb/usb_hub.c

Modified: head/sys/dev/usb/controller/ehci.c
==============================================================================
--- head/sys/dev/usb/controller/ehci.c  Wed Apr 22 16:51:01 2009        
(r191394)
+++ head/sys/dev/usb/controller/ehci.c  Wed Apr 22 17:07:53 2009        
(r191395)
@@ -3651,8 +3651,8 @@ ehci_pipe_init(struct usb2_device *udev,
                if ((udev->speed != USB_SPEED_HIGH) &&
                    ((udev->hs_hub_addr == 0) ||
                    (udev->hs_port_no == 0) ||
-                   (udev->bus->devices[udev->hs_hub_addr] == NULL) ||
-                   (udev->bus->devices[udev->hs_hub_addr]->hub == NULL))) {
+                   (udev->parent_hs_hub == NULL) ||
+                   (udev->parent_hs_hub->hub == NULL))) {
                        /* We need a transaction translator */
                        goto done;
                }

Modified: head/sys/dev/usb/usb_device.c
==============================================================================
--- head/sys/dev/usb/usb_device.c       Wed Apr 22 16:51:01 2009        
(r191394)
+++ head/sys/dev/usb/usb_device.c       Wed Apr 22 17:07:53 2009        
(r191395)
@@ -1490,6 +1490,7 @@ usb2_alloc_device(device_t parent_dev, s
        while (hub) {
                if (hub->speed == USB_SPEED_HIGH) {
                        udev->hs_hub_addr = hub->address;
+                       udev->parent_hs_hub = hub;
                        udev->hs_port_no = adev->port_no;
                        break;
                }

Modified: head/sys/dev/usb/usb_device.h
==============================================================================
--- head/sys/dev/usb/usb_device.h       Wed Apr 22 16:51:01 2009        
(r191394)
+++ head/sys/dev/usb/usb_device.h       Wed Apr 22 17:07:53 2009        
(r191395)
@@ -121,6 +121,7 @@ struct usb2_device {
        struct usb2_bus *bus;           /* our USB BUS */
        device_t parent_dev;            /* parent device */
        struct usb2_device *parent_hub;
+       struct usb2_device *parent_hs_hub;      /* high-speed parent HUB */
        struct usb2_config_descriptor *cdesc;   /* full config descr */
        struct usb2_hub *hub;           /* only if this is a hub */
 #if USB_HAVE_COMPAT_LINUX

Modified: head/sys/dev/usb/usb_hub.c
==============================================================================
--- head/sys/dev/usb/usb_hub.c  Wed Apr 22 16:51:01 2009        (r191394)
+++ head/sys/dev/usb/usb_hub.c  Wed Apr 22 17:07:53 2009        (r191395)
@@ -1117,7 +1117,7 @@ usb2_intr_schedule_adjust(struct usb2_de
                 * access.
                 */
 
-               hub = bus->devices[udev->hs_hub_addr]->hub;
+               hub = udev->parent_hs_hub->hub;
                if (slot >= USB_HS_MICRO_FRAMES_MAX) {
                        slot = usb2_intr_find_best_slot(hub->uframe_usage,
                            USB_FS_ISOC_UFRAME_MAX, 6);
@@ -1232,7 +1232,7 @@ usb2_fs_isoc_schedule_isoc_time_expand(s
 
        isoc_time = usb2_isoc_time_expand(udev->bus, isoc_time);
 
-       hs_hub = udev->bus->devices[udev->hs_hub_addr]->hub;
+       hs_hub = udev->parent_hs_hub->hub;
 
        if (hs_hub != NULL) {
 
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to