Hello again bugs@
Problem: EFIBOOT from removable disk fails to load kernel.
Will succeed eventually after 1 to 15 tries.
Example: 1) Wrote install59.fs to USB flash drive.
2) Boot UEFI mode.
3) boot> boot hd1a:/bsd
booting hd1a:/bsd 6838420read text: Unknown error: code 255
failed(255). will try /bsd
4) boot> boot hd1a:/bsd
5) Repeat 4).
After much digging I narrowed the problem to efid_io()
Instrumented with printf() I saw failure occur at random LBA.
EFI_STATUS returned from EFI_CALL() is EFI_NO_RESPONSE.
My thoughts are this problem is caused by crummy UEFI firmware.
I wrote patch to retry reading blocks if status indicates EFI_NO_RESPONSE.
Now booting successfully first try every time. Message occurs 1 to 5 times
every boot. Each time once at different LBA.
Index: efidev.c
===================================================================
RCS file: /cvs/src/sys/arch/amd64/stand/efiboot/efidev.c,v
retrieving revision 1.16
diff -u -p -r1.16 efidev.c
--- efidev.c 6 Jan 2016 02:10:03 -0000 1.16
+++ efidev.c 18 Feb 2016 05:22:40 -0000
@@ -110,32 +110,37 @@ efid_io(int rw, efi_diskinfo_t ed, u_int
iblksz = ed->blkio->Media->BlockSize;
}
}
- if (i_lblks > 0) {
- status = EFI_CALL(ed->blkio->ReadBlocks,
- ed->blkio, ed->mediaid, lba - 1,
- ed->blkio->Media->BlockSize, iblk);
- if (EFI_ERROR(status))
- goto on_eio;
- memcpy(buf, iblk + (blks - i_lblks),
- i_lblks * DEV_BSIZE);
- }
- if (i_nblks > 0) {
- status = EFI_CALL(ed->blkio->ReadBlocks,
- ed->blkio, ed->mediaid, lba,
- ed->blkio->Media->BlockSize * (i_nblks / blks),
- buf + (i_lblks * DEV_BSIZE));
- if (EFI_ERROR(status))
- goto on_eio;
- }
- if (i_tblks > 0) {
- status = EFI_CALL(ed->blkio->ReadBlocks,
- ed->blkio, ed->mediaid, lba + (i_nblks / blks),
- ed->blkio->Media->BlockSize, iblk);
- if (EFI_ERROR(status))
- goto on_eio;
- memcpy(buf + (i_lblks + i_nblks) * DEV_BSIZE, iblk,
- i_tblks * DEV_BSIZE);
- }
+
+ do {
+ if (i_lblks > 0) {
+ status = EFI_CALL(ed->blkio->ReadBlocks,
+ ed->blkio, ed->mediaid, lba - 1,
+ ed->blkio->Media->BlockSize, iblk);
+ if (EFI_ERROR(status) && status !=
EFI_NO_RESPONSE)
+ goto on_eio;
+ memcpy(buf, iblk + (blks - i_lblks),
+ i_lblks * DEV_BSIZE);
+ }
+ if (i_nblks > 0) {
+ status = EFI_CALL(ed->blkio->ReadBlocks,
+ ed->blkio, ed->mediaid, lba,
+ ed->blkio->Media->BlockSize * (i_nblks /
blks),
+ buf + (i_lblks * DEV_BSIZE));
+ if (EFI_ERROR(status) && status !=
EFI_NO_RESPONSE)
+ goto on_eio;
+ }
+ if (i_tblks > 0) {
+ status = EFI_CALL(ed->blkio->ReadBlocks,
+ ed->blkio, ed->mediaid, lba + (i_nblks /
blks),
+ ed->blkio->Media->BlockSize, iblk);
+ if (EFI_ERROR(status) && status !=
EFI_NO_RESPONSE)
+ goto on_eio;
+ memcpy(buf + (i_lblks + i_nblks) * DEV_BSIZE,
iblk,
+ i_tblks * DEV_BSIZE);
+ }
+ if (status == EFI_NO_RESPONSE)
+ printf("LBA=%u EFI_NO_RESPONSE\n", lba);
+ } while (status == EFI_NO_RESPONSE);
break;
case F_WRITE:
if (ed->blkio->Media->ReadOnly)