1
0
Fork 0

ALSA: asihpi - Interrelated HPI tidy up.

Remove many unused functions.
Update some message and cache structs.
Use pci info directly from pci_dev.
Allow control cache elements with variable size, and handle
large message/response from dsp.
hpi6000 and hpi6205: fix error path when adapter bootload fails.
hpimsgx.c get rid of code duplicated in hpicmn.c

Signed-off-by: Eliot Blennerhassett <eblennerhassett@audioscience.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
hifive-unleashed-5.1
Eliot Blennerhassett 2011-02-10 17:25:58 +13:00 committed by Takashi Iwai
parent ad210ad10e
commit 3285ea10e9
11 changed files with 1103 additions and 2212 deletions

View File

@ -43,16 +43,16 @@
#define HPI_HIF_ERROR_MASK 0x4000
/* HPI6000 specific error codes */
#define HPI6000_ERROR_BASE 900
#define HPI6000_ERROR_BASE 900 /* not actually used anywhere */
/* operational/messaging errors */
#define HPI6000_ERROR_MSG_RESP_IDLE_TIMEOUT 901
#define HPI6000_ERROR_MSG_RESP_SEND_MSG_ACK 902
#define HPI6000_ERROR_MSG_RESP_GET_RESP_ACK 903
#define HPI6000_ERROR_MSG_GET_ADR 904
#define HPI6000_ERROR_RESP_GET_ADR 905
#define HPI6000_ERROR_MSG_RESP_BLOCKWRITE32 906
#define HPI6000_ERROR_MSG_RESP_BLOCKREAD32 907
#define HPI6000_ERROR_MSG_INVALID_DSP_INDEX 908
#define HPI6000_ERROR_CONTROL_CACHE_PARAMS 909
#define HPI6000_ERROR_SEND_DATA_IDLE_TIMEOUT 911
@ -62,7 +62,6 @@
#define HPI6000_ERROR_SEND_DATA_CMD 915
#define HPI6000_ERROR_SEND_DATA_WRITE 916
#define HPI6000_ERROR_SEND_DATA_IDLECMD 917
#define HPI6000_ERROR_SEND_DATA_VERIFY 918
#define HPI6000_ERROR_GET_DATA_IDLE_TIMEOUT 921
#define HPI6000_ERROR_GET_DATA_ACK 922
@ -76,9 +75,8 @@
#define HPI6000_ERROR_MSG_RESP_GETRESPCMD 961
#define HPI6000_ERROR_MSG_RESP_IDLECMD 962
#define HPI6000_ERROR_MSG_RESP_BLOCKVERIFY32 963
/* adapter init errors */
/* Initialisation/bootload errors */
#define HPI6000_ERROR_UNHANDLED_SUBSYS_ID 930
/* can't access PCI2040 */
@ -210,6 +208,8 @@ static void adapter_get_asserts(struct hpi_adapter_obj *pao,
static short create_adapter_obj(struct hpi_adapter_obj *pao,
u32 *pos_error_code);
static void delete_adapter_obj(struct hpi_adapter_obj *pao);
/* local globals */
static u16 gw_pci_read_asserts; /* used to count PCI2040 errors */
@ -217,17 +217,7 @@ static u16 gw_pci_write_asserts; /* used to count PCI2040 errors */
static void subsys_message(struct hpi_message *phm, struct hpi_response *phr)
{
switch (phm->function) {
case HPI_SUBSYS_OPEN:
case HPI_SUBSYS_CLOSE:
case HPI_SUBSYS_GET_INFO:
case HPI_SUBSYS_DRIVER_UNLOAD:
case HPI_SUBSYS_DRIVER_LOAD:
case HPI_SUBSYS_FIND_ADAPTERS:
/* messages that should not get here */
phr->error = HPI_ERROR_UNIMPLEMENTED;
break;
case HPI_SUBSYS_CREATE_ADAPTER:
subsys_create_adapter(phm, phr);
break;
@ -243,17 +233,13 @@ static void subsys_message(struct hpi_message *phm, struct hpi_response *phr)
static void control_message(struct hpi_adapter_obj *pao,
struct hpi_message *phm, struct hpi_response *phr)
{
switch (phm->function) {
case HPI_CONTROL_GET_STATE:
if (pao->has_control_cache) {
u16 err;
err = hpi6000_update_control_cache(pao, phm);
phr->error = hpi6000_update_control_cache(pao, phm);
if (err) {
phr->error = err;
if (phr->error)
break;
}
if (hpi_check_control_cache(((struct hpi_hw_obj *)
pao->priv)->p_cache, phm,
@ -262,16 +248,15 @@ static void control_message(struct hpi_adapter_obj *pao,
}
hw_message(pao, phm, phr);
break;
case HPI_CONTROL_GET_INFO:
hw_message(pao, phm, phr);
break;
case HPI_CONTROL_SET_STATE:
hw_message(pao, phm, phr);
hpi_sync_control_cache(((struct hpi_hw_obj *)pao->priv)->
p_cache, phm, phr);
hpi_cmn_control_cache_sync_to_msg(((struct hpi_hw_obj *)pao->
priv)->p_cache, phm, phr);
break;
case HPI_CONTROL_GET_INFO:
default:
phr->error = HPI_ERROR_INVALID_FUNC;
hw_message(pao, phm, phr);
break;
}
}
@ -280,26 +265,12 @@ static void adapter_message(struct hpi_adapter_obj *pao,
struct hpi_message *phm, struct hpi_response *phr)
{
switch (phm->function) {
case HPI_ADAPTER_GET_INFO:
hw_message(pao, phm, phr);
break;
case HPI_ADAPTER_GET_ASSERT:
adapter_get_asserts(pao, phm, phr);
break;
case HPI_ADAPTER_OPEN:
case HPI_ADAPTER_CLOSE:
case HPI_ADAPTER_TEST_ASSERT:
case HPI_ADAPTER_SELFTEST:
case HPI_ADAPTER_GET_MODE:
case HPI_ADAPTER_SET_MODE:
case HPI_ADAPTER_FIND_OBJECT:
case HPI_ADAPTER_GET_PROPERTY:
case HPI_ADAPTER_SET_PROPERTY:
case HPI_ADAPTER_ENUM_PROPERTY:
hw_message(pao, phm, phr);
break;
default:
phr->error = HPI_ERROR_INVALID_FUNC;
hw_message(pao, phm, phr);
break;
}
}
@ -311,7 +282,7 @@ static void outstream_message(struct hpi_adapter_obj *pao,
case HPI_OSTREAM_HOSTBUFFER_ALLOC:
case HPI_OSTREAM_HOSTBUFFER_FREE:
/* Don't let these messages go to the HW function because
* they're called without allocating the spinlock.
* they're called without locking the spinlock.
* For the HPI6000 adapters the HW would return
* HPI_ERROR_INVALID_FUNC anyway.
*/
@ -331,7 +302,7 @@ static void instream_message(struct hpi_adapter_obj *pao,
case HPI_ISTREAM_HOSTBUFFER_ALLOC:
case HPI_ISTREAM_HOSTBUFFER_FREE:
/* Don't let these messages go to the HW function because
* they're called without allocating the spinlock.
* they're called without locking the spinlock.
* For the HPI6000 adapters the HW would return
* HPI_ERROR_INVALID_FUNC anyway.
*/
@ -355,7 +326,7 @@ void HPI_6000(struct hpi_message *phm, struct hpi_response *phr)
/* subsytem messages get executed by every HPI. */
/* All other messages are ignored unless the adapter index matches */
/* an adapter in the HPI */
HPI_DEBUG_LOG(DEBUG, "O %d,F %x\n", phm->object, phm->function);
/*HPI_DEBUG_LOG(DEBUG, "O %d,F %x\n", phm->wObject, phm->wFunction); */
/* if Dsp has crashed then do not communicate with it any more */
if (phm->object != HPI_OBJ_SUBSYSTEM) {
@ -440,14 +411,6 @@ static void subsys_create_adapter(struct hpi_message *phm,
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");
@ -456,16 +419,13 @@ static void subsys_create_adapter(struct hpi_message *phm,
}
/* 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);
delete_adapter_obj(&ao);
phr->error = error;
phr->u.s.data = os_error_code;
return;
}
/* need to update paParentAdapter */
@ -492,20 +452,13 @@ static void subsys_delete_adapter(struct hpi_message *phm,
struct hpi_response *phr)
{
struct hpi_adapter_obj *pao = NULL;
struct hpi_hw_obj *phw;
pao = hpi_find_adapter(phm->adapter_index);
pao = hpi_find_adapter(phm->obj_index);
if (!pao)
return;
phw = (struct hpi_hw_obj *)pao->priv;
if (pao->has_control_cache)
hpi_free_control_cache(phw->p_cache);
delete_adapter_obj(pao);
hpi_delete_adapter(pao);
kfree(phw);
phr->error = 0;
}
@ -519,9 +472,6 @@ static short create_adapter_obj(struct hpi_adapter_obj *pao,
u32 control_cache_count = 0;
struct hpi_hw_obj *phw = (struct hpi_hw_obj *)pao->priv;
/* init error reporting */
pao->dsp_crashed = 0;
/* The PCI2040 has the following address map */
/* BAR0 - 4K = HPI control and status registers on PCI2040 (HPI CSR) */
/* BAR1 - 32K = HPI registers on DSP */
@ -575,36 +525,36 @@ static short create_adapter_obj(struct hpi_adapter_obj *pao,
/* 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 */
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_MESSAGE;
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);
memset(&hm, 0, sizeof(hm));
hm.type = HPI_TYPE_MESSAGE;
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;
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);
error = hpi6000_message_response_sequence(pao, 1, &hm,
&hr1);
if (error)
return error;
}
pao->adapter_type = hR0.u.a.adapter_type;
pao->index = hR0.u.a.adapter_index;
pao->adapter_type = hr0.u.ax.info.adapter_type;
pao->index = hr0.u.ax.info.adapter_index;
}
memset(&phw->control_cache[0], 0,
@ -618,22 +568,34 @@ static short create_adapter_obj(struct hpi_adapter_obj *pao,
control_cache_count =
hpi_read_word(&phw->ado[0],
HPI_HIF_ADDR(control_cache_count));
pao->has_control_cache = 1;
phw->p_cache =
hpi_alloc_control_cache(control_cache_count,
control_cache_size, (struct hpi_control_cache_info *)
control_cache_size, (unsigned char *)
&phw->control_cache[0]
);
if (!phw->p_cache)
pao->has_control_cache = 0;
} else
pao->has_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->adapter_type, pao->index);
pao->open = 0; /* upon creation the adapter is closed */
return 0;
return hpi_add_adapter(pao);
}
static void delete_adapter_obj(struct hpi_adapter_obj *pao)
{
struct hpi_hw_obj *phw = (struct hpi_hw_obj *)pao->priv;
if (pao->has_control_cache)
hpi_free_control_cache(phw->p_cache);
/* reset DSPs on adapter */
iowrite32(0x0003000F, phw->dw2040_HPICSR + HPI_RESET);
kfree(phw);
}
/************************************************************************/
@ -645,11 +607,13 @@ static void adapter_get_asserts(struct hpi_adapter_obj *pao,
#ifndef HIDE_PCI_ASSERTS
/* if we have PCI2040 asserts then collect them */
if ((gw_pci_read_asserts > 0) || (gw_pci_write_asserts > 0)) {
phr->u.a.serial_number =
phr->u.ax.assert.p1 =
gw_pci_read_asserts * 100 + gw_pci_write_asserts;
phr->u.a.adapter_index = 1; /* assert count */
phr->u.a.adapter_type = -1; /* "dsp index" */
strcpy(phr->u.a.sz_adapter_assert, "PCI2040 error");
phr->u.ax.assert.p2 = 0;
phr->u.ax.assert.count = 1; /* assert count */
phr->u.ax.assert.dsp_index = -1; /* "dsp index" */
strcpy(phr->u.ax.assert.sz_message, "PCI2040 error");
phr->u.ax.assert.dsp_msg_addr = 0;
gw_pci_read_asserts = 0;
gw_pci_write_asserts = 0;
phr->error = 0;
@ -686,10 +650,10 @@ static short hpi6000_adapter_boot_load_dsp(struct hpi_adapter_obj *pao,
/* NOTE don't use wAdapterType in this routine. It is not setup yet */
switch (pao->pci.subsys_device_id) {
switch (pao->pci.pci_dev->subsystem_device) {
case 0x5100:
case 0x5110: /* ASI5100 revB or higher with C6711D */
case 0x5200: /* ASI5200 PC_ie version of ASI5100 */
case 0x5200: /* ASI5200 PCIe version of ASI5100 */
case 0x6100:
case 0x6200:
boot_load_family = HPI_ADAPTER_FAMILY_ASI(0x6200);
@ -709,8 +673,9 @@ static short hpi6000_adapter_boot_load_dsp(struct hpi_adapter_obj *pao,
* note that bits 4..15 are read-only and so should always return zero,
* even though we wrote 1 to them
*/
for (i = 0; i < 1000; i++)
delay = ioread32(phw->dw2040_HPICSR + HPI_RESET);
hpios_delay_micro_seconds(1000);
delay = ioread32(phw->dw2040_HPICSR + HPI_RESET);
if (delay != dw2040_reset) {
HPI_DEBUG_LOG(ERROR, "INIT_PCI2040 %x %x\n", dw2040_reset,
delay);
@ -743,8 +708,7 @@ static short hpi6000_adapter_boot_load_dsp(struct hpi_adapter_obj *pao,
dw2040_reset = dw2040_reset & (~0x00000008);
iowrite32(dw2040_reset, phw->dw2040_HPICSR + HPI_RESET);
/*delay to allow DSP to get going */
for (i = 0; i < 100; i++)
delay = ioread32(phw->dw2040_HPICSR + HPI_RESET);
hpios_delay_micro_seconds(100);
/* loop through all DSPs, downloading DSP code */
for (dsp_index = 0; dsp_index < phw->num_dsp; dsp_index++) {
@ -783,27 +747,27 @@ static short hpi6000_adapter_boot_load_dsp(struct hpi_adapter_obj *pao,
*/
/* bypass PLL */
hpi_write_word(pdo, 0x01B7C100, 0x0000);
for (i = 0; i < 100; i++)
delay = ioread32(phw->dw2040_HPICSR +
HPI_RESET);
hpios_delay_micro_seconds(100);
/* ** use default of PLL x7 ** */
/* EMIF = 225/3=75MHz */
hpi_write_word(pdo, 0x01B7C120, 0x8002);
hpios_delay_micro_seconds(100);
/* peri = 225/2 */
hpi_write_word(pdo, 0x01B7C11C, 0x8001);
hpios_delay_micro_seconds(100);
/* cpu = 225/1 */
hpi_write_word(pdo, 0x01B7C118, 0x8000);
/* ~200us delay */
for (i = 0; i < 2000; i++)
delay = ioread32(phw->dw2040_HPICSR +
HPI_RESET);
/* ~2ms delay */
hpios_delay_micro_seconds(2000);
/* PLL not bypassed */
hpi_write_word(pdo, 0x01B7C100, 0x0001);
/* ~200us delay */
for (i = 0; i < 2000; i++)
delay = ioread32(phw->dw2040_HPICSR +
HPI_RESET);
/* ~2ms delay */
hpios_delay_micro_seconds(2000);
}
/* test r/w to internal DSP memory
@ -927,9 +891,7 @@ static short hpi6000_adapter_boot_load_dsp(struct hpi_adapter_obj *pao,
}
/* delay a little to allow SDRAM and DSP to "get going" */
for (i = 0; i < 1000; i++)
delay = ioread32(phw->dw2040_HPICSR + HPI_RESET);
hpios_delay_micro_seconds(1000);
/* test access to SDRAM */
{
@ -976,7 +938,7 @@ static short hpi6000_adapter_boot_load_dsp(struct hpi_adapter_obj *pao,
/* write the DSP code down into the DSPs memory */
/*HpiDspCode_Open(nBootLoadFamily,&DspCode,pdwOsErrorCode); */
dsp_code.ps_dev = pao->pci.p_os_data;
dsp_code.ps_dev = pao->pci.pci_dev;
error = hpi_dsp_code_open(boot_load_family, &dsp_code,
pos_error_code);
@ -1073,8 +1035,7 @@ static short hpi6000_adapter_boot_load_dsp(struct hpi_adapter_obj *pao,
/* step 3. Start code by sending interrupt */
iowrite32(0x00030003, pdo->prHPI_control);
for (i = 0; i < 10000; i++)
delay = ioread32(phw->dw2040_HPICSR + HPI_RESET);
hpios_delay_micro_seconds(10000);
/* wait for a non-zero value in hostcmd -
* indicating initialization is complete
@ -1101,7 +1062,7 @@ static short hpi6000_adapter_boot_load_dsp(struct hpi_adapter_obj *pao,
* locks up with a bluescreen (NOT GPF or pagefault).
*/
else
hpios_delay_micro_seconds(1000);
hpios_delay_micro_seconds(10000);
}
if (timeout == 0)
return HPI6000_ERROR_INIT_NOACK;
@ -1132,14 +1093,14 @@ static short hpi6000_adapter_boot_load_dsp(struct hpi_adapter_obj *pao,
mask = 0xFFFFFF00L;
/* ASI5100 uses AX6 code, */
/* but has no PLD r/w register to test */
if (HPI_ADAPTER_FAMILY_ASI(pao->pci.
subsys_device_id) ==
if (HPI_ADAPTER_FAMILY_ASI(pao->pci.pci_dev->
subsystem_device) ==
HPI_ADAPTER_FAMILY_ASI(0x5100))
mask = 0x00000000L;
/* ASI5200 uses AX6 code, */
/* but has no PLD r/w register to test */
if (HPI_ADAPTER_FAMILY_ASI(pao->pci.
subsys_device_id) ==
if (HPI_ADAPTER_FAMILY_ASI(pao->pci.pci_dev->
subsystem_device) ==
HPI_ADAPTER_FAMILY_ASI(0x5200))
mask = 0x00000000L;
break;
@ -1204,7 +1165,7 @@ static u32 hpi_read_word(struct dsp_obj *pdo, u32 address)
u32 data = 0;
if (hpi_set_address(pdo, address))
return 0; /*? no way to return error */
return 0; /*? No way to return error */
/* take care of errata in revB DSP (2.0.1) */
data = ioread32(pdo->prHPI_data);
@ -1340,10 +1301,6 @@ static short hpi6000_message_response_sequence(struct hpi_adapter_obj *pao,
u32 *p_data;
u16 error = 0;
/* does the DSP we are referencing exist? */
if (dsp_index >= phw->num_dsp)
return HPI6000_ERROR_MSG_INVALID_DSP_INDEX;
ack = hpi6000_wait_dsp_ack(pao, dsp_index, HPI_HIF_IDLE);
if (ack & HPI_HIF_ERROR_MASK) {
pao->dsp_crashed++;
@ -1351,9 +1308,7 @@ static short hpi6000_message_response_sequence(struct hpi_adapter_obj *pao,
}
pao->dsp_crashed = 0;
/* send the message */
/* get the address and size */
/* get the message address and size */
if (phw->message_buffer_address_on_dsp == 0) {
timeout = TIMEOUT;
do {
@ -1368,10 +1323,9 @@ static short hpi6000_message_response_sequence(struct hpi_adapter_obj *pao,
} else
address = phw->message_buffer_address_on_dsp;
/* dwLength = sizeof(struct hpi_message); */
length = phm->size;
/* send it */
/* send the message */
p_data = (u32 *)phm;
if (hpi6000_dsp_block_write32(pao, dsp_index, address, p_data,
(u16)length / 4))
@ -1385,7 +1339,7 @@ static short hpi6000_message_response_sequence(struct hpi_adapter_obj *pao,
if (ack & HPI_HIF_ERROR_MASK)
return HPI6000_ERROR_MSG_RESP_GET_RESP_ACK;
/* get the address and size */
/* get the response address */
if (phw->response_buffer_address_on_dsp == 0) {
timeout = TIMEOUT;
do {
@ -1409,7 +1363,7 @@ static short hpi6000_message_response_sequence(struct hpi_adapter_obj *pao,
if (!timeout)
length = sizeof(struct hpi_response);
/* get it */
/* get the response */
p_data = (u32 *)phr;
if (hpi6000_dsp_block_read32(pao, dsp_index, address, p_data,
(u16)length / 4))
@ -1827,13 +1781,13 @@ static void hw_message(struct hpi_adapter_obj *pao, struct hpi_message *phm,
error = hpi6000_get_data(pao, dsp_index, phm, phr);
break;
case HPI_ADAPTER_GET_ASSERT:
phr->u.a.adapter_index = 0; /* dsp 0 default */
phr->u.ax.assert.dsp_index = 0; /* dsp 0 default */
if (num_dsp == 2) {
if (!phr->u.a.adapter_type) {
if (!phr->u.ax.assert.count) {
/* no assert from dsp 0, check dsp 1 */
error = hpi6000_message_response_sequence(pao,
1, phm, phr);
phr->u.a.adapter_index = 1;
phr->u.ax.assert.dsp_index = 1;
}
}
}

View File

@ -38,27 +38,26 @@
/*****************************************************************************/
/* HPI6205 specific error codes */
#define HPI6205_ERROR_BASE 1000
/*#define HPI6205_ERROR_MEM_ALLOC 1001 */
#define HPI6205_ERROR_BASE 1000 /* not actually used anywhere */
/* operational/messaging errors */
#define HPI6205_ERROR_MSG_RESP_IDLE_TIMEOUT 1015
#define HPI6205_ERROR_MSG_RESP_TIMEOUT 1016
/* initialization/bootload errors */
#define HPI6205_ERROR_6205_NO_IRQ 1002
#define HPI6205_ERROR_6205_INIT_FAILED 1003
/*#define HPI6205_ERROR_MISSING_DSPCODE 1004 */
#define HPI6205_ERROR_UNKNOWN_PCI_DEVICE 1005
#define HPI6205_ERROR_6205_REG 1006
#define HPI6205_ERROR_6205_DSPPAGE 1007
#define HPI6205_ERROR_BAD_DSPINDEX 1008
#define HPI6205_ERROR_C6713_HPIC 1009
#define HPI6205_ERROR_C6713_HPIA 1010
#define HPI6205_ERROR_C6713_PLL 1011
#define HPI6205_ERROR_DSP_INTMEM 1012
#define HPI6205_ERROR_DSP_EXTMEM 1013
#define HPI6205_ERROR_DSP_PLD 1014
#define HPI6205_ERROR_MSG_RESP_IDLE_TIMEOUT 1015
#define HPI6205_ERROR_MSG_RESP_TIMEOUT 1016
#define HPI6205_ERROR_6205_EEPROM 1017
#define HPI6205_ERROR_DSP_EMIF 1018
#define hpi6205_error(dsp_index, err) (err)
/*****************************************************************************/
/* for C6205 PCI i/f */
/* Host Status Register (HSR) bitfields */
@ -208,8 +207,8 @@ static void instream_start(struct hpi_adapter_obj *pao,
static u32 boot_loader_read_mem32(struct hpi_adapter_obj *pao, int dsp_index,
u32 address);
static u16 boot_loader_write_mem32(struct hpi_adapter_obj *pao, int dsp_index,
u32 address, u32 data);
static void boot_loader_write_mem32(struct hpi_adapter_obj *pao,
int dsp_index, u32 address, u32 data);
static u16 boot_loader_config_emif(struct hpi_adapter_obj *pao,
int dsp_index);
@ -229,17 +228,7 @@ static u16 boot_loader_test_pld(struct hpi_adapter_obj *pao, int dsp_index);
static void subsys_message(struct hpi_message *phm, struct hpi_response *phr)
{
switch (phm->function) {
case HPI_SUBSYS_OPEN:
case HPI_SUBSYS_CLOSE:
case HPI_SUBSYS_GET_INFO:
case HPI_SUBSYS_DRIVER_UNLOAD:
case HPI_SUBSYS_DRIVER_LOAD:
case HPI_SUBSYS_FIND_ADAPTERS:
/* messages that should not get here */
phr->error = HPI_ERROR_UNIMPLEMENTED;
break;
case HPI_SUBSYS_CREATE_ADAPTER:
subsys_create_adapter(phm, phr);
break;
@ -257,15 +246,22 @@ static void control_message(struct hpi_adapter_obj *pao,
{
struct hpi_hw_obj *phw = pao->priv;
u16 pending_cache_error = 0;
switch (phm->function) {
case HPI_CONTROL_GET_STATE:
if (pao->has_control_cache) {
rmb(); /* make sure we see updates DM_aed from DSP */
if (hpi_check_control_cache(phw->p_cache, phm, phr))
rmb(); /* make sure we see updates DMAed from DSP */
if (hpi_check_control_cache(phw->p_cache, phm, phr)) {
break;
} else if (phm->u.c.attribute == HPI_METER_PEAK) {
pending_cache_error =
HPI_ERROR_CONTROL_CACHING;
}
}
hw_message(pao, phm, phr);
if (pending_cache_error && !phr->error)
phr->error = pending_cache_error;
break;
case HPI_CONTROL_GET_INFO:
hw_message(pao, phm, phr);
@ -273,7 +269,8 @@ static void control_message(struct hpi_adapter_obj *pao,
case HPI_CONTROL_SET_STATE:
hw_message(pao, phm, phr);
if (pao->has_control_cache)
hpi_sync_control_cache(phw->p_cache, phm, phr);
hpi_cmn_control_cache_sync_to_msg(phw->p_cache, phm,
phr);
break;
default:
phr->error = HPI_ERROR_INVALID_FUNC;
@ -298,7 +295,7 @@ static void outstream_message(struct hpi_adapter_obj *pao,
if (phm->obj_index >= HPI_MAX_STREAMS) {
phr->error = HPI_ERROR_INVALID_STREAM;
HPI_DEBUG_LOG(WARNING,
"message referencing invalid stream %d "
"Message referencing invalid stream %d "
"on adapter index %d\n", phm->obj_index,
phm->adapter_index);
return;
@ -342,7 +339,7 @@ static void instream_message(struct hpi_adapter_obj *pao,
if (phm->obj_index >= HPI_MAX_STREAMS) {
phr->error = HPI_ERROR_INVALID_STREAM;
HPI_DEBUG_LOG(WARNING,
"message referencing invalid stream %d "
"Message referencing invalid stream %d "
"on adapter index %d\n", phm->obj_index,
phm->adapter_index);
return;
@ -385,8 +382,8 @@ void HPI_6205(struct hpi_message *phm, struct hpi_response *phr)
* All other messages are ignored unless the adapter index matches
* an adapter in the HPI
*/
HPI_DEBUG_LOG(DEBUG, "HPI obj=%d, func=%d\n", phm->object,
phm->function);
/* HPI_DEBUG_LOG(DEBUG, "HPI Obj=%d, Func=%d\n", phm->wObject,
phm->wFunction); */
/* if Dsp has crashed then do not communicate with it any more */
if (phm->object != HPI_OBJ_SUBSYSTEM) {
@ -411,8 +408,7 @@ void HPI_6205(struct hpi_message *phm, struct hpi_response *phr)
/* Init default response */
if (phm->function != HPI_SUBSYS_CREATE_ADAPTER)
hpi_init_response(phr, phm->object, phm->function,
HPI_ERROR_PROCESSING_MESSAGE);
phr->error = HPI_ERROR_PROCESSING_MESSAGE;
HPI_DEBUG_LOG(VERBOSE, "start of switch\n");
switch (phm->type) {
@ -423,9 +419,6 @@ void HPI_6205(struct hpi_message *phm, struct hpi_response *phr)
break;
case HPI_OBJ_ADAPTER:
phr->size =
sizeof(struct hpi_response_header) +
sizeof(struct hpi_adapter_res);
adapter_message(pao, phm, phr);
break;
@ -474,14 +467,6 @@ static void subsys_create_adapter(struct hpi_message *phm,
memset(&ao, 0, sizeof(ao));
/* this HPI only creates adapters for TI/PCI 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_DSP6205)
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");
@ -491,12 +476,10 @@ static void subsys_create_adapter(struct hpi_message *phm,
ao.pci = *phm->u.s.resource.r.pci;
err = create_adapter_obj(&ao, &os_error_code);
if (!err)
err = hpi_add_adapter(&ao);
if (err) {
phr->u.s.data = os_error_code;
delete_adapter_obj(&ao);
phr->error = err;
phr->u.s.data = os_error_code;
return;
}
@ -513,7 +496,7 @@ static void subsys_delete_adapter(struct hpi_message *phm,
struct hpi_adapter_obj *pao;
struct hpi_hw_obj *phw;
pao = hpi_find_adapter(phm->adapter_index);
pao = hpi_find_adapter(phm->obj_index);
if (!pao) {
phr->error = HPI_ERROR_INVALID_OBJ_INDEX;
return;
@ -526,6 +509,7 @@ static void subsys_delete_adapter(struct hpi_message *phm,
iowrite32(C6205_HDCR_WARMRESET, phw->prHDCR);
delete_adapter_obj(pao);
hpi_delete_adapter(pao);
phr->error = 0;
}
@ -566,7 +550,7 @@ static u16 create_adapter_obj(struct hpi_adapter_obj *pao,
if (hpios_locked_mem_alloc(&phw->h_locked_mem,
sizeof(struct bus_master_interface),
pao->pci.p_os_data))
pao->pci.pci_dev))
phw->p_interface_buffer = NULL;
else if (hpios_locked_mem_get_virt_addr(&phw->h_locked_mem,
(void *)&phw->p_interface_buffer))
@ -591,7 +575,7 @@ static u16 create_adapter_obj(struct hpi_adapter_obj *pao,
/* allow boot load even if mem alloc wont work */
if (!phw->p_interface_buffer)
return hpi6205_error(0, HPI_ERROR_MEMORY_ALLOC);
return HPI_ERROR_MEMORY_ALLOC;
interface = phw->p_interface_buffer;
@ -604,12 +588,12 @@ static u16 create_adapter_obj(struct hpi_adapter_obj *pao,
if (temp1 & C6205_HSR_INTSRC)
HPI_DEBUG_LOG(INFO,
"interrupt confirming DSP code running OK\n");
"Interrupt confirming DSP code running OK\n");
else {
HPI_DEBUG_LOG(ERROR,
"timed out waiting for interrupt "
"Timed out waiting for interrupt "
"confirming DSP code running\n");
return hpi6205_error(0, HPI6205_ERROR_6205_NO_IRQ);
return HPI6205_ERROR_6205_NO_IRQ;
}
/* reset the interrupt */
@ -619,21 +603,22 @@ static u16 create_adapter_obj(struct hpi_adapter_obj *pao,
/* make sure the DSP has started ok */
if (!wait_dsp_ack(phw, H620_HIF_RESET, HPI6205_TIMEOUT * 10)) {
HPI_DEBUG_LOG(ERROR, "timed out waiting reset state \n");
return hpi6205_error(0, HPI6205_ERROR_6205_INIT_FAILED);
return HPI6205_ERROR_6205_INIT_FAILED;
}
/* Note that *pao, *phw are zeroed after allocation,
* so pointers and flags are NULL by default.
* Allocate bus mastering control cache buffer and tell the DSP about it
*/
if (interface->control_cache.number_of_controls) {
void *p_control_cache_virtual;
u8 *p_control_cache_virtual;
err = hpios_locked_mem_alloc(&phw->h_control_cache,
interface->control_cache.size_in_bytes,
pao->pci.p_os_data);
pao->pci.pci_dev);
if (!err)
err = hpios_locked_mem_get_virt_addr(&phw->
h_control_cache, &p_control_cache_virtual);
h_control_cache,
(void *)&p_control_cache_virtual);
if (!err) {
memset(p_control_cache_virtual, 0,
interface->control_cache.size_in_bytes);
@ -642,7 +627,6 @@ static u16 create_adapter_obj(struct hpi_adapter_obj *pao,
hpi_alloc_control_cache(interface->
control_cache.number_of_controls,
interface->control_cache.size_in_bytes,
(struct hpi_control_cache_info *)
p_control_cache_virtual);
if (!phw->p_cache)
err = HPI_ERROR_MEMORY_ALLOC;
@ -666,7 +650,7 @@ static u16 create_adapter_obj(struct hpi_adapter_obj *pao,
if (interface->async_buffer.b.size) {
err = hpios_locked_mem_alloc(&phw->h_async_event_buffer,
interface->async_buffer.b.size *
sizeof(struct hpi_async_event), pao->pci.p_os_data);
sizeof(struct hpi_async_event), pao->pci.pci_dev);
if (!err)
err = hpios_locked_mem_get_virt_addr
(&phw->h_async_event_buffer, (void *)
@ -693,47 +677,50 @@ static u16 create_adapter_obj(struct hpi_adapter_obj *pao,
send_dsp_command(phw, H620_HIF_IDLE);
{
struct hpi_message hM;
struct hpi_response hR;
struct hpi_message hm;
struct hpi_response hr;
u32 max_streams;
HPI_DEBUG_LOG(VERBOSE, "init ADAPTER_GET_INFO\n");
memset(&hM, 0, sizeof(hM));
hM.type = HPI_TYPE_MESSAGE;
hM.size = sizeof(hM);
hM.object = HPI_OBJ_ADAPTER;
hM.function = HPI_ADAPTER_GET_INFO;
hM.adapter_index = 0;
memset(&hR, 0, sizeof(hR));
hR.size = sizeof(hR);
memset(&hm, 0, sizeof(hm));
hm.type = HPI_TYPE_MESSAGE;
hm.size = sizeof(hm);
hm.object = HPI_OBJ_ADAPTER;
hm.function = HPI_ADAPTER_GET_INFO;
hm.adapter_index = 0;
memset(&hr, 0, sizeof(hr));
hr.size = sizeof(hr);
err = message_response_sequence(pao, &hM, &hR);
err = message_response_sequence(pao, &hm, &hr);
if (err) {
HPI_DEBUG_LOG(ERROR, "message transport error %d\n",
err);
return err;
}
if (hR.error)
return hR.error;
if (hr.error)
return hr.error;
pao->adapter_type = hR.u.a.adapter_type;
pao->index = hR.u.a.adapter_index;
pao->adapter_type = hr.u.ax.info.adapter_type;
pao->index = hr.u.ax.info.adapter_index;
max_streams = hR.u.a.num_outstreams + hR.u.a.num_instreams;
max_streams =
hr.u.ax.info.num_outstreams +
hr.u.ax.info.num_instreams;
hpios_locked_mem_prepare((max_streams * 6) / 10, max_streams,
65536, pao->pci.p_os_data);
65536, pao->pci.pci_dev);
HPI_DEBUG_LOG(VERBOSE,
"got adapter info type %x index %d serial %d\n",
hR.u.a.adapter_type, hR.u.a.adapter_index,
hR.u.a.serial_number);
hr.u.ax.info.adapter_type, hr.u.ax.info.adapter_index,
hr.u.ax.info.serial_number);
}
pao->open = 0; /* upon creation the adapter is closed */
HPI_DEBUG_LOG(INFO, "bootload DSP OK\n");
return 0;
return hpi_add_adapter(pao);
}
/** Free memory areas allocated by adapter
@ -776,9 +763,8 @@ static void delete_adapter_obj(struct hpi_adapter_obj *pao)
phw->outstream_host_buffer_size[i] = 0;
}
hpios_locked_mem_unprepare(pao->pci.p_os_data);
hpios_locked_mem_unprepare(pao->pci.pci_dev);
hpi_delete_adapter(pao);
kfree(phw);
}
@ -824,7 +810,7 @@ static void outstream_host_buffer_allocate(struct hpi_adapter_obj *pao,
err = hpios_locked_mem_alloc(&phw->outstream_host_buffers
[phm->obj_index], phm->u.d.u.buffer.buffer_size,
pao->pci.p_os_data);
pao->pci.pci_dev);
if (err) {
phr->error = HPI_ERROR_INVALID_DATASIZE;
@ -861,7 +847,7 @@ static void outstream_host_buffer_allocate(struct hpi_adapter_obj *pao,
if (phm->u.d.u.buffer.buffer_size & (phm->u.d.u.buffer.
buffer_size - 1)) {
HPI_DEBUG_LOG(ERROR,
"buffer size must be 2^N not %d\n",
"Buffer size must be 2^N not %d\n",
phm->u.d.u.buffer.buffer_size);
phr->error = HPI_ERROR_INVALID_DATASIZE;
return;
@ -966,51 +952,6 @@ static void outstream_write(struct hpi_adapter_obj *pao,
hpi_init_response(phr, phm->object, phm->function, 0);
status = &interface->outstream_host_buffer_status[phm->obj_index];
if (phw->flag_outstream_just_reset[phm->obj_index]) {
/* First OutStremWrite() call following reset will write data to the
adapter's buffers, reducing delay before stream can start. The DSP
takes care of setting the stream data format using format information
embedded in phm.
*/
int partial_write = 0;
unsigned int original_size = 0;
phw->flag_outstream_just_reset[phm->obj_index] = 0;
/* Send the first buffer to the DSP the old way. */
/* Limit size of first transfer - */
/* expect that this will not usually be triggered. */
if (phm->u.d.u.data.data_size > HPI6205_SIZEOF_DATA) {
partial_write = 1;
original_size = phm->u.d.u.data.data_size;
phm->u.d.u.data.data_size = HPI6205_SIZEOF_DATA;
}
/* write it */
phm->function = HPI_OSTREAM_WRITE;
hw_message(pao, phm, phr);
if (phr->error)
return;
/* update status information that the DSP would typically
* update (and will update next time the DSP
* buffer update task reads data from the host BBM buffer)
*/
status->auxiliary_data_available = phm->u.d.u.data.data_size;
status->host_index += phm->u.d.u.data.data_size;
status->dSP_index += phm->u.d.u.data.data_size;
/* if we did a full write, we can return from here. */
if (!partial_write)
return;
/* tweak buffer parameters and let the rest of the */
/* buffer land in internal BBM buffer */
phm->u.d.u.data.data_size =
original_size - HPI6205_SIZEOF_DATA;
phm->u.d.u.data.pb_data += HPI6205_SIZEOF_DATA;
}
space_available = outstream_get_space_available(status);
if (space_available < phm->u.d.u.data.data_size) {
phr->error = HPI_ERROR_INVALID_DATASIZE;
@ -1047,6 +988,24 @@ static void outstream_write(struct hpi_adapter_obj *pao,
memcpy(p_bbm_data, p_app_data + l_first_write,
phm->u.d.u.data.data_size - l_first_write);
}
/*
* This version relies on the DSP code triggering an OStream buffer
* update immediately following a SET_FORMAT call. The host has
* already written data into the BBM buffer, but the DSP won't know about
* it until dwHostIndex is adjusted.
*/
if (phw->flag_outstream_just_reset[phm->obj_index]) {
/* Format can only change after reset. Must tell DSP. */
u16 function = phm->function;
phw->flag_outstream_just_reset[phm->obj_index] = 0;
phm->function = HPI_OSTREAM_SET_FORMAT;
hw_message(pao, phm, phr); /* send the format to the DSP */
phm->function = function;
if (phr->error)
return;
}
status->host_index += phm->u.d.u.data.data_size;
}
@ -1132,7 +1091,7 @@ static void instream_host_buffer_allocate(struct hpi_adapter_obj *pao,
err = hpios_locked_mem_alloc(&phw->instream_host_buffers[phm->
obj_index], phm->u.d.u.buffer.buffer_size,
pao->pci.p_os_data);
pao->pci.pci_dev);
if (err) {
phr->error = HPI_ERROR_INVALID_DATASIZE;
@ -1163,7 +1122,7 @@ static void instream_host_buffer_allocate(struct hpi_adapter_obj *pao,
if (phm->u.d.u.buffer.buffer_size & (phm->u.d.u.buffer.
buffer_size - 1)) {
HPI_DEBUG_LOG(ERROR,
"buffer size must be 2^N not %d\n",
"Buffer size must be 2^N not %d\n",
phm->u.d.u.buffer.buffer_size);
phr->error = HPI_ERROR_INVALID_DATASIZE;
return;
@ -1344,7 +1303,7 @@ static u16 adapter_boot_load_dsp(struct hpi_adapter_obj *pao,
struct hpi_hw_obj *phw = pao->priv;
struct dsp_code dsp_code;
u16 boot_code_id[HPI6205_MAX_FILES_TO_LOAD];
u16 firmware_id = pao->pci.subsys_device_id;
u16 firmware_id = pao->pci.pci_dev->subsystem_device;
u32 temp;
int dsp = 0, i = 0;
u16 err = 0;
@ -1381,7 +1340,7 @@ static u16 adapter_boot_load_dsp(struct hpi_adapter_obj *pao,
temp = ioread32(phw->prHSR);
if ((temp & (C6205_HSR_CFGERR | C6205_HSR_EEREAD)) !=
C6205_HSR_EEREAD)
return hpi6205_error(0, HPI6205_ERROR_6205_EEPROM);
return HPI6205_ERROR_6205_EEPROM;
temp |= 0x04;
/* disable PINTA interrupt */
iowrite32(temp, phw->prHSR);
@ -1389,27 +1348,27 @@ static u16 adapter_boot_load_dsp(struct hpi_adapter_obj *pao,
/* check control register reports PCI boot mode */
temp = ioread32(phw->prHDCR);
if (!(temp & C6205_HDCR_PCIBOOT))
return hpi6205_error(0, HPI6205_ERROR_6205_REG);
return HPI6205_ERROR_6205_REG;
/* try writing a couple of numbers to the DSP page register */
/* try writing a few numbers to the DSP page register */
/* and reading them back. */
temp = 1;
iowrite32(temp, phw->prDSPP);
if ((temp | C6205_DSPP_MAP1) != ioread32(phw->prDSPP))
return hpi6205_error(0, HPI6205_ERROR_6205_DSPPAGE);
temp = 2;
iowrite32(temp, phw->prDSPP);
if ((temp | C6205_DSPP_MAP1) != ioread32(phw->prDSPP))
return hpi6205_error(0, HPI6205_ERROR_6205_DSPPAGE);
temp = 3;
iowrite32(temp, phw->prDSPP);
if ((temp | C6205_DSPP_MAP1) != ioread32(phw->prDSPP))
return hpi6205_error(0, HPI6205_ERROR_6205_DSPPAGE);
return HPI6205_ERROR_6205_DSPPAGE;
temp = 2;
iowrite32(temp, phw->prDSPP);
if ((temp | C6205_DSPP_MAP1) != ioread32(phw->prDSPP))
return HPI6205_ERROR_6205_DSPPAGE;
temp = 1;
iowrite32(temp, phw->prDSPP);
if ((temp | C6205_DSPP_MAP1) != ioread32(phw->prDSPP))
return HPI6205_ERROR_6205_DSPPAGE;
/* reset DSP page to the correct number */
temp = 0;
iowrite32(temp, phw->prDSPP);
if ((temp | C6205_DSPP_MAP1) != ioread32(phw->prDSPP))
return hpi6205_error(0, HPI6205_ERROR_6205_DSPPAGE);
return HPI6205_ERROR_6205_DSPPAGE;
phw->dsp_page = 0;
/* release 6713 from reset before 6205 is bootloaded.
@ -1455,7 +1414,7 @@ static u16 adapter_boot_load_dsp(struct hpi_adapter_obj *pao,
return err;
/* write the DSP code down into the DSPs memory */
dsp_code.ps_dev = pao->pci.p_os_data;
dsp_code.ps_dev = pao->pci.pci_dev;
err = hpi_dsp_code_open(boot_code_id[dsp], &dsp_code,
pos_error_code);
if (err)
@ -1484,10 +1443,8 @@ static u16 adapter_boot_load_dsp(struct hpi_adapter_obj *pao,
if (err)
break;
for (i = 0; i < (int)length; i++) {
err = boot_loader_write_mem32(pao, dsp,
address, *pcode);
if (err)
break;
boot_loader_write_mem32(pao, dsp, address,
*pcode);
/* dummy read every 4 words */
/* for 6205 advisory 1.4.4 */
if (i % 4 == 0)
@ -1561,7 +1518,7 @@ static u16 adapter_boot_load_dsp(struct hpi_adapter_obj *pao,
host_mailbox_address_on_dsp = 0x80000000;
while ((physicalPC_iaddress != physicalPC_iaddress_verify)
&& time_out--) {
err = boot_loader_write_mem32(pao, 0,
boot_loader_write_mem32(pao, 0,
host_mailbox_address_on_dsp,
physicalPC_iaddress);
physicalPC_iaddress_verify =
@ -1631,11 +1588,10 @@ static u32 boot_loader_read_mem32(struct hpi_adapter_obj *pao, int dsp_index,
return data;
}
static u16 boot_loader_write_mem32(struct hpi_adapter_obj *pao, int dsp_index,
u32 address, u32 data)
static void boot_loader_write_mem32(struct hpi_adapter_obj *pao,
int dsp_index, u32 address, u32 data)
{
struct hpi_hw_obj *phw = pao->priv;
u16 err = 0;
__iomem u32 *p_data;
/* u32 dwVerifyData=0; */
@ -1675,15 +1631,11 @@ static u16 boot_loader_write_mem32(struct hpi_adapter_obj *pao, int dsp_index,
/* dummy read every 4 words for 6205 advisory 1.4.4 */
boot_loader_read_mem32(pao, 0, 0);
} else
err = hpi6205_error(dsp_index, HPI6205_ERROR_BAD_DSPINDEX);
return err;
}
}
static u16 boot_loader_config_emif(struct hpi_adapter_obj *pao, int dsp_index)
{
u16 err = 0;
if (dsp_index == 0) {
u32 setting;
@ -1711,8 +1663,7 @@ static u16 boot_loader_config_emif(struct hpi_adapter_obj *pao, int dsp_index)
boot_loader_write_mem32(pao, dsp_index, 0x01800008, setting);
if (setting != boot_loader_read_mem32(pao, dsp_index,
0x01800008))
return hpi6205_error(dsp_index,
HPI6205_ERROR_DSP_EMIF);
return HPI6205_ERROR_DSP_EMIF;
/* EMIF CE1 setup - 32 bit async. This is 6713 #1 HPI, */
/* which occupies D15..0. 6713 starts at 27MHz, so need */
@ -1725,8 +1676,7 @@ static u16 boot_loader_config_emif(struct hpi_adapter_obj *pao, int dsp_index)
boot_loader_write_mem32(pao, dsp_index, 0x01800004, setting);
if (setting != boot_loader_read_mem32(pao, dsp_index,
0x01800004))
return hpi6205_error(dsp_index,
HPI6205_ERROR_DSP_EMIF);
return HPI6205_ERROR_DSP_EMIF;
/* EMIF CE2 setup - 32 bit async. This is 6713 #2 HPI, */
/* which occupies D15..0. 6713 starts at 27MHz, so need */
@ -1738,8 +1688,7 @@ static u16 boot_loader_config_emif(struct hpi_adapter_obj *pao, int dsp_index)
boot_loader_write_mem32(pao, dsp_index, 0x01800010, setting);
if (setting != boot_loader_read_mem32(pao, dsp_index,
0x01800010))
return hpi6205_error(dsp_index,
HPI6205_ERROR_DSP_EMIF);
return HPI6205_ERROR_DSP_EMIF;
/* EMIF CE3 setup - 32 bit async. */
/* This is the PLD on the ASI5000 cards only */
@ -1750,8 +1699,7 @@ static u16 boot_loader_config_emif(struct hpi_adapter_obj *pao, int dsp_index)
boot_loader_write_mem32(pao, dsp_index, 0x01800014, setting);
if (setting != boot_loader_read_mem32(pao, dsp_index,
0x01800014))
return hpi6205_error(dsp_index,
HPI6205_ERROR_DSP_EMIF);
return HPI6205_ERROR_DSP_EMIF;
/* set EMIF SDRAM control for 2Mx32 SDRAM (512x32x4 bank) */
/* need to use this else DSP code crashes? */
@ -1775,12 +1723,9 @@ static u16 boot_loader_config_emif(struct hpi_adapter_obj *pao, int dsp_index)
read_data =
0xFFF7 & boot_loader_read_mem32(pao, 0, HPICL_ADDR);
if (write_data != read_data) {
err = hpi6205_error(dsp_index,
HPI6205_ERROR_C6713_HPIC);
HPI_DEBUG_LOG(ERROR, "HPICL %x %x\n", write_data,
read_data);
return err;
return HPI6205_ERROR_C6713_HPIC;
}
/* HPIA - walking ones test */
write_data = 1;
@ -1798,11 +1743,9 @@ static u16 boot_loader_config_emif(struct hpi_adapter_obj *pao, int dsp_index)
HPIAH_ADDR))
<< 16);
if (read_data != write_data) {
err = hpi6205_error(dsp_index,
HPI6205_ERROR_C6713_HPIA);
HPI_DEBUG_LOG(ERROR, "HPIA %x %x\n",
write_data, read_data);
return err;
return HPI6205_ERROR_C6713_HPIA;
}
write_data = write_data << 1;
}
@ -1847,9 +1790,7 @@ static u16 boot_loader_config_emif(struct hpi_adapter_obj *pao, int dsp_index)
/* PLL should not be bypassed! */
if ((boot_loader_read_mem32(pao, dsp_index, 0x01B7C100) & 0xF)
!= 0x0001) {
err = hpi6205_error(dsp_index,
HPI6205_ERROR_C6713_PLL);
return err;
return HPI6205_ERROR_C6713_PLL;
}
/* setup C67x EMIF (note this is the only use of
BAR1 via BootLoader_WriteMem32) */
@ -1867,10 +1808,9 @@ static u16 boot_loader_config_emif(struct hpi_adapter_obj *pao, int dsp_index)
hpios_delay_micro_seconds(1000);
} else if (dsp_index == 2) {
/* DSP 2 is a C6713 */
}
} else
err = hpi6205_error(dsp_index, HPI6205_ERROR_BAD_DSPINDEX);
return err;
return 0;
}
static u16 boot_loader_test_memory(struct hpi_adapter_obj *pao, int dsp_index,
@ -1896,7 +1836,7 @@ static u16 boot_loader_test_memory(struct hpi_adapter_obj *pao, int dsp_index,
test_addr);
if (data != test_data) {
HPI_DEBUG_LOG(VERBOSE,
"memtest error details "
"Memtest error details "
"%08x %08x %08x %i\n", test_addr,
test_data, data, dsp_index);
return 1; /* error */
@ -1916,7 +1856,7 @@ static u16 boot_loader_test_memory(struct hpi_adapter_obj *pao, int dsp_index,
data = boot_loader_read_mem32(pao, dsp_index, test_addr);
if (data != test_data) {
HPI_DEBUG_LOG(VERBOSE,
"memtest error details "
"Memtest error details "
"%08x %08x %08x %i\n", test_addr, test_data,
data, dsp_index);
return 1; /* error */
@ -1946,8 +1886,8 @@ static u16 boot_loader_test_internal_memory(struct hpi_adapter_obj *pao,
/* 64K data mem */
err = boot_loader_test_memory(pao, dsp_index,
0x80000000, 0x10000);
} else if ((dsp_index == 1) || (dsp_index == 2)) {
/* DSP 1&2 are a C6713 */
} else if (dsp_index == 1) {
/* DSP 1 is a C6713 */
/* 192K internal mem */
err = boot_loader_test_memory(pao, dsp_index, 0x00000000,
0x30000);
@ -1955,11 +1895,10 @@ static u16 boot_loader_test_internal_memory(struct hpi_adapter_obj *pao,
/* 64K internal mem / L2 cache */
err = boot_loader_test_memory(pao, dsp_index,
0x00030000, 0x10000);
} else
return hpi6205_error(dsp_index, HPI6205_ERROR_BAD_DSPINDEX);
}
if (err)
return hpi6205_error(dsp_index, HPI6205_ERROR_DSP_INTMEM);
return HPI6205_ERROR_DSP_INTMEM;
else
return 0;
}
@ -1972,24 +1911,23 @@ static u16 boot_loader_test_external_memory(struct hpi_adapter_obj *pao,
if (dsp_index == 0) {
/* only test for SDRAM if an ASI5000 card */
if (pao->pci.subsys_device_id == 0x5000) {
if (pao->pci.pci_dev->subsystem_device == 0x5000) {
/* DSP 0 is always C6205 */
dRAM_start_address = 0x00400000;
dRAM_size = 0x200000;
/*dwDRAMinc=1024; */
} else
return 0;
} else if ((dsp_index == 1) || (dsp_index == 2)) {
} else if (dsp_index == 1) {
/* DSP 1 is a C6713 */
dRAM_start_address = 0x80000000;
dRAM_size = 0x200000;
/*dwDRAMinc=1024; */
} else
return hpi6205_error(dsp_index, HPI6205_ERROR_BAD_DSPINDEX);
}
if (boot_loader_test_memory(pao, dsp_index, dRAM_start_address,
dRAM_size))
return hpi6205_error(dsp_index, HPI6205_ERROR_DSP_EXTMEM);
return HPI6205_ERROR_DSP_EXTMEM;
return 0;
}
@ -1998,28 +1936,25 @@ static u16 boot_loader_test_pld(struct hpi_adapter_obj *pao, int dsp_index)
u32 data = 0;
if (dsp_index == 0) {
/* only test for DSP0 PLD on ASI5000 card */
if (pao->pci.subsys_device_id == 0x5000) {
if (pao->pci.pci_dev->subsystem_device == 0x5000) {
/* PLD is located at CE3=0x03000000 */
data = boot_loader_read_mem32(pao, dsp_index,
0x03000008);
if ((data & 0xF) != 0x5)
return hpi6205_error(dsp_index,
HPI6205_ERROR_DSP_PLD);
return HPI6205_ERROR_DSP_PLD;
data = boot_loader_read_mem32(pao, dsp_index,
0x0300000C);
if ((data & 0xF) != 0xA)
return hpi6205_error(dsp_index,
HPI6205_ERROR_DSP_PLD);
return HPI6205_ERROR_DSP_PLD;
}
} else if (dsp_index == 1) {
/* DSP 1 is a C6713 */
if (pao->pci.subsys_device_id == 0x8700) {
if (pao->pci.pci_dev->subsystem_device == 0x8700) {
/* PLD is located at CE1=0x90000000 */
data = boot_loader_read_mem32(pao, dsp_index,
0x90000010);
if ((data & 0xFF) != 0xAA)
return hpi6205_error(dsp_index,
HPI6205_ERROR_DSP_PLD);
return HPI6205_ERROR_DSP_PLD;
/* 8713 - LED on */
boot_loader_write_mem32(pao, dsp_index, 0x90000000,
0x02);
@ -2079,7 +2014,7 @@ static short hpi6205_transfer_data(struct hpi_adapter_obj *pao, u8 *p_data,
if (!temp2) {
/* timed out */
HPI_DEBUG_LOG(ERROR,
"timed out waiting for " "state %d got %d\n",
"Timed out waiting for " "state %d got %d\n",
operation, interface->dsp_ack);
break;
@ -2099,7 +2034,7 @@ static short hpi6205_transfer_data(struct hpi_adapter_obj *pao, u8 *p_data,
HPI6205_TIMEOUT - time_out, this_copy);
if (temp2 == C6205_HSR_INTSRC) {
HPI_DEBUG_LOG(VERBOSE,
"interrupt from HIF <data> OK\n");
"Interrupt from HIF <data> OK\n");
/*
if(interface->dwDspAck != nOperation) {
HPI_DEBUG_LOG(DEBUG("interface->dwDspAck=%d,
@ -2111,7 +2046,7 @@ static short hpi6205_transfer_data(struct hpi_adapter_obj *pao, u8 *p_data,
/* need to handle this differently... */
else {
HPI_DEBUG_LOG(ERROR,
"interrupt from HIF <data> BAD\n");
"Interrupt from HIF <data> BAD\n");
err = HPI_ERROR_DSP_HARDWARE;
}
@ -2183,22 +2118,34 @@ static u16 message_response_sequence(struct hpi_adapter_obj *pao,
u16 err = 0;
message_count++;
if (phm->size > sizeof(interface->u)) {
/* really MESSAGE buffer too small */
phr->error = HPI_ERROR_RESPONSE_BUFFER_TOO_SMALL;
phr->specific_error = sizeof(interface->u);
phr->size = sizeof(struct hpi_response_header);
HPI_DEBUG_LOG(ERROR,
"message len %d too big for buffer %ld \n", phm->size,
sizeof(interface->u));
return 0;
}
/* Assume buffer of type struct bus_master_interface
is allocated "noncacheable" */
if (!wait_dsp_ack(phw, H620_HIF_IDLE, HPI6205_TIMEOUT)) {
HPI_DEBUG_LOG(DEBUG, "timeout waiting for idle\n");
return hpi6205_error(0, HPI6205_ERROR_MSG_RESP_IDLE_TIMEOUT);
return HPI6205_ERROR_MSG_RESP_IDLE_TIMEOUT;
}
interface->u.message_buffer = *phm;
memcpy(&interface->u.message_buffer, phm, phm->size);
/* signal we want a response */
send_dsp_command(phw, H620_HIF_GET_RESP);
time_out2 = wait_dsp_ack(phw, H620_HIF_GET_RESP, HPI6205_TIMEOUT);
if (time_out2 == 0) {
if (!time_out2) {
HPI_DEBUG_LOG(ERROR,
"(%u) timed out waiting for " "GET_RESP state [%x]\n",
"(%u) Timed out waiting for " "GET_RESP state [%x]\n",
message_count, interface->dsp_ack);
} else {
HPI_DEBUG_LOG(VERBOSE,
@ -2232,7 +2179,7 @@ static u16 message_response_sequence(struct hpi_adapter_obj *pao,
} else {
/* can we do anything else in response to the error ? */
HPI_DEBUG_LOG(ERROR,
"interrupt from HIF module BAD (function %x)\n",
"Interrupt from HIF module BAD (function %x)\n",
phm->function);
}
@ -2241,25 +2188,37 @@ static u16 message_response_sequence(struct hpi_adapter_obj *pao,
#endif
/* read the result */
if (time_out != 0)
*phr = interface->u.response_buffer;
if (time_out) {
if (interface->u.response_buffer.size <= phr->size)
memcpy(phr, &interface->u.response_buffer,
interface->u.response_buffer.size);
else {
HPI_DEBUG_LOG(ERROR,
"response len %d too big for buffer %d\n",
interface->u.response_buffer.size, phr->size);
memcpy(phr, &interface->u.response_buffer,
sizeof(struct hpi_response_header));
phr->error = HPI_ERROR_RESPONSE_BUFFER_TOO_SMALL;
phr->specific_error =
interface->u.response_buffer.size;
phr->size = sizeof(struct hpi_response_header);
}
}
/* set interface back to idle */
send_dsp_command(phw, H620_HIF_IDLE);
if ((time_out == 0) || (time_out2 == 0)) {
if (!time_out || !time_out2) {
HPI_DEBUG_LOG(DEBUG, "something timed out!\n");
return hpi6205_error(0, HPI6205_ERROR_MSG_RESP_TIMEOUT);
return HPI6205_ERROR_MSG_RESP_TIMEOUT;
}
/* special case for adapter close - */
/* wait for the DSP to indicate it is idle */
if (phm->function == HPI_ADAPTER_CLOSE) {
if (!wait_dsp_ack(phw, H620_HIF_IDLE, HPI6205_TIMEOUT)) {
HPI_DEBUG_LOG(DEBUG,
"timeout waiting for idle "
"Timeout waiting for idle "
"(on adapter_close)\n");
return hpi6205_error(0,
HPI6205_ERROR_MSG_RESP_IDLE_TIMEOUT);
return HPI6205_ERROR_MSG_RESP_IDLE_TIMEOUT;
}
}
err = hpi_validate_response(phm, phr);

View File

@ -78,8 +78,8 @@ struct bus_master_interface {
u32 dsp_ack;
u32 transfer_size_in_bytes;
union {
struct hpi_message message_buffer;
struct hpi_response response_buffer;
struct hpi_message_header message_buffer;
struct hpi_response_header response_buffer;
u8 b_data[HPI6205_SIZEOF_DATA];
} u;
struct controlcache_6205 control_cache;

File diff suppressed because it is too large Load Diff

View File

@ -26,6 +26,8 @@
#include "hpi_internal.h"
#include "hpidebug.h"
#include "hpimsginit.h"
#include "hpicmn.h"
struct hpi_adapters_list {
@ -43,14 +45,22 @@ static struct hpi_adapters_list adapters;
**/
u16 hpi_validate_response(struct hpi_message *phm, struct hpi_response *phr)
{
u16 error = 0;
if (phr->type != HPI_TYPE_RESPONSE) {
HPI_DEBUG_LOG(ERROR, "header type %d invalid", phr->type);
return HPI_ERROR_INVALID_RESPONSE;
}
if ((phr->type != HPI_TYPE_RESPONSE)
|| (phr->object != phm->object)
|| (phr->function != phm->function))
error = HPI_ERROR_INVALID_RESPONSE;
if (phr->object != phm->object) {
HPI_DEBUG_LOG(ERROR, "header object %d invalid", phr->object);
return HPI_ERROR_INVALID_RESPONSE;
}
return error;
if (phr->function != phm->function) {
HPI_DEBUG_LOG(ERROR, "header type %d invalid", phr->function);
return HPI_ERROR_INVALID_RESPONSE;
}
return 0;
}
u16 hpi_add_adapter(struct hpi_adapter_obj *pao)
@ -76,17 +86,22 @@ u16 hpi_add_adapter(struct hpi_adapter_obj *pao)
adapters.gw_num_adapters++;
unlock:
hpios_alistlock_un_lock(&adapters);
hpios_alistlock_unlock(&adapters);
return retval;
}
void hpi_delete_adapter(struct hpi_adapter_obj *pao)
{
memset(pao, 0, sizeof(struct hpi_adapter_obj));
if (!pao->adapter_type) {
HPI_DEBUG_LOG(ERROR, "removing null adapter?\n");
return;
}
hpios_alistlock_lock(&adapters);
adapters.gw_num_adapters--; /* dec the number of adapters */
hpios_alistlock_un_lock(&adapters);
if (adapters.adapter[pao->index].adapter_type)
adapters.gw_num_adapters--;
memset(&adapters.adapter[pao->index], 0, sizeof(adapters.adapter[0]));
hpios_alistlock_unlock(&adapters);
}
/**
@ -125,51 +140,35 @@ struct hpi_adapter_obj *hpi_find_adapter(u16 adapter_index)
* wipe an HPI_ADAPTERS_LIST structure.
*
**/
static void wipe_adapter_list(void
)
static void wipe_adapter_list(void)
{
memset(&adapters, 0, sizeof(adapters));
}
/**
* SubSysGetAdapters fills awAdapterList in an struct hpi_response structure
* with all adapters in the given HPI_ADAPTERS_LIST.
*
*/
static void subsys_get_adapters(struct hpi_response *phr)
static void subsys_get_adapter(struct hpi_message *phm,
struct hpi_response *phr)
{
/* fill in the response adapter array with the position */
/* identified by the adapter number/index of the adapters in */
/* this HPI */
/* i.e. if we have an A120 with it's jumper set to */
/* Adapter Number 2 then put an Adapter type A120 in the */
/* array in position 1 */
/* NOTE: AdapterNumber is 1..N, Index is 0..N-1 */
int count = phm->obj_index;
u16 index = 0;
/* input: NONE */
/* output: wNumAdapters */
/* awAdapter[] */
/* */
short i;
struct hpi_adapter_obj *pao = NULL;
HPI_DEBUG_LOG(VERBOSE, "subsys_get_adapters\n");
/* for each adapter, place it's type in the position of the array */
/* corresponding to it's adapter number */
for (i = 0; i < adapters.gw_num_adapters; i++) {
pao = &adapters.adapter[i];
if (phr->u.s.aw_adapter_list[pao->index] != 0) {
phr->error = HPI_DUPLICATE_ADAPTER_NUMBER;
phr->specific_error = pao->index;
return;
/* find the nCount'th nonzero adapter in array */
for (index = 0; index < HPI_MAX_ADAPTERS; index++) {
if (adapters.adapter[index].adapter_type) {
if (count == 0)
break;
count--;
}
phr->u.s.aw_adapter_list[pao->index] = pao->adapter_type;
}
phr->u.s.num_adapters = adapters.gw_num_adapters;
phr->error = 0; /* the function completed OK; */
if (index < HPI_MAX_ADAPTERS) {
phr->u.s.adapter_index = adapters.adapter[index].index;
phr->u.s.aw_adapter_list[0] =
adapters.adapter[index].adapter_type;
} else {
phr->u.s.adapter_index = 0;
phr->u.s.aw_adapter_list[0] = 0;
phr->error = HPI_ERROR_BAD_ADAPTER_NUMBER;
}
}
static unsigned int control_cache_alloc_check(struct hpi_control_cache *pC)
@ -178,67 +177,88 @@ static unsigned int control_cache_alloc_check(struct hpi_control_cache *pC)
int cached = 0;
if (!pC)
return 0;
if ((!pC->init) && (pC->p_cache != NULL) && (pC->control_count)
&& (pC->cache_size_in_bytes)
) {
u32 *p_master_cache;
pC->init = 1;
p_master_cache = (u32 *)pC->p_cache;
HPI_DEBUG_LOG(VERBOSE, "check %d controls\n",
if (pC->init)
return pC->init;
if (!pC->p_cache)
return 0;
if (pC->control_count && pC->cache_size_in_bytes) {
char *p_master_cache;
unsigned int byte_count = 0;
p_master_cache = (char *)pC->p_cache;
HPI_DEBUG_LOG(DEBUG, "check %d controls\n",
pC->control_count);
for (i = 0; i < pC->control_count; i++) {
struct hpi_control_cache_info *info =
(struct hpi_control_cache_info *)
p_master_cache;
&p_master_cache[byte_count];
if (!info->size_in32bit_words) {
/* ? This is a severe error, the cache is probably
corrupted. Minimum valid entry size is
sizeof(struct hpi_control_cache_info) */
HPI_DEBUG_LOG(ERROR,
"zero size cache entry %d\n", i);
break;
}
if (info->control_type) {
pC->p_info[i] = info;
pC->p_info[info->control_index] = info;
cached++;
} else
pC->p_info[i] = NULL;
} else /* dummy cache entry */
pC->p_info[info->control_index] = NULL;
if (info->size_in32bit_words)
p_master_cache += info->size_in32bit_words;
else
p_master_cache +=
sizeof(struct
hpi_control_cache_single) /
sizeof(u32);
byte_count += info->size_in32bit_words * 4;
HPI_DEBUG_LOG(VERBOSE,
"cached %d, pinfo %p index %d type %d\n",
cached, pC->p_info[i], info->control_index,
info->control_type);
"cached %d, pinfo %p index %d type %d size %d\n",
cached, pC->p_info[info->control_index],
info->control_index, info->control_type,
info->size_in32bit_words);
/* quit loop early if whole cache has been scanned. */
/* pC->dwControlCount is the maximum possible entries, */
/* but some may not be in the cache at all */
if (byte_count >= pC->cache_size_in_bytes)
break;
/* have seen last control index */
if (info->control_index == pC->control_count - 1)
break;
}
/*
We didn't find anything to cache, so try again later !
*/
if (!cached)
pC->init = 0;
if (byte_count != pC->cache_size_in_bytes)
HPI_DEBUG_LOG(WARNING,
"bytecount %d != cache size %d", byte_count,
pC->cache_size_in_bytes);
else
HPI_DEBUG_LOG(DEBUG,
"cache good. bytecount == cache size = %d",
byte_count);
pC->init = cached;
}
return pC->init;
}
/** Find a control.
*/
static short find_control(struct hpi_message *phm,
struct hpi_control_cache *p_cache, struct hpi_control_cache_info **pI,
u16 *pw_control_index)
static short find_control(u16 control_index,
struct hpi_control_cache *p_cache, struct hpi_control_cache_info **pI)
{
*pw_control_index = phm->obj_index;
if (!control_cache_alloc_check(p_cache)) {
HPI_DEBUG_LOG(VERBOSE,
"control_cache_alloc_check() failed. adap%d ci%d\n",
phm->adapter_index, *pw_control_index);
"control_cache_alloc_check() failed %d\n",
control_index);
return 0;
}
*pI = p_cache->p_info[*pw_control_index];
*pI = p_cache->p_info[control_index];
if (!*pI) {
HPI_DEBUG_LOG(VERBOSE, "uncached adap %d, control %d\n",
phm->adapter_index, *pw_control_index);
HPI_DEBUG_LOG(VERBOSE, "Uncached Control %d\n",
control_index);
return 0;
} else {
HPI_DEBUG_LOG(VERBOSE, "find_control() type %d\n",
@ -257,11 +277,14 @@ short hpi_check_buffer_mapping(struct hpi_control_cache *p_cache,
if ((phm->function == HPI_CONTROL_GET_STATE)
&& (phm->object == HPI_OBJ_CONTROLEX)
) {
u16 control_index;
struct hpi_control_cache_info *pI;
if (!find_control(phm, p_cache, &pI, &control_index))
if (!find_control(phm->obj_index, p_cache, &pI)) {
HPI_DEBUG_LOG(VERBOSE,
"HPICMN find_control() failed for adap %d\n",
phm->adapter_index);
return 0;
}
}
return 0;
}
@ -290,13 +313,16 @@ short hpi_check_control_cache(struct hpi_control_cache *p_cache,
struct hpi_message *phm, struct hpi_response *phr)
{
short found = 1;
u16 control_index;
struct hpi_control_cache_info *pI;
struct hpi_control_cache_single *pC;
struct hpi_control_cache_pad *p_pad;
if (!find_control(phm, p_cache, &pI, &control_index))
if (!find_control(phm->obj_index, p_cache, &pI)) {
HPI_DEBUG_LOG(VERBOSE,
"HPICMN find_control() failed for adap %d\n",
phm->adapter_index);
return 0;
}
phr->error = 0;
@ -310,55 +336,66 @@ short hpi_check_control_cache(struct hpi_control_cache *p_cache,
case HPI_CONTROL_METER:
if (phm->u.c.attribute == HPI_METER_PEAK) {
phr->u.c.an_log_value[0] = pC->u.p.an_log_peak[0];
phr->u.c.an_log_value[1] = pC->u.p.an_log_peak[1];
phr->u.c.an_log_value[0] = pC->u.meter.an_log_peak[0];
phr->u.c.an_log_value[1] = pC->u.meter.an_log_peak[1];
} else if (phm->u.c.attribute == HPI_METER_RMS) {
phr->u.c.an_log_value[0] = pC->u.p.an_logRMS[0];
phr->u.c.an_log_value[1] = pC->u.p.an_logRMS[1];
if (pC->u.meter.an_logRMS[0] ==
HPI_CACHE_INVALID_SHORT) {
phr->error =
HPI_ERROR_INVALID_CONTROL_ATTRIBUTE;
phr->u.c.an_log_value[0] = HPI_METER_MINIMUM;
phr->u.c.an_log_value[1] = HPI_METER_MINIMUM;
} else {
phr->u.c.an_log_value[0] =
pC->u.meter.an_logRMS[0];
phr->u.c.an_log_value[1] =
pC->u.meter.an_logRMS[1];
}
} else
found = 0;
break;
case HPI_CONTROL_VOLUME:
if (phm->u.c.attribute == HPI_VOLUME_GAIN) {
phr->u.c.an_log_value[0] = pC->u.v.an_log[0];
phr->u.c.an_log_value[1] = pC->u.v.an_log[1];
phr->u.c.an_log_value[0] = pC->u.vol.an_log[0];
phr->u.c.an_log_value[1] = pC->u.vol.an_log[1];
} else
found = 0;
break;
case HPI_CONTROL_MULTIPLEXER:
if (phm->u.c.attribute == HPI_MULTIPLEXER_SOURCE) {
phr->u.c.param1 = pC->u.x.source_node_type;
phr->u.c.param2 = pC->u.x.source_node_index;
phr->u.c.param1 = pC->u.mux.source_node_type;
phr->u.c.param2 = pC->u.mux.source_node_index;
} else {
found = 0;
}
break;
case HPI_CONTROL_CHANNEL_MODE:
if (phm->u.c.attribute == HPI_CHANNEL_MODE_MODE)
phr->u.c.param1 = pC->u.m.mode;
phr->u.c.param1 = pC->u.mode.mode;
else
found = 0;
break;
case HPI_CONTROL_LEVEL:
if (phm->u.c.attribute == HPI_LEVEL_GAIN) {
phr->u.c.an_log_value[0] = pC->u.l.an_log[0];
phr->u.c.an_log_value[1] = pC->u.l.an_log[1];
phr->u.c.an_log_value[0] = pC->u.level.an_log[0];
phr->u.c.an_log_value[1] = pC->u.level.an_log[1];
} else
found = 0;
break;
case HPI_CONTROL_TUNER:
if (phm->u.c.attribute == HPI_TUNER_FREQ)
phr->u.c.param1 = pC->u.t.freq_ink_hz;
phr->u.c.param1 = pC->u.tuner.freq_ink_hz;
else if (phm->u.c.attribute == HPI_TUNER_BAND)
phr->u.c.param1 = pC->u.t.band;
else if ((phm->u.c.attribute == HPI_TUNER_LEVEL)
&& (phm->u.c.param1 == HPI_TUNER_LEVEL_AVERAGE))
if (pC->u.t.level == HPI_ERROR_ILLEGAL_CACHE_VALUE) {
phr->u.c.param1 = 0;
phr->u.c.param1 = pC->u.tuner.band;
else if (phm->u.c.attribute == HPI_TUNER_LEVEL_AVG)
if (pC->u.tuner.s_level_avg ==
HPI_CACHE_INVALID_SHORT) {
phr->u.cu.tuner.s_level = 0;
phr->error =
HPI_ERROR_INVALID_CONTROL_ATTRIBUTE;
} else
phr->u.c.param1 = pC->u.t.level;
phr->u.cu.tuner.s_level =
pC->u.tuner.s_level_avg;
else
found = 0;
break;
@ -366,7 +403,7 @@ short hpi_check_control_cache(struct hpi_control_cache *p_cache,
if (phm->u.c.attribute == HPI_AESEBURX_ERRORSTATUS)
phr->u.c.param1 = pC->u.aes3rx.error_status;
else if (phm->u.c.attribute == HPI_AESEBURX_FORMAT)
phr->u.c.param1 = pC->u.aes3rx.source;
phr->u.c.param1 = pC->u.aes3rx.format;
else
found = 0;
break;
@ -385,13 +422,13 @@ short hpi_check_control_cache(struct hpi_control_cache *p_cache,
case HPI_CONTROL_SILENCEDETECTOR:
if (phm->u.c.attribute == HPI_SILENCEDETECTOR_STATE) {
phr->u.c.param1 = pC->u.silence.state;
phr->u.c.param2 = pC->u.silence.count;
/*? phr->u.c.dwParam2 = pC->u.silence.dwCount; */
} else
found = 0;
break;
case HPI_CONTROL_MICROPHONE:
if (phm->u.c.attribute == HPI_MICROPHONE_PHANTOM_POWER)
phr->u.c.param1 = pC->u.phantom_power.state;
phr->u.c.param1 = pC->u.microphone.phantom_state;
else
found = 0;
break;
@ -400,7 +437,7 @@ short hpi_check_control_cache(struct hpi_control_cache *p_cache,
phr->u.c.param1 = pC->u.clk.source;
else if (phm->u.c.attribute == HPI_SAMPLECLOCK_SOURCE_INDEX) {
if (pC->u.clk.source_index ==
HPI_ERROR_ILLEGAL_CACHE_VALUE) {
HPI_CACHE_INVALID_UINT16) {
phr->u.c.param1 = 0;
phr->error =
HPI_ERROR_INVALID_CONTROL_ATTRIBUTE;
@ -411,60 +448,63 @@ short hpi_check_control_cache(struct hpi_control_cache *p_cache,
else
found = 0;
break;
case HPI_CONTROL_PAD:
case HPI_CONTROL_PAD:{
struct hpi_control_cache_pad *p_pad;
p_pad = (struct hpi_control_cache_pad *)pI;
if (!(p_pad->field_valid_flags & (1 <<
HPI_CTL_ATTR_INDEX(phm->u.c.
attribute)))) {
phr->error = HPI_ERROR_INVALID_CONTROL_ATTRIBUTE;
break;
}
if (phm->u.c.attribute == HPI_PAD_PROGRAM_ID)
phr->u.c.param1 = p_pad->pI;
else if (phm->u.c.attribute == HPI_PAD_PROGRAM_TYPE)
phr->u.c.param1 = p_pad->pTY;
else {
unsigned int index =
HPI_CTL_ATTR_INDEX(phm->u.c.attribute) - 1;
unsigned int offset = phm->u.c.param1;
unsigned int pad_string_len, field_size;
char *pad_string;
unsigned int tocopy;
HPI_DEBUG_LOG(VERBOSE, "PADS HPI_PADS_ %d\n",
phm->u.c.attribute);
if (index > ARRAY_SIZE(pad_desc) - 1) {
if (!(p_pad->field_valid_flags & (1 <<
HPI_CTL_ATTR_INDEX(phm->u.c.
attribute)))) {
phr->error =
HPI_ERROR_INVALID_CONTROL_ATTRIBUTE;
break;
}
pad_string = ((char *)p_pad) + pad_desc[index].offset;
field_size = pad_desc[index].field_size;
/* Ensure null terminator */
pad_string[field_size - 1] = 0;
if (phm->u.c.attribute == HPI_PAD_PROGRAM_ID)
phr->u.c.param1 = p_pad->pI;
else if (phm->u.c.attribute == HPI_PAD_PROGRAM_TYPE)
phr->u.c.param1 = p_pad->pTY;
else {
unsigned int index =
HPI_CTL_ATTR_INDEX(phm->u.c.
attribute) - 1;
unsigned int offset = phm->u.c.param1;
unsigned int pad_string_len, field_size;
char *pad_string;
unsigned int tocopy;
pad_string_len = strlen(pad_string) + 1;
if (index > ARRAY_SIZE(pad_desc) - 1) {
phr->error =
HPI_ERROR_INVALID_CONTROL_ATTRIBUTE;
break;
}
if (offset > pad_string_len) {
phr->error = HPI_ERROR_INVALID_CONTROL_VALUE;
break;
pad_string =
((char *)p_pad) +
pad_desc[index].offset;
field_size = pad_desc[index].field_size;
/* Ensure null terminator */
pad_string[field_size - 1] = 0;
pad_string_len = strlen(pad_string) + 1;
if (offset > pad_string_len) {
phr->error =
HPI_ERROR_INVALID_CONTROL_VALUE;
break;
}
tocopy = pad_string_len - offset;
if (tocopy > sizeof(phr->u.cu.chars8.sz_data))
tocopy = sizeof(phr->u.cu.chars8.
sz_data);
memcpy(phr->u.cu.chars8.sz_data,
&pad_string[offset], tocopy);
phr->u.cu.chars8.remaining_chars =
pad_string_len - offset - tocopy;
}
tocopy = pad_string_len - offset;
if (tocopy > sizeof(phr->u.cu.chars8.sz_data))
tocopy = sizeof(phr->u.cu.chars8.sz_data);
HPI_DEBUG_LOG(VERBOSE,
"PADS memcpy(%d), offset %d \n", tocopy,
offset);
memcpy(phr->u.cu.chars8.sz_data, &pad_string[offset],
tocopy);
phr->u.cu.chars8.remaining_chars =
pad_string_len - offset - tocopy;
}
break;
default:
@ -472,16 +512,9 @@ short hpi_check_control_cache(struct hpi_control_cache *p_cache,
break;
}
if (found)
HPI_DEBUG_LOG(VERBOSE,
"cached adap %d, ctl %d, type %d, attr %d\n",
phm->adapter_index, pI->control_index,
pI->control_type, phm->u.c.attribute);
else
HPI_DEBUG_LOG(VERBOSE,
"uncached adap %d, ctl %d, ctl type %d\n",
phm->adapter_index, pI->control_index,
pI->control_type);
HPI_DEBUG_LOG(VERBOSE, "%s Adap %d, Ctl %d, Type %d, Attr %d\n",
found ? "Cached" : "Uncached", phm->adapter_index,
pI->control_index, pI->control_type, phm->u.c.attribute);
if (found)
phr->size =
@ -497,18 +530,21 @@ Only update if no error.
Volume and Level return the limited values in the response, so use these
Multiplexer does so use sent values
*/
void hpi_sync_control_cache(struct hpi_control_cache *p_cache,
void hpi_cmn_control_cache_sync_to_msg(struct hpi_control_cache *p_cache,
struct hpi_message *phm, struct hpi_response *phr)
{
u16 control_index;
struct hpi_control_cache_single *pC;
struct hpi_control_cache_info *pI;
if (phr->error)
return;
if (!find_control(phm, p_cache, &pI, &control_index))
if (!find_control(phm->obj_index, p_cache, &pI)) {
HPI_DEBUG_LOG(VERBOSE,
"HPICMN find_control() failed for adap %d\n",
phm->adapter_index);
return;
}
/* pC is the default cached control strucure.
May be cast to something else in the following switch statement.
@ -518,31 +554,31 @@ void hpi_sync_control_cache(struct hpi_control_cache *p_cache,
switch (pI->control_type) {
case HPI_CONTROL_VOLUME:
if (phm->u.c.attribute == HPI_VOLUME_GAIN) {
pC->u.v.an_log[0] = phr->u.c.an_log_value[0];
pC->u.v.an_log[1] = phr->u.c.an_log_value[1];
pC->u.vol.an_log[0] = phr->u.c.an_log_value[0];
pC->u.vol.an_log[1] = phr->u.c.an_log_value[1];
}
break;
case HPI_CONTROL_MULTIPLEXER:
/* mux does not return its setting on Set command. */
if (phm->u.c.attribute == HPI_MULTIPLEXER_SOURCE) {
pC->u.x.source_node_type = (u16)phm->u.c.param1;
pC->u.x.source_node_index = (u16)phm->u.c.param2;
pC->u.mux.source_node_type = (u16)phm->u.c.param1;
pC->u.mux.source_node_index = (u16)phm->u.c.param2;
}
break;
case HPI_CONTROL_CHANNEL_MODE:
/* mode does not return its setting on Set command. */
if (phm->u.c.attribute == HPI_CHANNEL_MODE_MODE)
pC->u.m.mode = (u16)phm->u.c.param1;
pC->u.mode.mode = (u16)phm->u.c.param1;
break;
case HPI_CONTROL_LEVEL:
if (phm->u.c.attribute == HPI_LEVEL_GAIN) {
pC->u.v.an_log[0] = phr->u.c.an_log_value[0];
pC->u.v.an_log[1] = phr->u.c.an_log_value[1];
pC->u.vol.an_log[0] = phr->u.c.an_log_value[0];
pC->u.vol.an_log[1] = phr->u.c.an_log_value[1];
}
break;
case HPI_CONTROL_MICROPHONE:
if (phm->u.c.attribute == HPI_MICROPHONE_PHANTOM_POWER)
pC->u.phantom_power.state = (u16)phm->u.c.param1;
pC->u.microphone.phantom_state = (u16)phm->u.c.param1;
break;
case HPI_CONTROL_AESEBU_TRANSMITTER:
if (phm->u.c.attribute == HPI_AESEBUTX_FORMAT)
@ -550,7 +586,7 @@ void hpi_sync_control_cache(struct hpi_control_cache *p_cache,
break;
case HPI_CONTROL_AESEBU_RECEIVER:
if (phm->u.c.attribute == HPI_AESEBURX_FORMAT)
pC->u.aes3rx.source = phm->u.c.param1;
pC->u.aes3rx.format = phm->u.c.param1;
break;
case HPI_CONTROL_SAMPLECLOCK:
if (phm->u.c.attribute == HPI_SAMPLECLOCK_SOURCE)
@ -566,8 +602,7 @@ void hpi_sync_control_cache(struct hpi_control_cache *p_cache,
}
struct hpi_control_cache *hpi_alloc_control_cache(const u32
number_of_controls, const u32 size_in_bytes,
struct hpi_control_cache_info *pDSP_control_buffer)
number_of_controls, const u32 size_in_bytes, u8 *pDSP_control_buffer)
{
struct hpi_control_cache *p_cache =
kmalloc(sizeof(*p_cache), GFP_KERNEL);
@ -590,7 +625,7 @@ struct hpi_control_cache *hpi_alloc_control_cache(const u32
void hpi_free_control_cache(struct hpi_control_cache *p_cache)
{
if (p_cache->init) {
if (p_cache) {
kfree(p_cache->p_info);
p_cache->p_info = NULL;
p_cache->init = 0;
@ -600,24 +635,25 @@ void hpi_free_control_cache(struct hpi_control_cache *p_cache)
static void subsys_message(struct hpi_message *phm, struct hpi_response *phr)
{
hpi_init_response(phr, HPI_OBJ_SUBSYSTEM, phm->function, 0);
switch (phm->function) {
case HPI_SUBSYS_OPEN:
case HPI_SUBSYS_CLOSE:
case HPI_SUBSYS_DRIVER_UNLOAD:
phr->error = 0;
break;
case HPI_SUBSYS_DRIVER_LOAD:
wipe_adapter_list();
hpios_alistlock_init(&adapters);
phr->error = 0;
break;
case HPI_SUBSYS_GET_INFO:
subsys_get_adapters(phr);
case HPI_SUBSYS_GET_ADAPTER:
subsys_get_adapter(phm, phr);
break;
case HPI_SUBSYS_GET_NUM_ADAPTERS:
phr->u.s.num_adapters = adapters.gw_num_adapters;
break;
case HPI_SUBSYS_CREATE_ADAPTER:
case HPI_SUBSYS_DELETE_ADAPTER:
phr->error = 0;
break;
default:
phr->error = HPI_ERROR_INVALID_FUNC;

View File

@ -40,8 +40,7 @@ struct hpi_control_cache {
struct hpi_control_cache_info
**p_info; /**< pointer to allocated memory of
lookup pointers. */
struct hpi_control_cache_single
*p_cache; /**< pointer to DSP's control cache. */
u8 *p_cache; /**< pointer to DSP's control cache. */
};
struct hpi_adapter_obj *hpi_find_adapter(u16 adapter_index);
@ -52,12 +51,10 @@ void hpi_delete_adapter(struct hpi_adapter_obj *pao);
short hpi_check_control_cache(struct hpi_control_cache *pC,
struct hpi_message *phm, struct hpi_response *phr);
struct hpi_control_cache *hpi_alloc_control_cache(const u32
number_of_controls, const u32 size_in_bytes,
struct hpi_control_cache_info
*pDSP_control_buffer);
number_of_controls, const u32 size_in_bytes, u8 *pDSP_control_buffer);
void hpi_free_control_cache(struct hpi_control_cache *p_cache);
void hpi_sync_control_cache(struct hpi_control_cache *pC,
void hpi_cmn_control_cache_sync_to_msg(struct hpi_control_cache *pC,
struct hpi_message *phm, struct hpi_response *phr);
u16 hpi_validate_response(struct hpi_message *phm, struct hpi_response *phr);
short hpi_check_buffer_mapping(struct hpi_control_cache *p_cache,

File diff suppressed because it is too large Load Diff

View File

@ -50,7 +50,7 @@ static void hpi_init_message(struct hpi_message *phm, u16 object,
phm->object = object;
phm->function = function;
phm->version = 0;
phm->adapter_index = 0xFFFF;
phm->adapter_index = HPI_ADAPTER_INDEX_INVALID;
/* Expect actual adapter index to be set by caller */
}

View File

@ -23,6 +23,7 @@ Extended Message Function With Response Cacheing
#define SOURCEFILE_NAME "hpimsgx.c"
#include "hpi_internal.h"
#include "hpimsginit.h"
#include "hpicmn.h"
#include "hpimsgx.h"
#include "hpidebug.h"
@ -42,22 +43,24 @@ static hpi_handler_func *hpi_lookup_entry_point_function(const struct hpi_pci
for (i = 0; asihpi_pci_tbl[i].vendor != 0; i++) {
if (asihpi_pci_tbl[i].vendor != PCI_ANY_ID
&& asihpi_pci_tbl[i].vendor != pci_info->vendor_id)
&& asihpi_pci_tbl[i].vendor !=
pci_info->pci_dev->vendor)
continue;
if (asihpi_pci_tbl[i].device != PCI_ANY_ID
&& asihpi_pci_tbl[i].device != pci_info->device_id)
&& asihpi_pci_tbl[i].device !=
pci_info->pci_dev->device)
continue;
if (asihpi_pci_tbl[i].subvendor != PCI_ANY_ID
&& asihpi_pci_tbl[i].subvendor !=
pci_info->subsys_vendor_id)
pci_info->pci_dev->subsystem_vendor)
continue;
if (asihpi_pci_tbl[i].subdevice != PCI_ANY_ID
&& asihpi_pci_tbl[i].subdevice !=
pci_info->subsys_device_id)
pci_info->pci_dev->subsystem_device)
continue;
HPI_DEBUG_LOG(DEBUG, " %x,%lu\n", i,
asihpi_pci_tbl[i].driver_data);
/* HPI_DEBUG_LOG(DEBUG, " %x,%lx\n", i,
asihpi_pci_tbl[i].driver_data); */
return (hpi_handler_func *) asihpi_pci_tbl[i].driver_data;
}
@ -67,21 +70,12 @@ static hpi_handler_func *hpi_lookup_entry_point_function(const struct hpi_pci
static inline void hw_entry_point(struct hpi_message *phm,
struct hpi_response *phr)
{
hpi_handler_func *ep;
if (phm->adapter_index < HPI_MAX_ADAPTERS) {
ep = (hpi_handler_func *) hpi_entry_points[phm->
adapter_index];
if (ep) {
HPI_DEBUG_MESSAGE(DEBUG, phm);
ep(phm, phr);
HPI_DEBUG_RESPONSE(phr);
return;
}
}
hpi_init_response(phr, phm->object, phm->function,
HPI_ERROR_PROCESSING_MESSAGE);
if ((phm->adapter_index < HPI_MAX_ADAPTERS)
&& hpi_entry_points[phm->adapter_index])
hpi_entry_points[phm->adapter_index] (phm, phr);
else
hpi_init_response(phr, phm->object, phm->function,
HPI_ERROR_PROCESSING_MESSAGE);
}
static void adapter_open(struct hpi_message *phm, struct hpi_response *phr);
@ -100,6 +94,7 @@ static void instream_close(struct hpi_message *phm, struct hpi_response *phr,
void *h_owner);
static void HPIMSGX__reset(u16 adapter_index);
static u16 HPIMSGX__init(struct hpi_message *phm, struct hpi_response *phr);
static void HPIMSGX__cleanup(u16 adapter_index, void *h_owner);
@ -153,8 +148,6 @@ static struct hpi_stream_response
static struct hpi_mixer_response rESP_HPI_MIXER_OPEN[HPI_MAX_ADAPTERS];
static struct hpi_subsys_response gRESP_HPI_SUBSYS_FIND_ADAPTERS;
static struct adapter_info aDAPTER_INFO[HPI_MAX_ADAPTERS];
/* use these to keep track of opens from user mode apps/DLLs */
@ -167,6 +160,11 @@ static struct asi_open_state
static void subsys_message(struct hpi_message *phm, struct hpi_response *phr,
void *h_owner)
{
if (phm->adapter_index != HPI_ADAPTER_INDEX_INVALID)
HPI_DEBUG_LOG(WARNING,
"suspicious adapter index %d in subsys message 0x%x.\n",
phm->adapter_index, phm->function);
switch (phm->function) {
case HPI_SUBSYS_GET_VERSION:
hpi_init_response(phr, HPI_OBJ_SUBSYSTEM,
@ -204,85 +202,37 @@ static void subsys_message(struct hpi_message *phm, struct hpi_response *phr,
HPI_SUBSYS_DRIVER_UNLOAD, 0);
return;
case HPI_SUBSYS_GET_INFO:
case HPI_SUBSYS_GET_NUM_ADAPTERS:
case HPI_SUBSYS_GET_ADAPTER:
HPI_COMMON(phm, phr);
break;
case HPI_SUBSYS_FIND_ADAPTERS:
memcpy(phr, &gRESP_HPI_SUBSYS_FIND_ADAPTERS,
sizeof(gRESP_HPI_SUBSYS_FIND_ADAPTERS));
break;
case HPI_SUBSYS_GET_NUM_ADAPTERS:
memcpy(phr, &gRESP_HPI_SUBSYS_FIND_ADAPTERS,
sizeof(gRESP_HPI_SUBSYS_FIND_ADAPTERS));
phr->function = HPI_SUBSYS_GET_NUM_ADAPTERS;
break;
case HPI_SUBSYS_GET_ADAPTER:
{
int count = phm->adapter_index;
int index = 0;
hpi_init_response(phr, HPI_OBJ_SUBSYSTEM,
HPI_SUBSYS_GET_ADAPTER, 0);
/* This is complicated by the fact that we want to
* "skip" 0's in the adapter list.
* First, make sure we are pointing to a
* non-zero adapter type.
*/
while (gRESP_HPI_SUBSYS_FIND_ADAPTERS.
s.aw_adapter_list[index] == 0) {
index++;
if (index >= HPI_MAX_ADAPTERS)
break;
}
while (count) {
/* move on to the next adapter */
index++;
if (index >= HPI_MAX_ADAPTERS)
break;
while (gRESP_HPI_SUBSYS_FIND_ADAPTERS.
s.aw_adapter_list[index] == 0) {
index++;
if (index >= HPI_MAX_ADAPTERS)
break;
}
count--;
}
if (index < HPI_MAX_ADAPTERS) {
phr->u.s.adapter_index = (u16)index;
phr->u.s.aw_adapter_list[0] =
gRESP_HPI_SUBSYS_FIND_ADAPTERS.
s.aw_adapter_list[index];
} else {
phr->u.s.adapter_index = 0;
phr->u.s.aw_adapter_list[0] = 0;
phr->error = HPI_ERROR_BAD_ADAPTER_NUMBER;
}
break;
}
case HPI_SUBSYS_CREATE_ADAPTER:
HPIMSGX__init(phm, phr);
break;
case HPI_SUBSYS_DELETE_ADAPTER:
HPIMSGX__cleanup(phm->adapter_index, h_owner);
HPIMSGX__cleanup(phm->obj_index, h_owner);
{
struct hpi_message hm;
struct hpi_response hr;
/* call to HPI_ADAPTER_CLOSE */
hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER,
HPI_ADAPTER_CLOSE);
hm.adapter_index = phm->adapter_index;
hm.adapter_index = phm->obj_index;
hw_entry_point(&hm, &hr);
}
hw_entry_point(phm, phr);
gRESP_HPI_SUBSYS_FIND_ADAPTERS.s.
aw_adapter_list[phm->adapter_index]
= 0;
hpi_entry_points[phm->adapter_index] = NULL;
if ((phm->obj_index < HPI_MAX_ADAPTERS)
&& hpi_entry_points[phm->obj_index]) {
hpi_entry_points[phm->obj_index] (phm, phr);
hpi_entry_points[phm->obj_index] = NULL;
} else
phr->error = HPI_ERROR_INVALID_OBJ_INDEX;
break;
default:
hw_entry_point(phm, phr);
/* Must explicitly send subsys messages to individual backends */
hpi_init_response(phr, HPI_OBJ_SUBSYSTEM, phm->function,
HPI_ERROR_INVALID_FUNC);
break;
}
}
@ -409,33 +359,7 @@ void hpi_send_recv_ex(struct hpi_message *phm, struct hpi_response *phr,
break;
}
HPI_DEBUG_RESPONSE(phr);
#if 1
if (phr->error >= HPI_ERROR_BACKEND_BASE) {
void *ep = NULL;
char *ep_name;
HPI_DEBUG_MESSAGE(ERROR, phm);
if (phm->adapter_index < HPI_MAX_ADAPTERS)
ep = hpi_entry_points[phm->adapter_index];
/* Don't need this? Have adapter index in debug info
Know at driver load time index->backend mapping */
if (ep == HPI_6000)
ep_name = "HPI_6000";
else if (ep == HPI_6205)
ep_name = "HPI_6205";
else
ep_name = "unknown";
HPI_DEBUG_LOG(ERROR, "HPI %s response - error# %d\n", ep_name,
phr->error);
if (hpi_debug_level >= HPI_DEBUG_LEVEL_VERBOSE)
hpi_debug_data((u16 *)phm,
sizeof(*phm) / sizeof(u16));
}
#endif
}
static void adapter_open(struct hpi_message *phm, struct hpi_response *phr)
@ -484,7 +408,7 @@ static void instream_open(struct hpi_message *phm, struct hpi_response *phr,
else {
instream_user_open[phm->adapter_index][phm->
obj_index].open_flag = 1;
hpios_msgxlock_un_lock(&msgx_lock);
hpios_msgxlock_unlock(&msgx_lock);
/* issue a reset */
hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
@ -509,7 +433,7 @@ static void instream_open(struct hpi_message *phm, struct hpi_response *phr,
sizeof(rESP_HPI_ISTREAM_OPEN[0][0]));
}
}
hpios_msgxlock_un_lock(&msgx_lock);
hpios_msgxlock_unlock(&msgx_lock);
}
static void instream_close(struct hpi_message *phm, struct hpi_response *phr,
@ -530,7 +454,7 @@ static void instream_close(struct hpi_message *phm, struct hpi_response *phr,
phm->wAdapterIndex, phm->wObjIndex, hOwner); */
instream_user_open[phm->adapter_index][phm->
obj_index].h_owner = NULL;
hpios_msgxlock_un_lock(&msgx_lock);
hpios_msgxlock_unlock(&msgx_lock);
/* issue a reset */
hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
HPI_ISTREAM_RESET);
@ -556,7 +480,7 @@ static void instream_close(struct hpi_message *phm, struct hpi_response *phr,
obj_index].h_owner);
phr->error = HPI_ERROR_OBJ_NOT_OPEN;
}
hpios_msgxlock_un_lock(&msgx_lock);
hpios_msgxlock_unlock(&msgx_lock);
}
static void outstream_open(struct hpi_message *phm, struct hpi_response *phr,
@ -581,7 +505,7 @@ static void outstream_open(struct hpi_message *phm, struct hpi_response *phr,
else {
outstream_user_open[phm->adapter_index][phm->
obj_index].open_flag = 1;
hpios_msgxlock_un_lock(&msgx_lock);
hpios_msgxlock_unlock(&msgx_lock);
/* issue a reset */
hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
@ -606,7 +530,7 @@ static void outstream_open(struct hpi_message *phm, struct hpi_response *phr,
sizeof(rESP_HPI_OSTREAM_OPEN[0][0]));
}
}
hpios_msgxlock_un_lock(&msgx_lock);
hpios_msgxlock_unlock(&msgx_lock);
}
static void outstream_close(struct hpi_message *phm, struct hpi_response *phr,
@ -628,7 +552,7 @@ static void outstream_close(struct hpi_message *phm, struct hpi_response *phr,
phm->wAdapterIndex, phm->wObjIndex, hOwner); */
outstream_user_open[phm->adapter_index][phm->
obj_index].h_owner = NULL;
hpios_msgxlock_un_lock(&msgx_lock);
hpios_msgxlock_unlock(&msgx_lock);
/* issue a reset */
hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
HPI_OSTREAM_RESET);
@ -654,7 +578,7 @@ static void outstream_close(struct hpi_message *phm, struct hpi_response *phr,
obj_index].h_owner);
phr->error = HPI_ERROR_OBJ_NOT_OPEN;
}
hpios_msgxlock_un_lock(&msgx_lock);
hpios_msgxlock_unlock(&msgx_lock);
}
static u16 adapter_prepare(u16 adapter)
@ -683,16 +607,9 @@ static u16 adapter_prepare(u16 adapter)
if (hr.error)
return hr.error;
aDAPTER_INFO[adapter].num_outstreams = hr.u.a.num_outstreams;
aDAPTER_INFO[adapter].num_instreams = hr.u.a.num_instreams;
aDAPTER_INFO[adapter].type = hr.u.a.adapter_type;
gRESP_HPI_SUBSYS_FIND_ADAPTERS.s.aw_adapter_list[adapter] =
hr.u.a.adapter_type;
gRESP_HPI_SUBSYS_FIND_ADAPTERS.s.num_adapters++;
if (gRESP_HPI_SUBSYS_FIND_ADAPTERS.s.num_adapters > HPI_MAX_ADAPTERS)
gRESP_HPI_SUBSYS_FIND_ADAPTERS.s.num_adapters =
HPI_MAX_ADAPTERS;
aDAPTER_INFO[adapter].num_outstreams = hr.u.ax.info.num_outstreams;
aDAPTER_INFO[adapter].num_instreams = hr.u.ax.info.num_instreams;
aDAPTER_INFO[adapter].type = hr.u.ax.info.adapter_type;
/* call to HPI_OSTREAM_OPEN */
for (i = 0; i < aDAPTER_INFO[adapter].num_outstreams; i++) {
@ -727,7 +644,7 @@ static u16 adapter_prepare(u16 adapter)
memcpy(&rESP_HPI_MIXER_OPEN[adapter], &hr,
sizeof(rESP_HPI_MIXER_OPEN[0]));
return gRESP_HPI_SUBSYS_FIND_ADAPTERS.h.error;
return 0;
}
static void HPIMSGX__reset(u16 adapter_index)
@ -737,12 +654,6 @@ static void HPIMSGX__reset(u16 adapter_index)
struct hpi_response hr;
if (adapter_index == HPIMSGX_ALLADAPTERS) {
/* reset all responses to contain errors */
hpi_init_response(&hr, HPI_OBJ_SUBSYSTEM,
HPI_SUBSYS_FIND_ADAPTERS, 0);
memcpy(&gRESP_HPI_SUBSYS_FIND_ADAPTERS, &hr,
sizeof(gRESP_HPI_SUBSYS_FIND_ADAPTERS));
for (adapter = 0; adapter < HPI_MAX_ADAPTERS; adapter++) {
hpi_init_response(&hr, HPI_OBJ_ADAPTER,
@ -783,12 +694,6 @@ static void HPIMSGX__reset(u16 adapter_index)
rESP_HPI_ISTREAM_OPEN[adapter_index][i].h.error =
HPI_ERROR_INVALID_OBJ;
}
if (gRESP_HPI_SUBSYS_FIND_ADAPTERS.
s.aw_adapter_list[adapter_index]) {
gRESP_HPI_SUBSYS_FIND_ADAPTERS.
s.aw_adapter_list[adapter_index] = 0;
gRESP_HPI_SUBSYS_FIND_ADAPTERS.s.num_adapters--;
}
}
}
@ -802,15 +707,9 @@ static u16 HPIMSGX__init(struct hpi_message *phm,
hpi_handler_func *entry_point_func;
struct hpi_response hr;
if (gRESP_HPI_SUBSYS_FIND_ADAPTERS.s.num_adapters >= HPI_MAX_ADAPTERS)
return HPI_ERROR_BAD_ADAPTER_NUMBER;
/* Init response here so we can pass in previous adapter list */
hpi_init_response(&hr, phm->object, phm->function,
HPI_ERROR_INVALID_OBJ);
memcpy(hr.u.s.aw_adapter_list,
gRESP_HPI_SUBSYS_FIND_ADAPTERS.s.aw_adapter_list,
sizeof(gRESP_HPI_SUBSYS_FIND_ADAPTERS.s.aw_adapter_list));
entry_point_func =
hpi_lookup_entry_point_function(phm->u.s.resource.r.pci);
@ -860,7 +759,7 @@ static void HPIMSGX__cleanup(u16 adapter_index, void *h_owner)
struct hpi_response hr;
HPI_DEBUG_LOG(DEBUG,
"close adapter %d ostream %d\n",
"Close adapter %d ostream %d\n",
adapter, i);
hpi_init_message_response(&hm, &hr,
@ -884,7 +783,7 @@ static void HPIMSGX__cleanup(u16 adapter_index, void *h_owner)
struct hpi_response hr;
HPI_DEBUG_LOG(DEBUG,
"close adapter %d istream %d\n",
"Close adapter %d istream %d\n",
adapter, i);
hpi_init_message_response(&hm, &hr,

View File

@ -30,6 +30,7 @@ Common Linux HPI ioctl and module probe/remove functions
#include <linux/slab.h>
#include <linux/moduleparam.h>
#include <asm/uaccess.h>
#include <linux/pci.h>
#include <linux/stringify.h>
#ifdef MODULE_FIRMWARE
@ -45,7 +46,7 @@ MODULE_FIRMWARE("asihpi/dsp8900.bin");
static int prealloc_stream_buf;
module_param(prealloc_stream_buf, int, S_IRUGO);
MODULE_PARM_DESC(prealloc_stream_buf,
"preallocate size for per-adapter stream buffer");
"Preallocate size for per-adapter stream buffer");
/* Allow the debug level to be changed after module load.
E.g. echo 2 > /sys/module/asihpi/parameters/hpiDebugLevel
@ -121,8 +122,8 @@ long asihpi_hpi_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
phpi_ioctl_data = (struct hpi_ioctl_linux __user *)arg;
/* Read the message and response pointers from user space. */
if (get_user(puhm, &phpi_ioctl_data->phm) ||
get_user(puhr, &phpi_ioctl_data->phr)) {
if (get_user(puhm, &phpi_ioctl_data->phm)
|| get_user(puhr, &phpi_ioctl_data->phr)) {
err = -EFAULT;
goto out;
}
@ -135,7 +136,7 @@ long asihpi_hpi_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
if (hm->h.size > sizeof(*hm))
hm->h.size = sizeof(*hm);
/*printk(KERN_INFO "message size %d\n", hm->h.wSize); */
/* printk(KERN_INFO "message size %d\n", hm->h.wSize); */
uncopied_bytes = copy_from_user(hm, puhm, hm->h.size);
if (uncopied_bytes) {
@ -156,7 +157,7 @@ long asihpi_hpi_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
}
pa = &adapters[hm->h.adapter_index];
hr->h.size = 0;
hr->h.size = res_max_size;
if (hm->h.object == HPI_OBJ_SUBSYSTEM) {
switch (hm->h.function) {
case HPI_SUBSYS_CREATE_ADAPTER:
@ -216,7 +217,7 @@ long asihpi_hpi_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
*/
if (pa->buffer_size < size) {
HPI_DEBUG_LOG(DEBUG,
"realloc adapter %d stream "
"Realloc adapter %d stream "
"buffer from %zd to %d\n",
hm->h.adapter_index,
pa->buffer_size, size);
@ -259,7 +260,7 @@ long asihpi_hpi_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
copy_from_user(pa->p_buffer, ptr, size);
if (uncopied_bytes)
HPI_DEBUG_LOG(WARNING,
"missed %d of %d "
"Missed %d of %d "
"bytes from user\n", uncopied_bytes,
size);
}
@ -271,7 +272,7 @@ long asihpi_hpi_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
copy_to_user(ptr, pa->p_buffer, size);
if (uncopied_bytes)
HPI_DEBUG_LOG(WARNING,
"missed %d of %d " "bytes to user\n",
"Missed %d of %d " "bytes to user\n",
uncopied_bytes, size);
}
@ -290,9 +291,9 @@ long asihpi_hpi_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
if (hr->h.size > res_max_size) {
HPI_DEBUG_LOG(ERROR, "response too big %d %d\n", hr->h.size,
res_max_size);
/*HPI_DEBUG_MESSAGE(ERROR, hm); */
err = -EFAULT;
goto out;
hr->h.error = HPI_ERROR_RESPONSE_BUFFER_TOO_SMALL;
hr->h.specific_error = hr->h.size;
hr->h.size = sizeof(hr->h);
}
uncopied_bytes = copy_to_user(puhr, hr, hr->h.size);
@ -320,18 +321,26 @@ int __devinit asihpi_adapter_probe(struct pci_dev *pci_dev,
memset(&adapter, 0, sizeof(adapter));
printk(KERN_DEBUG "probe PCI device (%04x:%04x,%04x:%04x,%04x)\n",
pci_dev->vendor, pci_dev->device, pci_dev->subsystem_vendor,
dev_printk(KERN_DEBUG, &pci_dev->dev,
"probe %04x:%04x,%04x:%04x,%04x\n", pci_dev->vendor,
pci_dev->device, pci_dev->subsystem_vendor,
pci_dev->subsystem_device, pci_dev->devfn);
if (pci_enable_device(pci_dev) < 0) {
dev_printk(KERN_ERR, &pci_dev->dev,
"pci_enable_device failed, disabling device\n");
return -EIO;
}
pci_set_master(pci_dev); /* also sets latency timer if < 16 */
hpi_init_message_response(&hm, &hr, HPI_OBJ_SUBSYSTEM,
HPI_SUBSYS_CREATE_ADAPTER);
hpi_init_response(&hr, HPI_OBJ_SUBSYSTEM, HPI_SUBSYS_CREATE_ADAPTER,
HPI_ERROR_PROCESSING_MESSAGE);
hm.adapter_index = -1; /* an invalid index */
hm.adapter_index = HPI_ADAPTER_INDEX_INVALID;
/* fill in HPI_PCI information from kernel provided information */
adapter.pci = pci_dev;
nm = HPI_MAX_ADAPTER_MEM_SPACES;
@ -359,19 +368,7 @@ int __devinit asihpi_adapter_probe(struct pci_dev *pci_dev,
pci.ap_mem_base[idx] = adapter.ap_remapped_mem_base[idx];
}
/* could replace Pci with direct pointer to pci_dev for linux
Instead wrap accessor functions for IDs etc.
Would it work for windows?
*/
pci.bus_number = pci_dev->bus->number;
pci.vendor_id = (u16)pci_dev->vendor;
pci.device_id = (u16)pci_dev->device;
pci.subsys_vendor_id = (u16)(pci_dev->subsystem_vendor & 0xffff);
pci.subsys_device_id = (u16)(pci_dev->subsystem_device & 0xffff);
pci.device_number = pci_dev->devfn;
pci.interrupt = pci_dev->irq;
pci.p_os_data = pci_dev;
pci.pci_dev = pci_dev;
hm.u.s.resource.bus_type = HPI_BUS_PCI;
hm.u.s.resource.r.pci = &pci;
@ -407,8 +404,9 @@ int __devinit asihpi_adapter_probe(struct pci_dev *pci_dev,
mutex_init(&adapters[adapter.index].mutex);
pci_set_drvdata(pci_dev, &adapters[adapter.index]);
printk(KERN_INFO "probe found adapter ASI%04X HPI index #%d.\n",
adapter.type, adapter.index);
dev_printk(KERN_INFO, &pci_dev->dev,
"probe succeeded for ASI%04X HPI index %d\n", adapter.type,
adapter.index);
return 0;
@ -439,7 +437,8 @@ void __devexit asihpi_adapter_remove(struct pci_dev *pci_dev)
hpi_init_message_response(&hm, &hr, HPI_OBJ_SUBSYSTEM,
HPI_SUBSYS_DELETE_ADAPTER);
hm.adapter_index = pa->index;
hm.obj_index = pa->index;
hm.adapter_index = HPI_ADAPTER_INDEX_INVALID;
hpi_send_recv_ex(&hm, &hr, HOWNER_KERNEL);
/* unmap PCI memory space, mapped during device init. */
@ -456,14 +455,12 @@ void __devexit asihpi_adapter_remove(struct pci_dev *pci_dev)
}
pci_set_drvdata(pci_dev, NULL);
/*
printk(KERN_INFO "PCI device (%04x:%04x,%04x:%04x,%04x),"
" HPI index # %d, removed.\n",
pci_dev->vendor, pci_dev->device,
pci_dev->subsystem_vendor,
pci_dev->subsystem_device, pci_dev->devfn,
pa->index);
*/
if (1)
dev_printk(KERN_INFO, &pci_dev->dev,
"remove %04x:%04x,%04x:%04x,%04x," " HPI index %d.\n",
pci_dev->vendor, pci_dev->device,
pci_dev->subsystem_vendor, pci_dev->subsystem_device,
pci_dev->devfn, pa->index);
}
void __init asihpi_init(void)

View File

@ -135,7 +135,7 @@ static inline void cond_unlock(struct hpios_spinlock *l)
#define hpios_msgxlock_init(obj) spin_lock_init(&(obj)->lock)
#define hpios_msgxlock_lock(obj) cond_lock(obj)
#define hpios_msgxlock_un_lock(obj) cond_unlock(obj)
#define hpios_msgxlock_unlock(obj) cond_unlock(obj)
#define hpios_dsplock_init(obj) spin_lock_init(&(obj)->dsp_lock.lock)
#define hpios_dsplock_lock(obj) cond_lock(&(obj)->dsp_lock)
@ -148,7 +148,7 @@ static inline void cond_unlock(struct hpios_spinlock *l)
#define HPI_ALIST_LOCKING
#define hpios_alistlock_init(obj) spin_lock_init(&((obj)->list_lock.lock))
#define hpios_alistlock_lock(obj) spin_lock(&((obj)->list_lock.lock))
#define hpios_alistlock_un_lock(obj) spin_unlock(&((obj)->list_lock.lock))
#define hpios_alistlock_unlock(obj) spin_unlock(&((obj)->list_lock.lock))
struct hpi_adapter {
/* mutex prevents contention for one card