1
0
Fork 0
mirror of synced 2025-03-06 20:59:54 +01:00

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>
This commit is contained in:
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 #define HPI_HIF_ERROR_MASK 0x4000
/* HPI6000 specific error codes */ /* HPI6000 specific error codes */
#define HPI6000_ERROR_BASE 900 /* not actually used anywhere */
#define HPI6000_ERROR_BASE 900 /* operational/messaging errors */
#define HPI6000_ERROR_MSG_RESP_IDLE_TIMEOUT 901 #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_RESP_GET_RESP_ACK 903
#define HPI6000_ERROR_MSG_GET_ADR 904 #define HPI6000_ERROR_MSG_GET_ADR 904
#define HPI6000_ERROR_RESP_GET_ADR 905 #define HPI6000_ERROR_RESP_GET_ADR 905
#define HPI6000_ERROR_MSG_RESP_BLOCKWRITE32 906 #define HPI6000_ERROR_MSG_RESP_BLOCKWRITE32 906
#define HPI6000_ERROR_MSG_RESP_BLOCKREAD32 907 #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_CONTROL_CACHE_PARAMS 909
#define HPI6000_ERROR_SEND_DATA_IDLE_TIMEOUT 911 #define HPI6000_ERROR_SEND_DATA_IDLE_TIMEOUT 911
@ -62,7 +62,6 @@
#define HPI6000_ERROR_SEND_DATA_CMD 915 #define HPI6000_ERROR_SEND_DATA_CMD 915
#define HPI6000_ERROR_SEND_DATA_WRITE 916 #define HPI6000_ERROR_SEND_DATA_WRITE 916
#define HPI6000_ERROR_SEND_DATA_IDLECMD 917 #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_IDLE_TIMEOUT 921
#define HPI6000_ERROR_GET_DATA_ACK 922 #define HPI6000_ERROR_GET_DATA_ACK 922
@ -76,9 +75,8 @@
#define HPI6000_ERROR_MSG_RESP_GETRESPCMD 961 #define HPI6000_ERROR_MSG_RESP_GETRESPCMD 961
#define HPI6000_ERROR_MSG_RESP_IDLECMD 962 #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 #define HPI6000_ERROR_UNHANDLED_SUBSYS_ID 930
/* can't access PCI2040 */ /* 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, static short create_adapter_obj(struct hpi_adapter_obj *pao,
u32 *pos_error_code); u32 *pos_error_code);
static void delete_adapter_obj(struct hpi_adapter_obj *pao);
/* local globals */ /* local globals */
static u16 gw_pci_read_asserts; /* used to count PCI2040 errors */ 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) static void subsys_message(struct hpi_message *phm, struct hpi_response *phr)
{ {
switch (phm->function) { 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: case HPI_SUBSYS_CREATE_ADAPTER:
subsys_create_adapter(phm, phr); subsys_create_adapter(phm, phr);
break; 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, static void control_message(struct hpi_adapter_obj *pao,
struct hpi_message *phm, struct hpi_response *phr) struct hpi_message *phm, struct hpi_response *phr)
{ {
switch (phm->function) { switch (phm->function) {
case HPI_CONTROL_GET_STATE: case HPI_CONTROL_GET_STATE:
if (pao->has_control_cache) { if (pao->has_control_cache) {
u16 err; phr->error = hpi6000_update_control_cache(pao, phm);
err = hpi6000_update_control_cache(pao, phm);
if (err) { if (phr->error)
phr->error = err;
break; break;
}
if (hpi_check_control_cache(((struct hpi_hw_obj *) if (hpi_check_control_cache(((struct hpi_hw_obj *)
pao->priv)->p_cache, phm, pao->priv)->p_cache, phm,
@ -262,16 +248,15 @@ static void control_message(struct hpi_adapter_obj *pao,
} }
hw_message(pao, phm, phr); hw_message(pao, phm, phr);
break; break;
case HPI_CONTROL_GET_INFO:
hw_message(pao, phm, phr);
break;
case HPI_CONTROL_SET_STATE: case HPI_CONTROL_SET_STATE:
hw_message(pao, phm, phr); hw_message(pao, phm, phr);
hpi_sync_control_cache(((struct hpi_hw_obj *)pao->priv)-> hpi_cmn_control_cache_sync_to_msg(((struct hpi_hw_obj *)pao->
p_cache, phm, phr); priv)->p_cache, phm, phr);
break; break;
case HPI_CONTROL_GET_INFO:
default: default:
phr->error = HPI_ERROR_INVALID_FUNC; hw_message(pao, phm, phr);
break; break;
} }
} }
@ -280,26 +265,12 @@ static void adapter_message(struct hpi_adapter_obj *pao,
struct hpi_message *phm, struct hpi_response *phr) struct hpi_message *phm, struct hpi_response *phr)
{ {
switch (phm->function) { switch (phm->function) {
case HPI_ADAPTER_GET_INFO:
hw_message(pao, phm, phr);
break;
case HPI_ADAPTER_GET_ASSERT: case HPI_ADAPTER_GET_ASSERT:
adapter_get_asserts(pao, phm, phr); adapter_get_asserts(pao, phm, phr);
break; 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: default:
phr->error = HPI_ERROR_INVALID_FUNC; hw_message(pao, phm, phr);
break; break;
} }
} }
@ -311,7 +282,7 @@ static void outstream_message(struct hpi_adapter_obj *pao,
case HPI_OSTREAM_HOSTBUFFER_ALLOC: case HPI_OSTREAM_HOSTBUFFER_ALLOC:
case HPI_OSTREAM_HOSTBUFFER_FREE: case HPI_OSTREAM_HOSTBUFFER_FREE:
/* Don't let these messages go to the HW function because /* 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 * For the HPI6000 adapters the HW would return
* HPI_ERROR_INVALID_FUNC anyway. * 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_ALLOC:
case HPI_ISTREAM_HOSTBUFFER_FREE: case HPI_ISTREAM_HOSTBUFFER_FREE:
/* Don't let these messages go to the HW function because /* 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 * For the HPI6000 adapters the HW would return
* HPI_ERROR_INVALID_FUNC anyway. * 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. */ /* subsytem messages get executed by every HPI. */
/* All other messages are ignored unless the adapter index matches */ /* All other messages are ignored unless the adapter index matches */
/* an adapter in the HPI */ /* 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 Dsp has crashed then do not communicate with it any more */
if (phm->object != HPI_OBJ_SUBSYSTEM) { if (phm->object != HPI_OBJ_SUBSYSTEM) {
@ -440,14 +411,6 @@ static void subsys_create_adapter(struct hpi_message *phm,
memset(&ao, 0, sizeof(ao)); 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); ao.priv = kzalloc(sizeof(struct hpi_hw_obj), GFP_KERNEL);
if (!ao.priv) { if (!ao.priv) {
HPI_DEBUG_LOG(ERROR, "cant get mem for adapter object\n"); 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 */ /* 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; ao.pci = *phm->u.s.resource.r.pci;
error = create_adapter_obj(&ao, &os_error_code); error = create_adapter_obj(&ao, &os_error_code);
if (!error)
error = hpi_add_adapter(&ao);
if (error) { if (error) {
phr->u.s.data = os_error_code; delete_adapter_obj(&ao);
kfree(ao.priv);
phr->error = error; phr->error = error;
phr->u.s.data = os_error_code;
return; return;
} }
/* need to update paParentAdapter */ /* need to update paParentAdapter */
@ -492,20 +452,13 @@ static void subsys_delete_adapter(struct hpi_message *phm,
struct hpi_response *phr) struct hpi_response *phr)
{ {
struct hpi_adapter_obj *pao = NULL; 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) if (!pao)
return; return;
phw = (struct hpi_hw_obj *)pao->priv; delete_adapter_obj(pao);
if (pao->has_control_cache)
hpi_free_control_cache(phw->p_cache);
hpi_delete_adapter(pao); hpi_delete_adapter(pao);
kfree(phw);
phr->error = 0; phr->error = 0;
} }
@ -519,9 +472,6 @@ static short create_adapter_obj(struct hpi_adapter_obj *pao,
u32 control_cache_count = 0; u32 control_cache_count = 0;
struct hpi_hw_obj *phw = (struct hpi_hw_obj *)pao->priv; 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 */ /* The PCI2040 has the following address map */
/* BAR0 - 4K = HPI control and status registers on PCI2040 (HPI CSR) */ /* BAR0 - 4K = HPI control and status registers on PCI2040 (HPI CSR) */
/* BAR1 - 32K = HPI registers on DSP */ /* 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 */ /* get info about the adapter by asking the adapter */
/* send a HPI_ADAPTER_GET_INFO message */ /* send a HPI_ADAPTER_GET_INFO message */
{ {
struct hpi_message hM; struct hpi_message hm;
struct hpi_response hR0; /* response from DSP 0 */ struct hpi_response hr0; /* response from DSP 0 */
struct hpi_response hR1; /* response from DSP 1 */ struct hpi_response hr1; /* response from DSP 1 */
u16 error = 0; u16 error = 0;
HPI_DEBUG_LOG(VERBOSE, "send ADAPTER_GET_INFO\n"); HPI_DEBUG_LOG(VERBOSE, "send ADAPTER_GET_INFO\n");
memset(&hM, 0, sizeof(hM)); memset(&hm, 0, sizeof(hm));
hM.type = HPI_TYPE_MESSAGE; hm.type = HPI_TYPE_MESSAGE;
hM.size = sizeof(struct hpi_message); hm.size = sizeof(struct hpi_message);
hM.object = HPI_OBJ_ADAPTER; hm.object = HPI_OBJ_ADAPTER;
hM.function = HPI_ADAPTER_GET_INFO; hm.function = HPI_ADAPTER_GET_INFO;
hM.adapter_index = 0; hm.adapter_index = 0;
memset(&hR0, 0, sizeof(hR0)); memset(&hr0, 0, sizeof(hr0));
memset(&hR1, 0, sizeof(hR1)); memset(&hr1, 0, sizeof(hr1));
hR0.size = sizeof(hR0); hr0.size = sizeof(hr0);
hR1.size = sizeof(hR1); hr1.size = sizeof(hr1);
error = hpi6000_message_response_sequence(pao, 0, &hM, &hR0); error = hpi6000_message_response_sequence(pao, 0, &hm, &hr0);
if (hR0.error) { if (hr0.error) {
HPI_DEBUG_LOG(DEBUG, "message error %d\n", hR0.error); HPI_DEBUG_LOG(DEBUG, "message error %d\n", hr0.error);
return hR0.error; return hr0.error;
} }
if (phw->num_dsp == 2) { if (phw->num_dsp == 2) {
error = hpi6000_message_response_sequence(pao, 1, &hM, error = hpi6000_message_response_sequence(pao, 1, &hm,
&hR1); &hr1);
if (error) if (error)
return error; return error;
} }
pao->adapter_type = hR0.u.a.adapter_type; pao->adapter_type = hr0.u.ax.info.adapter_type;
pao->index = hR0.u.a.adapter_index; pao->index = hr0.u.ax.info.adapter_index;
} }
memset(&phw->control_cache[0], 0, memset(&phw->control_cache[0], 0,
@ -618,22 +568,34 @@ static short create_adapter_obj(struct hpi_adapter_obj *pao,
control_cache_count = control_cache_count =
hpi_read_word(&phw->ado[0], hpi_read_word(&phw->ado[0],
HPI_HIF_ADDR(control_cache_count)); HPI_HIF_ADDR(control_cache_count));
pao->has_control_cache = 1;
phw->p_cache = phw->p_cache =
hpi_alloc_control_cache(control_cache_count, hpi_alloc_control_cache(control_cache_count,
control_cache_size, (struct hpi_control_cache_info *) control_cache_size, (unsigned char *)
&phw->control_cache[0] &phw->control_cache[0]
); );
if (!phw->p_cache) if (phw->p_cache)
pao->has_control_cache = 0; pao->has_control_cache = 1;
} else }
pao->has_control_cache = 0;
HPI_DEBUG_LOG(DEBUG, "get adapter info ASI%04X index %d\n", HPI_DEBUG_LOG(DEBUG, "get adapter info ASI%04X index %d\n",
pao->adapter_type, pao->index); pao->adapter_type, pao->index);
pao->open = 0; /* upon creation the adapter is closed */ 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 #ifndef HIDE_PCI_ASSERTS
/* if we have PCI2040 asserts then collect them */ /* if we have PCI2040 asserts then collect them */
if ((gw_pci_read_asserts > 0) || (gw_pci_write_asserts > 0)) { 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; gw_pci_read_asserts * 100 + gw_pci_write_asserts;
phr->u.a.adapter_index = 1; /* assert count */ phr->u.ax.assert.p2 = 0;
phr->u.a.adapter_type = -1; /* "dsp index" */ phr->u.ax.assert.count = 1; /* assert count */
strcpy(phr->u.a.sz_adapter_assert, "PCI2040 error"); 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_read_asserts = 0;
gw_pci_write_asserts = 0; gw_pci_write_asserts = 0;
phr->error = 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 */ /* 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 0x5100:
case 0x5110: /* ASI5100 revB or higher with C6711D */ 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 0x6100:
case 0x6200: case 0x6200:
boot_load_family = HPI_ADAPTER_FAMILY_ASI(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, * note that bits 4..15 are read-only and so should always return zero,
* even though we wrote 1 to them * even though we wrote 1 to them
*/ */
for (i = 0; i < 1000; i++) hpios_delay_micro_seconds(1000);
delay = ioread32(phw->dw2040_HPICSR + HPI_RESET); delay = ioread32(phw->dw2040_HPICSR + HPI_RESET);
if (delay != dw2040_reset) { if (delay != dw2040_reset) {
HPI_DEBUG_LOG(ERROR, "INIT_PCI2040 %x %x\n", dw2040_reset, HPI_DEBUG_LOG(ERROR, "INIT_PCI2040 %x %x\n", dw2040_reset,
delay); delay);
@ -743,8 +708,7 @@ static short hpi6000_adapter_boot_load_dsp(struct hpi_adapter_obj *pao,
dw2040_reset = dw2040_reset & (~0x00000008); dw2040_reset = dw2040_reset & (~0x00000008);
iowrite32(dw2040_reset, phw->dw2040_HPICSR + HPI_RESET); iowrite32(dw2040_reset, phw->dw2040_HPICSR + HPI_RESET);
/*delay to allow DSP to get going */ /*delay to allow DSP to get going */
for (i = 0; i < 100; i++) hpios_delay_micro_seconds(100);
delay = ioread32(phw->dw2040_HPICSR + HPI_RESET);
/* loop through all DSPs, downloading DSP code */ /* loop through all DSPs, downloading DSP code */
for (dsp_index = 0; dsp_index < phw->num_dsp; dsp_index++) { 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 */ /* bypass PLL */
hpi_write_word(pdo, 0x01B7C100, 0x0000); hpi_write_word(pdo, 0x01B7C100, 0x0000);
for (i = 0; i < 100; i++) hpios_delay_micro_seconds(100);
delay = ioread32(phw->dw2040_HPICSR +
HPI_RESET);
/* ** use default of PLL x7 ** */ /* ** use default of PLL x7 ** */
/* EMIF = 225/3=75MHz */ /* EMIF = 225/3=75MHz */
hpi_write_word(pdo, 0x01B7C120, 0x8002); hpi_write_word(pdo, 0x01B7C120, 0x8002);
hpios_delay_micro_seconds(100);
/* peri = 225/2 */ /* peri = 225/2 */
hpi_write_word(pdo, 0x01B7C11C, 0x8001); hpi_write_word(pdo, 0x01B7C11C, 0x8001);
hpios_delay_micro_seconds(100);
/* cpu = 225/1 */ /* cpu = 225/1 */
hpi_write_word(pdo, 0x01B7C118, 0x8000); hpi_write_word(pdo, 0x01B7C118, 0x8000);
/* ~200us delay */
for (i = 0; i < 2000; i++) /* ~2ms delay */
delay = ioread32(phw->dw2040_HPICSR + hpios_delay_micro_seconds(2000);
HPI_RESET);
/* PLL not bypassed */ /* PLL not bypassed */
hpi_write_word(pdo, 0x01B7C100, 0x0001); hpi_write_word(pdo, 0x01B7C100, 0x0001);
/* ~200us delay */ /* ~2ms delay */
for (i = 0; i < 2000; i++) hpios_delay_micro_seconds(2000);
delay = ioread32(phw->dw2040_HPICSR +
HPI_RESET);
} }
/* test r/w to internal DSP memory /* 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" */ /* delay a little to allow SDRAM and DSP to "get going" */
hpios_delay_micro_seconds(1000);
for (i = 0; i < 1000; i++)
delay = ioread32(phw->dw2040_HPICSR + HPI_RESET);
/* test access to SDRAM */ /* 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 */ /* write the DSP code down into the DSPs memory */
/*HpiDspCode_Open(nBootLoadFamily,&DspCode,pdwOsErrorCode); */ /*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, error = hpi_dsp_code_open(boot_load_family, &dsp_code,
pos_error_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 */ /* step 3. Start code by sending interrupt */
iowrite32(0x00030003, pdo->prHPI_control); iowrite32(0x00030003, pdo->prHPI_control);
for (i = 0; i < 10000; i++) hpios_delay_micro_seconds(10000);
delay = ioread32(phw->dw2040_HPICSR + HPI_RESET);
/* wait for a non-zero value in hostcmd - /* wait for a non-zero value in hostcmd -
* indicating initialization is complete * 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). * locks up with a bluescreen (NOT GPF or pagefault).
*/ */
else else
hpios_delay_micro_seconds(1000); hpios_delay_micro_seconds(10000);
} }
if (timeout == 0) if (timeout == 0)
return HPI6000_ERROR_INIT_NOACK; return HPI6000_ERROR_INIT_NOACK;
@ -1132,14 +1093,14 @@ static short hpi6000_adapter_boot_load_dsp(struct hpi_adapter_obj *pao,
mask = 0xFFFFFF00L; mask = 0xFFFFFF00L;
/* ASI5100 uses AX6 code, */ /* ASI5100 uses AX6 code, */
/* but has no PLD r/w register to test */ /* but has no PLD r/w register to test */
if (HPI_ADAPTER_FAMILY_ASI(pao->pci. if (HPI_ADAPTER_FAMILY_ASI(pao->pci.pci_dev->
subsys_device_id) == subsystem_device) ==
HPI_ADAPTER_FAMILY_ASI(0x5100)) HPI_ADAPTER_FAMILY_ASI(0x5100))
mask = 0x00000000L; mask = 0x00000000L;
/* ASI5200 uses AX6 code, */ /* ASI5200 uses AX6 code, */
/* but has no PLD r/w register to test */ /* but has no PLD r/w register to test */
if (HPI_ADAPTER_FAMILY_ASI(pao->pci. if (HPI_ADAPTER_FAMILY_ASI(pao->pci.pci_dev->
subsys_device_id) == subsystem_device) ==
HPI_ADAPTER_FAMILY_ASI(0x5200)) HPI_ADAPTER_FAMILY_ASI(0x5200))
mask = 0x00000000L; mask = 0x00000000L;
break; break;
@ -1204,7 +1165,7 @@ static u32 hpi_read_word(struct dsp_obj *pdo, u32 address)
u32 data = 0; u32 data = 0;
if (hpi_set_address(pdo, address)) 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) */ /* take care of errata in revB DSP (2.0.1) */
data = ioread32(pdo->prHPI_data); data = ioread32(pdo->prHPI_data);
@ -1340,10 +1301,6 @@ static short hpi6000_message_response_sequence(struct hpi_adapter_obj *pao,
u32 *p_data; u32 *p_data;
u16 error = 0; 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); ack = hpi6000_wait_dsp_ack(pao, dsp_index, HPI_HIF_IDLE);
if (ack & HPI_HIF_ERROR_MASK) { if (ack & HPI_HIF_ERROR_MASK) {
pao->dsp_crashed++; pao->dsp_crashed++;
@ -1351,9 +1308,7 @@ static short hpi6000_message_response_sequence(struct hpi_adapter_obj *pao,
} }
pao->dsp_crashed = 0; pao->dsp_crashed = 0;
/* send the message */ /* get the message address and size */
/* get the address and size */
if (phw->message_buffer_address_on_dsp == 0) { if (phw->message_buffer_address_on_dsp == 0) {
timeout = TIMEOUT; timeout = TIMEOUT;
do { do {
@ -1368,10 +1323,9 @@ static short hpi6000_message_response_sequence(struct hpi_adapter_obj *pao,
} else } else
address = phw->message_buffer_address_on_dsp; address = phw->message_buffer_address_on_dsp;
/* dwLength = sizeof(struct hpi_message); */
length = phm->size; length = phm->size;
/* send it */ /* send the message */
p_data = (u32 *)phm; p_data = (u32 *)phm;
if (hpi6000_dsp_block_write32(pao, dsp_index, address, p_data, if (hpi6000_dsp_block_write32(pao, dsp_index, address, p_data,
(u16)length / 4)) (u16)length / 4))
@ -1385,7 +1339,7 @@ static short hpi6000_message_response_sequence(struct hpi_adapter_obj *pao,
if (ack & HPI_HIF_ERROR_MASK) if (ack & HPI_HIF_ERROR_MASK)
return HPI6000_ERROR_MSG_RESP_GET_RESP_ACK; 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) { if (phw->response_buffer_address_on_dsp == 0) {
timeout = TIMEOUT; timeout = TIMEOUT;
do { do {
@ -1409,7 +1363,7 @@ static short hpi6000_message_response_sequence(struct hpi_adapter_obj *pao,
if (!timeout) if (!timeout)
length = sizeof(struct hpi_response); length = sizeof(struct hpi_response);
/* get it */ /* get the response */
p_data = (u32 *)phr; p_data = (u32 *)phr;
if (hpi6000_dsp_block_read32(pao, dsp_index, address, p_data, if (hpi6000_dsp_block_read32(pao, dsp_index, address, p_data,
(u16)length / 4)) (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); error = hpi6000_get_data(pao, dsp_index, phm, phr);
break; break;
case HPI_ADAPTER_GET_ASSERT: 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 (num_dsp == 2) {
if (!phr->u.a.adapter_type) { if (!phr->u.ax.assert.count) {
/* no assert from dsp 0, check dsp 1 */ /* no assert from dsp 0, check dsp 1 */
error = hpi6000_message_response_sequence(pao, error = hpi6000_message_response_sequence(pao,
1, phm, phr); 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 */ /* HPI6205 specific error codes */
#define HPI6205_ERROR_BASE 1000 #define HPI6205_ERROR_BASE 1000 /* not actually used anywhere */
/*#define HPI6205_ERROR_MEM_ALLOC 1001 */
/* 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_NO_IRQ 1002
#define HPI6205_ERROR_6205_INIT_FAILED 1003 #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_REG 1006
#define HPI6205_ERROR_6205_DSPPAGE 1007 #define HPI6205_ERROR_6205_DSPPAGE 1007
#define HPI6205_ERROR_BAD_DSPINDEX 1008
#define HPI6205_ERROR_C6713_HPIC 1009 #define HPI6205_ERROR_C6713_HPIC 1009
#define HPI6205_ERROR_C6713_HPIA 1010 #define HPI6205_ERROR_C6713_HPIA 1010
#define HPI6205_ERROR_C6713_PLL 1011 #define HPI6205_ERROR_C6713_PLL 1011
#define HPI6205_ERROR_DSP_INTMEM 1012 #define HPI6205_ERROR_DSP_INTMEM 1012
#define HPI6205_ERROR_DSP_EXTMEM 1013 #define HPI6205_ERROR_DSP_EXTMEM 1013
#define HPI6205_ERROR_DSP_PLD 1014 #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_6205_EEPROM 1017
#define HPI6205_ERROR_DSP_EMIF 1018 #define HPI6205_ERROR_DSP_EMIF 1018
#define hpi6205_error(dsp_index, err) (err)
/*****************************************************************************/ /*****************************************************************************/
/* for C6205 PCI i/f */ /* for C6205 PCI i/f */
/* Host Status Register (HSR) bitfields */ /* 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, static u32 boot_loader_read_mem32(struct hpi_adapter_obj *pao, int dsp_index,
u32 address); u32 address);
static u16 boot_loader_write_mem32(struct hpi_adapter_obj *pao, int dsp_index, static void boot_loader_write_mem32(struct hpi_adapter_obj *pao,
u32 address, u32 data); int dsp_index, u32 address, u32 data);
static u16 boot_loader_config_emif(struct hpi_adapter_obj *pao, static u16 boot_loader_config_emif(struct hpi_adapter_obj *pao,
int dsp_index); 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) static void subsys_message(struct hpi_message *phm, struct hpi_response *phr)
{ {
switch (phm->function) { 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: case HPI_SUBSYS_CREATE_ADAPTER:
subsys_create_adapter(phm, phr); subsys_create_adapter(phm, phr);
break; break;
@ -257,15 +246,22 @@ static void control_message(struct hpi_adapter_obj *pao,
{ {
struct hpi_hw_obj *phw = pao->priv; struct hpi_hw_obj *phw = pao->priv;
u16 pending_cache_error = 0;
switch (phm->function) { switch (phm->function) {
case HPI_CONTROL_GET_STATE: case HPI_CONTROL_GET_STATE:
if (pao->has_control_cache) { if (pao->has_control_cache) {
rmb(); /* make sure we see updates DM_aed from DSP */ rmb(); /* make sure we see updates DMAed from DSP */
if (hpi_check_control_cache(phw->p_cache, phm, phr)) if (hpi_check_control_cache(phw->p_cache, phm, phr)) {
break; break;
} else if (phm->u.c.attribute == HPI_METER_PEAK) {
pending_cache_error =
HPI_ERROR_CONTROL_CACHING;
}
} }
hw_message(pao, phm, phr); hw_message(pao, phm, phr);
if (pending_cache_error && !phr->error)
phr->error = pending_cache_error;
break; break;
case HPI_CONTROL_GET_INFO: case HPI_CONTROL_GET_INFO:
hw_message(pao, phm, phr); hw_message(pao, phm, phr);
@ -273,7 +269,8 @@ static void control_message(struct hpi_adapter_obj *pao,
case HPI_CONTROL_SET_STATE: case HPI_CONTROL_SET_STATE:
hw_message(pao, phm, phr); hw_message(pao, phm, phr);
if (pao->has_control_cache) 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; break;
default: default:
phr->error = HPI_ERROR_INVALID_FUNC; 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) { if (phm->obj_index >= HPI_MAX_STREAMS) {
phr->error = HPI_ERROR_INVALID_STREAM; phr->error = HPI_ERROR_INVALID_STREAM;
HPI_DEBUG_LOG(WARNING, HPI_DEBUG_LOG(WARNING,
"message referencing invalid stream %d " "Message referencing invalid stream %d "
"on adapter index %d\n", phm->obj_index, "on adapter index %d\n", phm->obj_index,
phm->adapter_index); phm->adapter_index);
return; return;
@ -342,7 +339,7 @@ static void instream_message(struct hpi_adapter_obj *pao,
if (phm->obj_index >= HPI_MAX_STREAMS) { if (phm->obj_index >= HPI_MAX_STREAMS) {
phr->error = HPI_ERROR_INVALID_STREAM; phr->error = HPI_ERROR_INVALID_STREAM;
HPI_DEBUG_LOG(WARNING, HPI_DEBUG_LOG(WARNING,
"message referencing invalid stream %d " "Message referencing invalid stream %d "
"on adapter index %d\n", phm->obj_index, "on adapter index %d\n", phm->obj_index,
phm->adapter_index); phm->adapter_index);
return; 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 * All other messages are ignored unless the adapter index matches
* an adapter in the HPI * an adapter in the HPI
*/ */
HPI_DEBUG_LOG(DEBUG, "HPI obj=%d, func=%d\n", phm->object, /* HPI_DEBUG_LOG(DEBUG, "HPI Obj=%d, Func=%d\n", phm->wObject,
phm->function); phm->wFunction); */
/* if Dsp has crashed then do not communicate with it any more */ /* if Dsp has crashed then do not communicate with it any more */
if (phm->object != HPI_OBJ_SUBSYSTEM) { if (phm->object != HPI_OBJ_SUBSYSTEM) {
@ -411,8 +408,7 @@ void HPI_6205(struct hpi_message *phm, struct hpi_response *phr)
/* Init default response */ /* Init default response */
if (phm->function != HPI_SUBSYS_CREATE_ADAPTER) if (phm->function != HPI_SUBSYS_CREATE_ADAPTER)
hpi_init_response(phr, phm->object, phm->function, phr->error = HPI_ERROR_PROCESSING_MESSAGE;
HPI_ERROR_PROCESSING_MESSAGE);
HPI_DEBUG_LOG(VERBOSE, "start of switch\n"); HPI_DEBUG_LOG(VERBOSE, "start of switch\n");
switch (phm->type) { switch (phm->type) {
@ -423,9 +419,6 @@ void HPI_6205(struct hpi_message *phm, struct hpi_response *phr)
break; break;
case HPI_OBJ_ADAPTER: case HPI_OBJ_ADAPTER:
phr->size =
sizeof(struct hpi_response_header) +
sizeof(struct hpi_adapter_res);
adapter_message(pao, phm, phr); adapter_message(pao, phm, phr);
break; break;
@ -474,14 +467,6 @@ static void subsys_create_adapter(struct hpi_message *phm,
memset(&ao, 0, sizeof(ao)); 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); ao.priv = kzalloc(sizeof(struct hpi_hw_obj), GFP_KERNEL);
if (!ao.priv) { if (!ao.priv) {
HPI_DEBUG_LOG(ERROR, "cant get mem for adapter object\n"); 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; ao.pci = *phm->u.s.resource.r.pci;
err = create_adapter_obj(&ao, &os_error_code); err = create_adapter_obj(&ao, &os_error_code);
if (!err)
err = hpi_add_adapter(&ao);
if (err) { if (err) {
phr->u.s.data = os_error_code;
delete_adapter_obj(&ao); delete_adapter_obj(&ao);
phr->error = err; phr->error = err;
phr->u.s.data = os_error_code;
return; return;
} }
@ -513,7 +496,7 @@ static void subsys_delete_adapter(struct hpi_message *phm,
struct hpi_adapter_obj *pao; struct hpi_adapter_obj *pao;
struct hpi_hw_obj *phw; struct hpi_hw_obj *phw;
pao = hpi_find_adapter(phm->adapter_index); pao = hpi_find_adapter(phm->obj_index);
if (!pao) { if (!pao) {
phr->error = HPI_ERROR_INVALID_OBJ_INDEX; phr->error = HPI_ERROR_INVALID_OBJ_INDEX;
return; return;
@ -526,6 +509,7 @@ static void subsys_delete_adapter(struct hpi_message *phm,
iowrite32(C6205_HDCR_WARMRESET, phw->prHDCR); iowrite32(C6205_HDCR_WARMRESET, phw->prHDCR);
delete_adapter_obj(pao); delete_adapter_obj(pao);
hpi_delete_adapter(pao);
phr->error = 0; 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, if (hpios_locked_mem_alloc(&phw->h_locked_mem,
sizeof(struct bus_master_interface), sizeof(struct bus_master_interface),
pao->pci.p_os_data)) pao->pci.pci_dev))
phw->p_interface_buffer = NULL; phw->p_interface_buffer = NULL;
else if (hpios_locked_mem_get_virt_addr(&phw->h_locked_mem, else if (hpios_locked_mem_get_virt_addr(&phw->h_locked_mem,
(void *)&phw->p_interface_buffer)) (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 */ /* allow boot load even if mem alloc wont work */
if (!phw->p_interface_buffer) if (!phw->p_interface_buffer)
return hpi6205_error(0, HPI_ERROR_MEMORY_ALLOC); return HPI_ERROR_MEMORY_ALLOC;
interface = phw->p_interface_buffer; interface = phw->p_interface_buffer;
@ -604,12 +588,12 @@ static u16 create_adapter_obj(struct hpi_adapter_obj *pao,
if (temp1 & C6205_HSR_INTSRC) if (temp1 & C6205_HSR_INTSRC)
HPI_DEBUG_LOG(INFO, HPI_DEBUG_LOG(INFO,
"interrupt confirming DSP code running OK\n"); "Interrupt confirming DSP code running OK\n");
else { else {
HPI_DEBUG_LOG(ERROR, HPI_DEBUG_LOG(ERROR,
"timed out waiting for interrupt " "Timed out waiting for interrupt "
"confirming DSP code running\n"); "confirming DSP code running\n");
return hpi6205_error(0, HPI6205_ERROR_6205_NO_IRQ); return HPI6205_ERROR_6205_NO_IRQ;
} }
/* reset the interrupt */ /* reset the interrupt */
@ -619,21 +603,22 @@ static u16 create_adapter_obj(struct hpi_adapter_obj *pao,
/* make sure the DSP has started ok */ /* make sure the DSP has started ok */
if (!wait_dsp_ack(phw, H620_HIF_RESET, HPI6205_TIMEOUT * 10)) { if (!wait_dsp_ack(phw, H620_HIF_RESET, HPI6205_TIMEOUT * 10)) {
HPI_DEBUG_LOG(ERROR, "timed out waiting reset state \n"); 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, /* Note that *pao, *phw are zeroed after allocation,
* so pointers and flags are NULL by default. * so pointers and flags are NULL by default.
* Allocate bus mastering control cache buffer and tell the DSP about it * Allocate bus mastering control cache buffer and tell the DSP about it
*/ */
if (interface->control_cache.number_of_controls) { 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, err = hpios_locked_mem_alloc(&phw->h_control_cache,
interface->control_cache.size_in_bytes, interface->control_cache.size_in_bytes,
pao->pci.p_os_data); pao->pci.pci_dev);
if (!err) if (!err)
err = hpios_locked_mem_get_virt_addr(&phw-> 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) { if (!err) {
memset(p_control_cache_virtual, 0, memset(p_control_cache_virtual, 0,
interface->control_cache.size_in_bytes); 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-> hpi_alloc_control_cache(interface->
control_cache.number_of_controls, control_cache.number_of_controls,
interface->control_cache.size_in_bytes, interface->control_cache.size_in_bytes,
(struct hpi_control_cache_info *)
p_control_cache_virtual); p_control_cache_virtual);
if (!phw->p_cache) if (!phw->p_cache)
err = HPI_ERROR_MEMORY_ALLOC; 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) { if (interface->async_buffer.b.size) {
err = hpios_locked_mem_alloc(&phw->h_async_event_buffer, err = hpios_locked_mem_alloc(&phw->h_async_event_buffer,
interface->async_buffer.b.size * 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) if (!err)
err = hpios_locked_mem_get_virt_addr err = hpios_locked_mem_get_virt_addr
(&phw->h_async_event_buffer, (void *) (&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); send_dsp_command(phw, H620_HIF_IDLE);
{ {
struct hpi_message hM; struct hpi_message hm;
struct hpi_response hR; struct hpi_response hr;
u32 max_streams; u32 max_streams;
HPI_DEBUG_LOG(VERBOSE, "init ADAPTER_GET_INFO\n"); HPI_DEBUG_LOG(VERBOSE, "init ADAPTER_GET_INFO\n");
memset(&hM, 0, sizeof(hM)); memset(&hm, 0, sizeof(hm));
hM.type = HPI_TYPE_MESSAGE; hm.type = HPI_TYPE_MESSAGE;
hM.size = sizeof(hM); hm.size = sizeof(hm);
hM.object = HPI_OBJ_ADAPTER; hm.object = HPI_OBJ_ADAPTER;
hM.function = HPI_ADAPTER_GET_INFO; hm.function = HPI_ADAPTER_GET_INFO;
hM.adapter_index = 0; hm.adapter_index = 0;
memset(&hR, 0, sizeof(hR)); memset(&hr, 0, sizeof(hr));
hR.size = sizeof(hR); hr.size = sizeof(hr);
err = message_response_sequence(pao, &hM, &hR); err = message_response_sequence(pao, &hm, &hr);
if (err) { if (err) {
HPI_DEBUG_LOG(ERROR, "message transport error %d\n", HPI_DEBUG_LOG(ERROR, "message transport error %d\n",
err); err);
return err; return err;
} }
if (hR.error) if (hr.error)
return hR.error; return hr.error;
pao->adapter_type = hR.u.a.adapter_type; pao->adapter_type = hr.u.ax.info.adapter_type;
pao->index = hR.u.a.adapter_index; 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, 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, HPI_DEBUG_LOG(VERBOSE,
"got adapter info type %x index %d serial %d\n", "got adapter info type %x index %d serial %d\n",
hR.u.a.adapter_type, hR.u.a.adapter_index, hr.u.ax.info.adapter_type, hr.u.ax.info.adapter_index,
hR.u.a.serial_number); hr.u.ax.info.serial_number);
} }
pao->open = 0; /* upon creation the adapter is closed */ pao->open = 0; /* upon creation the adapter is closed */
HPI_DEBUG_LOG(INFO, "bootload DSP OK\n"); HPI_DEBUG_LOG(INFO, "bootload DSP OK\n");
return 0;
return hpi_add_adapter(pao);
} }
/** Free memory areas allocated by adapter /** 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; 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); 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 err = hpios_locked_mem_alloc(&phw->outstream_host_buffers
[phm->obj_index], phm->u.d.u.buffer.buffer_size, [phm->obj_index], phm->u.d.u.buffer.buffer_size,
pao->pci.p_os_data); pao->pci.pci_dev);
if (err) { if (err) {
phr->error = HPI_ERROR_INVALID_DATASIZE; 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. if (phm->u.d.u.buffer.buffer_size & (phm->u.d.u.buffer.
buffer_size - 1)) { buffer_size - 1)) {
HPI_DEBUG_LOG(ERROR, 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); phm->u.d.u.buffer.buffer_size);
phr->error = HPI_ERROR_INVALID_DATASIZE; phr->error = HPI_ERROR_INVALID_DATASIZE;
return; return;
@ -966,51 +952,6 @@ static void outstream_write(struct hpi_adapter_obj *pao,
hpi_init_response(phr, phm->object, phm->function, 0); hpi_init_response(phr, phm->object, phm->function, 0);
status = &interface->outstream_host_buffer_status[phm->obj_index]; 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); space_available = outstream_get_space_available(status);
if (space_available < phm->u.d.u.data.data_size) { if (space_available < phm->u.d.u.data.data_size) {
phr->error = HPI_ERROR_INVALID_DATASIZE; 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, memcpy(p_bbm_data, p_app_data + l_first_write,
phm->u.d.u.data.data_size - 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; 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-> err = hpios_locked_mem_alloc(&phw->instream_host_buffers[phm->
obj_index], phm->u.d.u.buffer.buffer_size, obj_index], phm->u.d.u.buffer.buffer_size,
pao->pci.p_os_data); pao->pci.pci_dev);
if (err) { if (err) {
phr->error = HPI_ERROR_INVALID_DATASIZE; 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. if (phm->u.d.u.buffer.buffer_size & (phm->u.d.u.buffer.
buffer_size - 1)) { buffer_size - 1)) {
HPI_DEBUG_LOG(ERROR, 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); phm->u.d.u.buffer.buffer_size);
phr->error = HPI_ERROR_INVALID_DATASIZE; phr->error = HPI_ERROR_INVALID_DATASIZE;
return; return;
@ -1344,7 +1303,7 @@ static u16 adapter_boot_load_dsp(struct hpi_adapter_obj *pao,
struct hpi_hw_obj *phw = pao->priv; struct hpi_hw_obj *phw = pao->priv;
struct dsp_code dsp_code; struct dsp_code dsp_code;
u16 boot_code_id[HPI6205_MAX_FILES_TO_LOAD]; 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; u32 temp;
int dsp = 0, i = 0; int dsp = 0, i = 0;
u16 err = 0; u16 err = 0;
@ -1381,7 +1340,7 @@ static u16 adapter_boot_load_dsp(struct hpi_adapter_obj *pao,
temp = ioread32(phw->prHSR); temp = ioread32(phw->prHSR);
if ((temp & (C6205_HSR_CFGERR | C6205_HSR_EEREAD)) != if ((temp & (C6205_HSR_CFGERR | C6205_HSR_EEREAD)) !=
C6205_HSR_EEREAD) C6205_HSR_EEREAD)
return hpi6205_error(0, HPI6205_ERROR_6205_EEPROM); return HPI6205_ERROR_6205_EEPROM;
temp |= 0x04; temp |= 0x04;
/* disable PINTA interrupt */ /* disable PINTA interrupt */
iowrite32(temp, phw->prHSR); 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 */ /* check control register reports PCI boot mode */
temp = ioread32(phw->prHDCR); temp = ioread32(phw->prHDCR);
if (!(temp & C6205_HDCR_PCIBOOT)) 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. */ /* 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; temp = 3;
iowrite32(temp, phw->prDSPP); iowrite32(temp, phw->prDSPP);
if ((temp | C6205_DSPP_MAP1) != ioread32(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 */ /* reset DSP page to the correct number */
temp = 0; temp = 0;
iowrite32(temp, phw->prDSPP); iowrite32(temp, phw->prDSPP);
if ((temp | C6205_DSPP_MAP1) != ioread32(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; phw->dsp_page = 0;
/* release 6713 from reset before 6205 is bootloaded. /* 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; return err;
/* write the DSP code down into the DSPs memory */ /* 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, err = hpi_dsp_code_open(boot_code_id[dsp], &dsp_code,
pos_error_code); pos_error_code);
if (err) if (err)
@ -1484,10 +1443,8 @@ static u16 adapter_boot_load_dsp(struct hpi_adapter_obj *pao,
if (err) if (err)
break; break;
for (i = 0; i < (int)length; i++) { for (i = 0; i < (int)length; i++) {
err = boot_loader_write_mem32(pao, dsp, boot_loader_write_mem32(pao, dsp, address,
address, *pcode); *pcode);
if (err)
break;
/* dummy read every 4 words */ /* dummy read every 4 words */
/* for 6205 advisory 1.4.4 */ /* for 6205 advisory 1.4.4 */
if (i % 4 == 0) 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; host_mailbox_address_on_dsp = 0x80000000;
while ((physicalPC_iaddress != physicalPC_iaddress_verify) while ((physicalPC_iaddress != physicalPC_iaddress_verify)
&& time_out--) { && time_out--) {
err = boot_loader_write_mem32(pao, 0, boot_loader_write_mem32(pao, 0,
host_mailbox_address_on_dsp, host_mailbox_address_on_dsp,
physicalPC_iaddress); physicalPC_iaddress);
physicalPC_iaddress_verify = physicalPC_iaddress_verify =
@ -1631,11 +1588,10 @@ static u32 boot_loader_read_mem32(struct hpi_adapter_obj *pao, int dsp_index,
return data; return data;
} }
static u16 boot_loader_write_mem32(struct hpi_adapter_obj *pao, int dsp_index, static void boot_loader_write_mem32(struct hpi_adapter_obj *pao,
u32 address, u32 data) int dsp_index, u32 address, u32 data)
{ {
struct hpi_hw_obj *phw = pao->priv; struct hpi_hw_obj *phw = pao->priv;
u16 err = 0;
__iomem u32 *p_data; __iomem u32 *p_data;
/* u32 dwVerifyData=0; */ /* 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 */ /* dummy read every 4 words for 6205 advisory 1.4.4 */
boot_loader_read_mem32(pao, 0, 0); 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) static u16 boot_loader_config_emif(struct hpi_adapter_obj *pao, int dsp_index)
{ {
u16 err = 0;
if (dsp_index == 0) { if (dsp_index == 0) {
u32 setting; 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); boot_loader_write_mem32(pao, dsp_index, 0x01800008, setting);
if (setting != boot_loader_read_mem32(pao, dsp_index, if (setting != boot_loader_read_mem32(pao, dsp_index,
0x01800008)) 0x01800008))
return hpi6205_error(dsp_index, return HPI6205_ERROR_DSP_EMIF;
HPI6205_ERROR_DSP_EMIF);
/* EMIF CE1 setup - 32 bit async. This is 6713 #1 HPI, */ /* EMIF CE1 setup - 32 bit async. This is 6713 #1 HPI, */
/* which occupies D15..0. 6713 starts at 27MHz, so need */ /* 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); boot_loader_write_mem32(pao, dsp_index, 0x01800004, setting);
if (setting != boot_loader_read_mem32(pao, dsp_index, if (setting != boot_loader_read_mem32(pao, dsp_index,
0x01800004)) 0x01800004))
return hpi6205_error(dsp_index, return HPI6205_ERROR_DSP_EMIF;
HPI6205_ERROR_DSP_EMIF);
/* EMIF CE2 setup - 32 bit async. This is 6713 #2 HPI, */ /* EMIF CE2 setup - 32 bit async. This is 6713 #2 HPI, */
/* which occupies D15..0. 6713 starts at 27MHz, so need */ /* 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); boot_loader_write_mem32(pao, dsp_index, 0x01800010, setting);
if (setting != boot_loader_read_mem32(pao, dsp_index, if (setting != boot_loader_read_mem32(pao, dsp_index,
0x01800010)) 0x01800010))
return hpi6205_error(dsp_index, return HPI6205_ERROR_DSP_EMIF;
HPI6205_ERROR_DSP_EMIF);
/* EMIF CE3 setup - 32 bit async. */ /* EMIF CE3 setup - 32 bit async. */
/* This is the PLD on the ASI5000 cards only */ /* 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); boot_loader_write_mem32(pao, dsp_index, 0x01800014, setting);
if (setting != boot_loader_read_mem32(pao, dsp_index, if (setting != boot_loader_read_mem32(pao, dsp_index,
0x01800014)) 0x01800014))
return hpi6205_error(dsp_index, return HPI6205_ERROR_DSP_EMIF;
HPI6205_ERROR_DSP_EMIF);
/* set EMIF SDRAM control for 2Mx32 SDRAM (512x32x4 bank) */ /* set EMIF SDRAM control for 2Mx32 SDRAM (512x32x4 bank) */
/* need to use this else DSP code crashes? */ /* 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 = read_data =
0xFFF7 & boot_loader_read_mem32(pao, 0, HPICL_ADDR); 0xFFF7 & boot_loader_read_mem32(pao, 0, HPICL_ADDR);
if (write_data != read_data) { if (write_data != read_data) {
err = hpi6205_error(dsp_index,
HPI6205_ERROR_C6713_HPIC);
HPI_DEBUG_LOG(ERROR, "HPICL %x %x\n", write_data, HPI_DEBUG_LOG(ERROR, "HPICL %x %x\n", write_data,
read_data); read_data);
return HPI6205_ERROR_C6713_HPIC;
return err;
} }
/* HPIA - walking ones test */ /* HPIA - walking ones test */
write_data = 1; write_data = 1;
@ -1798,11 +1743,9 @@ static u16 boot_loader_config_emif(struct hpi_adapter_obj *pao, int dsp_index)
HPIAH_ADDR)) HPIAH_ADDR))
<< 16); << 16);
if (read_data != write_data) { if (read_data != write_data) {
err = hpi6205_error(dsp_index,
HPI6205_ERROR_C6713_HPIA);
HPI_DEBUG_LOG(ERROR, "HPIA %x %x\n", HPI_DEBUG_LOG(ERROR, "HPIA %x %x\n",
write_data, read_data); write_data, read_data);
return err; return HPI6205_ERROR_C6713_HPIA;
} }
write_data = write_data << 1; 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! */ /* PLL should not be bypassed! */
if ((boot_loader_read_mem32(pao, dsp_index, 0x01B7C100) & 0xF) if ((boot_loader_read_mem32(pao, dsp_index, 0x01B7C100) & 0xF)
!= 0x0001) { != 0x0001) {
err = hpi6205_error(dsp_index, return HPI6205_ERROR_C6713_PLL;
HPI6205_ERROR_C6713_PLL);
return err;
} }
/* setup C67x EMIF (note this is the only use of /* setup C67x EMIF (note this is the only use of
BAR1 via BootLoader_WriteMem32) */ 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); hpios_delay_micro_seconds(1000);
} else if (dsp_index == 2) { } else if (dsp_index == 2) {
/* DSP 2 is a C6713 */ /* DSP 2 is a C6713 */
}
} else return 0;
err = hpi6205_error(dsp_index, HPI6205_ERROR_BAD_DSPINDEX);
return err;
} }
static u16 boot_loader_test_memory(struct hpi_adapter_obj *pao, int dsp_index, 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); test_addr);
if (data != test_data) { if (data != test_data) {
HPI_DEBUG_LOG(VERBOSE, HPI_DEBUG_LOG(VERBOSE,
"memtest error details " "Memtest error details "
"%08x %08x %08x %i\n", test_addr, "%08x %08x %08x %i\n", test_addr,
test_data, data, dsp_index); test_data, data, dsp_index);
return 1; /* error */ 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); data = boot_loader_read_mem32(pao, dsp_index, test_addr);
if (data != test_data) { if (data != test_data) {
HPI_DEBUG_LOG(VERBOSE, HPI_DEBUG_LOG(VERBOSE,
"memtest error details " "Memtest error details "
"%08x %08x %08x %i\n", test_addr, test_data, "%08x %08x %08x %i\n", test_addr, test_data,
data, dsp_index); data, dsp_index);
return 1; /* error */ return 1; /* error */
@ -1946,8 +1886,8 @@ static u16 boot_loader_test_internal_memory(struct hpi_adapter_obj *pao,
/* 64K data mem */ /* 64K data mem */
err = boot_loader_test_memory(pao, dsp_index, err = boot_loader_test_memory(pao, dsp_index,
0x80000000, 0x10000); 0x80000000, 0x10000);
} else if ((dsp_index == 1) || (dsp_index == 2)) { } else if (dsp_index == 1) {
/* DSP 1&2 are a C6713 */ /* DSP 1 is a C6713 */
/* 192K internal mem */ /* 192K internal mem */
err = boot_loader_test_memory(pao, dsp_index, 0x00000000, err = boot_loader_test_memory(pao, dsp_index, 0x00000000,
0x30000); 0x30000);
@ -1955,11 +1895,10 @@ static u16 boot_loader_test_internal_memory(struct hpi_adapter_obj *pao,
/* 64K internal mem / L2 cache */ /* 64K internal mem / L2 cache */
err = boot_loader_test_memory(pao, dsp_index, err = boot_loader_test_memory(pao, dsp_index,
0x00030000, 0x10000); 0x00030000, 0x10000);
} else }
return hpi6205_error(dsp_index, HPI6205_ERROR_BAD_DSPINDEX);
if (err) if (err)
return hpi6205_error(dsp_index, HPI6205_ERROR_DSP_INTMEM); return HPI6205_ERROR_DSP_INTMEM;
else else
return 0; return 0;
} }
@ -1972,24 +1911,23 @@ static u16 boot_loader_test_external_memory(struct hpi_adapter_obj *pao,
if (dsp_index == 0) { if (dsp_index == 0) {
/* only test for SDRAM if an ASI5000 card */ /* 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 */ /* DSP 0 is always C6205 */
dRAM_start_address = 0x00400000; dRAM_start_address = 0x00400000;
dRAM_size = 0x200000; dRAM_size = 0x200000;
/*dwDRAMinc=1024; */ /*dwDRAMinc=1024; */
} else } else
return 0; return 0;
} else if ((dsp_index == 1) || (dsp_index == 2)) { } else if (dsp_index == 1) {
/* DSP 1 is a C6713 */ /* DSP 1 is a C6713 */
dRAM_start_address = 0x80000000; dRAM_start_address = 0x80000000;
dRAM_size = 0x200000; dRAM_size = 0x200000;
/*dwDRAMinc=1024; */ /*dwDRAMinc=1024; */
} else }
return hpi6205_error(dsp_index, HPI6205_ERROR_BAD_DSPINDEX);
if (boot_loader_test_memory(pao, dsp_index, dRAM_start_address, if (boot_loader_test_memory(pao, dsp_index, dRAM_start_address,
dRAM_size)) dRAM_size))
return hpi6205_error(dsp_index, HPI6205_ERROR_DSP_EXTMEM); return HPI6205_ERROR_DSP_EXTMEM;
return 0; return 0;
} }
@ -1998,28 +1936,25 @@ static u16 boot_loader_test_pld(struct hpi_adapter_obj *pao, int dsp_index)
u32 data = 0; u32 data = 0;
if (dsp_index == 0) { if (dsp_index == 0) {
/* only test for DSP0 PLD on ASI5000 card */ /* 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 */ /* PLD is located at CE3=0x03000000 */
data = boot_loader_read_mem32(pao, dsp_index, data = boot_loader_read_mem32(pao, dsp_index,
0x03000008); 0x03000008);
if ((data & 0xF) != 0x5) if ((data & 0xF) != 0x5)
return hpi6205_error(dsp_index, return HPI6205_ERROR_DSP_PLD;
HPI6205_ERROR_DSP_PLD);
data = boot_loader_read_mem32(pao, dsp_index, data = boot_loader_read_mem32(pao, dsp_index,
0x0300000C); 0x0300000C);
if ((data & 0xF) != 0xA) if ((data & 0xF) != 0xA)
return hpi6205_error(dsp_index, return HPI6205_ERROR_DSP_PLD;
HPI6205_ERROR_DSP_PLD);
} }
} else if (dsp_index == 1) { } else if (dsp_index == 1) {
/* DSP 1 is a C6713 */ /* 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 */ /* PLD is located at CE1=0x90000000 */
data = boot_loader_read_mem32(pao, dsp_index, data = boot_loader_read_mem32(pao, dsp_index,
0x90000010); 0x90000010);
if ((data & 0xFF) != 0xAA) if ((data & 0xFF) != 0xAA)
return hpi6205_error(dsp_index, return HPI6205_ERROR_DSP_PLD;
HPI6205_ERROR_DSP_PLD);
/* 8713 - LED on */ /* 8713 - LED on */
boot_loader_write_mem32(pao, dsp_index, 0x90000000, boot_loader_write_mem32(pao, dsp_index, 0x90000000,
0x02); 0x02);
@ -2079,7 +2014,7 @@ static short hpi6205_transfer_data(struct hpi_adapter_obj *pao, u8 *p_data,
if (!temp2) { if (!temp2) {
/* timed out */ /* timed out */
HPI_DEBUG_LOG(ERROR, 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); operation, interface->dsp_ack);
break; break;
@ -2099,7 +2034,7 @@ static short hpi6205_transfer_data(struct hpi_adapter_obj *pao, u8 *p_data,
HPI6205_TIMEOUT - time_out, this_copy); HPI6205_TIMEOUT - time_out, this_copy);
if (temp2 == C6205_HSR_INTSRC) { if (temp2 == C6205_HSR_INTSRC) {
HPI_DEBUG_LOG(VERBOSE, HPI_DEBUG_LOG(VERBOSE,
"interrupt from HIF <data> OK\n"); "Interrupt from HIF <data> OK\n");
/* /*
if(interface->dwDspAck != nOperation) { if(interface->dwDspAck != nOperation) {
HPI_DEBUG_LOG(DEBUG("interface->dwDspAck=%d, 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... */ /* need to handle this differently... */
else { else {
HPI_DEBUG_LOG(ERROR, HPI_DEBUG_LOG(ERROR,
"interrupt from HIF <data> BAD\n"); "Interrupt from HIF <data> BAD\n");
err = HPI_ERROR_DSP_HARDWARE; err = HPI_ERROR_DSP_HARDWARE;
} }
@ -2183,22 +2118,34 @@ static u16 message_response_sequence(struct hpi_adapter_obj *pao,
u16 err = 0; u16 err = 0;
message_count++; 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 /* Assume buffer of type struct bus_master_interface
is allocated "noncacheable" */ is allocated "noncacheable" */
if (!wait_dsp_ack(phw, H620_HIF_IDLE, HPI6205_TIMEOUT)) { if (!wait_dsp_ack(phw, H620_HIF_IDLE, HPI6205_TIMEOUT)) {
HPI_DEBUG_LOG(DEBUG, "timeout waiting for idle\n"); 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 */ /* signal we want a response */
send_dsp_command(phw, H620_HIF_GET_RESP); send_dsp_command(phw, H620_HIF_GET_RESP);
time_out2 = wait_dsp_ack(phw, H620_HIF_GET_RESP, HPI6205_TIMEOUT); time_out2 = wait_dsp_ack(phw, H620_HIF_GET_RESP, HPI6205_TIMEOUT);
if (time_out2 == 0) { if (!time_out2) {
HPI_DEBUG_LOG(ERROR, 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); message_count, interface->dsp_ack);
} else { } else {
HPI_DEBUG_LOG(VERBOSE, HPI_DEBUG_LOG(VERBOSE,
@ -2232,7 +2179,7 @@ static u16 message_response_sequence(struct hpi_adapter_obj *pao,
} else { } else {
/* can we do anything else in response to the error ? */ /* can we do anything else in response to the error ? */
HPI_DEBUG_LOG(ERROR, HPI_DEBUG_LOG(ERROR,
"interrupt from HIF module BAD (function %x)\n", "Interrupt from HIF module BAD (function %x)\n",
phm->function); phm->function);
} }
@ -2241,25 +2188,37 @@ static u16 message_response_sequence(struct hpi_adapter_obj *pao,
#endif #endif
/* read the result */ /* read the result */
if (time_out != 0) if (time_out) {
*phr = interface->u.response_buffer; 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 */ /* set interface back to idle */
send_dsp_command(phw, H620_HIF_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"); 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 - */ /* special case for adapter close - */
/* wait for the DSP to indicate it is idle */ /* wait for the DSP to indicate it is idle */
if (phm->function == HPI_ADAPTER_CLOSE) { if (phm->function == HPI_ADAPTER_CLOSE) {
if (!wait_dsp_ack(phw, H620_HIF_IDLE, HPI6205_TIMEOUT)) { if (!wait_dsp_ack(phw, H620_HIF_IDLE, HPI6205_TIMEOUT)) {
HPI_DEBUG_LOG(DEBUG, HPI_DEBUG_LOG(DEBUG,
"timeout waiting for idle " "Timeout waiting for idle "
"(on adapter_close)\n"); "(on adapter_close)\n");
return hpi6205_error(0, return HPI6205_ERROR_MSG_RESP_IDLE_TIMEOUT;
HPI6205_ERROR_MSG_RESP_IDLE_TIMEOUT);
} }
} }
err = hpi_validate_response(phm, phr); err = hpi_validate_response(phm, phr);

View file

@ -78,8 +78,8 @@ struct bus_master_interface {
u32 dsp_ack; u32 dsp_ack;
u32 transfer_size_in_bytes; u32 transfer_size_in_bytes;
union { union {
struct hpi_message message_buffer; struct hpi_message_header message_buffer;
struct hpi_response response_buffer; struct hpi_response_header response_buffer;
u8 b_data[HPI6205_SIZEOF_DATA]; u8 b_data[HPI6205_SIZEOF_DATA];
} u; } u;
struct controlcache_6205 control_cache; 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 "hpi_internal.h"
#include "hpidebug.h" #include "hpidebug.h"
#include "hpimsginit.h"
#include "hpicmn.h" #include "hpicmn.h"
struct hpi_adapters_list { 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 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) if (phr->object != phm->object) {
|| (phr->object != phm->object) HPI_DEBUG_LOG(ERROR, "header object %d invalid", phr->object);
|| (phr->function != phm->function)) return HPI_ERROR_INVALID_RESPONSE;
error = 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) 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++; adapters.gw_num_adapters++;
unlock: unlock:
hpios_alistlock_un_lock(&adapters); hpios_alistlock_unlock(&adapters);
return retval; return retval;
} }
void hpi_delete_adapter(struct hpi_adapter_obj *pao) 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); hpios_alistlock_lock(&adapters);
adapters.gw_num_adapters--; /* dec the number of adapters */ if (adapters.adapter[pao->index].adapter_type)
hpios_alistlock_un_lock(&adapters); 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. * wipe an HPI_ADAPTERS_LIST structure.
* *
**/ **/
static void wipe_adapter_list(void static void wipe_adapter_list(void)
)
{ {
memset(&adapters, 0, sizeof(adapters)); memset(&adapters, 0, sizeof(adapters));
} }
/** static void subsys_get_adapter(struct hpi_message *phm,
* SubSysGetAdapters fills awAdapterList in an struct hpi_response structure struct hpi_response *phr)
* with all adapters in the given HPI_ADAPTERS_LIST.
*
*/
static void subsys_get_adapters(struct hpi_response *phr)
{ {
/* fill in the response adapter array with the position */ int count = phm->obj_index;
/* identified by the adapter number/index of the adapters in */ u16 index = 0;
/* 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 */
/* input: NONE */ /* find the nCount'th nonzero adapter in array */
/* output: wNumAdapters */ for (index = 0; index < HPI_MAX_ADAPTERS; index++) {
/* awAdapter[] */ if (adapters.adapter[index].adapter_type) {
/* */ if (count == 0)
break;
short i; count--;
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;
} }
phr->u.s.aw_adapter_list[pao->index] = pao->adapter_type;
} }
phr->u.s.num_adapters = adapters.gw_num_adapters; if (index < HPI_MAX_ADAPTERS) {
phr->error = 0; /* the function completed OK; */ 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) 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; int cached = 0;
if (!pC) if (!pC)
return 0; 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; if (pC->init)
HPI_DEBUG_LOG(VERBOSE, "check %d controls\n", 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); pC->control_count);
for (i = 0; i < pC->control_count; i++) { for (i = 0; i < pC->control_count; i++) {
struct hpi_control_cache_info *info = struct hpi_control_cache_info *info =
(struct hpi_control_cache_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) { if (info->control_type) {
pC->p_info[i] = info; pC->p_info[info->control_index] = info;
cached++; cached++;
} else } else /* dummy cache entry */
pC->p_info[i] = NULL; pC->p_info[info->control_index] = NULL;
if (info->size_in32bit_words) byte_count += info->size_in32bit_words * 4;
p_master_cache += info->size_in32bit_words;
else
p_master_cache +=
sizeof(struct
hpi_control_cache_single) /
sizeof(u32);
HPI_DEBUG_LOG(VERBOSE, HPI_DEBUG_LOG(VERBOSE,
"cached %d, pinfo %p index %d type %d\n", "cached %d, pinfo %p index %d type %d size %d\n",
cached, pC->p_info[i], info->control_index, cached, pC->p_info[info->control_index],
info->control_type); 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 (byte_count != pC->cache_size_in_bytes)
*/ HPI_DEBUG_LOG(WARNING,
if (!cached) "bytecount %d != cache size %d", byte_count,
pC->init = 0; pC->cache_size_in_bytes);
else
HPI_DEBUG_LOG(DEBUG,
"cache good. bytecount == cache size = %d",
byte_count);
pC->init = cached;
} }
return pC->init; return pC->init;
} }
/** Find a control. /** Find a control.
*/ */
static short find_control(struct hpi_message *phm, static short find_control(u16 control_index,
struct hpi_control_cache *p_cache, struct hpi_control_cache_info **pI, struct hpi_control_cache *p_cache, struct hpi_control_cache_info **pI)
u16 *pw_control_index)
{ {
*pw_control_index = phm->obj_index;
if (!control_cache_alloc_check(p_cache)) { if (!control_cache_alloc_check(p_cache)) {
HPI_DEBUG_LOG(VERBOSE, HPI_DEBUG_LOG(VERBOSE,
"control_cache_alloc_check() failed. adap%d ci%d\n", "control_cache_alloc_check() failed %d\n",
phm->adapter_index, *pw_control_index); control_index);
return 0; return 0;
} }
*pI = p_cache->p_info[*pw_control_index]; *pI = p_cache->p_info[control_index];
if (!*pI) { if (!*pI) {
HPI_DEBUG_LOG(VERBOSE, "uncached adap %d, control %d\n", HPI_DEBUG_LOG(VERBOSE, "Uncached Control %d\n",
phm->adapter_index, *pw_control_index); control_index);
return 0; return 0;
} else { } else {
HPI_DEBUG_LOG(VERBOSE, "find_control() type %d\n", HPI_DEBUG_LOG(VERBOSE, "find_control() type %d\n",
@ -257,12 +277,15 @@ short hpi_check_buffer_mapping(struct hpi_control_cache *p_cache,
if ((phm->function == HPI_CONTROL_GET_STATE) if ((phm->function == HPI_CONTROL_GET_STATE)
&& (phm->object == HPI_OBJ_CONTROLEX) && (phm->object == HPI_OBJ_CONTROLEX)
) { ) {
u16 control_index;
struct hpi_control_cache_info *pI; 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;
} }
}
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) struct hpi_message *phm, struct hpi_response *phr)
{ {
short found = 1; short found = 1;
u16 control_index;
struct hpi_control_cache_info *pI; struct hpi_control_cache_info *pI;
struct hpi_control_cache_single *pC; struct hpi_control_cache_single *pC;
struct hpi_control_cache_pad *p_pad; 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; return 0;
}
phr->error = 0; phr->error = 0;
@ -310,55 +336,66 @@ short hpi_check_control_cache(struct hpi_control_cache *p_cache,
case HPI_CONTROL_METER: case HPI_CONTROL_METER:
if (phm->u.c.attribute == HPI_METER_PEAK) { 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[0] = pC->u.meter.an_log_peak[0];
phr->u.c.an_log_value[1] = pC->u.p.an_log_peak[1]; phr->u.c.an_log_value[1] = pC->u.meter.an_log_peak[1];
} else if (phm->u.c.attribute == HPI_METER_RMS) { } else if (phm->u.c.attribute == HPI_METER_RMS) {
phr->u.c.an_log_value[0] = pC->u.p.an_logRMS[0]; if (pC->u.meter.an_logRMS[0] ==
phr->u.c.an_log_value[1] = pC->u.p.an_logRMS[1]; 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 } else
found = 0; found = 0;
break; break;
case HPI_CONTROL_VOLUME: case HPI_CONTROL_VOLUME:
if (phm->u.c.attribute == HPI_VOLUME_GAIN) { 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[0] = pC->u.vol.an_log[0];
phr->u.c.an_log_value[1] = pC->u.v.an_log[1]; phr->u.c.an_log_value[1] = pC->u.vol.an_log[1];
} else } else
found = 0; found = 0;
break; break;
case HPI_CONTROL_MULTIPLEXER: case HPI_CONTROL_MULTIPLEXER:
if (phm->u.c.attribute == HPI_MULTIPLEXER_SOURCE) { if (phm->u.c.attribute == HPI_MULTIPLEXER_SOURCE) {
phr->u.c.param1 = pC->u.x.source_node_type; phr->u.c.param1 = pC->u.mux.source_node_type;
phr->u.c.param2 = pC->u.x.source_node_index; phr->u.c.param2 = pC->u.mux.source_node_index;
} else { } else {
found = 0; found = 0;
} }
break; break;
case HPI_CONTROL_CHANNEL_MODE: case HPI_CONTROL_CHANNEL_MODE:
if (phm->u.c.attribute == HPI_CHANNEL_MODE_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 else
found = 0; found = 0;
break; break;
case HPI_CONTROL_LEVEL: case HPI_CONTROL_LEVEL:
if (phm->u.c.attribute == HPI_LEVEL_GAIN) { 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[0] = pC->u.level.an_log[0];
phr->u.c.an_log_value[1] = pC->u.l.an_log[1]; phr->u.c.an_log_value[1] = pC->u.level.an_log[1];
} else } else
found = 0; found = 0;
break; break;
case HPI_CONTROL_TUNER: case HPI_CONTROL_TUNER:
if (phm->u.c.attribute == HPI_TUNER_FREQ) 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) else if (phm->u.c.attribute == HPI_TUNER_BAND)
phr->u.c.param1 = pC->u.t.band; phr->u.c.param1 = pC->u.tuner.band;
else if ((phm->u.c.attribute == HPI_TUNER_LEVEL) else if (phm->u.c.attribute == HPI_TUNER_LEVEL_AVG)
&& (phm->u.c.param1 == HPI_TUNER_LEVEL_AVERAGE)) if (pC->u.tuner.s_level_avg ==
if (pC->u.t.level == HPI_ERROR_ILLEGAL_CACHE_VALUE) { HPI_CACHE_INVALID_SHORT) {
phr->u.c.param1 = 0; phr->u.cu.tuner.s_level = 0;
phr->error = phr->error =
HPI_ERROR_INVALID_CONTROL_ATTRIBUTE; HPI_ERROR_INVALID_CONTROL_ATTRIBUTE;
} else } else
phr->u.c.param1 = pC->u.t.level; phr->u.cu.tuner.s_level =
pC->u.tuner.s_level_avg;
else else
found = 0; found = 0;
break; break;
@ -366,7 +403,7 @@ short hpi_check_control_cache(struct hpi_control_cache *p_cache,
if (phm->u.c.attribute == HPI_AESEBURX_ERRORSTATUS) if (phm->u.c.attribute == HPI_AESEBURX_ERRORSTATUS)
phr->u.c.param1 = pC->u.aes3rx.error_status; phr->u.c.param1 = pC->u.aes3rx.error_status;
else if (phm->u.c.attribute == HPI_AESEBURX_FORMAT) 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 else
found = 0; found = 0;
break; break;
@ -385,13 +422,13 @@ short hpi_check_control_cache(struct hpi_control_cache *p_cache,
case HPI_CONTROL_SILENCEDETECTOR: case HPI_CONTROL_SILENCEDETECTOR:
if (phm->u.c.attribute == HPI_SILENCEDETECTOR_STATE) { if (phm->u.c.attribute == HPI_SILENCEDETECTOR_STATE) {
phr->u.c.param1 = pC->u.silence.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 } else
found = 0; found = 0;
break; break;
case HPI_CONTROL_MICROPHONE: case HPI_CONTROL_MICROPHONE:
if (phm->u.c.attribute == HPI_MICROPHONE_PHANTOM_POWER) 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 else
found = 0; found = 0;
break; break;
@ -400,7 +437,7 @@ short hpi_check_control_cache(struct hpi_control_cache *p_cache,
phr->u.c.param1 = pC->u.clk.source; phr->u.c.param1 = pC->u.clk.source;
else if (phm->u.c.attribute == HPI_SAMPLECLOCK_SOURCE_INDEX) { else if (phm->u.c.attribute == HPI_SAMPLECLOCK_SOURCE_INDEX) {
if (pC->u.clk.source_index == if (pC->u.clk.source_index ==
HPI_ERROR_ILLEGAL_CACHE_VALUE) { HPI_CACHE_INVALID_UINT16) {
phr->u.c.param1 = 0; phr->u.c.param1 = 0;
phr->error = phr->error =
HPI_ERROR_INVALID_CONTROL_ATTRIBUTE; HPI_ERROR_INVALID_CONTROL_ATTRIBUTE;
@ -411,12 +448,15 @@ short hpi_check_control_cache(struct hpi_control_cache *p_cache,
else else
found = 0; found = 0;
break; 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 << if (!(p_pad->field_valid_flags & (1 <<
HPI_CTL_ATTR_INDEX(phm->u.c. HPI_CTL_ATTR_INDEX(phm->u.c.
attribute)))) { attribute)))) {
phr->error = HPI_ERROR_INVALID_CONTROL_ATTRIBUTE; phr->error =
HPI_ERROR_INVALID_CONTROL_ATTRIBUTE;
break; break;
} }
@ -426,22 +466,22 @@ short hpi_check_control_cache(struct hpi_control_cache *p_cache,
phr->u.c.param1 = p_pad->pTY; phr->u.c.param1 = p_pad->pTY;
else { else {
unsigned int index = unsigned int index =
HPI_CTL_ATTR_INDEX(phm->u.c.attribute) - 1; HPI_CTL_ATTR_INDEX(phm->u.c.
attribute) - 1;
unsigned int offset = phm->u.c.param1; unsigned int offset = phm->u.c.param1;
unsigned int pad_string_len, field_size; unsigned int pad_string_len, field_size;
char *pad_string; char *pad_string;
unsigned int tocopy; unsigned int tocopy;
HPI_DEBUG_LOG(VERBOSE, "PADS HPI_PADS_ %d\n",
phm->u.c.attribute);
if (index > ARRAY_SIZE(pad_desc) - 1) { if (index > ARRAY_SIZE(pad_desc) - 1) {
phr->error = phr->error =
HPI_ERROR_INVALID_CONTROL_ATTRIBUTE; HPI_ERROR_INVALID_CONTROL_ATTRIBUTE;
break; break;
} }
pad_string = ((char *)p_pad) + pad_desc[index].offset; pad_string =
((char *)p_pad) +
pad_desc[index].offset;
field_size = pad_desc[index].field_size; field_size = pad_desc[index].field_size;
/* Ensure null terminator */ /* Ensure null terminator */
pad_string[field_size - 1] = 0; pad_string[field_size - 1] = 0;
@ -449,39 +489,32 @@ short hpi_check_control_cache(struct hpi_control_cache *p_cache,
pad_string_len = strlen(pad_string) + 1; pad_string_len = strlen(pad_string) + 1;
if (offset > pad_string_len) { if (offset > pad_string_len) {
phr->error = HPI_ERROR_INVALID_CONTROL_VALUE; phr->error =
HPI_ERROR_INVALID_CONTROL_VALUE;
break; break;
} }
tocopy = pad_string_len - offset; tocopy = pad_string_len - offset;
if (tocopy > sizeof(phr->u.cu.chars8.sz_data)) if (tocopy > sizeof(phr->u.cu.chars8.sz_data))
tocopy = sizeof(phr->u.cu.chars8.sz_data); tocopy = sizeof(phr->u.cu.chars8.
sz_data);
HPI_DEBUG_LOG(VERBOSE, memcpy(phr->u.cu.chars8.sz_data,
"PADS memcpy(%d), offset %d \n", tocopy, &pad_string[offset], tocopy);
offset);
memcpy(phr->u.cu.chars8.sz_data, &pad_string[offset],
tocopy);
phr->u.cu.chars8.remaining_chars = phr->u.cu.chars8.remaining_chars =
pad_string_len - offset - tocopy; pad_string_len - offset - tocopy;
} }
}
break; break;
default: default:
found = 0; found = 0;
break; break;
} }
if (found) HPI_DEBUG_LOG(VERBOSE, "%s Adap %d, Ctl %d, Type %d, Attr %d\n",
HPI_DEBUG_LOG(VERBOSE, found ? "Cached" : "Uncached", phm->adapter_index,
"cached adap %d, ctl %d, type %d, attr %d\n", pI->control_index, pI->control_type, phm->u.c.attribute);
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);
if (found) if (found)
phr->size = phr->size =
@ -497,18 +530,21 @@ Only update if no error.
Volume and Level return the limited values in the response, so use these Volume and Level return the limited values in the response, so use these
Multiplexer does so use sent values 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) struct hpi_message *phm, struct hpi_response *phr)
{ {
u16 control_index;
struct hpi_control_cache_single *pC; struct hpi_control_cache_single *pC;
struct hpi_control_cache_info *pI; struct hpi_control_cache_info *pI;
if (phr->error) if (phr->error)
return; 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; return;
}
/* pC is the default cached control strucure. /* pC is the default cached control strucure.
May be cast to something else in the following switch statement. 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) { switch (pI->control_type) {
case HPI_CONTROL_VOLUME: case HPI_CONTROL_VOLUME:
if (phm->u.c.attribute == HPI_VOLUME_GAIN) { if (phm->u.c.attribute == HPI_VOLUME_GAIN) {
pC->u.v.an_log[0] = phr->u.c.an_log_value[0]; pC->u.vol.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[1] = phr->u.c.an_log_value[1];
} }
break; break;
case HPI_CONTROL_MULTIPLEXER: case HPI_CONTROL_MULTIPLEXER:
/* mux does not return its setting on Set command. */ /* mux does not return its setting on Set command. */
if (phm->u.c.attribute == HPI_MULTIPLEXER_SOURCE) { if (phm->u.c.attribute == HPI_MULTIPLEXER_SOURCE) {
pC->u.x.source_node_type = (u16)phm->u.c.param1; pC->u.mux.source_node_type = (u16)phm->u.c.param1;
pC->u.x.source_node_index = (u16)phm->u.c.param2; pC->u.mux.source_node_index = (u16)phm->u.c.param2;
} }
break; break;
case HPI_CONTROL_CHANNEL_MODE: case HPI_CONTROL_CHANNEL_MODE:
/* mode does not return its setting on Set command. */ /* mode does not return its setting on Set command. */
if (phm->u.c.attribute == HPI_CHANNEL_MODE_MODE) 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; break;
case HPI_CONTROL_LEVEL: case HPI_CONTROL_LEVEL:
if (phm->u.c.attribute == HPI_LEVEL_GAIN) { if (phm->u.c.attribute == HPI_LEVEL_GAIN) {
pC->u.v.an_log[0] = phr->u.c.an_log_value[0]; pC->u.vol.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[1] = phr->u.c.an_log_value[1];
} }
break; break;
case HPI_CONTROL_MICROPHONE: case HPI_CONTROL_MICROPHONE:
if (phm->u.c.attribute == HPI_MICROPHONE_PHANTOM_POWER) 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; break;
case HPI_CONTROL_AESEBU_TRANSMITTER: case HPI_CONTROL_AESEBU_TRANSMITTER:
if (phm->u.c.attribute == HPI_AESEBUTX_FORMAT) if (phm->u.c.attribute == HPI_AESEBUTX_FORMAT)
@ -550,7 +586,7 @@ void hpi_sync_control_cache(struct hpi_control_cache *p_cache,
break; break;
case HPI_CONTROL_AESEBU_RECEIVER: case HPI_CONTROL_AESEBU_RECEIVER:
if (phm->u.c.attribute == HPI_AESEBURX_FORMAT) 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; break;
case HPI_CONTROL_SAMPLECLOCK: case HPI_CONTROL_SAMPLECLOCK:
if (phm->u.c.attribute == HPI_SAMPLECLOCK_SOURCE) 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 struct hpi_control_cache *hpi_alloc_control_cache(const u32
number_of_controls, const u32 size_in_bytes, number_of_controls, const u32 size_in_bytes, u8 *pDSP_control_buffer)
struct hpi_control_cache_info *pDSP_control_buffer)
{ {
struct hpi_control_cache *p_cache = struct hpi_control_cache *p_cache =
kmalloc(sizeof(*p_cache), GFP_KERNEL); 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) void hpi_free_control_cache(struct hpi_control_cache *p_cache)
{ {
if (p_cache->init) { if (p_cache) {
kfree(p_cache->p_info); kfree(p_cache->p_info);
p_cache->p_info = NULL; p_cache->p_info = NULL;
p_cache->init = 0; 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) 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) { switch (phm->function) {
case HPI_SUBSYS_OPEN: case HPI_SUBSYS_OPEN:
case HPI_SUBSYS_CLOSE: case HPI_SUBSYS_CLOSE:
case HPI_SUBSYS_DRIVER_UNLOAD: case HPI_SUBSYS_DRIVER_UNLOAD:
phr->error = 0;
break; break;
case HPI_SUBSYS_DRIVER_LOAD: case HPI_SUBSYS_DRIVER_LOAD:
wipe_adapter_list(); wipe_adapter_list();
hpios_alistlock_init(&adapters); hpios_alistlock_init(&adapters);
phr->error = 0;
break; break;
case HPI_SUBSYS_GET_INFO: case HPI_SUBSYS_GET_ADAPTER:
subsys_get_adapters(phr); subsys_get_adapter(phm, phr);
break;
case HPI_SUBSYS_GET_NUM_ADAPTERS:
phr->u.s.num_adapters = adapters.gw_num_adapters;
break; break;
case HPI_SUBSYS_CREATE_ADAPTER: case HPI_SUBSYS_CREATE_ADAPTER:
case HPI_SUBSYS_DELETE_ADAPTER: case HPI_SUBSYS_DELETE_ADAPTER:
phr->error = 0;
break; break;
default: default:
phr->error = HPI_ERROR_INVALID_FUNC; phr->error = HPI_ERROR_INVALID_FUNC;

View file

@ -40,8 +40,7 @@ struct hpi_control_cache {
struct hpi_control_cache_info struct hpi_control_cache_info
**p_info; /**< pointer to allocated memory of **p_info; /**< pointer to allocated memory of
lookup pointers. */ lookup pointers. */
struct hpi_control_cache_single u8 *p_cache; /**< pointer to DSP's control cache. */
*p_cache; /**< pointer to DSP's control cache. */
}; };
struct hpi_adapter_obj *hpi_find_adapter(u16 adapter_index); 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, short hpi_check_control_cache(struct hpi_control_cache *pC,
struct hpi_message *phm, struct hpi_response *phr); struct hpi_message *phm, struct hpi_response *phr);
struct hpi_control_cache *hpi_alloc_control_cache(const u32 struct hpi_control_cache *hpi_alloc_control_cache(const u32
number_of_controls, const u32 size_in_bytes, number_of_controls, const u32 size_in_bytes, u8 *pDSP_control_buffer);
struct hpi_control_cache_info
*pDSP_control_buffer);
void hpi_free_control_cache(struct hpi_control_cache *p_cache); 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); struct hpi_message *phm, struct hpi_response *phr);
u16 hpi_validate_response(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, 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->object = object;
phm->function = function; phm->function = function;
phm->version = 0; phm->version = 0;
phm->adapter_index = 0xFFFF; phm->adapter_index = HPI_ADAPTER_INDEX_INVALID;
/* Expect actual adapter index to be set by caller */ /* 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" #define SOURCEFILE_NAME "hpimsgx.c"
#include "hpi_internal.h" #include "hpi_internal.h"
#include "hpimsginit.h" #include "hpimsginit.h"
#include "hpicmn.h"
#include "hpimsgx.h" #include "hpimsgx.h"
#include "hpidebug.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++) { for (i = 0; asihpi_pci_tbl[i].vendor != 0; i++) {
if (asihpi_pci_tbl[i].vendor != PCI_ANY_ID 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; continue;
if (asihpi_pci_tbl[i].device != PCI_ANY_ID 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; continue;
if (asihpi_pci_tbl[i].subvendor != PCI_ANY_ID if (asihpi_pci_tbl[i].subvendor != PCI_ANY_ID
&& asihpi_pci_tbl[i].subvendor != && asihpi_pci_tbl[i].subvendor !=
pci_info->subsys_vendor_id) pci_info->pci_dev->subsystem_vendor)
continue; continue;
if (asihpi_pci_tbl[i].subdevice != PCI_ANY_ID if (asihpi_pci_tbl[i].subdevice != PCI_ANY_ID
&& asihpi_pci_tbl[i].subdevice != && asihpi_pci_tbl[i].subdevice !=
pci_info->subsys_device_id) pci_info->pci_dev->subsystem_device)
continue; continue;
HPI_DEBUG_LOG(DEBUG, " %x,%lu\n", i, /* HPI_DEBUG_LOG(DEBUG, " %x,%lx\n", i,
asihpi_pci_tbl[i].driver_data); asihpi_pci_tbl[i].driver_data); */
return (hpi_handler_func *) asihpi_pci_tbl[i].driver_data; return (hpi_handler_func *) asihpi_pci_tbl[i].driver_data;
} }
@ -67,19 +70,10 @@ static hpi_handler_func *hpi_lookup_entry_point_function(const struct hpi_pci
static inline void hw_entry_point(struct hpi_message *phm, static inline void hw_entry_point(struct hpi_message *phm,
struct hpi_response *phr) struct hpi_response *phr)
{ {
if ((phm->adapter_index < HPI_MAX_ADAPTERS)
hpi_handler_func *ep; && hpi_entry_points[phm->adapter_index])
hpi_entry_points[phm->adapter_index] (phm, phr);
if (phm->adapter_index < HPI_MAX_ADAPTERS) { else
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_init_response(phr, phm->object, phm->function,
HPI_ERROR_PROCESSING_MESSAGE); HPI_ERROR_PROCESSING_MESSAGE);
} }
@ -100,6 +94,7 @@ static void instream_close(struct hpi_message *phm, struct hpi_response *phr,
void *h_owner); void *h_owner);
static void HPIMSGX__reset(u16 adapter_index); static void HPIMSGX__reset(u16 adapter_index);
static u16 HPIMSGX__init(struct hpi_message *phm, struct hpi_response *phr); static u16 HPIMSGX__init(struct hpi_message *phm, struct hpi_response *phr);
static void HPIMSGX__cleanup(u16 adapter_index, void *h_owner); 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_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]; static struct adapter_info aDAPTER_INFO[HPI_MAX_ADAPTERS];
/* use these to keep track of opens from user mode apps/DLLs */ /* 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, static void subsys_message(struct hpi_message *phm, struct hpi_response *phr,
void *h_owner) 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) { switch (phm->function) {
case HPI_SUBSYS_GET_VERSION: case HPI_SUBSYS_GET_VERSION:
hpi_init_response(phr, HPI_OBJ_SUBSYSTEM, 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); HPI_SUBSYS_DRIVER_UNLOAD, 0);
return; return;
case HPI_SUBSYS_GET_INFO: case HPI_SUBSYS_GET_NUM_ADAPTERS:
case HPI_SUBSYS_GET_ADAPTER:
HPI_COMMON(phm, phr); HPI_COMMON(phm, phr);
break; 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: case HPI_SUBSYS_CREATE_ADAPTER:
HPIMSGX__init(phm, phr); HPIMSGX__init(phm, phr);
break; break;
case HPI_SUBSYS_DELETE_ADAPTER: 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_message hm;
struct hpi_response hr; struct hpi_response hr;
/* call to HPI_ADAPTER_CLOSE */
hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER, hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER,
HPI_ADAPTER_CLOSE); HPI_ADAPTER_CLOSE);
hm.adapter_index = phm->adapter_index; hm.adapter_index = phm->obj_index;
hw_entry_point(&hm, &hr); hw_entry_point(&hm, &hr);
} }
hw_entry_point(phm, phr); if ((phm->obj_index < HPI_MAX_ADAPTERS)
gRESP_HPI_SUBSYS_FIND_ADAPTERS.s. && hpi_entry_points[phm->obj_index]) {
aw_adapter_list[phm->adapter_index] hpi_entry_points[phm->obj_index] (phm, phr);
= 0; hpi_entry_points[phm->obj_index] = NULL;
hpi_entry_points[phm->adapter_index] = NULL; } else
phr->error = HPI_ERROR_INVALID_OBJ_INDEX;
break; break;
default: 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; break;
} }
} }
@ -409,33 +359,7 @@ void hpi_send_recv_ex(struct hpi_message *phm, struct hpi_response *phr,
break; break;
} }
HPI_DEBUG_RESPONSE(phr); 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) 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 { else {
instream_user_open[phm->adapter_index][phm-> instream_user_open[phm->adapter_index][phm->
obj_index].open_flag = 1; obj_index].open_flag = 1;
hpios_msgxlock_un_lock(&msgx_lock); hpios_msgxlock_unlock(&msgx_lock);
/* issue a reset */ /* issue a reset */
hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM, 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])); 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, 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); */ phm->wAdapterIndex, phm->wObjIndex, hOwner); */
instream_user_open[phm->adapter_index][phm-> instream_user_open[phm->adapter_index][phm->
obj_index].h_owner = NULL; obj_index].h_owner = NULL;
hpios_msgxlock_un_lock(&msgx_lock); hpios_msgxlock_unlock(&msgx_lock);
/* issue a reset */ /* issue a reset */
hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM, hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
HPI_ISTREAM_RESET); HPI_ISTREAM_RESET);
@ -556,7 +480,7 @@ static void instream_close(struct hpi_message *phm, struct hpi_response *phr,
obj_index].h_owner); obj_index].h_owner);
phr->error = HPI_ERROR_OBJ_NOT_OPEN; 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, 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 { else {
outstream_user_open[phm->adapter_index][phm-> outstream_user_open[phm->adapter_index][phm->
obj_index].open_flag = 1; obj_index].open_flag = 1;
hpios_msgxlock_un_lock(&msgx_lock); hpios_msgxlock_unlock(&msgx_lock);
/* issue a reset */ /* issue a reset */
hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM, 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])); 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, 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); */ phm->wAdapterIndex, phm->wObjIndex, hOwner); */
outstream_user_open[phm->adapter_index][phm-> outstream_user_open[phm->adapter_index][phm->
obj_index].h_owner = NULL; obj_index].h_owner = NULL;
hpios_msgxlock_un_lock(&msgx_lock); hpios_msgxlock_unlock(&msgx_lock);
/* issue a reset */ /* issue a reset */
hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM, hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
HPI_OSTREAM_RESET); HPI_OSTREAM_RESET);
@ -654,7 +578,7 @@ static void outstream_close(struct hpi_message *phm, struct hpi_response *phr,
obj_index].h_owner); obj_index].h_owner);
phr->error = HPI_ERROR_OBJ_NOT_OPEN; phr->error = HPI_ERROR_OBJ_NOT_OPEN;
} }
hpios_msgxlock_un_lock(&msgx_lock); hpios_msgxlock_unlock(&msgx_lock);
} }
static u16 adapter_prepare(u16 adapter) static u16 adapter_prepare(u16 adapter)
@ -683,16 +607,9 @@ static u16 adapter_prepare(u16 adapter)
if (hr.error) if (hr.error)
return hr.error; return hr.error;
aDAPTER_INFO[adapter].num_outstreams = hr.u.a.num_outstreams; aDAPTER_INFO[adapter].num_outstreams = hr.u.ax.info.num_outstreams;
aDAPTER_INFO[adapter].num_instreams = hr.u.a.num_instreams; aDAPTER_INFO[adapter].num_instreams = hr.u.ax.info.num_instreams;
aDAPTER_INFO[adapter].type = hr.u.a.adapter_type; aDAPTER_INFO[adapter].type = hr.u.ax.info.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;
/* call to HPI_OSTREAM_OPEN */ /* call to HPI_OSTREAM_OPEN */
for (i = 0; i < aDAPTER_INFO[adapter].num_outstreams; i++) { 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, memcpy(&rESP_HPI_MIXER_OPEN[adapter], &hr,
sizeof(rESP_HPI_MIXER_OPEN[0])); sizeof(rESP_HPI_MIXER_OPEN[0]));
return gRESP_HPI_SUBSYS_FIND_ADAPTERS.h.error; return 0;
} }
static void HPIMSGX__reset(u16 adapter_index) static void HPIMSGX__reset(u16 adapter_index)
@ -737,12 +654,6 @@ static void HPIMSGX__reset(u16 adapter_index)
struct hpi_response hr; struct hpi_response hr;
if (adapter_index == HPIMSGX_ALLADAPTERS) { 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++) { for (adapter = 0; adapter < HPI_MAX_ADAPTERS; adapter++) {
hpi_init_response(&hr, HPI_OBJ_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 = rESP_HPI_ISTREAM_OPEN[adapter_index][i].h.error =
HPI_ERROR_INVALID_OBJ; 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; hpi_handler_func *entry_point_func;
struct hpi_response hr; 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 */ /* Init response here so we can pass in previous adapter list */
hpi_init_response(&hr, phm->object, phm->function, hpi_init_response(&hr, phm->object, phm->function,
HPI_ERROR_INVALID_OBJ); 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 = entry_point_func =
hpi_lookup_entry_point_function(phm->u.s.resource.r.pci); 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; struct hpi_response hr;
HPI_DEBUG_LOG(DEBUG, HPI_DEBUG_LOG(DEBUG,
"close adapter %d ostream %d\n", "Close adapter %d ostream %d\n",
adapter, i); adapter, i);
hpi_init_message_response(&hm, &hr, hpi_init_message_response(&hm, &hr,
@ -884,7 +783,7 @@ static void HPIMSGX__cleanup(u16 adapter_index, void *h_owner)
struct hpi_response hr; struct hpi_response hr;
HPI_DEBUG_LOG(DEBUG, HPI_DEBUG_LOG(DEBUG,
"close adapter %d istream %d\n", "Close adapter %d istream %d\n",
adapter, i); adapter, i);
hpi_init_message_response(&hm, &hr, 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/slab.h>
#include <linux/moduleparam.h> #include <linux/moduleparam.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <linux/pci.h>
#include <linux/stringify.h> #include <linux/stringify.h>
#ifdef MODULE_FIRMWARE #ifdef MODULE_FIRMWARE
@ -45,7 +46,7 @@ MODULE_FIRMWARE("asihpi/dsp8900.bin");
static int prealloc_stream_buf; static int prealloc_stream_buf;
module_param(prealloc_stream_buf, int, S_IRUGO); module_param(prealloc_stream_buf, int, S_IRUGO);
MODULE_PARM_DESC(prealloc_stream_buf, 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. /* Allow the debug level to be changed after module load.
E.g. echo 2 > /sys/module/asihpi/parameters/hpiDebugLevel 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; phpi_ioctl_data = (struct hpi_ioctl_linux __user *)arg;
/* Read the message and response pointers from user space. */ /* Read the message and response pointers from user space. */
if (get_user(puhm, &phpi_ioctl_data->phm) || if (get_user(puhm, &phpi_ioctl_data->phm)
get_user(puhr, &phpi_ioctl_data->phr)) { || get_user(puhr, &phpi_ioctl_data->phr)) {
err = -EFAULT; err = -EFAULT;
goto out; goto out;
} }
@ -156,7 +157,7 @@ long asihpi_hpi_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
} }
pa = &adapters[hm->h.adapter_index]; pa = &adapters[hm->h.adapter_index];
hr->h.size = 0; hr->h.size = res_max_size;
if (hm->h.object == HPI_OBJ_SUBSYSTEM) { if (hm->h.object == HPI_OBJ_SUBSYSTEM) {
switch (hm->h.function) { switch (hm->h.function) {
case HPI_SUBSYS_CREATE_ADAPTER: 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) { if (pa->buffer_size < size) {
HPI_DEBUG_LOG(DEBUG, HPI_DEBUG_LOG(DEBUG,
"realloc adapter %d stream " "Realloc adapter %d stream "
"buffer from %zd to %d\n", "buffer from %zd to %d\n",
hm->h.adapter_index, hm->h.adapter_index,
pa->buffer_size, size); 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); copy_from_user(pa->p_buffer, ptr, size);
if (uncopied_bytes) if (uncopied_bytes)
HPI_DEBUG_LOG(WARNING, HPI_DEBUG_LOG(WARNING,
"missed %d of %d " "Missed %d of %d "
"bytes from user\n", uncopied_bytes, "bytes from user\n", uncopied_bytes,
size); 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); copy_to_user(ptr, pa->p_buffer, size);
if (uncopied_bytes) if (uncopied_bytes)
HPI_DEBUG_LOG(WARNING, HPI_DEBUG_LOG(WARNING,
"missed %d of %d " "bytes to user\n", "Missed %d of %d " "bytes to user\n",
uncopied_bytes, size); 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) { if (hr->h.size > res_max_size) {
HPI_DEBUG_LOG(ERROR, "response too big %d %d\n", hr->h.size, HPI_DEBUG_LOG(ERROR, "response too big %d %d\n", hr->h.size,
res_max_size); res_max_size);
/*HPI_DEBUG_MESSAGE(ERROR, hm); */ hr->h.error = HPI_ERROR_RESPONSE_BUFFER_TOO_SMALL;
err = -EFAULT; hr->h.specific_error = hr->h.size;
goto out; hr->h.size = sizeof(hr->h);
} }
uncopied_bytes = copy_to_user(puhr, hr, hr->h.size); 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)); memset(&adapter, 0, sizeof(adapter));
printk(KERN_DEBUG "probe PCI device (%04x:%04x,%04x:%04x,%04x)\n", dev_printk(KERN_DEBUG, &pci_dev->dev,
pci_dev->vendor, pci_dev->device, pci_dev->subsystem_vendor, "probe %04x:%04x,%04x:%04x,%04x\n", pci_dev->vendor,
pci_dev->device, pci_dev->subsystem_vendor,
pci_dev->subsystem_device, pci_dev->devfn); 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_init_message_response(&hm, &hr, HPI_OBJ_SUBSYSTEM,
HPI_SUBSYS_CREATE_ADAPTER); HPI_SUBSYS_CREATE_ADAPTER);
hpi_init_response(&hr, HPI_OBJ_SUBSYSTEM, HPI_SUBSYS_CREATE_ADAPTER, hpi_init_response(&hr, HPI_OBJ_SUBSYSTEM, HPI_SUBSYS_CREATE_ADAPTER,
HPI_ERROR_PROCESSING_MESSAGE); 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; adapter.pci = pci_dev;
nm = HPI_MAX_ADAPTER_MEM_SPACES; 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]; pci.ap_mem_base[idx] = adapter.ap_remapped_mem_base[idx];
} }
/* could replace Pci with direct pointer to pci_dev for linux pci.pci_dev = pci_dev;
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;
hm.u.s.resource.bus_type = HPI_BUS_PCI; hm.u.s.resource.bus_type = HPI_BUS_PCI;
hm.u.s.resource.r.pci = &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); mutex_init(&adapters[adapter.index].mutex);
pci_set_drvdata(pci_dev, &adapters[adapter.index]); pci_set_drvdata(pci_dev, &adapters[adapter.index]);
printk(KERN_INFO "probe found adapter ASI%04X HPI index #%d.\n", dev_printk(KERN_INFO, &pci_dev->dev,
adapter.type, adapter.index); "probe succeeded for ASI%04X HPI index %d\n", adapter.type,
adapter.index);
return 0; 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_init_message_response(&hm, &hr, HPI_OBJ_SUBSYSTEM,
HPI_SUBSYS_DELETE_ADAPTER); 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); hpi_send_recv_ex(&hm, &hr, HOWNER_KERNEL);
/* unmap PCI memory space, mapped during device init. */ /* 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); pci_set_drvdata(pci_dev, NULL);
/* if (1)
printk(KERN_INFO "PCI device (%04x:%04x,%04x:%04x,%04x)," dev_printk(KERN_INFO, &pci_dev->dev,
" HPI index # %d, removed.\n", "remove %04x:%04x,%04x:%04x,%04x," " HPI index %d.\n",
pci_dev->vendor, pci_dev->device, pci_dev->vendor, pci_dev->device,
pci_dev->subsystem_vendor, pci_dev->subsystem_vendor, pci_dev->subsystem_device,
pci_dev->subsystem_device, pci_dev->devfn, pci_dev->devfn, pa->index);
pa->index);
*/
} }
void __init asihpi_init(void) 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_init(obj) spin_lock_init(&(obj)->lock)
#define hpios_msgxlock_lock(obj) cond_lock(obj) #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_init(obj) spin_lock_init(&(obj)->dsp_lock.lock)
#define hpios_dsplock_lock(obj) cond_lock(&(obj)->dsp_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 HPI_ALIST_LOCKING
#define hpios_alistlock_init(obj) spin_lock_init(&((obj)->list_lock.lock)) #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_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 { struct hpi_adapter {
/* mutex prevents contention for one card /* mutex prevents contention for one card