From 5cbfeb124984065661dca86f240fe6916b5c8163 Mon Sep 17 00:00:00 2001 From: Yoshihiro Shimoda Date: Tue, 16 Mar 2010 12:29:35 +0900 Subject: [PATCH] --- yaml --- r: 188791 b: refs/heads/master c: d835933436ac0d1e8f5b35fe809fd4e767e55d6e h: refs/heads/master i: 188789: e551adf576a253051c6feae81956792492ce91b3 188787: f36ef35a4962aaff2648ef6c0950378611d4cacd 188783: cf633ec6d9d4af4448783ae608da0702352925b6 v: v3 --- [refs] | 2 +- trunk/drivers/usb/host/r8a66597-hcd.c | 16 +++++++++++----- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/[refs] b/[refs] index c98e3d13dcb2..0f03f3c98478 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 9ce669a8924c61b7321d6e2f27ed67bcd46c1fbb +refs/heads/master: d835933436ac0d1e8f5b35fe809fd4e767e55d6e diff --git a/trunk/drivers/usb/host/r8a66597-hcd.c b/trunk/drivers/usb/host/r8a66597-hcd.c index bee558aed427..f71a73a93d0c 100644 --- a/trunk/drivers/usb/host/r8a66597-hcd.c +++ b/trunk/drivers/usb/host/r8a66597-hcd.c @@ -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));