5aa196df7decfa658c47ee4bcc16314fe84da041
[profile/ivi/syslinux.git] / com32 / chain / utility.c
1 #include <com32.h>
2 #include <stdint.h>
3 #include <stdio.h>
4 #include <errno.h>
5 #include <unistd.h>
6 #include <string.h>
7 #include <syslinux/disk.h>
8 #include "utility.h"
9
10 void error(const char *msg)
11 {
12     fputs(msg, stderr);
13 }
14
15 int guid_is0(const struct guid *guid)
16 {
17     return !*(const uint64_t *)guid && !*((const uint64_t *)guid+1);
18 }
19
20 void wait_key(void)
21 {
22     int cnt;
23     char junk;
24
25     /* drain */
26     do {
27         errno = 0;
28         cnt = read(0, &junk, 1);
29     } while (cnt > 0 || (cnt < 0 && errno == EAGAIN));
30
31     /* wait */
32     do {
33         errno = 0;
34         cnt = read(0, &junk, 1);
35     } while (!cnt || (cnt < 0 && errno == EAGAIN));
36 }
37
38 uint32_t lba2chs(const struct disk_info *di, uint64_t lba)
39 {
40     uint32_t c, h, s, t;
41
42     if (di->cbios) {
43         if (lba >= di->cyl * di->head * di->sect) {
44             s = di->sect;
45             h = di->head - 1;
46             c = di->cyl - 1;
47             goto out;
48         }
49         s = ((uint32_t)lba % di->sect) + 1;
50         t = (uint32_t)lba / di->sect;
51         h = t % di->head;
52         c = t / di->head;
53     } else
54         goto fallback;
55
56 out:
57     return h | (s << 8) | ((c & 0x300) << 6) | ((c & 0xFF) << 16);
58
59 fallback:
60     if (di->disk & 0x80)
61         return 0x00FFFFFE; /* 1023/63/254 */
62     else
63         /*
64          * adjust ?
65          * this is somewhat "useful" with partitioned floppy,
66          * maybe stick to 2.88mb ?
67          */
68         return 0x004F1201; /* 79/18/1 */
69 #if 0
70         return 0x004F2401; /* 79/36/1 */
71 #endif
72 }
73
74 uint32_t get_file_lba(const char *filename)
75 {
76     com32sys_t inregs;
77     uint32_t lba;
78
79     /* Start with clean registers */
80     memset(&inregs, 0, sizeof(com32sys_t));
81
82     /* Put the filename in the bounce buffer */
83     strlcpy(__com32.cs_bounce, filename, __com32.cs_bounce_size);
84
85     /* Call comapi_open() which returns a structure pointer in SI
86      * to a structure whose first member happens to be the LBA.
87      */
88     inregs.eax.w[0] = 0x0006;
89     inregs.esi.w[0] = OFFS(__com32.cs_bounce);
90     inregs.es = SEG(__com32.cs_bounce);
91     __com32.cs_intcall(0x22, &inregs, &inregs);
92
93     if ((inregs.eflags.l & EFLAGS_CF) || inregs.esi.w[0] == 0) {
94         return 0;               /* Filename not found */
95     }
96
97     /* Since the first member is the LBA, we simply cast */
98     lba = *((uint32_t *) MK_PTR(inregs.ds, inregs.esi.w[0]));
99
100     /* Clean the registers for the next call */
101     memset(&inregs, 0, sizeof(com32sys_t));
102
103     /* Put the filename in the bounce buffer */
104     strlcpy(__com32.cs_bounce, filename, __com32.cs_bounce_size);
105
106     /* Call comapi_close() to free the structure */
107     inregs.eax.w[0] = 0x0008;
108     inregs.esi.w[0] = OFFS(__com32.cs_bounce);
109     inregs.es = SEG(__com32.cs_bounce);
110     __com32.cs_intcall(0x22, &inregs, &inregs);
111
112     return lba;
113 }
114
115 /* vim: set ts=8 sts=4 sw=4 noet: */