From patchwork Tue Mar 16 03:29:35 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yoshihiro Shimoda X-Patchwork-Id: 86076 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter.kernel.org (8.14.3/8.14.3) with ESMTP id o2G3U8Jp020670 for ; Tue, 16 Mar 2010 03:30:08 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S937424Ab0CPDaG (ORCPT ); Mon, 15 Mar 2010 23:30:06 -0400 Received: from mail.renesas.com ([202.234.163.13]:53544 "EHLO mail01.idc.renesas.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S937411Ab0CPDaF (ORCPT ); Mon, 15 Mar 2010 23:30:05 -0400 X-AuditID: ac140384-00000007000004f6-17-4b9efb1f6a9b Received: from guardian02.idc.renesas.com ([172.20.8.201]) by mail01.idc.renesas.com (sendmail) with ESMTP id o2G3TZgu001220; Tue, 16 Mar 2010 12:29:35 +0900 (JST) Received: (from root@localhost) by guardian02.idc.renesas.com with id o2G3Tacd014262; Tue, 16 Mar 2010 12:29:36 +0900 (JST) Received: from mta02.idc.renesas.com (localhost [127.0.0.1]) by mta02.idc.renesas.com with ESMTP id o2G3TbfS022698; Tue, 16 Mar 2010 12:29:37 +0900 (JST) Received: from [172.30.8.157] by ims05.idc.renesas.com (Sendmail) with ESMTPA id <0KZC006RFV1BSF@ims05.idc.renesas.com>; Tue, 16 Mar 2010 12:29:35 +0900 (JST) Date: Tue, 16 Mar 2010 12:29:35 +0900 From: Yoshihiro Shimoda Subject: Re: r8a66597-hcd panics when a USB device is removed from an attached hub In-reply-to: <20100315185907.GB17028@linux-sh.org> To: Paul Mundt , "Pietrek, Markus" Cc: Alan Stern , linux-sh@vger.kernel.org, USB list Message-id: <4B9EFB1F.3090201@renesas.com> MIME-version: 1.0 Content-type: text/plain; charset=ISO-8859-1 Content-transfer-encoding: 7bit User-Agent: Thunderbird 2.0.0.14 (Windows/20080421) References: <20100315035425.GB14501@linux-sh.org> <20100315185907.GB17028@linux-sh.org> X-Brightmail-Tracker: AAAAAA== Sender: linux-sh-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-sh@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.3 (demeter.kernel.org [140.211.167.41]); Tue, 16 Mar 2010 03:30:08 +0000 (UTC) diff --git a/drivers/usb/host/r8a66597-hcd.c b/drivers/usb/host/r8a66597-hcd.c index bee558a..f71a73a 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) /* 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));