static int signalinsert_inner(struct visorchannel *channel, u32 queue, void *msg) { struct signal_queue_header sig_hdr; int err; err = sig_read_header(channel, queue, &sig_hdr); if (err) return err; sig_hdr.head = (sig_hdr.head + 1) % sig_hdr.max_slots; if (sig_hdr.head == sig_hdr.tail) { sig_hdr.num_overflows++; err = SIG_WRITE_FIELD(channel, queue, &sig_hdr, num_overflows); if (err) return err; return -EIO; } err = sig_write_data(channel, queue, &sig_hdr, sig_hdr.head, msg); if (err) return err; sig_hdr.num_sent++; /* * For each data field in SIGNAL_QUEUE_HEADER that was modified, update * host memory. Required for channel sync. */ mb(); err = SIG_WRITE_FIELD(channel, queue, &sig_hdr, head); if (err) return err; err = SIG_WRITE_FIELD(channel, queue, &sig_hdr, num_sent); if (err) return err; return 0; }
static int signalremove_inner(struct visorchannel *channel, u32 queue, void *msg) { struct signal_queue_header sig_hdr; int error; error = sig_read_header(channel, queue, &sig_hdr); if (error) return error; /* No signals to remove; have caller try again. */ if (sig_hdr.head == sig_hdr.tail) return -EAGAIN; sig_hdr.tail = (sig_hdr.tail + 1) % sig_hdr.max_slots; error = sig_read_data(channel, queue, &sig_hdr, sig_hdr.tail, msg); if (error) return error; sig_hdr.num_received++; /* * For each data field in SIGNAL_QUEUE_HEADER that was modified, update * host memory. Required for channel sync. */ mb(); error = SIG_WRITE_FIELD(channel, queue, &sig_hdr, tail); if (error) return error; error = SIG_WRITE_FIELD(channel, queue, &sig_hdr, num_received); if (error) return error; return 0; }
static BOOL signalremove_inner(struct visorchannel *channel, u32 queue, void *msg) { struct signal_queue_header sig_hdr; if (!sig_read_header(channel, queue, &sig_hdr)) { return FALSE; } if (sig_hdr.head == sig_hdr.tail) return FALSE; /* no signals to remove */ sig_hdr.tail = (sig_hdr.tail + 1) % sig_hdr.max_slots; if (!sig_read_data(channel, queue, &sig_hdr, sig_hdr.tail, msg)) { ERRDRV("sig_read_data failed\n"); return FALSE; } sig_hdr.num_received++; /* For each data field in SIGNAL_QUEUE_HEADER that was modified, * update host memory. */ mb(); /* required for channel synch */ if (!SIG_WRITE_FIELD(channel, queue, &sig_hdr, tail)) { ERRDRV("visor_memregion_write of Tail failed\n"); return FALSE; } if (!SIG_WRITE_FIELD(channel, queue, &sig_hdr, num_received)) { ERRDRV("visor_memregion_write of NumSignalsReceived failed\n"); return FALSE; } return TRUE; }
int visorchannel_signalqueue_max_slots(VISORCHANNEL *channel, U32 queue) { SIGNAL_QUEUE_HEADER sig_hdr; if (!sig_read_header(channel, queue, &sig_hdr)) return 0; return (int) sig_hdr.MaxSignals; }
static bool queue_empty(struct visorchannel *channel, u32 queue) { struct signal_queue_header sig_hdr; if (sig_read_header(channel, queue, &sig_hdr)) return true; return (sig_hdr.head == sig_hdr.tail); }
int visorchannel_signalqueue_max_slots(VISORCHANNEL *channel, u32 queue) { struct signal_queue_header sig_hdr; if (!sig_read_header(channel, queue, &sig_hdr)) return 0; return (int)sig_hdr.max_signals; }
BOOL visorchannel_signalinsert(VISORCHANNEL *channel, u32 queue, void *msg) { BOOL rc = FALSE; struct signal_queue_header sig_hdr; if (channel->needs_lock) spin_lock(&channel->insert_lock); if (!sig_read_header(channel, queue, &sig_hdr)) { rc = FALSE; goto cleanup; } sig_hdr.head = ((sig_hdr.head + 1) % sig_hdr.max_slots); if (sig_hdr.head == sig_hdr.tail) { sig_hdr.num_overflows++; if (!SIG_WRITE_FIELD(channel, queue, &sig_hdr, num_overflows)) { ERRDRV("visor_memregion_write of NumOverflows failed: (status=%d)\n", rc); goto cleanup; } rc = FALSE; goto cleanup; } if (!sig_write_data(channel, queue, &sig_hdr, sig_hdr.head, msg)) { ERRDRV("sig_write_data failed: (status=%d)\n", rc); goto cleanup; } sig_hdr.num_sent++; /* For each data field in SIGNAL_QUEUE_HEADER that was modified, * update host memory. */ mb(); /* required for channel synch */ if (!SIG_WRITE_FIELD(channel, queue, &sig_hdr, head)) { ERRDRV("visor_memregion_write of Head failed: (status=%d)\n", rc); goto cleanup; } if (!SIG_WRITE_FIELD(channel, queue, &sig_hdr, num_sent)) { ERRDRV("visor_memregion_write of NumSignalsSent failed: (status=%d)\n", rc); goto cleanup; } rc = TRUE; cleanup: if (channel->needs_lock) spin_unlock(&channel->insert_lock); return rc; }
BOOL visorchannel_signalinsert(VISORCHANNEL *channel, U32 queue, void *msg) { BOOL rc = FALSE; SIGNAL_QUEUE_HEADER sig_hdr; if (channel->needs_lock) spin_lock(&channel->insert_lock); if (!sig_read_header(channel, queue, &sig_hdr)) { rc = FALSE; goto Away; } sig_hdr.Head = ((sig_hdr.Head + 1) % sig_hdr.MaxSignalSlots); if (sig_hdr.Head == sig_hdr.Tail) { sig_hdr.NumOverflows++; if (!SIG_WRITE_FIELD(channel, queue, &sig_hdr, NumOverflows)) { ERRDRV("visor_memregion_write of NumOverflows failed: (status=%d)\n", rc); goto Away; } rc = FALSE; goto Away; } if (!sig_write_data(channel, queue, &sig_hdr, sig_hdr.Head, msg)) { ERRDRV("sig_write_data failed: (status=%d)\n", rc); goto Away; } sig_hdr.NumSignalsSent++; /* For each data field in SIGNAL_QUEUE_HEADER that was modified, * update host memory. */ MEMORYBARRIER; if (!SIG_WRITE_FIELD(channel, queue, &sig_hdr, Head)) { ERRDRV("visor_memregion_write of Head failed: (status=%d)\n", rc); goto Away; } if (!SIG_WRITE_FIELD(channel, queue, &sig_hdr, NumSignalsSent)) { ERRDRV("visor_memregion_write of NumSignalsSent failed: (status=%d)\n", rc); goto Away; } rc = TRUE; Away: if (channel->needs_lock) spin_unlock(&channel->insert_lock); return rc; }
int visorchannel_signalqueue_slots_avail(VISORCHANNEL *channel, U32 queue) { SIGNAL_QUEUE_HEADER sig_hdr; U32 slots_avail, slots_used; U32 head, tail; if (!sig_read_header(channel, queue, &sig_hdr)) return 0; head = sig_hdr.Head; tail = sig_hdr.Tail; if (head < tail) head = head + sig_hdr.MaxSignalSlots; slots_used = (head - tail); slots_avail = sig_hdr.MaxSignals - slots_used; return (int) slots_avail; }
int visorchannel_signalqueue_slots_avail(VISORCHANNEL *channel, u32 queue) { struct signal_queue_header sig_hdr; u32 slots_avail, slots_used; u32 head, tail; if (!sig_read_header(channel, queue, &sig_hdr)) return 0; head = sig_hdr.head; tail = sig_hdr.tail; if (head < tail) head = head + sig_hdr.max_slots; slots_used = (head - tail); slots_avail = sig_hdr.max_signals - slots_used; return (int)slots_avail; }
BOOL visorchannel_signalremove(VISORCHANNEL *channel, u32 queue, void *msg) { BOOL rc = FALSE; struct signal_queue_header sig_hdr; if (channel->needs_lock) spin_lock(&channel->remove_lock); if (!sig_read_header(channel, queue, &sig_hdr)) { rc = FALSE; goto cleanup; } if (sig_hdr.head == sig_hdr.tail) { rc = FALSE; /* no signals to remove */ goto cleanup; } sig_hdr.tail = (sig_hdr.tail + 1) % sig_hdr.max_slots; if (!sig_read_data(channel, queue, &sig_hdr, sig_hdr.tail, msg)) { ERRDRV("sig_read_data failed: (status=%d)\n", rc); goto cleanup; } sig_hdr.num_received++; /* For each data field in SIGNAL_QUEUE_HEADER that was modified, * update host memory. */ mb(); /* required for channel synch */ if (!SIG_WRITE_FIELD(channel, queue, &sig_hdr, tail)) { ERRDRV("visor_memregion_write of Tail failed: (status=%d)\n", rc); goto cleanup; } if (!SIG_WRITE_FIELD(channel, queue, &sig_hdr, num_received)) { ERRDRV("visor_memregion_write of NumSignalsReceived failed: (status=%d)\n", rc); goto cleanup; } rc = TRUE; cleanup: if (channel->needs_lock) spin_unlock(&channel->remove_lock); return rc; }
BOOL visorchannel_signalremove(VISORCHANNEL *channel, U32 queue, void *msg) { BOOL rc = FALSE; SIGNAL_QUEUE_HEADER sig_hdr; if (channel->needs_lock) spin_lock(&channel->remove_lock); if (!sig_read_header(channel, queue, &sig_hdr)) { rc = FALSE; goto Away; } if (sig_hdr.Head == sig_hdr.Tail) { rc = FALSE; /* no signals to remove */ goto Away; } sig_hdr.Tail = (sig_hdr.Tail + 1) % sig_hdr.MaxSignalSlots; if (!sig_read_data(channel, queue, &sig_hdr, sig_hdr.Tail, msg)) { ERRDRV("sig_read_data failed: (status=%d)\n", rc); goto Away; } sig_hdr.NumSignalsReceived++; /* For each data field in SIGNAL_QUEUE_HEADER that was modified, * update host memory. */ MEMORYBARRIER; if (!SIG_WRITE_FIELD(channel, queue, &sig_hdr, Tail)) { ERRDRV("visor_memregion_write of Tail failed: (status=%d)\n", rc); goto Away; } if (!SIG_WRITE_FIELD(channel, queue, &sig_hdr, NumSignalsReceived)) { ERRDRV("visor_memregion_write of NumSignalsReceived failed: (status=%d)\n", rc); goto Away; } rc = TRUE; Away: if (channel->needs_lock) spin_unlock(&channel->remove_lock); return rc; }
static BOOL signalinsert_inner(struct visorchannel *channel, u32 queue, void *msg) { struct signal_queue_header sig_hdr; if (!sig_read_header(channel, queue, &sig_hdr)) { return FALSE; } sig_hdr.head = ((sig_hdr.head + 1) % sig_hdr.max_slots); if (sig_hdr.head == sig_hdr.tail) { sig_hdr.num_overflows++; if (!SIG_WRITE_FIELD(channel, queue, &sig_hdr, num_overflows)) ERRDRV("visor_memregion_write of NumOverflows failed\n"); return FALSE; } if (!sig_write_data(channel, queue, &sig_hdr, sig_hdr.head, msg)) { ERRDRV("sig_write_data failed\n"); return FALSE; } sig_hdr.num_sent++; /* For each data field in SIGNAL_QUEUE_HEADER that was modified, * update host memory. */ mb(); /* required for channel synch */ if (!SIG_WRITE_FIELD(channel, queue, &sig_hdr, head)) { ERRDRV("visor_memregion_write of Head failed\n"); return FALSE; } if (!SIG_WRITE_FIELD(channel, queue, &sig_hdr, num_sent)) { ERRDRV("visor_memregion_write of NumSignalsSent failed\n"); return FALSE; } return TRUE; }