84 lines
2.0 KiB
C
84 lines
2.0 KiB
C
#include "sys/dev.h"
|
|
#include "sys/blk.h"
|
|
#include "sys/assert.h"
|
|
#include "sys/panic.h"
|
|
#include "sys/debug.h"
|
|
#include "sys/string.h"
|
|
|
|
static struct dev_entry *dev_begin = NULL;
|
|
static struct dev_entry *dev_end = NULL;
|
|
|
|
static uint64_t dev_scsi_bitmap = 0;
|
|
static uint64_t dev_ide_bitmap = 0;
|
|
static int dev_ram_count = 0;
|
|
|
|
static int dev_alloc_block_name(uint16_t subclass, char *name) {
|
|
if (subclass == DEV_BLOCK_RAM) {
|
|
strcpy(name, "ram");
|
|
name[3] = dev_ram_count++ + '0';
|
|
name[4] = 0;
|
|
return 0;
|
|
}
|
|
if (subclass == DEV_BLOCK_SDx || subclass == DEV_BLOCK_HDx) {
|
|
uint64_t *bmp = subclass == DEV_BLOCK_SDx ? &dev_scsi_bitmap : &dev_ide_bitmap;
|
|
name[1] = 'd';
|
|
name[0] = subclass == DEV_BLOCK_SDx ? 's' : 'h';
|
|
|
|
for (size_t i = 0; i < 64; ++i) {
|
|
if (!(*bmp & (1ULL << i))) {
|
|
*bmp |= 1ULL << i;
|
|
name[2] = 'a' + i;
|
|
name[3] = 0;
|
|
return 0;
|
|
}
|
|
}
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
int dev_alloc_name(enum dev_class cls, uint16_t subclass, char *name) {
|
|
switch (cls) {
|
|
case DEV_CLASS_BLOCK:
|
|
return dev_alloc_block_name(subclass, name);
|
|
default:
|
|
panic("Not implemented\n");
|
|
}
|
|
}
|
|
|
|
static int dev_post_add(struct dev_entry *ent) {
|
|
if (ent->dev_class == DEV_CLASS_BLOCK) {
|
|
struct blkdev *blk = (struct blkdev *) ent->dev;
|
|
|
|
blk->ent = ent;
|
|
|
|
if (ent->dev_subclass < DEV_BLOCK_PART) {
|
|
if (blk_enumerate_partitions((struct blkdev *) ent->dev) != 0) {
|
|
return -1;
|
|
}
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
void dev_entry_add(struct dev_entry *ent) {
|
|
ent->cdr = NULL;
|
|
|
|
if (dev_end) {
|
|
dev_end->cdr = ent;
|
|
} else {
|
|
dev_begin = ent;
|
|
}
|
|
|
|
dev_end = ent;
|
|
|
|
kdebug("Add device %s\n", ent->dev_name);
|
|
|
|
// For example: enumerate partitions on block devices
|
|
_assert(dev_post_add(ent) == 0);
|
|
}
|
|
|
|
struct dev_entry *dev_iter(void) {
|
|
return dev_begin;
|
|
}
|