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; }
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; }