|
@@ -418,7 +418,7 @@ static u8 alloc_usb_address(struct r8a66597 *r8a66597, struct urb *urb)
|
|
|
|
|
|
/* this function must be called with interrupt disabled */
|
|
|
static void free_usb_address(struct r8a66597 *r8a66597,
|
|
|
- struct r8a66597_device *dev)
|
|
|
+ struct r8a66597_device *dev, int reset)
|
|
|
{
|
|
|
int port;
|
|
|
|
|
@@ -430,7 +430,13 @@ static void free_usb_address(struct r8a66597 *r8a66597,
|
|
|
dev->state = USB_STATE_DEFAULT;
|
|
|
r8a66597->address_map &= ~(1 << dev->address);
|
|
|
dev->address = 0;
|
|
|
- dev_set_drvdata(&dev->udev->dev, NULL);
|
|
|
+ /*
|
|
|
+ * Only when resetting USB, it is necessary to erase drvdata. When
|
|
|
+ * a usb device with usb hub is disconnect, "dev->udev" is already
|
|
|
+ * freed on usb_desconnect(). So we cannot access the data.
|
|
|
+ */
|
|
|
+ if (reset)
|
|
|
+ dev_set_drvdata(&dev->udev->dev, NULL);
|
|
|
list_del(&dev->device_list);
|
|
|
kfree(dev);
|
|
|
|
|
@@ -1069,7 +1075,7 @@ static void r8a66597_usb_disconnect(struct r8a66597 *r8a66597, int port)
|
|
|
struct r8a66597_device *dev = r8a66597->root_hub[port].dev;
|
|
|
|
|
|
disable_r8a66597_pipe_all(r8a66597, dev);
|
|
|
- free_usb_address(r8a66597, dev);
|
|
|
+ free_usb_address(r8a66597, dev, 0);
|
|
|
|
|
|
start_root_hub_sampling(r8a66597, port, 0);
|
|
|
}
|
|
@@ -2085,7 +2091,7 @@ static void update_usb_address_map(struct r8a66597 *r8a66597,
|
|
|
spin_lock_irqsave(&r8a66597->lock, flags);
|
|
|
dev = get_r8a66597_device(r8a66597, addr);
|
|
|
disable_r8a66597_pipe_all(r8a66597, dev);
|
|
|
- free_usb_address(r8a66597, dev);
|
|
|
+ free_usb_address(r8a66597, dev, 0);
|
|
|
put_child_connect_map(r8a66597, addr);
|
|
|
spin_unlock_irqrestore(&r8a66597->lock, flags);
|
|
|
}
|
|
@@ -2228,7 +2234,7 @@ static int r8a66597_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
|
|
|
rh->port |= (1 << USB_PORT_FEAT_RESET);
|
|
|
|
|
|
disable_r8a66597_pipe_all(r8a66597, dev);
|
|
|
- free_usb_address(r8a66597, dev);
|
|
|
+ free_usb_address(r8a66597, dev, 1);
|
|
|
|
|
|
r8a66597_mdfy(r8a66597, USBRST, USBRST | UACT,
|
|
|
get_dvstctr_reg(port));
|