/* this routine is called from SubSysFindAdapter and SubSysCreateAdapter */ static short create_adapter_obj(struct hpi_adapter_obj *pao, u32 *pos_error_code) { short boot_error = 0; u32 dsp_index = 0; u32 control_cache_size = 0; u32 control_cache_count = 0; struct hpi_hw_obj *phw = pao->priv; /* The PCI2040 has the following address map */ /* BAR0 - 4K = HPI control and status registers on PCI2040 (HPI CSR) */ /* BAR1 - 32K = HPI registers on DSP */ phw->dw2040_HPICSR = pao->pci.ap_mem_base[0]; phw->dw2040_HPIDSP = pao->pci.ap_mem_base[1]; HPI_DEBUG_LOG(VERBOSE, "csr %p, dsp %p\n", phw->dw2040_HPICSR, phw->dw2040_HPIDSP); /* set addresses for the possible DSP HPI interfaces */ for (dsp_index = 0; dsp_index < MAX_DSPS; dsp_index++) { phw->ado[dsp_index].prHPI_control = phw->dw2040_HPIDSP + (CONTROL + DSP_SPACING * dsp_index); phw->ado[dsp_index].prHPI_address = phw->dw2040_HPIDSP + (ADDRESS + DSP_SPACING * dsp_index); phw->ado[dsp_index].prHPI_data = phw->dw2040_HPIDSP + (DATA + DSP_SPACING * dsp_index); phw->ado[dsp_index].prHPI_data_auto_inc = phw->dw2040_HPIDSP + (DATA_AUTOINC + DSP_SPACING * dsp_index); HPI_DEBUG_LOG(VERBOSE, "ctl %p, adr %p, dat %p, dat++ %p\n", phw->ado[dsp_index].prHPI_control, phw->ado[dsp_index].prHPI_address, phw->ado[dsp_index].prHPI_data, phw->ado[dsp_index].prHPI_data_auto_inc); phw->ado[dsp_index].pa_parent_adapter = pao; } phw->pCI2040HPI_error_count = 0; pao->has_control_cache = 0; /* Set the default number of DSPs on this card */ /* This is (conditionally) adjusted after bootloading */ /* of the first DSP in the bootload section. */ phw->num_dsp = 1; boot_error = hpi6000_adapter_boot_load_dsp(pao, pos_error_code); if (boot_error) return boot_error; HPI_DEBUG_LOG(INFO, "bootload DSP OK\n"); phw->message_buffer_address_on_dsp = 0L; phw->response_buffer_address_on_dsp = 0L; /* get info about the adapter by asking the adapter */ /* send a HPI_ADAPTER_GET_INFO message */ { struct hpi_message hm; struct hpi_response hr0; /* response from DSP 0 */ struct hpi_response hr1; /* response from DSP 1 */ u16 error = 0; HPI_DEBUG_LOG(VERBOSE, "send ADAPTER_GET_INFO\n"); memset(&hm, 0, sizeof(hm)); hm.type = HPI_TYPE_REQUEST; hm.size = sizeof(struct hpi_message); hm.object = HPI_OBJ_ADAPTER; hm.function = HPI_ADAPTER_GET_INFO; hm.adapter_index = 0; memset(&hr0, 0, sizeof(hr0)); memset(&hr1, 0, sizeof(hr1)); hr0.size = sizeof(hr0); hr1.size = sizeof(hr1); error = hpi6000_message_response_sequence(pao, 0, &hm, &hr0); if (hr0.error) { HPI_DEBUG_LOG(DEBUG, "message error %d\n", hr0.error); return hr0.error; } if (phw->num_dsp == 2) { error = hpi6000_message_response_sequence(pao, 1, &hm, &hr1); if (error) return error; } pao->type = hr0.u.ax.info.adapter_type; pao->index = hr0.u.ax.info.adapter_index; } memset(&phw->control_cache[0], 0, sizeof(struct hpi_control_cache_single) * HPI_NMIXER_CONTROLS); /* Read the control cache length to figure out if it is turned on */ control_cache_size = hpi_read_word(&phw->ado[0], HPI_HIF_ADDR(control_cache_size_in_bytes)); if (control_cache_size) { control_cache_count = hpi_read_word(&phw->ado[0], HPI_HIF_ADDR(control_cache_count)); phw->p_cache = hpi_alloc_control_cache(control_cache_count, control_cache_size, (unsigned char *) &phw->control_cache[0] ); if (phw->p_cache) pao->has_control_cache = 1; } HPI_DEBUG_LOG(DEBUG, "get adapter info ASI%04X index %d\n", pao->type, pao->index); if (phw->p_cache) phw->p_cache->adap_idx = pao->index; return hpi_add_adapter(pao); }
/* create an adapter object and initialise it based on resource information * passed in in the message * NOTE - you cannot use this function AND the FindAdapters function at the * same time, the application must use only one of them to get the adapters */ static void subsys_create_adapter(struct hpi_message *phm, struct hpi_response *phr) { /* create temp adapter obj, because we don't know what index yet */ struct hpi_adapter_obj ao; struct hpi_adapter_obj *pao; u32 os_error_code; short error = 0; u32 dsp_index = 0; HPI_DEBUG_LOG(VERBOSE, "subsys_create_adapter\n"); memset(&ao, 0, sizeof(ao)); /* this HPI only creates adapters for TI/PCI2040 based devices */ if (phm->u.s.resource.bus_type != HPI_BUS_PCI) return; if (phm->u.s.resource.r.pci->vendor_id != HPI_PCI_VENDOR_ID_TI) return; if (phm->u.s.resource.r.pci->device_id != HPI_PCI_DEV_ID_PCI2040) return; ao.priv = kzalloc(sizeof(struct hpi_hw_obj), GFP_KERNEL); if (!ao.priv) { HPI_DEBUG_LOG(ERROR, "cant get mem for adapter object\n"); phr->error = HPI_ERROR_MEMORY_ALLOC; return; } /* create the adapter object based on the resource information */ /*? memcpy(&ao.Pci,&phm->u.s.Resource.r.Pci,sizeof(ao.Pci)); */ ao.pci = *phm->u.s.resource.r.pci; error = create_adapter_obj(&ao, &os_error_code); if (!error) error = hpi_add_adapter(&ao); if (error) { phr->u.s.data = os_error_code; kfree(ao.priv); phr->error = error; return; } /* need to update paParentAdapter */ pao = hpi_find_adapter(ao.index); if (!pao) { /* We just added this adapter, why can't we find it!? */ HPI_DEBUG_LOG(ERROR, "lost adapter after boot\n"); phr->error = 950; return; } for (dsp_index = 0; dsp_index < MAX_DSPS; dsp_index++) { struct hpi_hw_obj *phw = (struct hpi_hw_obj *)pao->priv; phw->ado[dsp_index].pa_parent_adapter = pao; } phr->u.s.aw_adapter_list[ao.index] = ao.adapter_type; phr->u.s.adapter_index = ao.index; phr->u.s.num_adapters++; phr->error = 0; }