dpc: add dpc_prepare

This commit is contained in:
2025-12-28 03:50:00 +01:00
parent a81ae88afb
commit 99d3374fc0
11 changed files with 45 additions and 27 deletions
+4 -4
View File
@@ -204,7 +204,7 @@ void ahci_dpc(context_t *, dpcarg_t arg) {
}
// notify waiters about command completion
while (port_data->waiters[port_data->command_waiting] &&
while (port_data->waiters[port_data->command_waiting] &&
(port_data->ahci->ports[port].ci & (1 << port_data->command_waiting)) == 0) {
thread_t *thread = port_data->waiters[port_data->command_waiting];
port_data->waiters[port_data->command_waiting] = NULL;
@@ -230,7 +230,7 @@ void ahci_isr(isr_t *isr, context_t *) {
if (ahci->port_data[i] == NULL)
continue;
dpc_enqueue(&ahci->port_data[i]->dpc, ahci_dpc, ahci->port_data[i]);
dpc_enqueue(&ahci->port_data[i]->dpc, ahci->port_data[i]);
ports_pending &= ~(1 << i);
ahci->ports[i].is = ahci->ports[i].is;
@@ -413,7 +413,7 @@ static void init_port(ahci_t *ahci, int port) {
return;
}
ahci->port_data[port]->sector_count = (uint64_t)identify->lba48_size[0] | ((uint64_t)identify->lba48_size[1] << 16) |
ahci->port_data[port]->sector_count = (uint64_t)identify->lba48_size[0] | ((uint64_t)identify->lba48_size[1] << 16) |
((uint64_t)identify->lba48_size[2] << 32) | ((uint64_t)identify->lba48_size[3] << 48);
printf("ahci%dp%d: ATA drive with %lu sectors\n", ahci->id, port, ahci->port_data[port]->sector_count);
@@ -549,7 +549,6 @@ static void init_controller(pcienum_t *pci_enum) {
continue;
}
// program command list base
void *cmd_ptr = (void *)((uintptr_t)command_slot_mem + command_slot_offset);
memset(MAKE_HHDM(cmd_ptr), 0, 1024);
@@ -609,6 +608,7 @@ static void init_controller(pcienum_t *pci_enum) {
port_data->command_list = MAKE_HHDM(cmd_ptr);
SPINLOCK_INIT(port_data->command_lock);
SEMAPHORE_INIT(&port_data->command_semaphore, ahci->command_slot_count);
dpc_prepare(&port_data->dpc, ahci_dpc);
ahci->port_data[i] = port_data;
}
+4 -1
View File
@@ -299,7 +299,7 @@ static void nvme_dpc(context_t *, dpcarg_t arg) {
static void nvme_irq(isr_t *isr, context_t *context) {
queuepair_t *pair = isr->priv;
dpc_enqueue(&pair->dpc, nvme_dpc, pair);
dpc_enqueue(&pair->dpc, pair);
}
static isr_t *msixnewisrforqueue(queuepair_t *queuepair) {
@@ -458,6 +458,7 @@ static int createiosubqueue(nvmecontroller_t *controller, queuedesc_t *desc, siz
}
static void newioqueuepair(nvmecontroller_t *controller, queuepair_t *pair, int id) {
dpc_prepare(&pair->dpc, nvme_dpc);
__assert(createiocompqueue(controller, &pair->completion, QUEUEPAIR_ENTRY_COUNT, id, id, 0) == 0);
__assert(createiosubqueue(controller, &pair->submission, QUEUEPAIR_ENTRY_COUNT, id, id, 0) == 0);
pair->controller = controller;
@@ -813,6 +814,8 @@ static void initcontroller(pcienum_t *e) {
controller->adminqueue.completion.doorbell = GET_DOORBELL(controller->bar0, 0, 1, controller->dbstride);
controller->adminqueue.completion.phase = 1;
dpc_prepare(&controller->adminqueue.dpc, nvme_dpc);
SPINLOCK_INIT(controller->adminqueue.lock);
SEMAPHORE_INIT(&controller->adminqueue.entrysem, QUEUEPAIR_ENTRY_COUNT);
+2 -1
View File
@@ -54,7 +54,7 @@ static void vioblk_dpc(context_t *context, dpcarg_t arg) {
static void vioblk_irq(isr_t *isr, context_t *context) {
vioblkdev_t *blkdev = isr->priv;
dpc_enqueue(&blkdev->queuedpc, vioblk_dpc, blkdev);
dpc_enqueue(&blkdev->queuedpc, blkdev);
}
// driver and device are physical addresses
@@ -176,6 +176,7 @@ int vioblk_newdevice(viodevice_t *viodevice) {
// initialize device object
vioblkdev_t *blkdev = alloc(sizeof(vioblkdev_t));
__assert(blkdev);
dpc_prepare(&blkdev->queuedpc, vioblk_dpc);
static int id = 0;
volatile blkdevconfig_t *blkconfig = viodevice->devconfig;
+2 -1
View File
@@ -43,7 +43,8 @@ static int loopback_sendpacket(netdev_t *netdev, netdesc_t desc, mac_t targetmac
memcpy(desc.address, &ethframe, sizeof(ethframe_t));
dpc_t dpc = {0};
dpc_enqueue(&dpc, rx_dpc, desc.address);
dpc_prepare(&dpc, rx_dpc);
dpc_enqueue(&dpc, desc.address);
return 0;
}
+6 -3
View File
@@ -152,10 +152,10 @@ static void rtl8169_isr(isr_t *self, context_t *) {
outw(dev->bar.address + REGISTER_IRQ_STATUS, status);
if (status & (REGISTER_IRQ_STATUS_TX_OK | REGISTER_IRQ_STATUS_TX_ERROR))
dpc_enqueue(&dev->tx_dpc, rtl8169_dpc_tx, dev);
dpc_enqueue(&dev->tx_dpc, dev);
if (status & (REGISTER_IRQ_STATUS_RX_OK | REGISTER_IRQ_STATUS_RX_ERROR))
dpc_enqueue(&dev->rx_dpc, rtl8169_dpc_rx, dev);
dpc_enqueue(&dev->rx_dpc, dev);
status = inw(dev->bar.address + REGISTER_IRQ_STATUS);
}
@@ -311,7 +311,7 @@ static void init_controller(pcienum_t *pci_enum) {
outb(pci_bar.address + REGISTER_COMMAND, REGISTER_COMMAND_TX_ENABLE);
outd(pci_bar.address + REGISTER_TX_CONFIG, REGISTER_TX_CONFIG_DMA_BURST_UNLIMITED | REGISTER_TX_CONFIG_IFG_NORMAL);
outw(pci_bar.address + REGISTER_RX_MAX_SIZE, 1518);
// 128 * 0xc, enough for an ethernet MTU (while 0xb would be enough, the datasheet says that it must be larger than the max size)
outb(pci_bar.address + REGISTER_TX_MAX_SIZE, 0xc);
@@ -337,6 +337,9 @@ static void init_controller(pcienum_t *pci_enum) {
SEMAPHORE_INIT(&netdev->tx_semaphore, TX_DESCRIPTOR_COUNT);
SPINLOCK_INIT(netdev->tx_lock);
dpc_prepare(&netdev->tx_dpc, rtl8169_dpc_tx);
dpc_prepare(&netdev->rx_dpc, rtl8169_dpc_rx);
isr->priv = netdev;
char name[10];
+4 -2
View File
@@ -54,7 +54,7 @@ static void rx_dpc(context_t *context, dpcarg_t arg) {
static void rx_irq(isr_t *isr, context_t *context) {
vionetdev_t *netdev = isr->priv;
dpc_enqueue(&netdev->rxdpc, rx_dpc, netdev);
dpc_enqueue(&netdev->rxdpc, netdev);
}
static void tx_dpc(context_t *context, dpcarg_t arg) {
@@ -75,7 +75,7 @@ static void tx_dpc(context_t *context, dpcarg_t arg) {
static void tx_irq(isr_t *isr, context_t *context) {
vionetdev_t *netdev = isr->priv;
dpc_enqueue(&netdev->txdpc, tx_dpc, netdev);
dpc_enqueue(&netdev->txdpc, netdev);
}
#define PREFIX_SIZE (sizeof(ethframe_t) + sizeof(vioframe_t))
@@ -178,6 +178,8 @@ int vionet_newdevice(viodevice_t *viodevice) {
netdev->netdev.allocdesc = vionet_allocdesc;
netdev->netdev.freedesc = vionet_freedesc;
__assert(hashtable_init(&netdev->netdev.arpcache, 30) == 0);
dpc_prepare(&netdev->rxdpc, rx_dpc);
dpc_prepare(&netdev->txdpc, tx_dpc);
// initialize queues
size_t rxsize = min(QUEUE_MAX_SIZE, virtio_queuesize(viodevice, 0));