static void print_info(struct ddb *db) { static const char yes[] = "true"; static const char no[] = "false"; const char *boolstr(int boolean) { return boolean ? yes: no; } ddb_features_t feat; ddb_features(db, feat); printf("Total size: %llu bytes\n", FEAT(DDB_TOTAL_SIZE)); printf("Items size: %llu bytes\n", FEAT(DDB_ITEMS_SIZE)); printf("Values size: %llu bytes\n", FEAT(DDB_VALUES_SIZE)); printf("Number of keys: %llu\n", FEAT(DDB_NUM_KEYS)); printf("Number of items: %llu\n", FEAT(DDB_NUM_VALUES)); printf("Number of unique values: %llu\n", FEAT(DDB_NUM_UNIQUE_VALUES)); printf("Compressed? %s\n", boolstr(feat[DDB_IS_COMPRESSED])); printf("Hashed? %s\n", boolstr(feat[DDB_IS_HASHED])); printf("Multiset? %s\n", boolstr(feat[DDB_IS_MULTISET])); }
VirtioBlk::VirtioBlk(hw::PCI_Device& d) : Virtio(d), hw::Drive(), req(queue_size(0), 0, iobase()), inflight(0) { INFO("VirtioBlk", "Driver initializing"); { auto& reqs = Statman::get().create( Stat::UINT32, blkname() + ".requests"); this->requests = &reqs.get_uint32(); *this->requests = 0; auto& err = Statman::get().create( Stat::UINT32, blkname() + ".errors"); this->errors = &err.get_uint32(); *this->errors = 0; } uint32_t needed_features = FEAT(VIRTIO_BLK_F_BLK_SIZE); negotiate_features(needed_features); CHECK(features() & FEAT(VIRTIO_BLK_F_BARRIER), "Barrier is enabled"); CHECK(features() & FEAT(VIRTIO_BLK_F_SIZE_MAX), "Size-max is known"); CHECK(features() & FEAT(VIRTIO_BLK_F_SEG_MAX), "Seg-max is known"); CHECK(features() & FEAT(VIRTIO_BLK_F_GEOMETRY), "Geometry structure is used"); CHECK(features() & FEAT(VIRTIO_BLK_F_RO), "Device is read-only"); CHECK(features() & FEAT(VIRTIO_BLK_F_BLK_SIZE), "Block-size is known"); CHECK(features() & FEAT(VIRTIO_BLK_F_SCSI), "SCSI is enabled :("); CHECK(features() & FEAT(VIRTIO_BLK_F_FLUSH), "Flush enabled"); CHECK ((features() & needed_features) == needed_features, "Negotiated needed features"); // Step 1 - Initialize REQ queue auto success = assign_queue(0, (uint32_t) req.queue_desc()); CHECK(success, "Request queue assigned (0x%x) to device", (uint32_t) req.queue_desc()); // Step 3 - Fill receive queue with buffers // DEBUG: Disable INFO("VirtioBlk", "Queue size: %i\tRequest size: %u\n", req.size(), sizeof(request_t)); // Get device configuration get_config(); // Signal setup complete. setup_complete((features() & needed_features) == needed_features); CHECK((features() & needed_features) == needed_features, "Signalled driver OK"); // Hook up IRQ handler (inherited from Virtio) if (is_msix()) { // update IRQ subscriptions IRQ_manager::get().subscribe(irq() + 0, {this, &VirtioBlk::service_RX}); IRQ_manager::get().subscribe(irq() + 1, {this, &VirtioBlk::msix_conf_handler}); } else { auto del(delegate<void()>{this, &VirtioBlk::irq_handler}); IRQ_manager::get().subscribe(irq(), del); } // Done INFO("VirtioBlk", "Block device with %llu sectors capacity", config.capacity); }