From: Marek Vasut <marex@denx.de>
To: u-boot@lists.denx.de
Subject: [U-Boot] [PATCH v2] common: usb_storage : Implement logic to calculate optimal usb maximum trasfer blocks
Date: Mon, 06 Jun 2016 15:19:01 +0200 [thread overview]
Message-ID: <57557845.70705@denx.de> (raw)
In-Reply-To: <HE1PR0401MB20286AF7B766BD37D65EAEA0E35C0@HE1PR0401MB2028.eurprd04.prod.outlook.com>
On 06/06/2016 06:19 AM, Rajesh Bhagat wrote:
>
>
>> -----Original Message-----
>> From: Marek Vasut [mailto:marex at denx.de]
>> Sent: Saturday, June 04, 2016 4:22 AM
>> To: Rajesh Bhagat <rajesh.bhagat@nxp.com>; u-boot at lists.denx.de
>> Cc: sjg at chromium.org; york sun <york.sun@nxp.com>; Sriram Dash
>> <sriram.dash@nxp.com>
>> Subject: Re: [PATCH v2] common: usb_storage : Implement logic to calculate optimal
>> usb maximum trasfer blocks
>>
>> On 06/02/2016 06:56 AM, Rajesh Bhagat wrote:
>>> Implements the logic to calculate the optimal usb maximum trasfer
>>> blocks instead of sending USB_MAX_XFER_BLK blocks which is 65535 and
>>> 20 in case of EHCI and other USB protocols respectively.
>>>
>>> It defines USB_MIN_XFER_BLK/USB_MAX_XFER_BLK trasfer blocks that
>>> should be checked for success starting from minimum to maximum, and
>>> rest of the read/write are performed with that optimal value. It tries
>>> to increase/ decrease the blocks in follwing scenarios:
>>>
>>> 1.decrease blocks: when read/write for a particular number of blocks
>>> fails.
>>> 2. increase blocks: when read/write for a particular number of blocks
>>> pass and amount left to trasfer is greater than current number of
>>> blocks.
>>>
>>> Currently changes are done for EHCI where min = 4096 and max = 65535
>>> is taken. And for other cases code is left unchanged by keeping min =
>>> max = 20.
>>>
>>> Signed-off-by: Sriram Dash <sriram.dash@nxp.com>
>>> Signed-off-by: Rajesh Bhagat <rajesh.bhagat@nxp.com>
>>> ---
>>> common/usb_storage.c | 71
>>> +++++++++++++++++++++++++++++++++++++++++++---------
>>> 1 file changed, 59 insertions(+), 12 deletions(-)
>>>
>>> diff --git a/common/usb_storage.c b/common/usb_storage.c index
>>> 7e6e52d..eee8f4c 100644
>>> --- a/common/usb_storage.c
>>> +++ b/common/usb_storage.c
>>> @@ -106,10 +106,13 @@ struct us_data {
>>> * enough free heap space left, but the SCSI READ(10) and WRITE(10) commands
>> are
>>> * limited to 65535 blocks.
>>> */
>>> +#define USB_MIN_XFER_BLK 4095
>>> #define USB_MAX_XFER_BLK 65535
>>> #else
>>> +#define USB_MIN_XFER_BLK 20
>>> #define USB_MAX_XFER_BLK 20
>>> #endif
>>> +#define USB_CUR_XFER_BLK(n) (n >= 0 ? ((1 << (12 + (n))) - 1) : 0)
>>
>
> Hello Marek,
>
>> Can this be ever called with n < 0 ? You should make this into a function to get
>> typechecking on it too.
>>
>
> Yes. When transfer fails for the first time (pos - 1) is passed to this macro. Ok,
> I will convert it to a function in v3.
This should be handled outside of the macro then.
>>> #ifndef CONFIG_BLK
>>> static struct us_data usb_stor[USB_MAX_STOR_DEV]; @@ -1117,11
>>> +1120,13 @@ static unsigned long usb_stor_read(struct blk_desc *block_dev,
>> lbaint_t blknr,
>>> unsigned short smallblks;
>>> struct usb_device *udev;
>>> struct us_data *ss;
>>> - int retry;
>>> + int retry, pos = 0;
>>> + bool retry_flag = false;
>>> ccb *srb = &usb_ccb;
>>> #ifdef CONFIG_BLK
>>> struct blk_desc *block_dev;
>>> #endif
>>> + unsigned short usb_cur_xfer_blk = USB_CUR_XFER_BLK(pos);
>>
>> How will this behave if you keep alternating between two block_dev devices ? It will
>> always start looking for the best possible transfer length from scratch, right ? That's
>> not great ...
>
> How about adding a field name "cur_xfer_blks" in struct usb_device and updating it
> on device basis , it will help retain the value.
That might work, yes.
> struct usb_device {
> ...
> unsigned short cur_xfer_blks;
> };
>
>>
>>> if (blkcnt == 0)
>>> return 0;
>>> @@ -1153,26 +1158,46 @@ static unsigned long usb_stor_read(struct blk_desc
>> *block_dev, lbaint_t blknr,
>>> /* XXX need some comment here */
>>> retry = 2;
>>> srb->pdata = (unsigned char *)buf_addr;
>>> - if (blks > USB_MAX_XFER_BLK)
>>> - smallblks = USB_MAX_XFER_BLK;
>>> + if (blks > usb_cur_xfer_blk)
>>> + smallblks = usb_cur_xfer_blk;
>>> else
>>> smallblks = (unsigned short) blks;
>>> retry_it:
>>> - if (smallblks == USB_MAX_XFER_BLK)
>>> + debug("usb_read: retry #%d, usb_cur_xfer_blk %hu, smallblks %hu\n",
>>> + retry, usb_cur_xfer_blk, smallblks);
>>> + if (smallblks == usb_cur_xfer_blk)
>>> usb_show_progress();
>>> srb->datalen = block_dev->blksz * smallblks;
>>> srb->pdata = (unsigned char *)buf_addr;
>>> if (usb_read_10(srb, ss, start, smallblks)) {
>>> debug("Read ERROR\n");
>>> usb_request_sense(srb, ss);
>>> - if (retry--)
>>> + if (retry--) {
>>> + /* decrease the usb_cur_xfer_blk */
>>> + unsigned short size = USB_CUR_XFER_BLK(pos - 1);
>>> + if (size >= USB_MIN_XFER_BLK) {
>>> + smallblks = size;
>>> + usb_cur_xfer_blk = smallblks;
>>> + pos--;
>>> + }
>>> + retry_flag = true;
>>> goto retry_it;
>>
>> What is the reason for having the same code twice in this patch ? Just pull the identical
>> stuff into a function.
>>
>
> Ok, I will add above code in function namely dec_cur_xfer_blks/ inc_cur_xfer_blks in v3.
>
> Best Regards,
> Rajesh Bhagat
>
>>> + }
>>> blkcnt -= blks;
>>> break;
>>> }
>>> start += smallblks;
>>> blks -= smallblks;
>>> buf_addr += srb->datalen;
>>> +
>>> + /* try to increase the usb_cur_xfer_blk */
>>> + if (!retry_flag) {
>>> + unsigned short size = USB_CUR_XFER_BLK(pos + 1);
>>> + if (size <= blks && size <= USB_MAX_XFER_BLK) {
>>> + usb_cur_xfer_blk = size;
>>> + pos++;
>>> + }
>>> + }
>>> } while (blks != 0);
>>> ss->flags &= ~USB_READY;
>>>
>>> @@ -1181,7 +1206,7 @@ retry_it:
>>> start, smallblks, buf_addr);
>>>
>>> usb_disable_asynch(0); /* asynch transfer allowed */
>>> - if (blkcnt >= USB_MAX_XFER_BLK)
>>> + if (blkcnt >= usb_cur_xfer_blk)
>>> debug("\n");
>>> return blkcnt;
>>> }
>>> @@ -1199,11 +1224,13 @@ static unsigned long usb_stor_write(struct blk_desc
>> *block_dev, lbaint_t blknr,
>>> unsigned short smallblks;
>>> struct usb_device *udev;
>>> struct us_data *ss;
>>> - int retry;
>>> + int retry, pos = 0;
>>> + bool retry_flag = false;
>>> ccb *srb = &usb_ccb;
>>> #ifdef CONFIG_BLK
>>> struct blk_desc *block_dev;
>>> #endif
>>> + unsigned short usb_cur_xfer_blk = USB_CUR_XFER_BLK(pos);
>>>
>>> if (blkcnt == 0)
>>> return 0;
>>> @@ -1239,26 +1266,46 @@ static unsigned long usb_stor_write(struct blk_desc
>> *block_dev, lbaint_t blknr,
>>> */
>>> retry = 2;
>>> srb->pdata = (unsigned char *)buf_addr;
>>> - if (blks > USB_MAX_XFER_BLK)
>>> - smallblks = USB_MAX_XFER_BLK;
>>> + if (blks > usb_cur_xfer_blk)
>>> + smallblks = usb_cur_xfer_blk;
>>> else
>>> smallblks = (unsigned short) blks;
>>> retry_it:
>>> - if (smallblks == USB_MAX_XFER_BLK)
>>> + debug("usb_write: retry #%d, usb_cur_xfer_blk %hu, smallblks %hu\n",
>>> + retry, usb_cur_xfer_blk, smallblks);
>>> + if (smallblks == usb_cur_xfer_blk)
>>> usb_show_progress();
>>> srb->datalen = block_dev->blksz * smallblks;
>>> srb->pdata = (unsigned char *)buf_addr;
>>> if (usb_write_10(srb, ss, start, smallblks)) {
>>> debug("Write ERROR\n");
>>> usb_request_sense(srb, ss);
>>> - if (retry--)
>>> + if (retry--) {
>>> + /* decrease the usb_cur_xfer_blk */
>>> + unsigned short size = USB_CUR_XFER_BLK(pos - 1);
>>> + if (size >= USB_MIN_XFER_BLK) {
>>> + smallblks = size;
>>> + usb_cur_xfer_blk = smallblks;
>>> + pos--;
>>> + }
>>> + retry_flag = true;
>>> goto retry_it;
>>> + }
>>> blkcnt -= blks;
>>> break;
>>> }
>>> start += smallblks;
>>> blks -= smallblks;
>>> buf_addr += srb->datalen;
>>> +
>>> + /* try to increase the usb_cur_xfer_blk */
>>> + if (!retry_flag) {
>>> + unsigned short size = USB_CUR_XFER_BLK(pos + 1);
>>> + if (size <= blks && size <= USB_MAX_XFER_BLK) {
>>> + usb_cur_xfer_blk = size;
>>> + pos++;
>>> + }
>>> + }
>>> } while (blks != 0);
>>> ss->flags &= ~USB_READY;
>>>
>>> @@ -1266,7 +1313,7 @@ retry_it:
>>> PRIxPTR "\n", start, smallblks, buf_addr);
>>>
>>> usb_disable_asynch(0); /* asynch transfer allowed */
>>> - if (blkcnt >= USB_MAX_XFER_BLK)
>>> + if (blkcnt >= usb_cur_xfer_blk)
>>> debug("\n");
>>> return blkcnt;
>>>
>>>
>>
>>
>> --
>> Best regards,
>> Marek Vasut
--
Best regards,
Marek Vasut
prev parent reply other threads:[~2016-06-06 13:19 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-06-02 4:56 [U-Boot] [PATCH v2] common: usb_storage : Implement logic to calculate optimal usb maximum trasfer blocks Rajesh Bhagat
2016-06-03 22:51 ` Marek Vasut
2016-06-06 4:19 ` Rajesh Bhagat
2016-06-06 13:19 ` Marek Vasut [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=57557845.70705@denx.de \
--to=marex@denx.de \
--cc=u-boot@lists.denx.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.