return version;
}
-// Extract common information from IDENTIFY commands.
-static void
-extract_identify(struct drive_s *drive_g, u16 *buffer)
-{
- dprintf(3, "Identify w0=%x w2=%x\n", buffer[0], buffer[2]);
+#define MAXMODEL 40
+// Extract the ATA/ATAPI model info.
+static char *
+extract_model(char *model, u16 *buffer)
+{
// Read model name
- char *model = drive_g->model;
- int maxsize = ARRAY_SIZE(drive_g->model);
int i;
- for (i=0; i<maxsize/2; i++) {
- u16 v = buffer[27+i];
- model[i*2] = v >> 8;
- model[i*2+1] = v & 0xff;
- }
- model[maxsize-1] = 0x00;
+ for (i=0; i<MAXMODEL/2; i++)
+ *(u16*)&model[i*2] = ntohs(buffer[27+i]);
+ model[MAXMODEL] = 0x00;
// Trim trailing spaces from model name.
- for (i=maxsize-2; i>0 && model[i] == 0x20; i--)
+ for (i=MAXMODEL-1; i>0 && model[i] == 0x20; i--)
model[i] = 0x00;
- // Common flags.
- SET_GLOBAL(drive_g->removable, (buffer[0] & 0x80) ? 1 : 0);
- SET_GLOBAL(drive_g->cntl_info, extract_version(buffer));
-}
-
-// Print out a description of the given atapi drive.
-void
-describe_atapi(struct drive_s *drive_g)
-{
- u8 ataid = drive_g->cntl_id;
- u8 channel = ataid / 2;
- u8 slave = ataid % 2;
- u8 version = drive_g->cntl_info;
- int iscd = drive_g->floppy_type;
- printf("ata%d-%d: %s ATAPI-%d %s", channel, slave
- , drive_g->model, version
- , (iscd ? "CD-Rom/DVD-Rom" : "Device"));
+ return model;
}
// Detect if the given drive is an atapi - initialize it if so.
return NULL;
// Success - setup as ATAPI.
+ char *desc = malloc_tmp(MAXDESCSIZE);
struct drive_s *drive_g = malloc_fseg(sizeof(*drive_g));
- if (! drive_g) {
+ if (!drive_g || !desc) {
warn_noalloc();
+ free(desc);
+ free(drive_g);
return NULL;
}
memset(drive_g, 0, sizeof(*drive_g));
SET_GLOBAL(drive_g->cntl_id, dummy->cntl_id);
- extract_identify(drive_g, buffer);
SET_GLOBAL(drive_g->type, DTYPE_ATAPI);
SET_GLOBAL(drive_g->blksize, CDROM_SECTOR_SIZE);
SET_GLOBAL(drive_g->sectors, (u64)-1);
+ SET_GLOBAL(drive_g->removable, (buffer[0] & 0x80) ? 1 : 0);
u8 iscd = ((buffer[0] >> 8) & 0x1f) == 0x05;
- SET_GLOBAL(drive_g->floppy_type, iscd);
+ u8 ataid = drive_g->cntl_id;
+ u8 channel = ataid / 2;
+ u8 slave = ataid % 2;
+ char model[MAXMODEL+1];
+ drive_g->desc = desc;
+ snprintf(desc, MAXDESCSIZE, "ata%d-%d: %s ATAPI-%d %s", channel, slave
+ , extract_model(model, buffer), extract_version(buffer)
+ , (iscd ? "CD-Rom/DVD-Rom" : "Device"));
// fill cdidmap
if (iscd)
return drive_g;
}
-// Print out a description of the given ata drive.
-void
-describe_ata(struct drive_s *drive_g)
-{
- u8 ataid = drive_g->cntl_id;
- u8 channel = ataid / 2;
- u8 slave = ataid % 2;
- u64 sectors = drive_g->sectors;
- u8 version = drive_g->cntl_info;
- char *model = drive_g->model;
- printf("ata%d-%d: %s ATA-%d Hard-Disk", channel, slave, model, version);
- u64 sizeinmb = sectors >> 11;
- if (sizeinmb < (1 << 16))
- printf(" (%u MiBytes)", (u32)sizeinmb);
- else
- printf(" (%u GiBytes)", (u32)(sizeinmb >> 10));
-}
-
// Detect if the given drive is a regular ata drive - initialize it if so.
static struct drive_s *
init_drive_ata(struct drive_s *dummy, u16 *buffer)
return NULL;
// Success - setup as ATA.
+ char *desc = malloc_tmp(MAXDESCSIZE);
struct drive_s *drive_g = malloc_fseg(sizeof(*drive_g));
- if (! drive_g) {
+ if (!drive_g || !desc) {
warn_noalloc();
+ free(desc);
+ free(drive_g);
return NULL;
}
memset(drive_g, 0, sizeof(*drive_g));
SET_GLOBAL(drive_g->cntl_id, dummy->cntl_id);
- extract_identify(drive_g, buffer);
SET_GLOBAL(drive_g->type, DTYPE_ATA);
SET_GLOBAL(drive_g->blksize, DISK_SECTOR_SIZE);
else
sectors = *(u32*)&buffer[60]; // word 60 and word 61
SET_GLOBAL(drive_g->sectors, sectors);
+ SET_GLOBAL(drive_g->removable, (buffer[0] & 0x80) ? 1 : 0);
+ u8 ataid = drive_g->cntl_id;
+ u8 channel = ataid / 2;
+ u8 slave = ataid % 2;
+ u64 adjsize = sectors >> 11;
+ char adjprefix = 'M';
+ if (adjsize >= (1 << 16)) {
+ adjsize >>= 10;
+ adjprefix = 'G';
+ }
+ char model[MAXMODEL+1];
+ drive_g->desc = desc;
+ snprintf(desc, MAXDESCSIZE, "ata%d-%d: %s ATA-%d Hard-Disk (%u %ciBytes)"
+ , channel, slave
+ , extract_model(model, buffer), extract_version(buffer)
+ , (u32)adjsize, adjprefix);
// Setup disk geometry translation.
setup_translation(drive_g);
void ata_setup(void);
int process_ata_op(struct disk_op_s *op);
int process_atapi_op(struct disk_op_s *op);
-void describe_ata(struct drive_s *drive_g);
-void describe_atapi(struct drive_s *drive_g);
// Global defines -- ATA register and register bits.
// command block & control block regs
}
}
-// Show a one line description (without trailing newline) of a drive.
-void
-describe_drive(struct drive_s *drive_g)
-{
- ASSERT32FLAT();
- u8 type = GET_GLOBAL(drive_g->type);
- switch (type) {
- case DTYPE_FLOPPY:
- describe_floppy(drive_g);
- break;
- case DTYPE_ATA:
- describe_ata(drive_g);
- break;
- case DTYPE_ATAPI:
- describe_atapi(drive_g);
- break;
- case DTYPE_RAMDISK:
- describe_ramdisk(drive_g);
- break;
- case DTYPE_USB:
- describe_usb(drive_g);
- break;
- default:
- printf("Unknown");
- break;
- }
-}
-
/****************************************************************
* 16bit calling interface
int i;
for (i = 0; i < Drives.floppycount; i++) {
struct drive_s *drive_g = getDrive(EXTTYPE_FLOPPY, i);
- printf("%d. Floppy [", menupos + i);
- describe_drive(drive_g);
- printf("]\n");
+ printf("%d. Floppy [%s]\n", menupos + i, drive_g->desc);
}
return Drives.floppycount;
}
int i;
for (i = 0; i < IPL.bcvcount; i++) {
struct ipl_entry_s *ie = &IPL.bcv[i];
+ struct drive_s *drive_g = (void*)ie->vector;
switch (ie->type) {
case BCV_TYPE_INTERNAL:
- printf("%d. ", menupos + i);
- describe_drive((void*)ie->vector);
- printf("\n");
+ printf("%d. %s\n", menupos + i, drive_g->desc);
break;
default:
menu_show_default(ie, menupos+i);
int i;
for (i = 0; i < Drives.cdcount; i++) {
struct drive_s *drive_g = getDrive(EXTTYPE_CD, i);
- printf("%d. CD-Rom [", menupos + i);
- describe_drive(drive_g);
- printf("]\n");
+ printf("%d. CD-Rom [%s]\n", menupos + i, drive_g->desc);
}
return Drives.cdcount;
}
u8 floppy_type; // Type of floppy (only for floppy drives).
struct chs_s lchs; // Logical CHS
u64 sectors; // Total sectors count
+ char *desc; // Drive description (only available during POST)
+ u32 cntl_id; // Unique id for a given driver type.
+ u8 removable; // Is media removable (currently unused)
// Info for EDD calls
+ u8 translation; // type of translation
u16 blksize; // block size
struct chs_s pchs; // Physical CHS
- u8 translation; // type of translation
-
- // Driver specific
- u32 cntl_id;
- u32 cntl_info;
- u8 removable; // Removable device flag
- char model[41];
};
#define DISK_SECTOR_SIZE 512
#define DTYPE_CDEMU 0x05
#define DTYPE_USB 0x06
+#define MAXDESCSIZE 80
+
#define TRANSLATION_NONE 0
#define TRANSLATION_LBA 1
#define TRANSLATION_LARGE 2
void map_floppy_drive(struct drive_s *drive_g);
void map_hd_drive(struct drive_s *drive_g);
void map_cd_drive(struct drive_s *drive_g);
-void describe_drive(struct drive_s *drive_g);
int process_op(struct disk_op_s *op);
int send_disk_op(struct disk_op_s *op);
void drive_setup(void);
extern struct floppy_ext_dbt_s diskette_param_table2;
void floppy_setup(void);
struct drive_s *addFloppy(int floppyid, int ftype, int driver);
-void describe_floppy(struct drive_s *drive_g);
int find_floppy_type(u32 size);
int process_floppy_op(struct disk_op_s *op);
void floppy_tick(void);
int cdrom_boot(int cdid);
// ramdisk.c
-void describe_ramdisk(struct drive_s *drive_g);
void ramdisk_setup(void);
int process_ramdisk_op(struct disk_op_s *op);
return NULL;
}
+ char *desc = malloc_tmp(MAXDESCSIZE);
struct drive_s *drive_g = malloc_fseg(sizeof(*drive_g));
- if (!drive_g) {
+ if (!drive_g || !desc) {
warn_noalloc();
+ free(desc);
+ free(drive_g);
return NULL;
}
memset(drive_g, 0, sizeof(*drive_g));
drive_g->blksize = DISK_SECTOR_SIZE;
drive_g->floppy_type = ftype;
drive_g->sectors = (u64)-1;
+ drive_g->desc = desc;
+ snprintf(desc, MAXDESCSIZE, "drive %c", 'A' + floppyid);
memcpy(&drive_g->lchs, &FloppyInfo[ftype].chs
, sizeof(FloppyInfo[ftype].chs));
return drive_g;
}
-void
-describe_floppy(struct drive_s *drive_g)
-{
- printf("drive %c", 'A' + drive_g->cntl_id);
-}
-
void
floppy_setup(void)
{
#include "biosvar.h" // GET_GLOBAL
#include "bregs.h" // struct bregs
-void
-describe_ramdisk(struct drive_s *drive_g)
-{
- printf("%s", drive_g->model);
-}
-
void
ramdisk_setup(void)
{
// Setup driver.
dprintf(1, "Mapping CBFS floppy %s to addr %p\n", cbfs_filename(file), pos);
struct drive_s *drive_g = addFloppy((u32)pos, ftype, DTYPE_RAMDISK);
- if (drive_g)
- strtcpy(drive_g->model, cbfs_filename(file), ARRAY_SIZE(drive_g->model));
+ if (!drive_g)
+ strtcpy(drive_g->desc, cbfs_filename(file), MAXDESCSIZE);
}
static int
#include "disk.h" // DTYPE_USB
#include "boot.h" // add_bcv_internal
-#define DESCSIZE 80
-
struct usbdrive_s {
struct drive_s drive;
struct usb_pipe *bulkin, *bulkout;
- char *desc;
};
}
}
-void
-describe_usb(struct drive_s *drive_g)
-{
- struct usbdrive_s *udrive_g = container_of(
- drive_g, struct usbdrive_s, drive);
- printf("%s", udrive_g->desc);
-}
-
/****************************************************************
* Setup
goto fail;
// Allocate drive structure.
- char *desc = malloc_tmphigh(DESCSIZE);
+ char *desc = malloc_tmphigh(MAXDESCSIZE);
struct usbdrive_s *udrive_g = malloc_fseg(sizeof(*udrive_g));
if (!udrive_g || !desc) {
warn_noalloc();
, strtcpy(product, data.product, sizeof(product))
, strtcpy(rev, data.rev, sizeof(rev))
, pdt, removable);
+ udrive_g->drive.removable = removable;
if (pdt == USB_MSC_TYPE_CDROM)
ret = setup_drive_cdrom(&dop);
if (ret)
goto fail;
- snprintf(desc, DESCSIZE, "USB Drive %s %s %s", vendor, product, rev);
- udrive_g->desc = desc;
+ snprintf(desc, MAXDESCSIZE, "USB Drive %s %s %s", vendor, product, rev);
+ udrive_g->drive.desc = desc;
return 0;
fail:
struct usb_interface_descriptor;
int usb_msc_init(u32 endp, struct usb_interface_descriptor *iface, int imax);
int process_usb_op(struct disk_op_s *op);
-struct drive_s;
-void describe_usb(struct drive_s *drive_g);
/****************************************************************
static inline void *malloc_tmphigh(u32 size) {
return pmm_malloc(&ZoneTmpHigh, PMM_DEFAULT_HANDLE, size, MALLOC_MIN_ALIGN);
}
+static inline void *malloc_tmp(u32 size) {
+ void *ret = malloc_tmphigh(size);
+ if (ret)
+ return ret;
+ return pmm_malloc(&ZoneTmpLow, PMM_DEFAULT_HANDLE, size, MALLOC_MIN_ALIGN);
+}
static inline void *memalign_low(u32 align, u32 size) {
return pmm_malloc(&ZoneLow, PMM_DEFAULT_HANDLE, size, align);
}