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:
François Revol
2008-01-18 01:50:36 +00:00
parent 21e73322d8
commit b516effeaa
3 changed files with 295 additions and 36 deletions
+126 -29
View File
@@ -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;
}
+161 -6
View File
@@ -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__ */