5 * Under ARM iOS quadwords are long-aligned, however in AROS (according to AAPCS)
6 * they are quad-aligned. This macro turns on some tricks which bypass this problem
8 #define HOST_LONG_ALIGNED
12 * Under i386 we pick up MacOS' libSystem.dylib instead of Simulator's libSystem.dylib,
13 * so we have to use special versions of certain functions. We can't simply #define _DARWIN_NO_64_BIT_INODE
14 * because iOS SDK forbids this (in iOS inode_t is always 64-bit wide)
16 #define INODE64_SUFFIX "$INODE64"
19 /* Correspondingly, there's no struct stat64. Use struct stat instead. */
24 * Use 32-bit inode_t on Darwin. Otherwise we are expected to use "stat$INODE64"
25 * instead of "stat" function which is available only on MacOS 10.6.
27 #define _DARWIN_NO_64_BIT_INODE
28 /* This enables struct stat64 definition */
29 #define _DARWIN_C_SOURCE /* For Darwin */
30 #define _LARGEFILE64_SOURCE /* For Linux */
33 #ifndef INODE64_SUFFIX
34 #define INODE64_SUFFIX
37 #include <aros/debug.h>
38 #include <aros/symbolsets.h>
39 #include <devices/trackdisk.h>
40 #include <exec/errors.h>
41 #include <proto/exec.h>
42 #include <proto/hostlib.h>
43 #include <proto/intuition.h>
44 #include <proto/kernel.h>
46 #ifdef HOST_LONG_ALIGNED
50 /* Prevents struct timeval redefinition */
51 #define timeval sys_timeval
54 * avoid conflicts between our __unused define and the ones that might come in
65 #include "hostdisk_host.h"
66 #include "hostdisk_device.h"
68 static ULONG
error(int unixerr
)
76 return TDERR_DriveInUse
;
79 return TDERR_WriteProt
;
82 return TDERR_NotSpecified
;
86 ULONG
Host_Open(struct unit
*Unit
)
88 struct HostDiskBase
*hdskBase
= Unit
->hdskBase
;
92 D(bug("hostdisk: Host_Open(%s)\n", Unit
->filename
));
96 Unit
->file
= hdskBase
->iface
->open(Unit
->filename
, O_RDWR
, 0755, &err
);
98 err
= *hdskBase
->errnoPtr
;
102 /* This allows to work on Darwin, at least in read-only mode */
103 D(bug("hostdisk: EBUSY, retrying with read-only access\n", Unit
->filename
, Unit
->file
, err
));
105 Unit
->file
= hdskBase
->iface
->open(Unit
->filename
, O_RDONLY
, 0755, &err
);
107 err
= *hdskBase
->errnoPtr
;
112 if (Unit
->file
== -1)
114 D(bug("hostdisk: Error %d\n", err
));
122 err
= hdskBase
->iface
->fstat64(Unit
->file
, &st
);
127 if (S_ISBLK(st
.st_mode
))
128 Unit
->flags
|= UNIT_DEVICE
;
131 D(bug("hostdisk: Unit flags 0x%02X\n", Unit
->flags
));
135 void Host_Close(struct unit
*Unit
)
137 struct HostDiskBase
*hdskBase
= Unit
->hdskBase
;
139 D(bug("hostdisk: Close device %s\n", Unit
->n
.ln_Name
));
140 D(bug("hostdisk: HostLibBase 0x%p, close() 0x%p\n", HostLibBase
, hdskBase
->iface
->close
));
144 hdskBase
->iface
->close(Unit
->file
);
150 LONG
Host_Read(struct unit
*Unit
, APTR buf
, ULONG size
, ULONG
*ioerr
)
152 struct HostDiskBase
*hdskBase
= Unit
->hdskBase
;
157 ret
= hdskBase
->iface
->read(Unit
->file
, buf
, size
);
159 err
= *hdskBase
->errnoPtr
;
169 LONG
Host_Write(struct unit
*Unit
, APTR buf
, ULONG size
, ULONG
*ioerr
)
171 struct HostDiskBase
*hdskBase
= Unit
->hdskBase
;
176 ret
= hdskBase
->iface
->write(Unit
->file
, buf
, size
);
178 err
= *hdskBase
->errnoPtr
;
188 ULONG
Host_Seek(struct unit
*Unit
, ULONG pos
)
190 return Host_Seek64(Unit
, pos
, 0);
193 ULONG
Host_Seek64(struct unit
*Unit
, ULONG pos
, ULONG pos_hi
)
195 struct HostDiskBase
*hdskBase
= Unit
->hdskBase
;
199 * Host OS is usually not reentrant.
200 * All host OS calls should be protected by global lock (since hostlib.resource v3).
204 res
= LSeek(Unit
->file
, pos
, pos_hi
, SEEK_SET
);
209 return (res
== -1) ? TDERR_SeekError
: 0;
212 ULONG
Host_GetGeometry(struct unit
*Unit
, struct DriveGeometry
*dg
)
214 struct HostDiskBase
*hdskBase
= Unit
->hdskBase
;
218 if (Unit
->flags
& UNIT_DEVICE
)
220 /* This routine returns UNIX error code, for simplicity */
221 err
= Host_DeviceGeometry(Unit
, dg
);
223 /* If this routine is not implemented, use fstat() (worst case) */
230 res
= hdskBase
->iface
->fstat64(Unit
->file
, &st
);
231 err
= *hdskBase
->errnoPtr
;
235 D(bug("hostdisk: Image file length: %ld\n", st
.st_size
));
238 dg
->dg_TotalSectors
= st
.st_size
/ dg
->dg_SectorSize
;
239 dg
->dg_Cylinders
= dg
->dg_TotalSectors
; /* LBA, CylSectors == 1 */
244 D(bug("hostdisk: Host_GetGeometry(): UNIX error %u\n", err
));
248 extern const char Hostdisk_LibName
[];
250 static const char *libcSymbols
[] =
262 #ifdef HOST_OS_android
267 "fstat64" INODE64_SUFFIX
,
272 static BOOL
CheckArch(const char *Component
, const char *MyArch
, const char *SystemArch
)
274 const char *arg
[3] = {Component
, MyArch
, SystemArch
};
276 D(bug("hostdisk: My architecture: %s, kernel architecture: %s\n", arg
[1], arg
[2]));
278 if (strcmp(arg
[1], arg
[2]))
280 struct IntuitionBase
*IntuitionBase
;
282 IntuitionBase
= (struct IntuitionBase
*)OpenLibrary("intuition.library", 36);
285 struct EasyStruct es
=
287 sizeof (struct EasyStruct
),
289 "Incompatible architecture",
290 "Used version of %s is built for use\n"
291 "with %s architecture, but your\n"
292 "system architecture is %s.",
296 EasyRequestArgs(NULL
, &es
, NULL
, (IPTR
*)arg
);
298 CloseLibrary(&IntuitionBase
->LibNode
);
303 D(bug("hostdisk: Architecture check done\n"));
307 static int Host_Init(struct HostDiskBase
*hdskBase
)
312 * This device is disk-based and it can travel from disk to disk.
313 * In order to prevent unexplained crashes we check that system architecture
314 * is the architecture we were built for.
316 APTR KernelBase
= OpenResource("kernel.resource");
321 arch
= (STRPTR
)KrnGetSystemAttr(KATTR_Architecture
);
325 if (!CheckArch(Hostdisk_LibName
, AROS_ARCHITECTURE
, arch
))
328 hdskBase
->KernelHandle
= HostLib_Open(LIBC_NAME
, NULL
);
329 if (!hdskBase
->KernelHandle
)
332 hdskBase
->iface
= (struct HostInterface
*)HostLib_GetInterface(hdskBase
->KernelHandle
, libcSymbols
, &r
);
333 if ((!hdskBase
->iface
) || r
)
336 hdskBase
->errnoPtr
= hdskBase
->iface
->__error();
338 hdskBase
->DiskDevice
= DISK_DEVICE
;
339 hdskBase
->unitBase
= DISK_BASE
;
344 ADD2INITLIB(Host_Init
, 0);