diff options
| -rw-r--r-- | drivers/usb/host/r8a66597-hcd.c | 16 |
1 files changed, 11 insertions, 5 deletions
diff --git a/drivers/usb/host/r8a66597-hcd.c b/drivers/usb/host/r8a66597-hcd.c index bee558aed427..f71a73a93d0c 100644 --- a/drivers/usb/host/r8a66597-hcd.c +++ b/drivers/usb/host/r8a66597-hcd.c | |||
| @@ -418,7 +418,7 @@ static u8 alloc_usb_address(struct r8a66597 *r8a66597, struct urb *urb) | |||
| 418 | 418 | ||
| 419 | /* this function must be called with interrupt disabled */ | 419 | /* this function must be called with interrupt disabled */ |
| 420 | static void free_usb_address(struct r8a66597 *r8a66597, | 420 | static void free_usb_address(struct r8a66597 *r8a66597, |
| 421 | struct r8a66597_device *dev) | 421 | struct r8a66597_device *dev, int reset) |
| 422 | { | 422 | { |
| 423 | int port; | 423 | int port; |
| 424 | 424 | ||
| @@ -430,7 +430,13 @@ static void free_usb_address(struct r8a66597 *r8a66597, | |||
| 430 | dev->state = USB_STATE_DEFAULT; | 430 | dev->state = USB_STATE_DEFAULT; |
| 431 | r8a66597->address_map &= ~(1 << dev->address); | 431 | r8a66597->address_map &= ~(1 << dev->address); |
| 432 | dev->address = 0; | 432 | dev->address = 0; |
| 433 | dev_set_drvdata(&dev->udev->dev, NULL); | 433 | /* |
| 434 | * Only when resetting USB, it is necessary to erase drvdata. When | ||
| 435 | * a usb device with usb hub is disconnect, "dev->udev" is already | ||
| 436 | * freed on usb_desconnect(). So we cannot access the data. | ||
| 437 | */ | ||
| 438 | if (reset) | ||
| 439 | dev_set_drvdata(&dev->udev->dev, NULL); | ||
| 434 | list_del(&dev->device_list); | 440 | list_del(&dev->device_list); |
| 435 | kfree(dev); | 441 | kfree(dev); |
| 436 | 442 | ||
| @@ -1069,7 +1075,7 @@ static void r8a66597_usb_disconnect(struct r8a66597 *r8a66597, int port) | |||
| 1069 | struct r8a66597_device *dev = r8a66597->root_hub[port].dev; | 1075 | struct r8a66597_device *dev = r8a66597->root_hub[port].dev; |
| 1070 | 1076 | ||
| 1071 | disable_r8a66597_pipe_all(r8a66597, dev); | 1077 | disable_r8a66597_pipe_all(r8a66597, dev); |
| 1072 | free_usb_address(r8a66597, dev); | 1078 | free_usb_address(r8a66597, dev, 0); |
| 1073 | 1079 | ||
| 1074 | start_root_hub_sampling(r8a66597, port, 0); | 1080 | start_root_hub_sampling(r8a66597, port, 0); |
| 1075 | } | 1081 | } |
| @@ -2085,7 +2091,7 @@ static void update_usb_address_map(struct r8a66597 *r8a66597, | |||
| 2085 | spin_lock_irqsave(&r8a66597->lock, flags); | 2091 | spin_lock_irqsave(&r8a66597->lock, flags); |
| 2086 | dev = get_r8a66597_device(r8a66597, addr); | 2092 | dev = get_r8a66597_device(r8a66597, addr); |
| 2087 | disable_r8a66597_pipe_all(r8a66597, dev); | 2093 | disable_r8a66597_pipe_all(r8a66597, dev); |
| 2088 | free_usb_address(r8a66597, dev); | 2094 | free_usb_address(r8a66597, dev, 0); |
| 2089 | put_child_connect_map(r8a66597, addr); | 2095 | put_child_connect_map(r8a66597, addr); |
| 2090 | spin_unlock_irqrestore(&r8a66597->lock, flags); | 2096 | spin_unlock_irqrestore(&r8a66597->lock, flags); |
| 2091 | } | 2097 | } |
| @@ -2228,7 +2234,7 @@ static int r8a66597_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, | |||
| 2228 | rh->port |= (1 << USB_PORT_FEAT_RESET); | 2234 | rh->port |= (1 << USB_PORT_FEAT_RESET); |
| 2229 | 2235 | ||
| 2230 | disable_r8a66597_pipe_all(r8a66597, dev); | 2236 | disable_r8a66597_pipe_all(r8a66597, dev); |
| 2231 | free_usb_address(r8a66597, dev); | 2237 | free_usb_address(r8a66597, dev, 1); |
| 2232 | 2238 | ||
| 2233 | r8a66597_mdfy(r8a66597, USBRST, USBRST | UACT, | 2239 | r8a66597_mdfy(r8a66597, USBRST, USBRST | UACT, |
| 2234 | get_dvstctr_reg(port)); | 2240 | get_dvstctr_reg(port)); |
