Enumerating drives through XHDI seems to work, at least it seems coherent.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@23598 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -160,7 +160,7 @@ class BIOSDrive : public BlockHandle {
|
||||
|
||||
class XHDIDrive : public BlockHandle {
|
||||
public:
|
||||
XHDIDrive(int handle/*, uint16 major, uint16 minor ??*/);
|
||||
XHDIDrive(int handle, uint16 major, uint16 minor);
|
||||
virtual ~XHDIDrive();
|
||||
|
||||
status_t FillIdentifier();
|
||||
@@ -431,29 +431,112 @@ add_block_devices(NodeList *devicesList, bool identifierMissing)
|
||||
if (sBlockDevicesAdded)
|
||||
return B_OK;
|
||||
|
||||
map = Drvmap();
|
||||
dprintf("Drvmap(): 0x%08lx\n", map);
|
||||
for (driveID = 0; driveID < 32; driveID++) {
|
||||
bool present = map & 0x1;
|
||||
map >>= 1;
|
||||
if (!present)
|
||||
continue;
|
||||
|
||||
if (driveID == gBootDriveID)
|
||||
continue;
|
||||
if (init_xhdi() >= B_OK) {
|
||||
uint16 major;
|
||||
uint16 minor;
|
||||
uint32 blocksize;
|
||||
uint32 blocks;
|
||||
uint32 devflags;
|
||||
uint32 lastacc;
|
||||
char product[33];
|
||||
int32 err;
|
||||
|
||||
BlockHandle *drive = new(nothrow) BlockHandle(driveID);
|
||||
if (drive->InitCheck() != B_OK) {
|
||||
dprintf("could not add drive %u\n", driveID);
|
||||
delete drive;
|
||||
continue;
|
||||
map = XHDrvMap();
|
||||
dprintf("XDrvMap() 0x%08lx\n", map);
|
||||
// sadly XDrvmap() has the same issues as XBIOS, it only lists known partitions.
|
||||
// so we just iterate on each major and try to see if there is something.
|
||||
for (driveID = 0; driveID < 32; driveID++) {
|
||||
uint32 startsect;
|
||||
err = XHInqDev(driveID, &major, &minor, &startsect, NULL);
|
||||
if (err < 0) {
|
||||
;//dprintf("XHInqDev(%d) error %d\n", driveID, err);
|
||||
} else {
|
||||
dprintf("XHInqDev(%d): (%d,%d):%d\n", driveID, major, minor, startsect);
|
||||
}
|
||||
}
|
||||
|
||||
devicesList->Add(drive);
|
||||
driveCount++;
|
||||
product[32] = '\0';
|
||||
for (major = 0; major < 256; major++) {
|
||||
if (major == 64) // we don't want floppies
|
||||
continue;
|
||||
if (major > 23) // extensions and non-standard stuff... skip for speed.
|
||||
break;
|
||||
|
||||
if (drive->FillIdentifier() != B_OK)
|
||||
identifierMissing = true;
|
||||
for (minor = 0; minor < 255; minor++) {
|
||||
if (minor && (major < 8 || major >15))
|
||||
break; // minor only used for the SCSI LUN AFAIK.
|
||||
if (minor > 15) // are more used at all ?
|
||||
break;
|
||||
|
||||
product[0] = '\0';
|
||||
blocksize = 0;
|
||||
#if 0
|
||||
err = XHLastAccess(major, minor, &lastacc);
|
||||
if (err < 0) {
|
||||
;//dprintf("XHLastAccess(%d,%d) error %d\n", major, minor, err);
|
||||
} else
|
||||
dprintf("XHLastAccess(%d,%d): %ld\n", major, minor, lastacc);
|
||||
//continue;
|
||||
#endif
|
||||
// we can pass NULL pointers but just to play safe we don't.
|
||||
err = XHInqTarget(major, minor, &blocksize, &devflags, product);
|
||||
if (err < 0) {
|
||||
dprintf("XHInqTarget(%d,%d) error %d\n", major, minor, err);
|
||||
continue;
|
||||
}
|
||||
err = XHGetCapacity(major, minor, &blocks, &blocksize);
|
||||
if (err < 0) {
|
||||
//dprintf("XHGetCapacity(%d,%d) error %d\n", major, minor, err);
|
||||
continue;
|
||||
}
|
||||
|
||||
dprintf("XHDI(%d,%d): blksize %d, blocks %d, flags 0x%08lx, '%s'\n", major, minor, blocksize, blocks, devflags, product);
|
||||
driveID = (uint8)major;
|
||||
|
||||
//if (driveID == gBootDriveID)
|
||||
// continue;
|
||||
//continue;
|
||||
|
||||
BlockHandle *drive = new(nothrow) XHDIDrive(driveID, major, minor);
|
||||
if (drive->InitCheck() != B_OK) {
|
||||
dprintf("could not add drive (%d,%d)\n", major, minor);
|
||||
delete drive;
|
||||
continue;
|
||||
}
|
||||
|
||||
devicesList->Add(drive);
|
||||
driveCount++;
|
||||
|
||||
if (drive->FillIdentifier() != B_OK)
|
||||
identifierMissing = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!driveCount) { // try to fallback to BIOS XXX: use MetaDOS
|
||||
map = Drvmap();
|
||||
dprintf("Drvmap(): 0x%08lx\n", map);
|
||||
for (driveID = 0; driveID < 32; driveID++) {
|
||||
bool present = map & 0x1;
|
||||
map >>= 1;
|
||||
if (!present)
|
||||
continue;
|
||||
|
||||
if (driveID == gBootDriveID)
|
||||
continue;
|
||||
|
||||
BlockHandle *drive = new(nothrow) BlockHandle(driveID);
|
||||
if (drive->InitCheck() != B_OK) {
|
||||
dprintf("could not add drive %u\n", driveID);
|
||||
delete drive;
|
||||
continue;
|
||||
}
|
||||
|
||||
devicesList->Add(drive);
|
||||
driveCount++;
|
||||
|
||||
if (drive->FillIdentifier() != B_OK)
|
||||
identifierMissing = true;
|
||||
}
|
||||
}
|
||||
dprintf("number of drives: %d\n", driveCount);
|
||||
|
||||
@@ -690,18 +773,29 @@ BIOSDrive::ReadBlocks(void *buffer, off_t first, int32 count)
|
||||
*/
|
||||
|
||||
|
||||
XHDIDrive::XHDIDrive(int handle)
|
||||
XHDIDrive::XHDIDrive(int handle, uint16 major, uint16 minor)
|
||||
: BlockHandle(handle)
|
||||
{
|
||||
/* first check if the drive exists */
|
||||
/* note floppy B can be reported present anyway... */
|
||||
uint32 map = Drvmap();
|
||||
if (!(map & (1 << fHandle))) {
|
||||
fSize = 0LL;
|
||||
return;
|
||||
}
|
||||
//XXX: check size
|
||||
int32 err;
|
||||
uint32 devflags;
|
||||
uint32 blocks;
|
||||
char product[33];
|
||||
|
||||
fMajor = major;
|
||||
fMinor = minor;
|
||||
product[32] = '\0';
|
||||
err = XHInqTarget(major, minor, &fBlockSize, &devflags, product);
|
||||
if (err < 0)
|
||||
return;
|
||||
//XXX: check size
|
||||
err = XHGetCapacity(major, minor, &blocks, &fBlockSize);
|
||||
if (err < 0)
|
||||
return;
|
||||
|
||||
fSize = blocks * fBlockSize;
|
||||
fHasParameters = false;
|
||||
#if 0
|
||||
if (get_drive_parameters(fHandle, &fParameters) != B_OK) {
|
||||
dprintf("getting drive parameters for: %u failed!\n", fHandle);
|
||||
return;
|
||||
@@ -709,7 +803,7 @@ XHDIDrive::XHDIDrive(int handle)
|
||||
fBlockSize = 512;
|
||||
fSize = fParameters.sectors * fBlockSize;
|
||||
fHasParameters = false;
|
||||
|
||||
#endif
|
||||
#if 0
|
||||
if (get_ext_drive_parameters(driveID, &fParameters) != B_OK) {
|
||||
// old style CHS support
|
||||
@@ -799,7 +893,9 @@ status_t
|
||||
platform_add_boot_device(struct stage2_args *args, NodeList *devicesList)
|
||||
{
|
||||
TRACE(("boot drive ID: %x\n", gBootDriveID));
|
||||
init_xhdi();
|
||||
|
||||
//XXX: FIXME
|
||||
BlockHandle *drive = new(nothrow) BlockHandle(gBootDriveID);
|
||||
if (drive->InitCheck() != B_OK) {
|
||||
dprintf("no boot drive!\n");
|
||||
@@ -851,6 +947,7 @@ platform_get_boot_partition(struct stage2_args *args, Node *bootDevice,
|
||||
status_t
|
||||
platform_add_block_devices(stage2_args *args, NodeList *devicesList)
|
||||
{
|
||||
init_xhdi();
|
||||
return add_block_devices(devicesList, false);
|
||||
}
|
||||
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
#include <Errors.h>
|
||||
|
||||
void *gXHDIEntryPoint = NULL;
|
||||
uint32 gXHDIVersion = 0;
|
||||
|
||||
NatFeatCookie *gNatFeatCookie = NULL;
|
||||
int32 gDebugPrintfNatFeatID = 0;
|
||||
|
||||
@@ -182,13 +184,18 @@ dump_tos_cookies(void)
|
||||
status_t
|
||||
init_xhdi(void)
|
||||
{
|
||||
struct tos_cookie *c;
|
||||
const struct tos_cookie *c;
|
||||
|
||||
if (gXHDIEntryPoint)
|
||||
return B_OK;
|
||||
|
||||
c = tos_find_cookie(XHDI_COOKIE);
|
||||
if (!c)
|
||||
return ENOENT;
|
||||
if (((uint32 *)c->pvalue)[-1] != XHDI_MAGIC)
|
||||
return EINVAL;
|
||||
gXHDIEntryPoint = c->pvalue;
|
||||
gXHDIVersion = XHGetVersion();
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -351,7 +351,8 @@ static inline int Bconputs(int16 handle, const char *string)
|
||||
|
||||
#define XHDI_COOKIE 'XHDI'
|
||||
#define XHDI_MAGIC 0x27011992
|
||||
#define XHDI_CLOBBER_LIST /* only d0 */
|
||||
//#define XHDI_CLOBBER_LIST "" /* only d0 */
|
||||
#define XHDI_CLOBBER_LIST "d1", "d2", "a0", "a1", "a2"
|
||||
|
||||
#define XH_TARGET_STOPPABLE 0x00000001L
|
||||
#define XH_TARGET_REMOVABLE 0x00000002L
|
||||
@@ -376,7 +377,7 @@ extern status_t init_xhdi(void);
|
||||
__asm__ volatile \
|
||||
("/* xhdicall(" #callnr ") */\n" \
|
||||
" move.w %[calln],-(%%sp)\n" \
|
||||
" call (%[entry])\n" \
|
||||
" jbsr (%[entry])\n" \
|
||||
" add.l #2,%%sp\n" \
|
||||
: "=r"(retvalue) /* output */ \
|
||||
: /* input */ \
|
||||
@@ -396,7 +397,7 @@ extern status_t init_xhdi(void);
|
||||
("/* xhdicall(" #callnr ") */\n" \
|
||||
" move.w %1,-(%%sp) \n" \
|
||||
" move.w %[calln],-(%%sp)\n" \
|
||||
" call (%[entry])\n" \
|
||||
" jbsr (%[entry])\n" \
|
||||
" add.l #4,%%sp \n" \
|
||||
: "=r"(retvalue) /* output */ \
|
||||
: "r"(_p1), /* input */ \
|
||||
@@ -407,6 +408,160 @@ extern status_t init_xhdi(void);
|
||||
retvalue; \
|
||||
})
|
||||
|
||||
#define xhdicallWWL(callnr, p1, p2, p3) \
|
||||
({ \
|
||||
register int32 retvalue __asm__("d0"); \
|
||||
int16 _p1 = (int16)(p1); \
|
||||
int16 _p2 = (int16)(p2); \
|
||||
int32 _p3 = (int32)(p3); \
|
||||
\
|
||||
__asm__ volatile \
|
||||
("/* xhdicall(" #callnr ") */\n" \
|
||||
" move.l %3,-(%%sp) \n" \
|
||||
" move.w %2,-(%%sp) \n" \
|
||||
" move.w %1,-(%%sp) \n" \
|
||||
" move.w %[calln],-(%%sp)\n" \
|
||||
" jbsr (%[entry])\n" \
|
||||
" add.l #10,%%sp \n" \
|
||||
: "=r"(retvalue) /* output */ \
|
||||
: "r"(_p1), "r"(_p2), \
|
||||
"r"(_p3), /* input */ \
|
||||
[entry]"a"(gXHDIEntryPoint), \
|
||||
[calln]"i"(callnr) \
|
||||
: XHDI_CLOBBER_LIST /* clobbered regs */ \
|
||||
); \
|
||||
retvalue; \
|
||||
})
|
||||
|
||||
#define xhdicallWWLL(callnr, p1, p2, p3, p4) \
|
||||
({ \
|
||||
register int32 retvalue __asm__("d0"); \
|
||||
int16 _p1 = (int16)(p1); \
|
||||
int16 _p2 = (int16)(p2); \
|
||||
int32 _p3 = (int32)(p3); \
|
||||
int32 _p4 = (int32)(p4); \
|
||||
\
|
||||
__asm__ volatile \
|
||||
("/* xhdicall(" #callnr ") */\n" \
|
||||
" move.l %4,-(%%sp) \n" \
|
||||
" move.l %3,-(%%sp) \n" \
|
||||
" move.w %2,-(%%sp) \n" \
|
||||
" move.w %1,-(%%sp) \n" \
|
||||
" move.w %[calln],-(%%sp)\n" \
|
||||
" jbsr (%[entry])\n" \
|
||||
" add.l #14,%%sp \n" \
|
||||
: "=r"(retvalue) /* output */ \
|
||||
: "r"(_p1), "r"(_p2), \
|
||||
"r"(_p3), "r"(_p4), /* input */ \
|
||||
[entry]"a"(gXHDIEntryPoint), \
|
||||
[calln]"i"(callnr) \
|
||||
: XHDI_CLOBBER_LIST /* clobbered regs */ \
|
||||
); \
|
||||
retvalue; \
|
||||
})
|
||||
|
||||
#define xhdicallWWLLL(callnr, p1, p2, p3, p4, p5) \
|
||||
({ \
|
||||
register int32 retvalue __asm__("d0"); \
|
||||
int16 _p1 = (int16)(p1); \
|
||||
int16 _p2 = (int16)(p2); \
|
||||
int32 _p3 = (int32)(p3); \
|
||||
int32 _p4 = (int32)(p4); \
|
||||
int32 _p5 = (int32)(p5); \
|
||||
\
|
||||
__asm__ volatile \
|
||||
("/* xhdicall(" #callnr ") */\n" \
|
||||
" move.l %5,-(%%sp) \n" \
|
||||
" move.l %4,-(%%sp) \n" \
|
||||
" move.l %3,-(%%sp) \n" \
|
||||
" move.w %2,-(%%sp) \n" \
|
||||
" move.w %1,-(%%sp) \n" \
|
||||
" move.w %[calln],-(%%sp)\n" \
|
||||
" jbsr (%[entry])\n" \
|
||||
" add.l #18,%%sp \n" \
|
||||
: "=r"(retvalue) /* output */ \
|
||||
: "r"(_p1), "r"(_p2), \
|
||||
"r"(_p3), "r"(_p4), \
|
||||
"r"(_p5), /* input */ \
|
||||
[entry]"a"(gXHDIEntryPoint), \
|
||||
[calln]"i"(callnr) \
|
||||
: XHDI_CLOBBER_LIST /* clobbered regs */ \
|
||||
); \
|
||||
retvalue; \
|
||||
})
|
||||
|
||||
#define xhdicallWLLLL(callnr, p1, p2, p3, p4, p5) \
|
||||
({ \
|
||||
register int32 retvalue __asm__("d0"); \
|
||||
int16 _p1 = (int16)(p1); \
|
||||
int32 _p2 = (int32)(p2); \
|
||||
int32 _p3 = (int32)(p3); \
|
||||
int32 _p4 = (int32)(p4); \
|
||||
int32 _p5 = (int32)(p5); \
|
||||
\
|
||||
__asm__ volatile \
|
||||
("/* xhdicall(" #callnr ") */\n" \
|
||||
" move.l %5,-(%%sp) \n" \
|
||||
" move.l %4,-(%%sp) \n" \
|
||||
" move.l %3,-(%%sp) \n" \
|
||||
" move.l %2,-(%%sp) \n" \
|
||||
" move.w %1,-(%%sp) \n" \
|
||||
" move.w %[calln],-(%%sp)\n" \
|
||||
" jbsr (%[entry])\n" \
|
||||
" add.l #20,%%sp \n" \
|
||||
: "=r"(retvalue) /* output */ \
|
||||
: "r"(_p1), "r"(_p2), \
|
||||
"r"(_p3), "r"(_p4), \
|
||||
"r"(_p5), /* input */ \
|
||||
[entry]"a"(gXHDIEntryPoint), \
|
||||
[calln]"i"(callnr) \
|
||||
: XHDI_CLOBBER_LIST /* clobbered regs */ \
|
||||
); \
|
||||
retvalue; \
|
||||
})
|
||||
|
||||
#define xhdicallWWWLWL(callnr, p1, p2, p3, p4, p5, p6) \
|
||||
({ \
|
||||
register int32 retvalue __asm__("d0"); \
|
||||
int16 _p1 = (int16)(p1); \
|
||||
int16 _p2 = (int16)(p2); \
|
||||
int16 _p3 = (int16)(p3); \
|
||||
int32 _p4 = (int32)(p4); \
|
||||
int16 _p5 = (int16)(p5); \
|
||||
int32 _p6 = (int32)(p6); \
|
||||
\
|
||||
__asm__ volatile \
|
||||
("/* xhdicall(" #callnr ") */\n" \
|
||||
" move.l %6,-(%%sp) \n" \
|
||||
" move.w %5,-(%%sp) \n" \
|
||||
" move.l %4,-(%%sp) \n" \
|
||||
" move.w %3,-(%%sp) \n" \
|
||||
" move.w %2,-(%%sp) \n" \
|
||||
" move.w %1,-(%%sp) \n" \
|
||||
" move.w %[calln],-(%%sp)\n" \
|
||||
" jbsr (%[entry])\n" \
|
||||
" add.l #18,%%sp \n" \
|
||||
: "=r"(retvalue) /* output */ \
|
||||
: "r"(_p1), "r"(_p2), \
|
||||
"r"(_p3), "r"(_p4), \
|
||||
"r"(_p5), "r"(_p6), /* input */ \
|
||||
[entry]"a"(gXHDIEntryPoint), \
|
||||
[calln]"i"(callnr) \
|
||||
: XHDI_CLOBBER_LIST /* clobbered regs */ \
|
||||
); \
|
||||
retvalue; \
|
||||
})
|
||||
|
||||
#define xhdicallWWP(callnr, p1, p2, p3) \
|
||||
xhdicallWWL(callnr, p1, p2, (int32)p3)
|
||||
#define xhdicallWWPP(callnr, p1, p2, p3, p4) \
|
||||
xhdicallWWLL(callnr, p1, p2, (int32)p3, (int32)p4)
|
||||
#define xhdicallWWPPP(callnr, p1, p2, p3, p4, p5) \
|
||||
xhdicallWWLLL(callnr, p1, p2, (int32)p3, (int32)p4, (int32)p5)
|
||||
#define xhdicallWPPPP(callnr, p1, p2, p3, p4, p5) \
|
||||
xhdicallWLLLL(callnr, p1, (uint32)p2, (int32)p3, (int32)p4, (int32)p5)
|
||||
#define xhdicallWWWPWP(callnr, p1, p2, p3, p4, p5, p6) \
|
||||
xhdicallWWWLWL(callnr, p1, p2, p3, (int32)p4, p5, (uint32)p6)
|
||||
|
||||
#define XHGetVersion() (uint16)xhdicallV(0)
|
||||
#define XHInqTarget(major, minor, bsize, flags, pname) xhdicallWWPPP(1, (uint16)major, (uint16)minor, (uint32 *)bsize, (uint32 *)flags, (char *)pname)
|
||||
@@ -415,18 +570,18 @@ extern status_t init_xhdi(void);
|
||||
//#define XHStop() 4
|
||||
#define XHEject(major, minor, doeject, key) xhdicallWWWW(5, (uint16)major, (uint16)minor, (uint16)doeject, (uint16)key)
|
||||
#define XHDrvMap() xhdicallV(6)
|
||||
//#define XHInqDev(dev,) xhdicall(7,)
|
||||
#define XHInqDev(dev,major,minor,startsect,bpb) xhdicallWPPPP(7,dev,(uint16 *)major,(uint16 *)minor,(uint32 *)startsect,(struct tos_bpb *)bpb)
|
||||
//XHInqDriver 8
|
||||
//XHNewCookie 9
|
||||
#define XHReadWrite(major, minor, rwflags, recno, count, buf) xhdicalWWWLWP(10, (uint16)major, (uint16)minor, (uint16)rwflags, (uint32)recno, (uint16)count, (void *)buf)
|
||||
#define XHInqTarget2(major, minor, bsize, flags, pname, pnlen) xhdicallWWPPPW(11, (uint16)major, (uint16)minor, (uint32 *)bsize, (uint32 *)flags, (char *)pname, (uint16)pnlen)
|
||||
//XHInqDev2 12
|
||||
//XHDriverSpecial 13
|
||||
#define XHGetCapacity(major, minor, blocks, blocksize) xhdicall(14, (uint16)major, (uint16)minor, (uint32 *)blocks, (uint32 *)blocksize)
|
||||
#define XHGetCapacity(major, minor, blocks, blocksize) xhdicallWWPP(14, (uint16)major, (uint16)minor, (uint32 *)blocks, (uint32 *)blocksize)
|
||||
//#define XHMediumChanged() 15
|
||||
//XHMiNTInfo 16
|
||||
//XHDosLimits 17
|
||||
//XHLastAccess 18
|
||||
#define XHLastAccess(major, minor, ms) xhdicallWWP(18, major, minor, (uint32 *)ms)
|
||||
//SHReaccess 19
|
||||
|
||||
#endif /* __ASSEMBLER__ */
|
||||
|
||||
Reference in New Issue
Block a user