From patchwork Wed Mar 6 12:22:32 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sergei Shtylyov X-Patchwork-Id: 2225231 Return-Path: X-Original-To: patchwork-davinci@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork2.kernel.org Received: from comal.ext.ti.com (comal.ext.ti.com [198.47.26.152]) by patchwork2.kernel.org (Postfix) with ESMTP id C0494DF23A for ; Wed, 6 Mar 2013 12:27:47 +0000 (UTC) Received: from dlelxv30.itg.ti.com ([172.17.2.17]) by comal.ext.ti.com (8.13.7/8.13.7) with ESMTP id r26CNLLh018899; Wed, 6 Mar 2013 06:23:21 -0600 Received: from DFLE73.ent.ti.com (dfle73.ent.ti.com [128.247.5.110]) by dlelxv30.itg.ti.com (8.13.8/8.13.8) with ESMTP id r26CNLIn022499; Wed, 6 Mar 2013 06:23:21 -0600 Received: from dlelxv24.itg.ti.com (172.17.1.199) by dfle73.ent.ti.com (128.247.5.110) with Microsoft SMTP Server id 14.1.323.3; Wed, 6 Mar 2013 06:23:20 -0600 Received: from linux.omap.com (dlelxs01.itg.ti.com [157.170.227.31]) by dlelxv24.itg.ti.com (8.13.8/8.13.8) with ESMTP id r26CNKwj017605; Wed, 6 Mar 2013 06:23:20 -0600 Received: from linux.omap.com (localhost [127.0.0.1]) by linux.omap.com (Postfix) with ESMTP id 297F480627; Wed, 6 Mar 2013 06:23:20 -0600 (CST) X-Original-To: davinci-linux-open-source@linux.davincidsp.com Delivered-To: davinci-linux-open-source@linux.davincidsp.com Received: from dflp52.itg.ti.com (dflp52.itg.ti.com [128.247.22.96]) by linux.omap.com (Postfix) with ESMTP id 085AE80626 for ; Wed, 6 Mar 2013 06:23:19 -0600 (CST) Received: from red.ext.ti.com (red.ext.ti.com [192.94.93.37]) by dflp52.itg.ti.com (8.13.7/8.13.8) with ESMTP id r26CNIgC009999 for ; Wed, 6 Mar 2013 06:23:18 -0600 (CST) Received: from mail6.bemta7.messagelabs.com (mail6.bemta7.messagelabs.com [216.82.255.55]) by red.ext.ti.com (8.13.7/8.13.7) with ESMTP id r26CNIa3002748 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Wed, 6 Mar 2013 06:23:18 -0600 Received: from [216.82.253.147:59385] by server-8.bemta-7.messagelabs.com id 97/53-09144-63537315; Wed, 06 Mar 2013 12:23:18 +0000 X-Env-Sender: sergei.shtylyov@cogentembedded.com X-Msg-Ref: server-6.tower-165.messagelabs.com!1362572595!13209326!1 X-Originating-IP: [209.85.215.52] X-SpamReason: No, hits=1.5 required=7.0 tests=BODY_RANDOMQ, BODY_RANDOM_LONG X-StarScan-Received: X-StarScan-Version: 6.8.6; banners=-,-,- X-VirusChecked: Checked Received: (qmail 23042 invoked from network); 6 Mar 2013 12:23:17 -0000 Received: from mail-la0-f52.google.com (HELO mail-la0-f52.google.com) (209.85.215.52) by server-6.tower-165.messagelabs.com with RC4-SHA encrypted SMTP; 6 Mar 2013 12:23:17 -0000 Received: by mail-la0-f52.google.com with SMTP id fs12so7208626lab.39 for ; Wed, 06 Mar 2013 04:23:14 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=x-received:message-id:date:from:organization:user-agent :mime-version:to:cc:subject:references:in-reply-to:content-type :content-transfer-encoding:x-gm-message-state; bh=kiy+pyhXiWdpmBdKnkNSqata3JdPYgRRun2guqCx0Lw=; b=VsVfNPBYxyyL7P68SBi7KQ3JpGRIroNHHHLWHzmrKAcGUhg9qLllgj0KovvoC/cd7k /QRFFqmU2FJQMpcuuscxutLTF1QlEuUbK/sO7DzmD8zuUcs1aKvIKqw/rczbkUF31JF8 grp8psJGUqcY+DgIrHuScrrAznEEG4Xwb0QjTJh4MVJfLGNWq3k49YEerTtt1YeRxylX U6enzdsjPuFHRYHGf/1bXvAkXCMCXPJWbrSxV52y9TmtRrYtWuhc5K2gLal2wHbuw1Ag EDmuBDcUilDi2revwAL/kJWZkMPRQyOa6VEQSERPrErfoeWB07gwFiH6aYZxq+W/5OHN lglg== X-Received: by 10.152.132.36 with SMTP id or4mr24916535lab.8.1362572594511; Wed, 06 Mar 2013 04:23:14 -0800 (PST) Received: from [192.168.2.2] (ppp91-79-95-8.pppoe.mtu-net.ru. [91.79.95.8]) by mx.google.com with ESMTPS id ng6sm15778339lab.2.2013.03.06.04.23.12 (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Wed, 06 Mar 2013 04:23:13 -0800 (PST) Message-ID: <51373508.9050005@cogentembedded.com> Date: Wed, 6 Mar 2013 16:22:32 +0400 From: Sergei Shtylyov Organization: Cogent Embedded User-Agent: Mozilla/5.0 (Windows NT 5.1; rv:17.0) Gecko/20130215 Thunderbird/17.0.3 MIME-Version: 1.0 To: "B, Ravi" Subject: Re: DM6446 using multiple USB devices References: <5135A9FC.3000003@ti.com> <5135DD85.60405@cogentembedded.com> <6C6B28D4DC342643927BEAFCE8707BF63EA82EE7@DBDE01.ent.ti.com> In-Reply-To: <6C6B28D4DC342643927BEAFCE8707BF63EA82EE7@DBDE01.ent.ti.com> X-Gm-Message-State: ALoCoQlujPxRgz4FOCfn2V4LsRbBtNz0VhrfSrN+zh27YBtfuTMRYKl3zNlK9gXtXTGEIOAEBjqS CC: "davinci-linux-open-source@linux.davincidsp.com" X-BeenThere: davinci-linux-open-source@linux.davincidsp.com X-Mailman-Version: 2.1.12 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: Errors-To: davinci-linux-open-source-bounces@linux.davincidsp.com Hello. On 06-03-2013 8:45, B, Ravi wrote: >> All bulk endpoint transfers are sheduled using the single MUSB EP 1, >> AFAIR. >>>> 2. Is there a software work around ("Interrupt endpoint scheduling") >>>> that works with devices that need Interrupt EPs? If so what kernel >>>> version do I need? >>> "Interrupt endpoint scheduling" was implemented for very early v2.6.10 >>> based MV kernels that TI used to ship. Recently Ravi up-ported that to >>> v3.3 but was only tested it on DA850 as per my knowledge. Here is the >>> link: >>> http://arago-project.org/git/projects/?p=linux-davinci.git;a=commit;h=0795c14aa91650d778a27fe7b2ef23e2d9ff8c89 >> This code seems to have the same mistake I fixed for 2.6.18 MV release >> -- >> it tries to schedule several URBs concurrently on the same endpoint. It >> seems >> TI engineers have learned nothing from my work. :-( > Is there different approach to this ? Can you explain in detail ? You can't execute several URBs to one endpoint in parallel, trying to "interleave" them -- that's totally incorrect. Please find the sources of 2.6.18 based TI PSP and compare with your 3.3 code. Although, here's the changes I did to the original interrupt scheduling patch (extracted from so called patch #47) back then: > -- > Ravi B WBR, Sergei diff -u linux-2.6.18/drivers/usb/musb/musb_host.c linux-2.6.18/drivers/usb/musb/musb_host.c --- linux-2.6.18/drivers/usb/musb/musb_host.c +++ linux-2.6.18/drivers/usb/musb/musb_host.c @@ -269,6 +269,11 @@ else musb->intr_hold = 1; } + + qh->interval = urb->interval; + if ((musb->port1_status & USB_PORT_STAT_HIGH_SPEED) && + urb->dev->speed != USB_SPEED_HIGH) + qh->interval *= 8; } /* FALLTHROUGH */ #endif /* CONFIG_MUSB_SCHEDULE_INTR_EP */ @@ -341,8 +346,6 @@ __releases(musb->lock) __acquires(musb->lock) { - struct musb_qh *qh = urb->hcpriv; - if ((urb->transfer_flags & URB_SHORT_NOT_OK) && (urb->actual_length < urb->transfer_buffer_length) && status == 0 @@ -350,10 +353,8 @@ status = -EREMOTEIO; spin_lock(&urb->lock); - urb->hcpriv = NULL; - if (urb->status == -EINPROGRESS || - (musb->intr_ep == qh->hw_ep && urb->status == -EPROTO)) + if (urb->status == -EINPROGRESS) urb->status = status; spin_unlock(&urb->lock); @@ -507,9 +508,10 @@ static void musb_host_intr_schedule(struct musb *musb) { struct musb_hw_ep *hw_ep = musb->intr_ep; + void __iomem *epio = hw_ep->regs; struct urb *purb, *hurb = NULL; struct musb_qh *pqh, *hqh = NULL; - u16 csr = 0; + u16 csr; /* * Hold the current interrupt request until the IN token is sent to @@ -517,50 +519,44 @@ * for scheduling other device's interrupt requests. */ if (musb->intr_hold != 0 && --musb->intr_hold == 0) { - csr = musb_readw(hw_ep->regs, MUSB_RXCSR); - + csr = musb_readw(epio, MUSB_RXCSR); csr &= ~(MUSB_RXCSR_H_ERROR | MUSB_RXCSR_DATAERROR | MUSB_RXCSR_H_RXSTALL | MUSB_RXCSR_H_REQPKT); /* Avoid clearing RXPKTRDY */ - musb_writew(hw_ep->regs, MUSB_RXCSR, csr | MUSB_RXCSR_RXPKTRDY); + musb_writew(epio, MUSB_RXCSR, csr | MUSB_RXCSR_RXPKTRDY); } - list_for_each_entry(pqh, &musb->in_intr, ring) - list_for_each_entry(purb, &pqh->hep->urb_list, urb_list) { - - if (purb->number_of_packets) - purb->number_of_packets--; - /* - * If a contention occurs in the same frame period - * between several Interrupt requests expiring - * then look for speed as the primary yardstick. - * If they are of the same speed then look for the - * lesser polling interval request. - */ - if (purb->number_of_packets <= 0 && !musb->intr_hold && - purb->status != -EPROTO) { - if (hurb) { - if (hurb->dev->speed == - purb->dev->speed) { - if (hurb->interval <= - purb->interval) - continue; - } else if (hurb->dev->speed > - purb->dev->speed) + list_for_each_entry(pqh, &musb->in_intr, ring) { + if (pqh->interval) + pqh->interval--; + /* + * If a contention occurs in the same frame period + * between several Interrupt requests expiring + * then look for speed as the primary yardstick. + * If they are of the same speed then look for the + * lesser polling interval request. + */ + if (pqh->interval <= 0 && musb->intr_hold == 0) { + purb = next_urb(pqh); + if (hurb) { + if (hurb->dev->speed == purb->dev->speed) { + if (hurb->interval <= purb->interval) continue; - } - hurb = purb; - hqh = pqh; + } else if (hurb->dev->speed > purb->dev->speed) + continue; } + hurb = purb; + hqh = pqh; } + } /* * If a request is chosen to be scheduled, check to see if RXPKTRDY * is set. If so, delay until this can be processed by the driver. */ if (hqh && hurb) { - csr = musb_readw(hw_ep->regs, MUSB_RXCSR); + csr = musb_readw(epio, MUSB_RXCSR); if (csr & MUSB_RXCSR_RXPKTRDY) return; @@ -569,14 +565,6 @@ if (pqh) musb_save_toggle(pqh, 1, next_urb(pqh)); - if (hurb->urb_list.prev != &hqh->hep->urb_list) - list_move(&hurb->urb_list, &hqh->hep->urb_list); - - hurb->number_of_packets = hurb->interval; - if ((musb->port1_status & USB_PORT_STAT_HIGH_SPEED) && - hurb->dev->speed != USB_SPEED_HIGH) - hurb->number_of_packets *= 8; - hw_ep->rx_reinit = 1; musb_start_urb(musb, 1, hqh); } @@ -840,7 +828,6 @@ void __iomem *epio = hw_ep->regs; struct musb_qh *qh = musb_ep_get_qh(hw_ep, !is_out); u16 packet_sz = qh->maxpacket; - int need_dma = 1; DBG(3, "%s hw%d urb %p spd%d dev%d ep%d%s " "h_addr%02x h_port%02x bytes %d\n", @@ -850,16 +837,17 @@ qh->h_addr_reg, qh->h_port_reg, len); -#ifdef CONFIG_MUSB_SCHEDULE_INTR_EP - if (qh->type == USB_ENDPOINT_XFER_INT) - need_dma = 0; -#endif - musb_ep_select(mbase, epnum); /* candidate for DMA? */ dma_controller = musb->dma_controller; - if (is_dma_capable() && epnum && dma_controller && need_dma) { +#ifdef CONFIG_MUSB_SCHEDULE_INTR_EP + if (qh->type == USB_ENDPOINT_XFER_INT) + /* Interrupt EP scheduling fails at least with CPPI DMA */ + dma_channel = NULL; + else +#endif + if (is_dma_capable() && epnum && dma_controller) { dma_channel = is_out ? hw_ep->tx_channel : hw_ep->rx_channel; if (!dma_channel) { dma_channel = dma_controller->channel_alloc( @@ -1902,14 +1890,6 @@ finish: urb->actual_length += xfer_len; qh->offset += xfer_len; - -#ifdef CONFIG_MUSB_SCHEDULE_INTR_EP - if (hw_ep == musb->intr_ep && status == -EPROTO) { - urb->status = status; - return; - } -#endif - if (done) { if (urb->status == -EINPROGRESS) urb->status = status; @@ -2071,15 +2051,6 @@ if (!is_host_active(musb) || !musb->is_active) return -ENODEV; -#ifdef CONFIG_MUSB_SCHEDULE_INTR_EP - if (usb_pipeint(urb->pipe) && usb_pipein(urb->pipe)) { - urb->number_of_packets = urb->interval; - if ((musb->port1_status & USB_PORT_STAT_HIGH_SPEED) && - urb->dev->speed != USB_SPEED_HIGH) - urb->number_of_packets *= 8; - } -#endif - /* DMA mapping was already done, if needed, and this urb is on * hep->urb_list ... so there's little to do unless hep wasn't * yet scheduled onto a live qh. diff -u linux-2.6.18/drivers/usb/musb/musb_host.h linux-2.6.18/drivers/usb/musb/musb_host.h --- linux-2.6.18/drivers/usb/musb/musb_host.h +++ linux-2.6.18/drivers/usb/musb/musb_host.h @@ -81,6 +81,9 @@ u16 maxpacket; u16 frame; /* for periodic schedule */ unsigned iso_idx; /* in urb->iso_frame_desc[] */ +#ifdef CONFIG_MUSB_SCHEDULE_INTR_EP + int interval; +#endif }; /* map from control or bulk queue head to the first qh on that ring */