Exemple #1
0
/****************************************************************************
NAME    
    deviceManagerCanConnect
    
DESCRIPTION
   Determines if max number of possible connections have been made
RETURNS
   TRUE if connection can be made, FALSE otherwise
*/
bool deviceManagerCanConnect(void)
{
    bdaddr dev_addr1, dev_addr2;
    DEV_DEBUG(("DEV: %d of %d connected\n", theSink.no_of_profiles_connected, (theSink.MultipointEnable ? MAX_MULTIPOINT_CONNECTIONS : 1)));
    /* If no devices connected we're okay */
    if(theSink.no_of_profiles_connected == 0)
        return TRUE;
    /* If multipoint is not enabled check if this is manual connect request for A2DP 
        for an already connected HFP profile to the same device
    */
    if(!theSink.MultipointEnable)
    {
        if((deviceManagerGetProfileAddr(conn_hfp_pri, &dev_addr1)) && 
            !(deviceManagerGetProfileAddr(conn_a2dp_pri, &dev_addr2)))
            {
                DEV_DEBUG(("DEV: Allow the device to connect \n"));
                return TRUE;
            }
    }
    /* If multipoint and not all devices connected then we're okay */
    if(theSink.MultipointEnable && (theSink.no_of_profiles_connected < MAX_MULTIPOINT_CONNECTIONS))
        return TRUE;
    /* We can't accept any more connections */
    return FALSE;
}
Exemple #2
0
/****************************************************************************
NAME
    deviceManagerStoreAttributes
    
DESCRIPTION
    Stores given attribute values against a given device in PS.

RETURNS
    void
*/
void deviceManagerStoreAttributes(sink_attributes* attributes, const bdaddr* dev_addr)
{
#ifdef ENABLE_SHAREME
    DEV_DEBUG(("DEV: StoreAttribs   - profiles %d, peer %d, hfp_vol %d, a2dp_vol %d\n", attributes->profiles, attributes->peer_device, attributes->hfp.volume,attributes->a2dp.volume));
#else
    DEV_DEBUG(("DEV: StoreAttribs   - profiles %d, hfp_vol %d, a2dp_vol %d\n", attributes->profiles, attributes->hfp.volume,attributes->a2dp.volume));
#endif
    ConnectionSmPutAttribute(PSKEY_ATTRIBUTE_BASE, dev_addr, sizeof(sink_attributes), (uint8*)attributes); 
}
Exemple #3
0
/****************************************************************************
NAME    
    deviceManagerGetDefaultAttributes
    
DESCRIPTION
    Initialise sink_attributes struct to default values

RETURNS
    void
*/
void deviceManagerGetDefaultAttributes(sink_attributes* attributes, bool is_subwoofer)
{
    /* profiles and clock_mismatch default to 0 */
    memset(attributes, 0, sizeof(sink_attributes));
    
#ifdef ENABLE_PEER
    attributes->peer_device = remote_device_unknown;
#endif
    
#ifdef ENABLE_SUBWOOFER
    if (is_subwoofer)
    {
        attributes->profiles = sink_swat;
        attributes->hfp.volume = 0;
        attributes->a2dp.volume = 0;
        attributes->sub.sub_trim = DEFAULT_SUB_TRIM_INDEX;
        return;
    }
#endif
    
    attributes->profiles    = sink_none;
    attributes->hfp.volume  = theSink.features.DefaultVolume;
    attributes->a2dp.volume = theSink.features.DefaultA2dpVolLevel;
    DEV_DEBUG(("DEV: getDefaultAttrib prof:%d HfpVol:%d a2dpVol:%d\n",attributes->profiles, attributes->hfp.volume, attributes->a2dp.volume));
}
Exemple #4
0
/****************************************************************************
NAME
    deviceManagerUpdateAttributes
    
DESCRIPTION
    Stores the current attribute values for a given HFP/A2DP connection in
    PS.

RETURNS
    void
*/
void deviceManagerUpdateAttributes(const bdaddr* bd_addr, sink_link_type link_type, hfp_link_priority hfp_priority, a2dp_link_priority a2dp_priority)
{
    EVENT_UPDATE_ATTRIBUTES_T* update = PanicUnlessNew(EVENT_UPDATE_ATTRIBUTES_T);
    
    memset(update,0,sizeof(EVENT_UPDATE_ATTRIBUTES_T)); 
    
    update->bd_addr = *bd_addr;
    
    if(link_type == sink_hfp)
    {
        update->attributes.profiles = sink_hfp;
        update->attributes.hfp.volume = theSink.profile_data[PROFILE_INDEX(hfp_priority)].audio.gSMVolumeLevel;
    }
    else if(link_type == sink_a2dp)
    {
        update->attributes.profiles = sink_a2dp;
        update->attributes.a2dp.volume = theSink.a2dp_link_data->gAvVolumeLevel[a2dp_priority];
        update->attributes.a2dp.clock_mismatch = theSink.a2dp_link_data->clockMismatchRate[a2dp_priority];
    }
#ifdef ENABLE_SUBWOOFER
    else if(link_type == sink_swat)
    {
        update->attributes.profiles = sink_swat;
        update->attributes.sub.sub_trim = theSink.rundata->subwoofer.sub_trim_idx;
    }
#endif        

    DEV_DEBUG(("DEV: DelayUpdateAttributes - type %d profiles %d, hfp_vol %d, a2dp_vol %d\n",link_type, update->attributes.profiles, update->attributes.hfp.volume, update->attributes.a2dp.volume));
    MessageSendConditionally(&theSink.task, EventUpdateAttributes, update, (const uint16 *)AudioBusyPtr());
}
Exemple #5
0
/****************************************************************************
NAME
    deviceManagerDelayedUpdateAttributes
    
DESCRIPTION
    Store attributes contained in EVENT_UPDATE_ATTRIBUTES_T in PS

RETURNS
    void
*/
void deviceManagerDelayedUpdateAttributes(EVENT_UPDATE_ATTRIBUTES_T* update)
{
	sink_attributes attributes;
    sink_attributes new_attributes;

    /* zero settings */
    memset(&new_attributes,0,sizeof(sink_attributes));
    
    /* Get attributes from PS */
    deviceManagerGetDefaultAttributes(&attributes, FALSE);
    deviceManagerGetAttributes(&attributes, &update->bd_addr);

    if(update->attributes.profiles == sink_hfp)
    {
        /* Update with current attribute values */
        new_attributes = attributes;
        new_attributes.profiles |= sink_hfp;
        new_attributes.hfp.volume = update->attributes.hfp.volume;
    }
    else if(update->attributes.profiles == sink_a2dp)
    {
        /* Update with current attribute values */
        new_attributes = attributes;
        new_attributes.profiles |= sink_a2dp;
        new_attributes.a2dp.volume = update->attributes.a2dp.volume;
        new_attributes.a2dp.clock_mismatch = update->attributes.a2dp.clock_mismatch;
    }
#ifdef ENABLE_SUBWOOFER
    else if(update->attributes.profiles == sink_swat)
    {
        new_attributes.sub.sub_trim = update->attributes.sub.sub_trim;
        new_attributes.profiles = sink_swat;
    }
#endif    
    
    DEV_DEBUG(("DEV: UpdateAttributesOld - profiles %d, hfp_vol %d, a2dp_vol %d, clock_mismatch %d\n", attributes.profiles, attributes.hfp.volume,
                                                                                         attributes.a2dp.volume, attributes.a2dp.clock_mismatch));
    DEV_DEBUG(("DEV: UpdateAttributesNew - profiles %d, hfp_vol %d, a2dp_vol %d, clock_mismatch %d\n", new_attributes.profiles, new_attributes.hfp.volume,
                                                                                         new_attributes.a2dp.volume, new_attributes.a2dp.clock_mismatch));
    /* Write updated attributes to PS */
    if(!deviceManagerCompareAttributes(&attributes, &new_attributes))
        deviceManagerStoreAttributes(&new_attributes, &update->bd_addr);
}
Exemple #6
0
/****************************************************************************
NAME    
    deviceManagerNumConnectedPeerDevs
    
DESCRIPTION
   determines the number of different connected peer devices, a device will only
   have connected a2dp
RETURNS
    number of connected peer devices
*/
uint8 deviceManagerNumConnectedPeerDevs(void)
{
    a2dp_link_priority priority;
    uint8 no_devices = 0;
    /* Go through all profiles */
    for(priority = a2dp_primary; priority <= a2dp_secondary; priority++)
    {
        /* Only valid if we have processed A2DP connect */
        if (theSink.a2dp_link_data && 
            (theSink.a2dp_link_data->device_id[priority] != INVALID_DEVICE_ID) && 
            (theSink.a2dp_link_data->peer_device[priority] == remote_device_peer))
        {
            no_devices++;
        }
    }
    DEV_DEBUG(("DEV: Peer Conn Count %d\n", no_devices));
    return no_devices;
}
Exemple #7
0
static void pci_dev_init_manager(struct device_mem *bar_info,
                                 int nr_mapped_bars)
{
    errval_t err;

    DEV_DEBUG("Initialize device @ [%016lx] with %u bars\n", bar_info->paddr,
              nr_mapped_bars);

    if (nr_mapped_bars != 1) {
        DEV_ERR("number of mapped bars is wrong. Skipping initialization\n");
        return;
    }

    err = ioat_mgr_svc_add_device(bar_info->frame_cap);
    if (err_is_fail(err)) {
        DEV_ERR("Device coult not be added to the manager: %s\n",
                err_getstring(err));
    }
}
Exemple #8
0
/****************************************************************************
NAME    
    deviceManagerNumConnectedDevs
    
DESCRIPTION
   determines the number of different connected devices, a device may connected
   both hfp and a2dp or only one of each
RETURNS
    number of connected devices
*/
uint8 deviceManagerNumConnectedDevs(void)
{
    conn_mask mask;
    bdaddr dev_addr;
    uint8 no_devices = 0;
    /* Go through all profiles */
    for(mask = conn_hfp_pri; mask <= conn_a2dp_sec; mask <<=1)
    {
        /* Get bluetooth address for profile if connected */
        if(deviceManagerGetProfileAddr(mask, &dev_addr))
        {
            /* If HFP connection, or A2DP connection on device with no HFP... */
            if( (mask & conn_hfp) || (!(conn_hfp & deviceManagerProfilesConnected(&dev_addr))) )
                no_devices++;
        }
    }
    DEV_DEBUG(("DEV: Conn Count %d\n", no_devices));
    return no_devices;
}
Exemple #9
0
/****************************************************************************
NAME    
    deviceManagerProfilesConnected
    
DESCRIPTION
    Compare bdaddr against those of the current connected devices

RETURNS
    conn_mask indicating which profiles the device is connected to
*/
conn_mask deviceManagerProfilesConnected(const bdaddr * bd_addr)
{
    bdaddr dev_addr;
    conn_mask mask, result = 0;
    
    /* Go through all profiles */
    for(mask = conn_hfp_pri; mask <= conn_a2dp_sec; mask <<=1)
    {
        /* Get bluetooth address for profile if connected */
        if(deviceManagerGetProfileAddr(mask, &dev_addr))
        {
            /* If address matches device passed in... */
            if(BdaddrIsSame(bd_addr, &dev_addr))
                result |= mask;
        }
    }
    DEV_DEBUG(("DEV: profiles connected bdaddr %x %x %x Conn Mask %X\n", (uint16)bd_addr->nap,(uint16)bd_addr->uap,(uint16)bd_addr->lap,result));
    return result;
}
Exemple #10
0
/****************************************************************************
NAME
    deviceManagerStoreDefaultAttributes
    
DESCRIPTION
    Stores the default attributes against a given device in PS.

RETURNS
    void
*/
void deviceManagerStoreDefaultAttributes(const bdaddr* dev_addr, bool is_subwoofer)
{
    sink_attributes attributes;
    
#ifdef ENABLE_SUBWOOFER
    if (is_subwoofer)
    {
        /* Setup and store attributes for the subwoofer device */
        sink_attributes attributes;
        deviceManagerGetDefaultAttributes(&attributes, TRUE);
        deviceManagerStoreAttributes(&attributes, dev_addr);
        return;
    }
#endif
    
    deviceManagerGetDefaultAttributes(&attributes, FALSE);
    DEV_DEBUG(("DEV: StoreDefaultAttribs   - profiles %d, hfp_vol %d, a2dp_vol %d\n", attributes.profiles, attributes.hfp.volume,attributes.a2dp.volume));
    deviceManagerStoreAttributes(&attributes, dev_addr);
}
Exemple #11
0
static void pci_dev_init_service(struct device_mem *bar_info,
                                 int nr_mapped_bars)
{
    errval_t err;

    DEV_DEBUG("Initialize device @ [%016lx] with %u bars\n", bar_info->paddr,
              nr_mapped_bars);

    if (nr_mapped_bars != 1) {
        DEV_ERR("number of mapped bars is wrong. Skipping initialization\n");
        return;
    }

    /* initialize the device */
    err = ioat_dma_device_init(*bar_info->frame_cap, &devices[device_count]);
    if (err_is_fail(err)) {
        DEV_ERR("Could not initialize the device: %s\n", err_getstring(err));
        return;
    }

    device_count++;
}
Exemple #12
0
errval_t ioat_device_discovery(struct pci_addr addr,
                               enum device_type devtype,
                               uint8_t is_dev_mgr)
{

    errval_t err;

    uint16_t *dev_ids = NULL;
    uint16_t dev_cnt = 0;

    err = pci_client_connect();
    if (err_is_fail(err)) {
        return err;
    }

    switch (devtype) {
        case IOAT_DEVICE_IVB:
            DEV_DEBUG("Doing device discovery: Ivy Bridge\n");
            if (addr.device != 4) {
                /* the IOAT DMA engine should be on device 4 on Ivy Bridge */
                return DMA_ERR_PCI_ADDRESS;
            }
            dev_ids = calloc(PCI_DEVICE_IOAT_IVB_CNT, sizeof(uint16_t));
            if (dev_ids == NULL) {
                return LIB_ERR_MALLOC_FAIL;
            }
            dev_ids[0] = PCI_DEVICE_IOAT_IVB0;
            dev_ids[1] = PCI_DEVICE_IOAT_IVB1;
            dev_ids[2] = PCI_DEVICE_IOAT_IVB2;
            dev_ids[3] = PCI_DEVICE_IOAT_IVB3;
            dev_ids[4] = PCI_DEVICE_IOAT_IVB4;
            dev_ids[5] = PCI_DEVICE_IOAT_IVB5;
            dev_ids[6] = PCI_DEVICE_IOAT_IVB6;
            dev_ids[7] = PCI_DEVICE_IOAT_IVB7;
            dev_ids[8] = PCI_DEVICE_IOAT_IVB8;
            dev_ids[9] = PCI_DEVICE_IOAT_IVB9;
            dev_cnt = PCI_DEVICE_IOAT_IVB_CNT;
            addr.function = 0;
            break;
        case IOAT_DEVICE_HSW:
            DEV_DEBUG("Doing device discovery: Haswell\n");
            if (addr.device != 4) {
                /* the IOAT DMA engine should be on device 4 on Haswell */
                return DMA_ERR_PCI_ADDRESS;
            }
            dev_ids = calloc(PCI_DEVICE_IOAT_HSW_CNT, sizeof(uint16_t));
            if (dev_ids == NULL) {
                return LIB_ERR_MALLOC_FAIL;
            }
            dev_ids[0] = PCI_DEVICE_IOAT_HSW0;
            dev_ids[1] = PCI_DEVICE_IOAT_HSW1;
            dev_ids[2] = PCI_DEVICE_IOAT_HSW2;
            dev_ids[3] = PCI_DEVICE_IOAT_HSW3;
            dev_ids[4] = PCI_DEVICE_IOAT_HSW4;
            dev_ids[5] = PCI_DEVICE_IOAT_HSW5;
            dev_ids[6] = PCI_DEVICE_IOAT_HSW6;
            dev_ids[7] = PCI_DEVICE_IOAT_HSW7;
            dev_ids[8] = PCI_DEVICE_IOAT_HSW8;
            dev_ids[9] = PCI_DEVICE_IOAT_HSW9;
            dev_cnt = PCI_DEVICE_IOAT_HSW_CNT;
            addr.function = 0;
            break;
            break;
        default:
            return DMA_ERR_DEVICE_UNSUPPORTED;
            break;
    }

    devices = calloc(dev_cnt, sizeof(struct ioat_dma_device *));
    if (devices == NULL) {
        free(dev_ids);
        return LIB_ERR_MALLOC_FAIL;
    }

    if (is_dev_mgr == IOAT_DMA_OPERATION_LIBRARY) {
        err = ioat_mgr_svc_init();
        if (err_is_fail(err)) {
            return err;
        }
    }

    /**
     * enumerating all the devices
     *
     * The devices on Haswell and Ivy Bridge are located on
     * Bus x, Device 4, Function 0..7
     */
    for (uint8_t i = 0; i < dev_cnt; ++i) {
        if (is_dev_mgr == IOAT_DMA_OPERATION_LIBRARY) {
            /*
             * discover devices as manager i.e. don't initialize them as they
             * are handed over to the domains upon request
             */
            err = pci_register_driver_noirq(pci_dev_init_manager,
            PCI_DONT_CARE,
                                            PCI_DONT_CARE,
                                            PCI_DONT_CARE,
                                            PCI_VENDOR_INTEL, dev_ids[i], addr.bus,
                                            addr.device, addr.function + i);
        } else {
            /*
             * discover devices as a service i.e. initialize and map devices
             */
            err = pci_register_driver_irq(pci_dev_init_service, PCI_DONT_CARE,
            PCI_DONT_CARE,
                                          PCI_DONT_CARE,
                                          PCI_VENDOR_INTEL,
                                          dev_ids[i], addr.bus, addr.device,
                                          addr.function + i, handle_device_interrupt,
                                          devices[i]);
        }
        if (err_is_fail(err)) {
            if (i == 0) {
                /* XXX: if a system does not implement all devices listed above,
                 *      the registration will fail which is ok. However if it
                 *      happens on the first device this is an error.
                 */
                return err;
            }
        }
    }

    DEV_DEBUG("Device discovery done: got %u devices.\n", device_count);

    free(dev_ids);

    return SYS_ERR_OK;
}
Exemple #13
0
/****************************************************************************
NAME
    deviceManagerSetPriority
    
DESCRIPTION
    Set a device's priority in the PDL

RETURNS
    new pdl listId of passed in src addr
*/
uint8 deviceManagerSetPriority(const bdaddr* dev_addr)
{
    conn_mask mask = deviceManagerProfilesConnected(dev_addr);
    uint8 ListId = 0;
    
    DEV_DEBUG(("DEV: Update PDL/MRU\n")) ;

    
    /* more than 1 connected device ? */
    if(deviceManagerNumConnectedDevs() > 1)
    {
        typed_bdaddr  typed_ag_addr;
        bdaddr ag_addr;
        sink_attributes attributes;      
 

        DEV_DEBUG(("DEV: Update MRU - two devices connected\n")) ;
        
        /* is this a connection of a2dp or hfp to the already connected primary device ? */            
        deviceManagerGetIndexedAttributes(0, &attributes, &typed_ag_addr);
        /* extract bluetooth address from packed structure */
        ag_addr = typed_ag_addr.addr;
        /* check if this is the primary device? */
        if(BdaddrIsSame(&ag_addr,dev_addr))
        {
            DEV_DEBUG(("DEV: Update MRU - two devices two profiles connected - primary device\n")) ;
            ListId = 0;
        }
        else
        {
            DEV_DEBUG(("DEV: Update MRU - two devices two profiles connected - secondary device\n")) ;
            /* Move the second device to top of the PDL */
            ConnectionSmUpdateMruDevice(dev_addr);      
            /* get bdaddr of the device that was previously the primary device but is
               now the secondary device */
            deviceManagerGetIndexedAttributes(1, &attributes, &typed_ag_addr);
            /* extract bluetooth address from packed structure */
            ag_addr = typed_ag_addr.addr;
            /* then move the what is now 'secondary device' back to the top of the PDL */                
            ConnectionSmUpdateMruDevice(&ag_addr);              
            /* this is the secondary device */
            ListId = 1;
            /* send connected event if not already done so */
            if(mask && !((mask & conn_hfp)&&(mask & conn_a2dp)))
            {
               MessageSend (&theSink.task , EventSecondaryDeviceConnected , NULL );        
            }
        }        
    }
    /* only 1 device so must be primary */
    else
    {
        /* Move device to top of the PDL */
        DEV_DEBUG(("DEV: Update MRU - primary device\n")) ;
        ConnectionSmUpdateMruDevice(dev_addr);    
        /* if this is the first profile for the device to be connected then send
           the primary device connected event */
        if(mask && !((mask & conn_hfp)&&(mask & conn_a2dp)))
        {
           MessageSend (&theSink.task , EventPrimaryDeviceConnected , NULL );        
        }
    }
   
    /* return current pdl list position of this device which is 0, top of list */        
    DEV_DEBUG(("DEV: Update MRU - ListId = %x\n",ListId)) ;
    return ListId;
}