1*592ffb21SWarner Losh /************************************************************************** 2*592ffb21SWarner Losh * 3*592ffb21SWarner Losh * Copyright 2010 Pauli Nieminen. 4*592ffb21SWarner Losh * All Rights Reserved. 5*592ffb21SWarner Losh * 6*592ffb21SWarner Losh * Permission is hereby granted, free of charge, to any person obtaining a 7*592ffb21SWarner Losh * copy of this software and associated documentation files (the 8*592ffb21SWarner Losh * "Software"), to deal in the Software without restriction, including 9*592ffb21SWarner Losh * without limitation the rights to use, copy, modify, merge, publish, 10*592ffb21SWarner Losh * distribute, sub license, and/or sell copies of the Software, and to 11*592ffb21SWarner Losh * permit persons to whom the Software is furnished to do so, subject to 12*592ffb21SWarner Losh * the following conditions: 13*592ffb21SWarner Losh * 14*592ffb21SWarner Losh * The above copyright notice and this permission notice (including the 15*592ffb21SWarner Losh * next paragraph) shall be included in all copies or substantial portions 16*592ffb21SWarner Losh * of the Software. 17*592ffb21SWarner Losh * 18*592ffb21SWarner Losh * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19*592ffb21SWarner Losh * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20*592ffb21SWarner Losh * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 21*592ffb21SWarner Losh * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, 22*592ffb21SWarner Losh * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 23*592ffb21SWarner Losh * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 24*592ffb21SWarner Losh * USE OR OTHER DEALINGS IN THE SOFTWARE. 25*592ffb21SWarner Losh * 26*592ffb21SWarner Losh * 27*592ffb21SWarner Losh **************************************************************************/ 28*592ffb21SWarner Losh /* 29*592ffb21SWarner Losh * Multipart buffer for coping data which is larger than the page size. 30*592ffb21SWarner Losh * 31*592ffb21SWarner Losh * Authors: 32*592ffb21SWarner Losh * Pauli Nieminen <suokkos-at-gmail-dot-com> 33*592ffb21SWarner Losh */ 34*592ffb21SWarner Losh 35*592ffb21SWarner Losh #include <sys/cdefs.h> 36*592ffb21SWarner Losh __FBSDID("$FreeBSD$"); 37*592ffb21SWarner Losh 38*592ffb21SWarner Losh #ifndef _DRM_BUFFER_H_ 39*592ffb21SWarner Losh #define _DRM_BUFFER_H_ 40*592ffb21SWarner Losh 41*592ffb21SWarner Losh #include <dev/drm2/drmP.h> 42*592ffb21SWarner Losh 43*592ffb21SWarner Losh struct drm_buffer { 44*592ffb21SWarner Losh int iterator; 45*592ffb21SWarner Losh int size; 46*592ffb21SWarner Losh char *data[]; 47*592ffb21SWarner Losh }; 48*592ffb21SWarner Losh 49*592ffb21SWarner Losh 50*592ffb21SWarner Losh /** 51*592ffb21SWarner Losh * Return the index of page that buffer is currently pointing at. 52*592ffb21SWarner Losh */ 53*592ffb21SWarner Losh static inline int drm_buffer_page(struct drm_buffer *buf) 54*592ffb21SWarner Losh { 55*592ffb21SWarner Losh return buf->iterator / PAGE_SIZE; 56*592ffb21SWarner Losh } 57*592ffb21SWarner Losh /** 58*592ffb21SWarner Losh * Return the index of the current byte in the page 59*592ffb21SWarner Losh */ 60*592ffb21SWarner Losh static inline int drm_buffer_index(struct drm_buffer *buf) 61*592ffb21SWarner Losh { 62*592ffb21SWarner Losh return buf->iterator & (PAGE_SIZE - 1); 63*592ffb21SWarner Losh } 64*592ffb21SWarner Losh /** 65*592ffb21SWarner Losh * Return number of bytes that is left to process 66*592ffb21SWarner Losh */ 67*592ffb21SWarner Losh static inline int drm_buffer_unprocessed(struct drm_buffer *buf) 68*592ffb21SWarner Losh { 69*592ffb21SWarner Losh return buf->size - buf->iterator; 70*592ffb21SWarner Losh } 71*592ffb21SWarner Losh 72*592ffb21SWarner Losh /** 73*592ffb21SWarner Losh * Advance the buffer iterator number of bytes that is given. 74*592ffb21SWarner Losh */ 75*592ffb21SWarner Losh static inline void drm_buffer_advance(struct drm_buffer *buf, int bytes) 76*592ffb21SWarner Losh { 77*592ffb21SWarner Losh buf->iterator += bytes; 78*592ffb21SWarner Losh } 79*592ffb21SWarner Losh 80*592ffb21SWarner Losh /** 81*592ffb21SWarner Losh * Allocate the drm buffer object. 82*592ffb21SWarner Losh * 83*592ffb21SWarner Losh * buf: A pointer to a pointer where the object is stored. 84*592ffb21SWarner Losh * size: The number of bytes to allocate. 85*592ffb21SWarner Losh */ 86*592ffb21SWarner Losh extern int drm_buffer_alloc(struct drm_buffer **buf, int size); 87*592ffb21SWarner Losh 88*592ffb21SWarner Losh /** 89*592ffb21SWarner Losh * Copy the user data to the begin of the buffer and reset the processing 90*592ffb21SWarner Losh * iterator. 91*592ffb21SWarner Losh * 92*592ffb21SWarner Losh * user_data: A pointer the data that is copied to the buffer. 93*592ffb21SWarner Losh * size: The Number of bytes to copy. 94*592ffb21SWarner Losh */ 95*592ffb21SWarner Losh extern int drm_buffer_copy_from_user(struct drm_buffer *buf, 96*592ffb21SWarner Losh void __user *user_data, int size); 97*592ffb21SWarner Losh 98*592ffb21SWarner Losh /** 99*592ffb21SWarner Losh * Free the drm buffer object 100*592ffb21SWarner Losh */ 101*592ffb21SWarner Losh extern void drm_buffer_free(struct drm_buffer *buf); 102*592ffb21SWarner Losh 103*592ffb21SWarner Losh /** 104*592ffb21SWarner Losh * Read an object from buffer that may be split to multiple parts. If object 105*592ffb21SWarner Losh * is not split function just returns the pointer to object in buffer. But in 106*592ffb21SWarner Losh * case of split object data is copied to given stack object that is suplied 107*592ffb21SWarner Losh * by caller. 108*592ffb21SWarner Losh * 109*592ffb21SWarner Losh * The processing location of the buffer is also advanced to the next byte 110*592ffb21SWarner Losh * after the object. 111*592ffb21SWarner Losh * 112*592ffb21SWarner Losh * objsize: The size of the objet in bytes. 113*592ffb21SWarner Losh * stack_obj: A pointer to a memory location where object can be copied. 114*592ffb21SWarner Losh */ 115*592ffb21SWarner Losh extern void *drm_buffer_read_object(struct drm_buffer *buf, 116*592ffb21SWarner Losh int objsize, void *stack_obj); 117*592ffb21SWarner Losh 118*592ffb21SWarner Losh /** 119*592ffb21SWarner Losh * Returns the pointer to the dword which is offset number of elements from the 120*592ffb21SWarner Losh * current processing location. 121*592ffb21SWarner Losh * 122*592ffb21SWarner Losh * Caller must make sure that dword is not split in the buffer. This 123*592ffb21SWarner Losh * requirement is easily met if all the sizes of objects in buffer are 124*592ffb21SWarner Losh * multiples of dword and PAGE_SIZE is multiple dword. 125*592ffb21SWarner Losh * 126*592ffb21SWarner Losh * Call to this function doesn't change the processing location. 127*592ffb21SWarner Losh * 128*592ffb21SWarner Losh * offset: The index of the dword relative to the internat iterator. 129*592ffb21SWarner Losh */ 130*592ffb21SWarner Losh static inline void *drm_buffer_pointer_to_dword(struct drm_buffer *buffer, 131*592ffb21SWarner Losh int offset) 132*592ffb21SWarner Losh { 133*592ffb21SWarner Losh int iter = buffer->iterator + offset * 4; 134*592ffb21SWarner Losh return &buffer->data[iter / PAGE_SIZE][iter & (PAGE_SIZE - 1)]; 135*592ffb21SWarner Losh } 136*592ffb21SWarner Losh /** 137*592ffb21SWarner Losh * Returns the pointer to the dword which is offset number of elements from 138*592ffb21SWarner Losh * the current processing location. 139*592ffb21SWarner Losh * 140*592ffb21SWarner Losh * Call to this function doesn't change the processing location. 141*592ffb21SWarner Losh * 142*592ffb21SWarner Losh * offset: The index of the byte relative to the internat iterator. 143*592ffb21SWarner Losh */ 144*592ffb21SWarner Losh static inline void *drm_buffer_pointer_to_byte(struct drm_buffer *buffer, 145*592ffb21SWarner Losh int offset) 146*592ffb21SWarner Losh { 147*592ffb21SWarner Losh int iter = buffer->iterator + offset; 148*592ffb21SWarner Losh return &buffer->data[iter / PAGE_SIZE][iter & (PAGE_SIZE - 1)]; 149*592ffb21SWarner Losh } 150*592ffb21SWarner Losh 151*592ffb21SWarner Losh #endif 152