From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from list by lists.gnu.org with archive (Exim 4.71) id 1VrOl7-0007FH-8Y for mharc-grub-devel@gnu.org; Fri, 13 Dec 2013 04:10:09 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:48121) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1VrOky-00079m-MJ for grub-devel@gnu.org; Fri, 13 Dec 2013 04:10:07 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1VrOkr-0007d3-CN for grub-devel@gnu.org; Fri, 13 Dec 2013 04:10:00 -0500 Received: from gmmr3.centrum.cz ([46.255.225.251]:57135) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1VrOkr-0007cg-1E for grub-devel@gnu.org; Fri, 13 Dec 2013 04:09:53 -0500 Received: from gm-as1.cent (unknown [10.32.3.101]) by gmmr3.centrum.cz (Postfix) with ESMTP id 78BBA180009FE for ; Fri, 13 Dec 2013 10:09:48 +0100 (CET) Received: by gm-as1.cent (Postfix, from userid 65534) id 700AFED9F; Fri, 13 Dec 2013 10:09:48 +0100 (CET) X-Original-From: starous@volny.cz X-Envelope-To: grub-devel@gnu.org X-Original-IP: 193.86.90.90 Received: from [192.168.6.11] (unknown [193.86.90.90]) by gm-smtp2.centrum.cz (Postfix) with ESMTPX id 86C49A4003 for ; Fri, 13 Dec 2013 10:09:47 +0100 (CET) Message-ID: <52AACEDA.9060201@volny.cz> Date: Fri, 13 Dec 2013 10:09:46 +0100 From: =?ISO-8859-2?Q?Ale=B9_Nesrsta?= User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Thunderbird/24.1.1 MIME-Version: 1.0 To: The development of GNU GRUB Subject: [PATCH] EHCI/USBMS corrections X-Enigmail-Version: 1.6 OpenPGP: id=9AEF08D1 Content-Type: multipart/signed; micalg=pgp-sha256; protocol="application/pgp-signature"; boundary="tJWEefbg28upLVwpTsVVHELK4pWCBtgEK" X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 46.255.225.251 X-BeenThere: grub-devel@gnu.org X-Mailman-Version: 2.1.14 Precedence: list Reply-To: The development of GNU GRUB List-Id: The development of GNU GRUB List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 13 Dec 2013 09:10:08 -0000 This is an OpenPGP/MIME signed message (RFC 4880 and 3156) --tJWEefbg28upLVwpTsVVHELK4pWCBtgEK Content-Type: text/plain; charset=ISO-8859-2 Content-Transfer-Encoding: quoted-printable I found serious mistake in grub_ehci_check_transfer which probably causes bad behavior explained in ML thread "flash drive timing out, can't boot vmlinuz/initrd (coreboot payload)". The problem is: If we cannot use interrupts, we can detect finish of EHCI transfer only by polling of QH's TD overlay. Unfortunately, the state of most important bits Active and Halted is the same at the beginning of the transfer and at the successful finish (both bits are zero in both cases).= Current code causes randomly false detection of transfer finish and this subsequently confuses USBMS and possibly other higher levels. Additionally, I found possible mistake in USBMS - "tag" number probably should not change during possible retries of CBW send phase. Attached patch should solve these problems and includes also some cosmetic changes related to better debugging when "usb" filter is used. =3D=3D=3D diff -purB '--exclude=3D.git*' ./grub/grub-core/bus/usb/ehci.c =2E/grub_patched/grub-core/bus/usb/ehci.c --- ./grub/grub-core/bus/usb/ehci.c 2013-12-13 08:37:58.898205106 +0100 +++ ./grub_patched/grub-core/bus/usb/ehci.c 2013-12-12 23:39:39.048697014 +0100 @@ -1483,6 +1483,8 @@ grub_ehci_parse_halt (grub_usb_controlle else if ((token & GRUB_EHCI_STATUS_MISSDMF) !=3D 0) err =3D GRUB_USB_ERR_DATA; + grub_dprintf ("usb", "EHCI-halt: token=3D%08x\n", token); + return err; } @@ -1513,7 +1515,7 @@ grub_ehci_check_transfer (grub_usb_contr struct grub_ehci *e =3D dev->data; struct grub_ehci_transfer_controller_data *cdata =3D transfer->controller_data; - grub_uint32_t token; + grub_uint32_t token, token_ftd; grub_dprintf ("ehci", "check_transfer: EHCI STATUS=3D%08x, cdata=3D%p, qh=3D%p\n", @@ -1541,13 +1543,18 @@ grub_ehci_check_transfer (grub_usb_contr return grub_ehci_parse_notrun (dev, transfer, actual); token =3D grub_le_to_cpu32 (cdata->qh_virt->td_overlay.token); + /* If the transfer consist from only one TD, we should check */ + /* if the TD was really executed and deactivated - to prevent */ + /* false detection of transfer finish. */ + token_ftd =3D grub_le_to_cpu32 (cdata->td_first_virt->token); /* Detect QH halted */ if ((token & GRUB_EHCI_STATUS_HALTED) !=3D 0) return grub_ehci_parse_halt (dev, transfer, actual); /* Detect QH not active - QH is not active and no next TD */ - if ((token & GRUB_EHCI_STATUS_ACTIVE) =3D=3D 0) + if (token && ((token & GRUB_EHCI_STATUS_ACTIVE) =3D=3D 0) + && ((token_ftd & GRUB_EHCI_STATUS_ACTIVE) =3D=3D 0)) { /* It could be finish at all or short packet condition */ if ((grub_le_to_cpu32 (cdata->qh_virt->td_overlay.next_td) diff -purB '--exclude=3D.git*' ./grub/grub-core/bus/usb/usbtrans.c =2E/grub_patched/grub-core/bus/usb/usbtrans.c --- ./grub/grub-core/bus/usb/usbtrans.c 2013-12-13 08:37:58.901538939 +01= 00 +++ ./grub_patched/grub-core/bus/usb/usbtrans.c 2013-12-12 22:45:44.077547313 +0100 @@ -302,7 +302,7 @@ grub_usb_bulk_finish_readwrite (grub_usb toggle =3D transfer->transactions[transfer->last_trans].toggle ? 0 := 1; else toggle =3D dev->toggle[transfer->endpoint]; /* Nothing done, take original */ - grub_dprintf ("usb", "bulk: toggle=3D%d\n", toggle); + grub_dprintf ("usb", "bulk: toggle[%d]=3D%d\n", transfer->endpoint, toggle); dev->toggle[transfer->endpoint] =3D toggle; if (transfer->dir =3D=3D GRUB_USB_TRANSFER_TYPE_IN) @@ -342,9 +342,9 @@ grub_usb_bulk_readwrite_packetize (grub_ grub_transfer_type_t type, grub_size_t size, char *data) { - grub_size_t actual, transferred; + grub_size_t actual=3D0, transferred; grub_usb_err_t err =3D GRUB_USB_ERR_NONE; - grub_size_t current_size, position; + grub_size_t current_size=3D0, position; grub_size_t max_bulk_transfer_len =3D MAX_USB_TRANSFER_LEN; grub_size_t max; @@ -369,7 +369,11 @@ grub_usb_bulk_readwrite_packetize (grub_ } if (!err && transferred !=3D size) + { err =3D GRUB_USB_ERR_DATA; + grub_dprintf ("usb", "short packet: size=3D%d, transferred=3D%d\n\t\tcurrent_size=3D%d, actual=3D%d\n", + size, transferred, current_size, actual); + } return err; } diff -purB '--exclude=3D.git*' ./grub/grub-core/disk/usbms.c =2E/grub_patched/grub-core/disk/usbms.c --- ./grub/grub-core/disk/usbms.c 2013-12-13 08:37:58.928209769 +0100 +++ ./grub_patched/grub-core/disk/usbms.c 2013-12-12 21:50:07.680775667 +0100 @@ -298,6 +298,8 @@ grub_usbms_transfer_bo (struct grub_scsi grub_usb_err_t errCSW =3D GRUB_USB_ERR_NONE; int retrycnt =3D 3 + 1; + tag++; + retry: retrycnt--; if (retrycnt =3D=3D 0) @@ -306,7 +308,7 @@ grub_usbms_transfer_bo (struct grub_scsi /* Setup the request. */ grub_memset (&cbw, 0, sizeof (cbw)); cbw.signature =3D grub_cpu_to_le32 (0x43425355); - cbw.tag =3D tag++; + cbw.tag =3D tag; cbw.transfer_length =3D grub_cpu_to_le32 (size); cbw.flags =3D (!read_write) << GRUB_USBMS_DIRECTION_BIT; cbw.lun =3D scsi->lun; /* In USB MS CBW are LUN bits on another place than in SCSI CDB, both should be set correctly. */ @@ -328,6 +330,7 @@ grub_usbms_transfer_bo (struct grub_scsi * XXX: Error recovery is maybe still not fully correct. */ err =3D grub_usb_bulk_write (dev->dev, dev->out, sizeof (cbw), (char *) &cbw); + grub_dprintf ("usb", "write: %d %d\n", err, GRUB_USB_ERR_STALL); if (err) { if (err =3D=3D GRUB_USB_ERR_STALL) @@ -335,7 +338,7 @@ grub_usbms_transfer_bo (struct grub_scsi grub_usb_clear_halt (dev->dev, dev->out->endp_addr); goto CheckCSW; } - return grub_error (GRUB_ERR_IO, "USB Mass Storage request failed")= ; + goto retry; } /* Read/write the data, (maybe) according to specification. */ OD --tJWEefbg28upLVwpTsVVHELK4pWCBtgEK Content-Type: application/pgp-signature; name="signature.asc" Content-Description: OpenPGP digital signature Content-Disposition: attachment; filename="signature.asc" -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.22 (GNU/Linux) Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/ iF4EAREIAAYFAlKqztoACgkQT72HYprvCNG3DgD/WT1ULzcIshXj62lvU4eRj4/7 9FMT2vA1kF2KLgzsytYA/0TuLbVJ2uztlEBmX6MFJVdsXd60Q+2bwa40OcvATZp/ =FamJ -----END PGP SIGNATURE----- --tJWEefbg28upLVwpTsVVHELK4pWCBtgEK--