static int savage_bci_event_wait(struct drm_device *dev, void *data, struct drm_file *file_priv) { drm_savage_private_t *dev_priv = dev->dev_private; drm_savage_event_wait_t *event = data; unsigned int event_e, hw_e; unsigned int event_w, hw_w; DRM_DEBUG("\n"); UPDATE_EVENT_COUNTER(); if (dev_priv->status_ptr) hw_e = dev_priv->status_ptr[1] & 0xffff; else hw_e = SAVAGE_READ(SAVAGE_STATUS_WORD1) & 0xffff; hw_w = dev_priv->event_wrap; if (hw_e > dev_priv->event_counter) hw_w--; /* hardware hasn't passed the last wrap yet */ event_e = event->count & 0xffff; event_w = event->count >> 16; /* Don't need to wait if * - event counter wrapped since the event was emitted or * - the hardware has advanced up to or over the event to wait for. */ if (event_w < hw_w || (event_w == hw_w && event_e <= hw_e)) return 0; else return dev_priv->wait_evnt(dev_priv, event_e); }
static struct drm_buf *savage_freelist_get(struct drm_device * dev) { drm_savage_private_t *dev_priv = dev->dev_private; drm_savage_buf_priv_t *tail = dev_priv->tail.prev; uint16_t event; unsigned int wrap; DRM_DEBUG("\n"); UPDATE_EVENT_COUNTER(); if (dev_priv->status_ptr) event = dev_priv->status_ptr[1] & 0xffff; else event = SAVAGE_READ(SAVAGE_STATUS_WORD1) & 0xffff; wrap = dev_priv->event_wrap; if (event > dev_priv->event_counter) wrap--; /* hardware hasn't passed the last wrap yet */ DRM_DEBUG(" tail=0x%04x %d\n", tail->age.event, tail->age.wrap); DRM_DEBUG(" head=0x%04x %d\n", event, wrap); if (tail->buf && (TEST_AGE(&tail->age, event, wrap) || event == 0)) { drm_savage_buf_priv_t *next = tail->next; drm_savage_buf_priv_t *prev = tail->prev; prev->next = next; next->prev = prev; tail->next = tail->prev = NULL; return tail->buf; } DRM_DEBUG("returning NULL, tail->buf=%p!\n", tail->buf); return NULL; }
void savage_dma_wait(drm_savage_private_t * dev_priv, unsigned int page) { uint16_t event; unsigned int wrap; /* Faked DMA buffer pages don't age. */ if (dev_priv->cmd_dma == &dev_priv->fake_dma) return; UPDATE_EVENT_COUNTER(); if (dev_priv->status_ptr) event = dev_priv->status_ptr[1] & 0xffff; else event = SAVAGE_READ(SAVAGE_STATUS_WORD1) & 0xffff; wrap = dev_priv->event_wrap; if (event > dev_priv->event_counter) wrap--; /* hardware hasn't passed the last wrap yet */ if (dev_priv->dma_pages[page].age.wrap > wrap || (dev_priv->dma_pages[page].age.wrap == wrap && dev_priv->dma_pages[page].age.event > event)) { if (dev_priv->wait_evnt(dev_priv, dev_priv->dma_pages[page].age.event) < 0) DRM_ERROR("wait_evnt failed!\n"); } }
static int savage_bci_event_wait(DRM_IOCTL_ARGS) { DRM_DEVICE; drm_savage_private_t *dev_priv = dev->dev_private; drm_savage_event_wait_t event; unsigned int event_e, hw_e; unsigned int event_w, hw_w; DRM_DEBUG("\n"); DRM_COPY_FROM_USER_IOCTL(event, (drm_savage_event_wait_t __user *)data, sizeof(event)); UPDATE_EVENT_COUNTER(); if (dev_priv->status_ptr) hw_e = dev_priv->status_ptr[1] & 0xffff; else hw_e = SAVAGE_READ(SAVAGE_STATUS_WORD1) & 0xffff; hw_w = dev_priv->event_wrap; if (hw_e > dev_priv->event_counter) hw_w--; /* hardware hasn't passed the last wrap yet */ event_e = event.count & 0xffff; event_w = event.count >> 16; /* Don't need to wait if * - event counter wrapped since the event was emitted or * - the hardware has advanced up to or over the event to wait for. */ if (event_w < hw_w || (event_w == hw_w && event_e <= hw_e) ) return 0; else return dev_priv->wait_evnt(dev_priv, event_e); }