/**++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  @function: Create a message queue

  @function name: SDLIB_CreateMessageQueue
  @prototype: PSDMESSAGE_QUEUE SDLIB_CreateMessageQueue(INT MaxMessages, INT MaxMessageLength)
  @category: Support_Reference
  
  @input: MaxMessages - Maximum number of messages this queue supports
  @input: MaxMessageLength - Maximum size of each message
 
  @return: Message queue object, NULL on failure
  
  @notes:  This function creates a simple first-in-first-out message queue.  The caller must determine 
           the maximum number of messages the queue supports and the size of each message.  This
           function will pre-allocate memory for each message. A producer of data posts a message
           using SDLIB_PostMessage with a user defined data structure. A consumer of this data 
           can retrieve the message (in FIFO order) using SDLIB_GetMessage. A message queue does not
           provide a signaling mechanism for notifying a consumer of data. Notifying a consumer is 
           user defined.
  
  @see also: SDLIB_DeleteMessageQueue, SDLIB_GetMessage, SDLIB_PostMessage.
  
  @example: Creating a message queue:
       typedef struct _MyMessage {
           UINT8 Code;
           PVOID pDataBuffer;
       } MyMessage;
            // create message queue, 16 messages max.
       pMsgQueue = SDLIB_CreateMessageQueue(16,sizeof(MyMessage));
       if (NULL == pMsgQueue) {
           .. failed
       }
  
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
PSDMESSAGE_QUEUE _CreateMessageQueue(INT MaxMessages, INT MaxMessageLength)
{
    PSDMESSAGE_QUEUE pQueue = NULL;
    SDIO_STATUS      status = SDIO_STATUS_SUCCESS;
    INT              ii;
    PSDMESSAGE_BLOCK pMsg;
    
    do {
        pQueue = (PSDMESSAGE_QUEUE)KernelAlloc(sizeof(SDMESSAGE_QUEUE));   
        
        if (NULL == pQueue) {
            status = SDIO_STATUS_NO_RESOURCES;
            break; 
        }
        SDLIST_INIT(&pQueue->MessageList);  
        SDLIST_INIT(&pQueue->FreeMessageList);  
        pQueue->MaxMessageLength = MaxMessageLength;       
        status = CriticalSectionInit(&pQueue->MessageCritSection);
        if (!SDIO_SUCCESS(status)) {
            break;   
        }       
            /* allocate message blocks */
        for (ii = 0; ii < MaxMessages; ii++) {
            pMsg = (PSDMESSAGE_BLOCK)KernelAlloc(sizeof(SDMESSAGE_BLOCK) + MaxMessageLength -1); 
            if (NULL == pMsg) {
                break;    
            }
            FreeMessageBlock(pQueue, pMsg);
        } 
       
        if (0 == ii) {
            status = SDIO_STATUS_NO_RESOURCES;
            break; 
        }
        
    } while (FALSE);      
  
    if (!SDIO_SUCCESS(status)) {
        if (pQueue != NULL) {
            _DeleteMessageQueue(pQueue);    
            pQueue = NULL;  
        } 
    }
    return pQueue;  
}
int vmw_fifo_init(struct vmw_private *dev_priv, struct vmw_fifo_state *fifo)
{
	__le32 __iomem *fifo_mem = dev_priv->mmio_virt;
	uint32_t max;
	uint32_t min;
	uint32_t dummy;

    ENTER();

	fifo->static_buffer_size = VMWGFX_FIFO_STATIC_SIZE;
    fifo->static_buffer = KernelAlloc(fifo->static_buffer_size);
	if (unlikely(fifo->static_buffer == NULL))
		return -ENOMEM;

	fifo->dynamic_buffer = NULL;
	fifo->reserved_size = 0;
	fifo->using_bounce_buffer = false;

	mutex_init(&fifo->fifo_mutex);
//   init_rwsem(&fifo->rwsem);

	/*
	 * Allow mapping the first page read-only to user-space.
	 */

	DRM_INFO("width %d\n", vmw_read(dev_priv, SVGA_REG_WIDTH));
	DRM_INFO("height %d\n", vmw_read(dev_priv, SVGA_REG_HEIGHT));
	DRM_INFO("bpp %d\n", vmw_read(dev_priv, SVGA_REG_BITS_PER_PIXEL));

	mutex_lock(&dev_priv->hw_mutex);
	dev_priv->enable_state = vmw_read(dev_priv, SVGA_REG_ENABLE);
	dev_priv->config_done_state = vmw_read(dev_priv, SVGA_REG_CONFIG_DONE);
	dev_priv->traces_state = vmw_read(dev_priv, SVGA_REG_TRACES);
	vmw_write(dev_priv, SVGA_REG_ENABLE, 1);

	min = 4;
	if (dev_priv->capabilities & SVGA_CAP_EXTENDED_FIFO)
		min = vmw_read(dev_priv, SVGA_REG_MEM_REGS);
	min <<= 2;

	if (min < PAGE_SIZE)
		min = PAGE_SIZE;

	iowrite32(min, fifo_mem + SVGA_FIFO_MIN);
	iowrite32(dev_priv->mmio_size, fifo_mem + SVGA_FIFO_MAX);
    wmb();
	iowrite32(min,  fifo_mem + SVGA_FIFO_NEXT_CMD);
	iowrite32(min,  fifo_mem + SVGA_FIFO_STOP);
	iowrite32(0, fifo_mem + SVGA_FIFO_BUSY);
    mb();

    vmw_write(dev_priv, SVGA_REG_CONFIG_DONE, 1);
	mutex_unlock(&dev_priv->hw_mutex);

	max = ioread32(fifo_mem + SVGA_FIFO_MAX);
	min = ioread32(fifo_mem  + SVGA_FIFO_MIN);
	fifo->capabilities = ioread32(fifo_mem + SVGA_FIFO_CAPABILITIES);

	DRM_INFO("Fifo max 0x%08x min 0x%08x cap 0x%08x\n",
		 (unsigned int) max,
		 (unsigned int) min,
		 (unsigned int) fifo->capabilities);

	atomic_set(&dev_priv->marker_seq, dev_priv->last_read_seqno);
	iowrite32(dev_priv->last_read_seqno, fifo_mem + SVGA_FIFO_FENCE);
    vmw_marker_queue_init(&fifo->marker_queue);

    int ret = 0; //vmw_fifo_send_fence(dev_priv, &dummy);
    LEAVE();
    return ret;
}
Esempio n. 3
0
BOOL
hifDeviceInserted(SDFUNCTION *function, SDDEVICE *handle)
{
    A_UINT32 count;
    HIF_DEVICE *device;
    BOOL accepted = FALSE;
    AR_DEBUG_ASSERT(function != NULL);
    AR_DEBUG_ASSERT(handle != NULL);

    do {
        
        device = (HIF_DEVICE *)KernelAlloc(sizeof(HIF_DEVICE));
    
        if (NULL == device) {
            break;    
        }
    
        AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("Device: %p\n", device));
     
        ZERO_POBJECT(device);
        
        CriticalSectionInit(&device->lock);
        device->busrequestfreelist = NULL;
        device->handle = handle;
        device->enabledSpiInts = ATH_SPI_INTR_PKT_AVAIL | ATH_SPI_INTR_CPU_INTR;
            /* set the IRQ Handler which associates the instance with the SDDEVICE */
        SDDEVICE_SET_IRQ_HANDLER(device->handle, hifIRQHandler, device);
    
        AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("Device: %p\n", device));
       
        if (handle->pId[0].CardFlags & CARD_RAW) {
            if (strstr(SDDEVICE_GET_HCDNAME(handle), SDIO_RAW_BD_BASE) == NULL) {
                /* Not supported */
                break;
            }
        }
    
        /* Card identification */
        AR_DEBUG_PRINTF(ATH_DEBUG_TRC, 
                        ("SPI card: %s\n", SDDEVICE_GET_HCDNAME(handle)));
    
        /* Version information */
        AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("Stack version: %d.%d\n", 
                                          SDDEVICE_GET_VERSION_MAJOR(handle), 
                                          SDDEVICE_GET_VERSION_MINOR(handle)));
    
        /* Get the maximum block size supported */
        AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("Maximum block length: %d bytes\n",
                        SDDEVICE_GET_MAX_BLOCK_LEN(handle)));
                        
        device->curBlockSize = SDDEVICE_GET_OPER_BLOCK_LEN(handle);
        
        AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("Current block length: %d bytes\n",
                        device->curBlockSize));
    
            /* Allocate the bus requests to be used later */
        for (count = 0; count < BUS_REQUEST_MAX_NUM_TOTAL; count ++) {
            if ((device->busrequestblob[count].request = SDDeviceAllocRequest(handle)) == NULL){
                AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("Unable to allocate bus request\n"));
                break;
            }
                /* free to the list */
            hifFreeBusRequest(device, &device->busrequestblob[count]);
        }
        
        if (count != BUS_REQUEST_MAX_NUM_TOTAL) {
            break;   
        }
        
            /* Configure the SPI interface */
        if ((hifConfigureSPI(device)) != A_OK) {
            AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("Failed to configure the device\n"));
            break;
        }
    
        /* Inform HTC */
        if ((osdrvCallbacks.deviceInsertedHandler(osdrvCallbacks.context, (void *)device)) != A_OK) {
            AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("Device rejected\n"));
            return FALSE;
        }

        accepted = TRUE;
        
    } while (FALSE);
    
    if (!accepted & (device != NULL)) {
        /* cleanup device */
        hifCleanupDevice(device);   
    }
    
    return accepted;
}