107d7fe7bSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only 2719f82d3SEliot Blennerhassett /****************************************************************************** 3719f82d3SEliot Blennerhassett 4719f82d3SEliot Blennerhassett AudioScience HPI driver 55bc91f5bSEliot Blennerhassett Copyright (C) 1997-2014 AudioScience Inc. <support@audioscience.com> 6719f82d3SEliot Blennerhassett 7719f82d3SEliot Blennerhassett 8938c565aSEliot Blennerhassett Extended Message Function With Response Caching 9719f82d3SEliot Blennerhassett 10719f82d3SEliot Blennerhassett (C) Copyright AudioScience Inc. 2002 11719f82d3SEliot Blennerhassett *****************************************************************************/ 12719f82d3SEliot Blennerhassett #define SOURCEFILE_NAME "hpimsgx.c" 13719f82d3SEliot Blennerhassett #include "hpi_internal.h" 14f6baaec2SEliot Blennerhassett #include "hpi_version.h" 15719f82d3SEliot Blennerhassett #include "hpimsginit.h" 163285ea10SEliot Blennerhassett #include "hpicmn.h" 17719f82d3SEliot Blennerhassett #include "hpimsgx.h" 18719f82d3SEliot Blennerhassett #include "hpidebug.h" 19719f82d3SEliot Blennerhassett 20*9ca7a0c9STakashi Iwai static const struct pci_device_id asihpi_pci_tbl[] = { 21719f82d3SEliot Blennerhassett #include "hpipcida.h" 22719f82d3SEliot Blennerhassett }; 23719f82d3SEliot Blennerhassett 24719f82d3SEliot Blennerhassett static struct hpios_spinlock msgx_lock; 25719f82d3SEliot Blennerhassett 26719f82d3SEliot Blennerhassett static hpi_handler_func *hpi_entry_points[HPI_MAX_ADAPTERS]; 275bc91f5bSEliot Blennerhassett static int logging_enabled = 1; 28719f82d3SEliot Blennerhassett 29719f82d3SEliot Blennerhassett static hpi_handler_func *hpi_lookup_entry_point_function(const struct hpi_pci 30719f82d3SEliot Blennerhassett *pci_info) 31719f82d3SEliot Blennerhassett { 32719f82d3SEliot Blennerhassett 33719f82d3SEliot Blennerhassett int i; 34719f82d3SEliot Blennerhassett 35719f82d3SEliot Blennerhassett for (i = 0; asihpi_pci_tbl[i].vendor != 0; i++) { 36719f82d3SEliot Blennerhassett if (asihpi_pci_tbl[i].vendor != PCI_ANY_ID 373285ea10SEliot Blennerhassett && asihpi_pci_tbl[i].vendor != 383285ea10SEliot Blennerhassett pci_info->pci_dev->vendor) 39719f82d3SEliot Blennerhassett continue; 40719f82d3SEliot Blennerhassett if (asihpi_pci_tbl[i].device != PCI_ANY_ID 413285ea10SEliot Blennerhassett && asihpi_pci_tbl[i].device != 423285ea10SEliot Blennerhassett pci_info->pci_dev->device) 43719f82d3SEliot Blennerhassett continue; 44719f82d3SEliot Blennerhassett if (asihpi_pci_tbl[i].subvendor != PCI_ANY_ID 45719f82d3SEliot Blennerhassett && asihpi_pci_tbl[i].subvendor != 463285ea10SEliot Blennerhassett pci_info->pci_dev->subsystem_vendor) 47719f82d3SEliot Blennerhassett continue; 48719f82d3SEliot Blennerhassett if (asihpi_pci_tbl[i].subdevice != PCI_ANY_ID 49719f82d3SEliot Blennerhassett && asihpi_pci_tbl[i].subdevice != 503285ea10SEliot Blennerhassett pci_info->pci_dev->subsystem_device) 51719f82d3SEliot Blennerhassett continue; 52719f82d3SEliot Blennerhassett 533285ea10SEliot Blennerhassett /* HPI_DEBUG_LOG(DEBUG, " %x,%lx\n", i, 543285ea10SEliot Blennerhassett asihpi_pci_tbl[i].driver_data); */ 55719f82d3SEliot Blennerhassett return (hpi_handler_func *) asihpi_pci_tbl[i].driver_data; 56719f82d3SEliot Blennerhassett } 57719f82d3SEliot Blennerhassett 58719f82d3SEliot Blennerhassett return NULL; 59719f82d3SEliot Blennerhassett } 60719f82d3SEliot Blennerhassett 61719f82d3SEliot Blennerhassett static inline void hw_entry_point(struct hpi_message *phm, 62719f82d3SEliot Blennerhassett struct hpi_response *phr) 63719f82d3SEliot Blennerhassett { 643285ea10SEliot Blennerhassett if ((phm->adapter_index < HPI_MAX_ADAPTERS) 653285ea10SEliot Blennerhassett && hpi_entry_points[phm->adapter_index]) 663285ea10SEliot Blennerhassett hpi_entry_points[phm->adapter_index] (phm, phr); 673285ea10SEliot Blennerhassett else 68719f82d3SEliot Blennerhassett hpi_init_response(phr, phm->object, phm->function, 69719f82d3SEliot Blennerhassett HPI_ERROR_PROCESSING_MESSAGE); 70719f82d3SEliot Blennerhassett } 71719f82d3SEliot Blennerhassett 72719f82d3SEliot Blennerhassett static void adapter_open(struct hpi_message *phm, struct hpi_response *phr); 73719f82d3SEliot Blennerhassett static void adapter_close(struct hpi_message *phm, struct hpi_response *phr); 74719f82d3SEliot Blennerhassett 75719f82d3SEliot Blennerhassett static void mixer_open(struct hpi_message *phm, struct hpi_response *phr); 76719f82d3SEliot Blennerhassett static void mixer_close(struct hpi_message *phm, struct hpi_response *phr); 77719f82d3SEliot Blennerhassett 78719f82d3SEliot Blennerhassett static void outstream_open(struct hpi_message *phm, struct hpi_response *phr, 79719f82d3SEliot Blennerhassett void *h_owner); 80719f82d3SEliot Blennerhassett static void outstream_close(struct hpi_message *phm, struct hpi_response *phr, 81719f82d3SEliot Blennerhassett void *h_owner); 82719f82d3SEliot Blennerhassett static void instream_open(struct hpi_message *phm, struct hpi_response *phr, 83719f82d3SEliot Blennerhassett void *h_owner); 84719f82d3SEliot Blennerhassett static void instream_close(struct hpi_message *phm, struct hpi_response *phr, 85719f82d3SEliot Blennerhassett void *h_owner); 86719f82d3SEliot Blennerhassett 87719f82d3SEliot Blennerhassett static void HPIMSGX__reset(u16 adapter_index); 883285ea10SEliot Blennerhassett 89719f82d3SEliot Blennerhassett static u16 HPIMSGX__init(struct hpi_message *phm, struct hpi_response *phr); 90719f82d3SEliot Blennerhassett static void HPIMSGX__cleanup(u16 adapter_index, void *h_owner); 91719f82d3SEliot Blennerhassett 92719f82d3SEliot Blennerhassett #ifndef DISABLE_PRAGMA_PACK1 93719f82d3SEliot Blennerhassett #pragma pack(push, 1) 94719f82d3SEliot Blennerhassett #endif 95719f82d3SEliot Blennerhassett 96719f82d3SEliot Blennerhassett struct hpi_subsys_response { 97719f82d3SEliot Blennerhassett struct hpi_response_header h; 98719f82d3SEliot Blennerhassett struct hpi_subsys_res s; 99719f82d3SEliot Blennerhassett }; 100719f82d3SEliot Blennerhassett 101719f82d3SEliot Blennerhassett struct hpi_adapter_response { 102719f82d3SEliot Blennerhassett struct hpi_response_header h; 103719f82d3SEliot Blennerhassett struct hpi_adapter_res a; 104719f82d3SEliot Blennerhassett }; 105719f82d3SEliot Blennerhassett 106719f82d3SEliot Blennerhassett struct hpi_mixer_response { 107719f82d3SEliot Blennerhassett struct hpi_response_header h; 108719f82d3SEliot Blennerhassett struct hpi_mixer_res m; 109719f82d3SEliot Blennerhassett }; 110719f82d3SEliot Blennerhassett 111719f82d3SEliot Blennerhassett struct hpi_stream_response { 112719f82d3SEliot Blennerhassett struct hpi_response_header h; 113719f82d3SEliot Blennerhassett struct hpi_stream_res d; 114719f82d3SEliot Blennerhassett }; 115719f82d3SEliot Blennerhassett 116719f82d3SEliot Blennerhassett struct adapter_info { 117719f82d3SEliot Blennerhassett u16 type; 118719f82d3SEliot Blennerhassett u16 num_instreams; 119719f82d3SEliot Blennerhassett u16 num_outstreams; 120719f82d3SEliot Blennerhassett }; 121719f82d3SEliot Blennerhassett 122719f82d3SEliot Blennerhassett struct asi_open_state { 123719f82d3SEliot Blennerhassett int open_flag; 124719f82d3SEliot Blennerhassett void *h_owner; 125719f82d3SEliot Blennerhassett }; 126719f82d3SEliot Blennerhassett 127719f82d3SEliot Blennerhassett #ifndef DISABLE_PRAGMA_PACK1 128719f82d3SEliot Blennerhassett #pragma pack(pop) 129719f82d3SEliot Blennerhassett #endif 130719f82d3SEliot Blennerhassett 131719f82d3SEliot Blennerhassett /* Globals */ 132719f82d3SEliot Blennerhassett static struct hpi_adapter_response rESP_HPI_ADAPTER_OPEN[HPI_MAX_ADAPTERS]; 133719f82d3SEliot Blennerhassett 134719f82d3SEliot Blennerhassett static struct hpi_stream_response 135719f82d3SEliot Blennerhassett rESP_HPI_OSTREAM_OPEN[HPI_MAX_ADAPTERS][HPI_MAX_STREAMS]; 136719f82d3SEliot Blennerhassett 137719f82d3SEliot Blennerhassett static struct hpi_stream_response 138719f82d3SEliot Blennerhassett rESP_HPI_ISTREAM_OPEN[HPI_MAX_ADAPTERS][HPI_MAX_STREAMS]; 139719f82d3SEliot Blennerhassett 140719f82d3SEliot Blennerhassett static struct hpi_mixer_response rESP_HPI_MIXER_OPEN[HPI_MAX_ADAPTERS]; 141719f82d3SEliot Blennerhassett 142719f82d3SEliot Blennerhassett static struct adapter_info aDAPTER_INFO[HPI_MAX_ADAPTERS]; 143719f82d3SEliot Blennerhassett 144719f82d3SEliot Blennerhassett /* use these to keep track of opens from user mode apps/DLLs */ 145719f82d3SEliot Blennerhassett static struct asi_open_state 146719f82d3SEliot Blennerhassett outstream_user_open[HPI_MAX_ADAPTERS][HPI_MAX_STREAMS]; 147719f82d3SEliot Blennerhassett 148719f82d3SEliot Blennerhassett static struct asi_open_state 149719f82d3SEliot Blennerhassett instream_user_open[HPI_MAX_ADAPTERS][HPI_MAX_STREAMS]; 150719f82d3SEliot Blennerhassett 151719f82d3SEliot Blennerhassett static void subsys_message(struct hpi_message *phm, struct hpi_response *phr, 152719f82d3SEliot Blennerhassett void *h_owner) 153719f82d3SEliot Blennerhassett { 1543285ea10SEliot Blennerhassett if (phm->adapter_index != HPI_ADAPTER_INDEX_INVALID) 1553285ea10SEliot Blennerhassett HPI_DEBUG_LOG(WARNING, 1563285ea10SEliot Blennerhassett "suspicious adapter index %d in subsys message 0x%x.\n", 1573285ea10SEliot Blennerhassett phm->adapter_index, phm->function); 1583285ea10SEliot Blennerhassett 159719f82d3SEliot Blennerhassett switch (phm->function) { 160719f82d3SEliot Blennerhassett case HPI_SUBSYS_GET_VERSION: 161719f82d3SEliot Blennerhassett hpi_init_response(phr, HPI_OBJ_SUBSYSTEM, 162719f82d3SEliot Blennerhassett HPI_SUBSYS_GET_VERSION, 0); 163719f82d3SEliot Blennerhassett phr->u.s.version = HPI_VER >> 8; /* return major.minor */ 164719f82d3SEliot Blennerhassett phr->u.s.data = HPI_VER; /* return major.minor.release */ 165719f82d3SEliot Blennerhassett break; 166719f82d3SEliot Blennerhassett case HPI_SUBSYS_OPEN: 167719f82d3SEliot Blennerhassett /*do not propagate the message down the chain */ 168719f82d3SEliot Blennerhassett hpi_init_response(phr, HPI_OBJ_SUBSYSTEM, HPI_SUBSYS_OPEN, 0); 169719f82d3SEliot Blennerhassett break; 170719f82d3SEliot Blennerhassett case HPI_SUBSYS_CLOSE: 171719f82d3SEliot Blennerhassett /*do not propagate the message down the chain */ 172719f82d3SEliot Blennerhassett hpi_init_response(phr, HPI_OBJ_SUBSYSTEM, HPI_SUBSYS_CLOSE, 173719f82d3SEliot Blennerhassett 0); 174719f82d3SEliot Blennerhassett HPIMSGX__cleanup(HPIMSGX_ALLADAPTERS, h_owner); 175719f82d3SEliot Blennerhassett break; 176719f82d3SEliot Blennerhassett case HPI_SUBSYS_DRIVER_LOAD: 177719f82d3SEliot Blennerhassett /* Initialize this module's internal state */ 178719f82d3SEliot Blennerhassett hpios_msgxlock_init(&msgx_lock); 179719f82d3SEliot Blennerhassett memset(&hpi_entry_points, 0, sizeof(hpi_entry_points)); 180719f82d3SEliot Blennerhassett /* Init subsys_findadapters response to no-adapters */ 181719f82d3SEliot Blennerhassett HPIMSGX__reset(HPIMSGX_ALLADAPTERS); 182719f82d3SEliot Blennerhassett hpi_init_response(phr, HPI_OBJ_SUBSYSTEM, 183719f82d3SEliot Blennerhassett HPI_SUBSYS_DRIVER_LOAD, 0); 184719f82d3SEliot Blennerhassett /* individual HPIs dont implement driver load */ 185719f82d3SEliot Blennerhassett HPI_COMMON(phm, phr); 186719f82d3SEliot Blennerhassett break; 187719f82d3SEliot Blennerhassett case HPI_SUBSYS_DRIVER_UNLOAD: 188719f82d3SEliot Blennerhassett HPI_COMMON(phm, phr); 189719f82d3SEliot Blennerhassett HPIMSGX__cleanup(HPIMSGX_ALLADAPTERS, h_owner); 190719f82d3SEliot Blennerhassett hpi_init_response(phr, HPI_OBJ_SUBSYSTEM, 191719f82d3SEliot Blennerhassett HPI_SUBSYS_DRIVER_UNLOAD, 0); 192719f82d3SEliot Blennerhassett return; 193719f82d3SEliot Blennerhassett 1943285ea10SEliot Blennerhassett case HPI_SUBSYS_GET_NUM_ADAPTERS: 1953285ea10SEliot Blennerhassett case HPI_SUBSYS_GET_ADAPTER: 196719f82d3SEliot Blennerhassett HPI_COMMON(phm, phr); 197719f82d3SEliot Blennerhassett break; 198719f82d3SEliot Blennerhassett 199719f82d3SEliot Blennerhassett case HPI_SUBSYS_CREATE_ADAPTER: 200719f82d3SEliot Blennerhassett HPIMSGX__init(phm, phr); 201719f82d3SEliot Blennerhassett break; 2023285ea10SEliot Blennerhassett 203719f82d3SEliot Blennerhassett default: 2041d595d2aSEliot Blennerhassett /* Must explicitly handle every subsys message in this switch */ 2053285ea10SEliot Blennerhassett hpi_init_response(phr, HPI_OBJ_SUBSYSTEM, phm->function, 2063285ea10SEliot Blennerhassett HPI_ERROR_INVALID_FUNC); 207719f82d3SEliot Blennerhassett break; 208719f82d3SEliot Blennerhassett } 209719f82d3SEliot Blennerhassett } 210719f82d3SEliot Blennerhassett 211719f82d3SEliot Blennerhassett static void adapter_message(struct hpi_message *phm, struct hpi_response *phr, 212719f82d3SEliot Blennerhassett void *h_owner) 213719f82d3SEliot Blennerhassett { 214719f82d3SEliot Blennerhassett switch (phm->function) { 215719f82d3SEliot Blennerhassett case HPI_ADAPTER_OPEN: 216719f82d3SEliot Blennerhassett adapter_open(phm, phr); 217719f82d3SEliot Blennerhassett break; 218719f82d3SEliot Blennerhassett case HPI_ADAPTER_CLOSE: 219719f82d3SEliot Blennerhassett adapter_close(phm, phr); 220719f82d3SEliot Blennerhassett break; 2216d0b898eSEliot Blennerhassett case HPI_ADAPTER_DELETE: 2226d0b898eSEliot Blennerhassett HPIMSGX__cleanup(phm->adapter_index, h_owner); 2236d0b898eSEliot Blennerhassett { 2246d0b898eSEliot Blennerhassett struct hpi_message hm; 2256d0b898eSEliot Blennerhassett struct hpi_response hr; 2266d0b898eSEliot Blennerhassett hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER, 2276d0b898eSEliot Blennerhassett HPI_ADAPTER_CLOSE); 2286d0b898eSEliot Blennerhassett hm.adapter_index = phm->adapter_index; 2296d0b898eSEliot Blennerhassett hw_entry_point(&hm, &hr); 2306d0b898eSEliot Blennerhassett } 2316d0b898eSEliot Blennerhassett hw_entry_point(phm, phr); 2326d0b898eSEliot Blennerhassett break; 2336d0b898eSEliot Blennerhassett 234719f82d3SEliot Blennerhassett default: 235719f82d3SEliot Blennerhassett hw_entry_point(phm, phr); 236719f82d3SEliot Blennerhassett break; 237719f82d3SEliot Blennerhassett } 238719f82d3SEliot Blennerhassett } 239719f82d3SEliot Blennerhassett 240719f82d3SEliot Blennerhassett static void mixer_message(struct hpi_message *phm, struct hpi_response *phr) 241719f82d3SEliot Blennerhassett { 242719f82d3SEliot Blennerhassett switch (phm->function) { 243719f82d3SEliot Blennerhassett case HPI_MIXER_OPEN: 244719f82d3SEliot Blennerhassett mixer_open(phm, phr); 245719f82d3SEliot Blennerhassett break; 246719f82d3SEliot Blennerhassett case HPI_MIXER_CLOSE: 247719f82d3SEliot Blennerhassett mixer_close(phm, phr); 248719f82d3SEliot Blennerhassett break; 249719f82d3SEliot Blennerhassett default: 250719f82d3SEliot Blennerhassett hw_entry_point(phm, phr); 251719f82d3SEliot Blennerhassett break; 252719f82d3SEliot Blennerhassett } 253719f82d3SEliot Blennerhassett } 254719f82d3SEliot Blennerhassett 255719f82d3SEliot Blennerhassett static void outstream_message(struct hpi_message *phm, 256719f82d3SEliot Blennerhassett struct hpi_response *phr, void *h_owner) 257719f82d3SEliot Blennerhassett { 258719f82d3SEliot Blennerhassett if (phm->obj_index >= aDAPTER_INFO[phm->adapter_index].num_outstreams) { 259719f82d3SEliot Blennerhassett hpi_init_response(phr, HPI_OBJ_OSTREAM, phm->function, 260719f82d3SEliot Blennerhassett HPI_ERROR_INVALID_OBJ_INDEX); 261719f82d3SEliot Blennerhassett return; 262719f82d3SEliot Blennerhassett } 263719f82d3SEliot Blennerhassett 264719f82d3SEliot Blennerhassett switch (phm->function) { 265719f82d3SEliot Blennerhassett case HPI_OSTREAM_OPEN: 266719f82d3SEliot Blennerhassett outstream_open(phm, phr, h_owner); 267719f82d3SEliot Blennerhassett break; 268719f82d3SEliot Blennerhassett case HPI_OSTREAM_CLOSE: 269719f82d3SEliot Blennerhassett outstream_close(phm, phr, h_owner); 270719f82d3SEliot Blennerhassett break; 271719f82d3SEliot Blennerhassett default: 272719f82d3SEliot Blennerhassett hw_entry_point(phm, phr); 273719f82d3SEliot Blennerhassett break; 274719f82d3SEliot Blennerhassett } 275719f82d3SEliot Blennerhassett } 276719f82d3SEliot Blennerhassett 277719f82d3SEliot Blennerhassett static void instream_message(struct hpi_message *phm, 278719f82d3SEliot Blennerhassett struct hpi_response *phr, void *h_owner) 279719f82d3SEliot Blennerhassett { 280719f82d3SEliot Blennerhassett if (phm->obj_index >= aDAPTER_INFO[phm->adapter_index].num_instreams) { 281719f82d3SEliot Blennerhassett hpi_init_response(phr, HPI_OBJ_ISTREAM, phm->function, 282719f82d3SEliot Blennerhassett HPI_ERROR_INVALID_OBJ_INDEX); 283719f82d3SEliot Blennerhassett return; 284719f82d3SEliot Blennerhassett } 285719f82d3SEliot Blennerhassett 286719f82d3SEliot Blennerhassett switch (phm->function) { 287719f82d3SEliot Blennerhassett case HPI_ISTREAM_OPEN: 288719f82d3SEliot Blennerhassett instream_open(phm, phr, h_owner); 289719f82d3SEliot Blennerhassett break; 290719f82d3SEliot Blennerhassett case HPI_ISTREAM_CLOSE: 291719f82d3SEliot Blennerhassett instream_close(phm, phr, h_owner); 292719f82d3SEliot Blennerhassett break; 293719f82d3SEliot Blennerhassett default: 294719f82d3SEliot Blennerhassett hw_entry_point(phm, phr); 295719f82d3SEliot Blennerhassett break; 296719f82d3SEliot Blennerhassett } 297719f82d3SEliot Blennerhassett } 298719f82d3SEliot Blennerhassett 299719f82d3SEliot Blennerhassett /* NOTE: HPI_Message() must be defined in the driver as a wrapper for 300719f82d3SEliot Blennerhassett * HPI_MessageEx so that functions in hpifunc.c compile. 301719f82d3SEliot Blennerhassett */ 302719f82d3SEliot Blennerhassett void hpi_send_recv_ex(struct hpi_message *phm, struct hpi_response *phr, 303719f82d3SEliot Blennerhassett void *h_owner) 304719f82d3SEliot Blennerhassett { 3055bc91f5bSEliot Blennerhassett 3065bc91f5bSEliot Blennerhassett if (logging_enabled) 307719f82d3SEliot Blennerhassett HPI_DEBUG_MESSAGE(DEBUG, phm); 308719f82d3SEliot Blennerhassett 30982b5774fSEliot Blennerhassett if (phm->type != HPI_TYPE_REQUEST) { 310719f82d3SEliot Blennerhassett hpi_init_response(phr, phm->object, phm->function, 311719f82d3SEliot Blennerhassett HPI_ERROR_INVALID_TYPE); 312719f82d3SEliot Blennerhassett return; 313719f82d3SEliot Blennerhassett } 314719f82d3SEliot Blennerhassett 315719f82d3SEliot Blennerhassett if (phm->adapter_index >= HPI_MAX_ADAPTERS 316719f82d3SEliot Blennerhassett && phm->adapter_index != HPIMSGX_ALLADAPTERS) { 317719f82d3SEliot Blennerhassett hpi_init_response(phr, phm->object, phm->function, 318719f82d3SEliot Blennerhassett HPI_ERROR_BAD_ADAPTER_NUMBER); 319719f82d3SEliot Blennerhassett return; 320719f82d3SEliot Blennerhassett } 321719f82d3SEliot Blennerhassett 322719f82d3SEliot Blennerhassett switch (phm->object) { 323719f82d3SEliot Blennerhassett case HPI_OBJ_SUBSYSTEM: 324719f82d3SEliot Blennerhassett subsys_message(phm, phr, h_owner); 325719f82d3SEliot Blennerhassett break; 326719f82d3SEliot Blennerhassett 327719f82d3SEliot Blennerhassett case HPI_OBJ_ADAPTER: 328719f82d3SEliot Blennerhassett adapter_message(phm, phr, h_owner); 329719f82d3SEliot Blennerhassett break; 330719f82d3SEliot Blennerhassett 331719f82d3SEliot Blennerhassett case HPI_OBJ_MIXER: 332719f82d3SEliot Blennerhassett mixer_message(phm, phr); 333719f82d3SEliot Blennerhassett break; 334719f82d3SEliot Blennerhassett 335719f82d3SEliot Blennerhassett case HPI_OBJ_OSTREAM: 336719f82d3SEliot Blennerhassett outstream_message(phm, phr, h_owner); 337719f82d3SEliot Blennerhassett break; 338719f82d3SEliot Blennerhassett 339719f82d3SEliot Blennerhassett case HPI_OBJ_ISTREAM: 340719f82d3SEliot Blennerhassett instream_message(phm, phr, h_owner); 341719f82d3SEliot Blennerhassett break; 342719f82d3SEliot Blennerhassett 343719f82d3SEliot Blennerhassett default: 344719f82d3SEliot Blennerhassett hw_entry_point(phm, phr); 345719f82d3SEliot Blennerhassett break; 346719f82d3SEliot Blennerhassett } 3475bc91f5bSEliot Blennerhassett 3485bc91f5bSEliot Blennerhassett if (logging_enabled) 349719f82d3SEliot Blennerhassett HPI_DEBUG_RESPONSE(phr); 350719f82d3SEliot Blennerhassett 3515bc91f5bSEliot Blennerhassett if (phr->error >= HPI_ERROR_DSP_COMMUNICATION) { 3525bc91f5bSEliot Blennerhassett hpi_debug_level_set(HPI_DEBUG_LEVEL_ERROR); 3535bc91f5bSEliot Blennerhassett logging_enabled = 0; 3545bc91f5bSEliot Blennerhassett } 355719f82d3SEliot Blennerhassett } 356719f82d3SEliot Blennerhassett 357719f82d3SEliot Blennerhassett static void adapter_open(struct hpi_message *phm, struct hpi_response *phr) 358719f82d3SEliot Blennerhassett { 359719f82d3SEliot Blennerhassett HPI_DEBUG_LOG(VERBOSE, "adapter_open\n"); 360719f82d3SEliot Blennerhassett memcpy(phr, &rESP_HPI_ADAPTER_OPEN[phm->adapter_index], 361719f82d3SEliot Blennerhassett sizeof(rESP_HPI_ADAPTER_OPEN[0])); 362719f82d3SEliot Blennerhassett } 363719f82d3SEliot Blennerhassett 364719f82d3SEliot Blennerhassett static void adapter_close(struct hpi_message *phm, struct hpi_response *phr) 365719f82d3SEliot Blennerhassett { 366719f82d3SEliot Blennerhassett HPI_DEBUG_LOG(VERBOSE, "adapter_close\n"); 367719f82d3SEliot Blennerhassett hpi_init_response(phr, HPI_OBJ_ADAPTER, HPI_ADAPTER_CLOSE, 0); 368719f82d3SEliot Blennerhassett } 369719f82d3SEliot Blennerhassett 370719f82d3SEliot Blennerhassett static void mixer_open(struct hpi_message *phm, struct hpi_response *phr) 371719f82d3SEliot Blennerhassett { 372719f82d3SEliot Blennerhassett memcpy(phr, &rESP_HPI_MIXER_OPEN[phm->adapter_index], 373719f82d3SEliot Blennerhassett sizeof(rESP_HPI_MIXER_OPEN[0])); 374719f82d3SEliot Blennerhassett } 375719f82d3SEliot Blennerhassett 376719f82d3SEliot Blennerhassett static void mixer_close(struct hpi_message *phm, struct hpi_response *phr) 377719f82d3SEliot Blennerhassett { 378719f82d3SEliot Blennerhassett hpi_init_response(phr, HPI_OBJ_MIXER, HPI_MIXER_CLOSE, 0); 379719f82d3SEliot Blennerhassett } 380719f82d3SEliot Blennerhassett 381719f82d3SEliot Blennerhassett static void instream_open(struct hpi_message *phm, struct hpi_response *phr, 382719f82d3SEliot Blennerhassett void *h_owner) 383719f82d3SEliot Blennerhassett { 384719f82d3SEliot Blennerhassett 385719f82d3SEliot Blennerhassett struct hpi_message hm; 386719f82d3SEliot Blennerhassett struct hpi_response hr; 387719f82d3SEliot Blennerhassett 388719f82d3SEliot Blennerhassett hpi_init_response(phr, HPI_OBJ_ISTREAM, HPI_ISTREAM_OPEN, 0); 389719f82d3SEliot Blennerhassett 390719f82d3SEliot Blennerhassett hpios_msgxlock_lock(&msgx_lock); 391719f82d3SEliot Blennerhassett 392719f82d3SEliot Blennerhassett if (instream_user_open[phm->adapter_index][phm->obj_index].open_flag) 393719f82d3SEliot Blennerhassett phr->error = HPI_ERROR_OBJ_ALREADY_OPEN; 394719f82d3SEliot Blennerhassett else if (rESP_HPI_ISTREAM_OPEN[phm->adapter_index] 395719f82d3SEliot Blennerhassett [phm->obj_index].h.error) 396719f82d3SEliot Blennerhassett memcpy(phr, 397719f82d3SEliot Blennerhassett &rESP_HPI_ISTREAM_OPEN[phm->adapter_index][phm-> 398719f82d3SEliot Blennerhassett obj_index], 399719f82d3SEliot Blennerhassett sizeof(rESP_HPI_ISTREAM_OPEN[0][0])); 400719f82d3SEliot Blennerhassett else { 401719f82d3SEliot Blennerhassett instream_user_open[phm->adapter_index][phm-> 402719f82d3SEliot Blennerhassett obj_index].open_flag = 1; 4033285ea10SEliot Blennerhassett hpios_msgxlock_unlock(&msgx_lock); 404719f82d3SEliot Blennerhassett 405719f82d3SEliot Blennerhassett /* issue a reset */ 406719f82d3SEliot Blennerhassett hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM, 407719f82d3SEliot Blennerhassett HPI_ISTREAM_RESET); 408719f82d3SEliot Blennerhassett hm.adapter_index = phm->adapter_index; 409719f82d3SEliot Blennerhassett hm.obj_index = phm->obj_index; 410719f82d3SEliot Blennerhassett hw_entry_point(&hm, &hr); 411719f82d3SEliot Blennerhassett 412719f82d3SEliot Blennerhassett hpios_msgxlock_lock(&msgx_lock); 413719f82d3SEliot Blennerhassett if (hr.error) { 414719f82d3SEliot Blennerhassett instream_user_open[phm->adapter_index][phm-> 415719f82d3SEliot Blennerhassett obj_index].open_flag = 0; 416719f82d3SEliot Blennerhassett phr->error = hr.error; 417719f82d3SEliot Blennerhassett } else { 418719f82d3SEliot Blennerhassett instream_user_open[phm->adapter_index][phm-> 419719f82d3SEliot Blennerhassett obj_index].open_flag = 1; 420719f82d3SEliot Blennerhassett instream_user_open[phm->adapter_index][phm-> 421719f82d3SEliot Blennerhassett obj_index].h_owner = h_owner; 422719f82d3SEliot Blennerhassett memcpy(phr, 423719f82d3SEliot Blennerhassett &rESP_HPI_ISTREAM_OPEN[phm->adapter_index] 424719f82d3SEliot Blennerhassett [phm->obj_index], 425719f82d3SEliot Blennerhassett sizeof(rESP_HPI_ISTREAM_OPEN[0][0])); 426719f82d3SEliot Blennerhassett } 427719f82d3SEliot Blennerhassett } 4283285ea10SEliot Blennerhassett hpios_msgxlock_unlock(&msgx_lock); 429719f82d3SEliot Blennerhassett } 430719f82d3SEliot Blennerhassett 431719f82d3SEliot Blennerhassett static void instream_close(struct hpi_message *phm, struct hpi_response *phr, 432719f82d3SEliot Blennerhassett void *h_owner) 433719f82d3SEliot Blennerhassett { 434719f82d3SEliot Blennerhassett 435719f82d3SEliot Blennerhassett struct hpi_message hm; 436719f82d3SEliot Blennerhassett struct hpi_response hr; 437719f82d3SEliot Blennerhassett 438719f82d3SEliot Blennerhassett hpi_init_response(phr, HPI_OBJ_ISTREAM, HPI_ISTREAM_CLOSE, 0); 439719f82d3SEliot Blennerhassett 440719f82d3SEliot Blennerhassett hpios_msgxlock_lock(&msgx_lock); 441719f82d3SEliot Blennerhassett if (h_owner == 442719f82d3SEliot Blennerhassett instream_user_open[phm->adapter_index][phm-> 443719f82d3SEliot Blennerhassett obj_index].h_owner) { 444719f82d3SEliot Blennerhassett /* HPI_DEBUG_LOG(INFO,"closing adapter %d " 445719f82d3SEliot Blennerhassett "instream %d owned by %p\n", 446719f82d3SEliot Blennerhassett phm->wAdapterIndex, phm->wObjIndex, hOwner); */ 447719f82d3SEliot Blennerhassett instream_user_open[phm->adapter_index][phm-> 448719f82d3SEliot Blennerhassett obj_index].h_owner = NULL; 4493285ea10SEliot Blennerhassett hpios_msgxlock_unlock(&msgx_lock); 450719f82d3SEliot Blennerhassett /* issue a reset */ 451719f82d3SEliot Blennerhassett hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM, 452719f82d3SEliot Blennerhassett HPI_ISTREAM_RESET); 453719f82d3SEliot Blennerhassett hm.adapter_index = phm->adapter_index; 454719f82d3SEliot Blennerhassett hm.obj_index = phm->obj_index; 455719f82d3SEliot Blennerhassett hw_entry_point(&hm, &hr); 456719f82d3SEliot Blennerhassett hpios_msgxlock_lock(&msgx_lock); 457719f82d3SEliot Blennerhassett if (hr.error) { 458719f82d3SEliot Blennerhassett instream_user_open[phm->adapter_index][phm-> 459719f82d3SEliot Blennerhassett obj_index].h_owner = h_owner; 460719f82d3SEliot Blennerhassett phr->error = hr.error; 461719f82d3SEliot Blennerhassett } else { 462719f82d3SEliot Blennerhassett instream_user_open[phm->adapter_index][phm-> 463719f82d3SEliot Blennerhassett obj_index].open_flag = 0; 464719f82d3SEliot Blennerhassett instream_user_open[phm->adapter_index][phm-> 465719f82d3SEliot Blennerhassett obj_index].h_owner = NULL; 466719f82d3SEliot Blennerhassett } 467719f82d3SEliot Blennerhassett } else { 468719f82d3SEliot Blennerhassett HPI_DEBUG_LOG(WARNING, 469719f82d3SEliot Blennerhassett "%p trying to close %d instream %d owned by %p\n", 470719f82d3SEliot Blennerhassett h_owner, phm->adapter_index, phm->obj_index, 471719f82d3SEliot Blennerhassett instream_user_open[phm->adapter_index][phm-> 472719f82d3SEliot Blennerhassett obj_index].h_owner); 473719f82d3SEliot Blennerhassett phr->error = HPI_ERROR_OBJ_NOT_OPEN; 474719f82d3SEliot Blennerhassett } 4753285ea10SEliot Blennerhassett hpios_msgxlock_unlock(&msgx_lock); 476719f82d3SEliot Blennerhassett } 477719f82d3SEliot Blennerhassett 478719f82d3SEliot Blennerhassett static void outstream_open(struct hpi_message *phm, struct hpi_response *phr, 479719f82d3SEliot Blennerhassett void *h_owner) 480719f82d3SEliot Blennerhassett { 481719f82d3SEliot Blennerhassett 482719f82d3SEliot Blennerhassett struct hpi_message hm; 483719f82d3SEliot Blennerhassett struct hpi_response hr; 484719f82d3SEliot Blennerhassett 485719f82d3SEliot Blennerhassett hpi_init_response(phr, HPI_OBJ_OSTREAM, HPI_OSTREAM_OPEN, 0); 486719f82d3SEliot Blennerhassett 487719f82d3SEliot Blennerhassett hpios_msgxlock_lock(&msgx_lock); 488719f82d3SEliot Blennerhassett 489719f82d3SEliot Blennerhassett if (outstream_user_open[phm->adapter_index][phm->obj_index].open_flag) 490719f82d3SEliot Blennerhassett phr->error = HPI_ERROR_OBJ_ALREADY_OPEN; 491719f82d3SEliot Blennerhassett else if (rESP_HPI_OSTREAM_OPEN[phm->adapter_index] 492719f82d3SEliot Blennerhassett [phm->obj_index].h.error) 493719f82d3SEliot Blennerhassett memcpy(phr, 494719f82d3SEliot Blennerhassett &rESP_HPI_OSTREAM_OPEN[phm->adapter_index][phm-> 495719f82d3SEliot Blennerhassett obj_index], 496719f82d3SEliot Blennerhassett sizeof(rESP_HPI_OSTREAM_OPEN[0][0])); 497719f82d3SEliot Blennerhassett else { 498719f82d3SEliot Blennerhassett outstream_user_open[phm->adapter_index][phm-> 499719f82d3SEliot Blennerhassett obj_index].open_flag = 1; 5003285ea10SEliot Blennerhassett hpios_msgxlock_unlock(&msgx_lock); 501719f82d3SEliot Blennerhassett 502719f82d3SEliot Blennerhassett /* issue a reset */ 503719f82d3SEliot Blennerhassett hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM, 504719f82d3SEliot Blennerhassett HPI_OSTREAM_RESET); 505719f82d3SEliot Blennerhassett hm.adapter_index = phm->adapter_index; 506719f82d3SEliot Blennerhassett hm.obj_index = phm->obj_index; 507719f82d3SEliot Blennerhassett hw_entry_point(&hm, &hr); 508719f82d3SEliot Blennerhassett 509719f82d3SEliot Blennerhassett hpios_msgxlock_lock(&msgx_lock); 510719f82d3SEliot Blennerhassett if (hr.error) { 511719f82d3SEliot Blennerhassett outstream_user_open[phm->adapter_index][phm-> 512719f82d3SEliot Blennerhassett obj_index].open_flag = 0; 513719f82d3SEliot Blennerhassett phr->error = hr.error; 514719f82d3SEliot Blennerhassett } else { 515719f82d3SEliot Blennerhassett outstream_user_open[phm->adapter_index][phm-> 516719f82d3SEliot Blennerhassett obj_index].open_flag = 1; 517719f82d3SEliot Blennerhassett outstream_user_open[phm->adapter_index][phm-> 518719f82d3SEliot Blennerhassett obj_index].h_owner = h_owner; 519719f82d3SEliot Blennerhassett memcpy(phr, 520719f82d3SEliot Blennerhassett &rESP_HPI_OSTREAM_OPEN[phm->adapter_index] 521719f82d3SEliot Blennerhassett [phm->obj_index], 522719f82d3SEliot Blennerhassett sizeof(rESP_HPI_OSTREAM_OPEN[0][0])); 523719f82d3SEliot Blennerhassett } 524719f82d3SEliot Blennerhassett } 5253285ea10SEliot Blennerhassett hpios_msgxlock_unlock(&msgx_lock); 526719f82d3SEliot Blennerhassett } 527719f82d3SEliot Blennerhassett 528719f82d3SEliot Blennerhassett static void outstream_close(struct hpi_message *phm, struct hpi_response *phr, 529719f82d3SEliot Blennerhassett void *h_owner) 530719f82d3SEliot Blennerhassett { 531719f82d3SEliot Blennerhassett 532719f82d3SEliot Blennerhassett struct hpi_message hm; 533719f82d3SEliot Blennerhassett struct hpi_response hr; 534719f82d3SEliot Blennerhassett 535719f82d3SEliot Blennerhassett hpi_init_response(phr, HPI_OBJ_OSTREAM, HPI_OSTREAM_CLOSE, 0); 536719f82d3SEliot Blennerhassett 537719f82d3SEliot Blennerhassett hpios_msgxlock_lock(&msgx_lock); 538719f82d3SEliot Blennerhassett 539719f82d3SEliot Blennerhassett if (h_owner == 540719f82d3SEliot Blennerhassett outstream_user_open[phm->adapter_index][phm-> 541719f82d3SEliot Blennerhassett obj_index].h_owner) { 542719f82d3SEliot Blennerhassett /* HPI_DEBUG_LOG(INFO,"closing adapter %d " 543719f82d3SEliot Blennerhassett "outstream %d owned by %p\n", 544719f82d3SEliot Blennerhassett phm->wAdapterIndex, phm->wObjIndex, hOwner); */ 545719f82d3SEliot Blennerhassett outstream_user_open[phm->adapter_index][phm-> 546719f82d3SEliot Blennerhassett obj_index].h_owner = NULL; 5473285ea10SEliot Blennerhassett hpios_msgxlock_unlock(&msgx_lock); 548719f82d3SEliot Blennerhassett /* issue a reset */ 549719f82d3SEliot Blennerhassett hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM, 550719f82d3SEliot Blennerhassett HPI_OSTREAM_RESET); 551719f82d3SEliot Blennerhassett hm.adapter_index = phm->adapter_index; 552719f82d3SEliot Blennerhassett hm.obj_index = phm->obj_index; 553719f82d3SEliot Blennerhassett hw_entry_point(&hm, &hr); 554719f82d3SEliot Blennerhassett hpios_msgxlock_lock(&msgx_lock); 555719f82d3SEliot Blennerhassett if (hr.error) { 556719f82d3SEliot Blennerhassett outstream_user_open[phm->adapter_index][phm-> 557719f82d3SEliot Blennerhassett obj_index].h_owner = h_owner; 558719f82d3SEliot Blennerhassett phr->error = hr.error; 559719f82d3SEliot Blennerhassett } else { 560719f82d3SEliot Blennerhassett outstream_user_open[phm->adapter_index][phm-> 561719f82d3SEliot Blennerhassett obj_index].open_flag = 0; 562719f82d3SEliot Blennerhassett outstream_user_open[phm->adapter_index][phm-> 563719f82d3SEliot Blennerhassett obj_index].h_owner = NULL; 564719f82d3SEliot Blennerhassett } 565719f82d3SEliot Blennerhassett } else { 566719f82d3SEliot Blennerhassett HPI_DEBUG_LOG(WARNING, 567719f82d3SEliot Blennerhassett "%p trying to close %d outstream %d owned by %p\n", 568719f82d3SEliot Blennerhassett h_owner, phm->adapter_index, phm->obj_index, 569719f82d3SEliot Blennerhassett outstream_user_open[phm->adapter_index][phm-> 570719f82d3SEliot Blennerhassett obj_index].h_owner); 571719f82d3SEliot Blennerhassett phr->error = HPI_ERROR_OBJ_NOT_OPEN; 572719f82d3SEliot Blennerhassett } 5733285ea10SEliot Blennerhassett hpios_msgxlock_unlock(&msgx_lock); 574719f82d3SEliot Blennerhassett } 575719f82d3SEliot Blennerhassett 576719f82d3SEliot Blennerhassett static u16 adapter_prepare(u16 adapter) 577719f82d3SEliot Blennerhassett { 578719f82d3SEliot Blennerhassett struct hpi_message hm; 579719f82d3SEliot Blennerhassett struct hpi_response hr; 580719f82d3SEliot Blennerhassett 581719f82d3SEliot Blennerhassett /* Open the adapter and streams */ 582719f82d3SEliot Blennerhassett u16 i; 583719f82d3SEliot Blennerhassett 584719f82d3SEliot Blennerhassett /* call to HPI_ADAPTER_OPEN */ 585719f82d3SEliot Blennerhassett hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER, 586719f82d3SEliot Blennerhassett HPI_ADAPTER_OPEN); 587719f82d3SEliot Blennerhassett hm.adapter_index = adapter; 588719f82d3SEliot Blennerhassett hw_entry_point(&hm, &hr); 589719f82d3SEliot Blennerhassett memcpy(&rESP_HPI_ADAPTER_OPEN[adapter], &hr, 590719f82d3SEliot Blennerhassett sizeof(rESP_HPI_ADAPTER_OPEN[0])); 591719f82d3SEliot Blennerhassett if (hr.error) 592719f82d3SEliot Blennerhassett return hr.error; 593719f82d3SEliot Blennerhassett 594719f82d3SEliot Blennerhassett /* call to HPI_ADAPTER_GET_INFO */ 595719f82d3SEliot Blennerhassett hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER, 596719f82d3SEliot Blennerhassett HPI_ADAPTER_GET_INFO); 597719f82d3SEliot Blennerhassett hm.adapter_index = adapter; 598719f82d3SEliot Blennerhassett hw_entry_point(&hm, &hr); 599719f82d3SEliot Blennerhassett if (hr.error) 600719f82d3SEliot Blennerhassett return hr.error; 601719f82d3SEliot Blennerhassett 6023285ea10SEliot Blennerhassett aDAPTER_INFO[adapter].num_outstreams = hr.u.ax.info.num_outstreams; 6033285ea10SEliot Blennerhassett aDAPTER_INFO[adapter].num_instreams = hr.u.ax.info.num_instreams; 6043285ea10SEliot Blennerhassett aDAPTER_INFO[adapter].type = hr.u.ax.info.adapter_type; 605719f82d3SEliot Blennerhassett 606719f82d3SEliot Blennerhassett /* call to HPI_OSTREAM_OPEN */ 607719f82d3SEliot Blennerhassett for (i = 0; i < aDAPTER_INFO[adapter].num_outstreams; i++) { 608719f82d3SEliot Blennerhassett hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM, 609719f82d3SEliot Blennerhassett HPI_OSTREAM_OPEN); 610719f82d3SEliot Blennerhassett hm.adapter_index = adapter; 611719f82d3SEliot Blennerhassett hm.obj_index = i; 612719f82d3SEliot Blennerhassett hw_entry_point(&hm, &hr); 613719f82d3SEliot Blennerhassett memcpy(&rESP_HPI_OSTREAM_OPEN[adapter][i], &hr, 614719f82d3SEliot Blennerhassett sizeof(rESP_HPI_OSTREAM_OPEN[0][0])); 615719f82d3SEliot Blennerhassett outstream_user_open[adapter][i].open_flag = 0; 616719f82d3SEliot Blennerhassett outstream_user_open[adapter][i].h_owner = NULL; 617719f82d3SEliot Blennerhassett } 618719f82d3SEliot Blennerhassett 619719f82d3SEliot Blennerhassett /* call to HPI_ISTREAM_OPEN */ 620719f82d3SEliot Blennerhassett for (i = 0; i < aDAPTER_INFO[adapter].num_instreams; i++) { 621719f82d3SEliot Blennerhassett hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM, 622719f82d3SEliot Blennerhassett HPI_ISTREAM_OPEN); 623719f82d3SEliot Blennerhassett hm.adapter_index = adapter; 624719f82d3SEliot Blennerhassett hm.obj_index = i; 625719f82d3SEliot Blennerhassett hw_entry_point(&hm, &hr); 626719f82d3SEliot Blennerhassett memcpy(&rESP_HPI_ISTREAM_OPEN[adapter][i], &hr, 627719f82d3SEliot Blennerhassett sizeof(rESP_HPI_ISTREAM_OPEN[0][0])); 628719f82d3SEliot Blennerhassett instream_user_open[adapter][i].open_flag = 0; 629719f82d3SEliot Blennerhassett instream_user_open[adapter][i].h_owner = NULL; 630719f82d3SEliot Blennerhassett } 631719f82d3SEliot Blennerhassett 632719f82d3SEliot Blennerhassett /* call to HPI_MIXER_OPEN */ 633719f82d3SEliot Blennerhassett hpi_init_message_response(&hm, &hr, HPI_OBJ_MIXER, HPI_MIXER_OPEN); 634719f82d3SEliot Blennerhassett hm.adapter_index = adapter; 635719f82d3SEliot Blennerhassett hw_entry_point(&hm, &hr); 636719f82d3SEliot Blennerhassett memcpy(&rESP_HPI_MIXER_OPEN[adapter], &hr, 637719f82d3SEliot Blennerhassett sizeof(rESP_HPI_MIXER_OPEN[0])); 638719f82d3SEliot Blennerhassett 6393285ea10SEliot Blennerhassett return 0; 640719f82d3SEliot Blennerhassett } 641719f82d3SEliot Blennerhassett 642719f82d3SEliot Blennerhassett static void HPIMSGX__reset(u16 adapter_index) 643719f82d3SEliot Blennerhassett { 644719f82d3SEliot Blennerhassett int i; 645719f82d3SEliot Blennerhassett u16 adapter; 646719f82d3SEliot Blennerhassett struct hpi_response hr; 647719f82d3SEliot Blennerhassett 648719f82d3SEliot Blennerhassett if (adapter_index == HPIMSGX_ALLADAPTERS) { 649719f82d3SEliot Blennerhassett for (adapter = 0; adapter < HPI_MAX_ADAPTERS; adapter++) { 650719f82d3SEliot Blennerhassett 651719f82d3SEliot Blennerhassett hpi_init_response(&hr, HPI_OBJ_ADAPTER, 652719f82d3SEliot Blennerhassett HPI_ADAPTER_OPEN, HPI_ERROR_BAD_ADAPTER); 653719f82d3SEliot Blennerhassett memcpy(&rESP_HPI_ADAPTER_OPEN[adapter], &hr, 654719f82d3SEliot Blennerhassett sizeof(rESP_HPI_ADAPTER_OPEN[adapter])); 655719f82d3SEliot Blennerhassett 656719f82d3SEliot Blennerhassett hpi_init_response(&hr, HPI_OBJ_MIXER, HPI_MIXER_OPEN, 657719f82d3SEliot Blennerhassett HPI_ERROR_INVALID_OBJ); 658719f82d3SEliot Blennerhassett memcpy(&rESP_HPI_MIXER_OPEN[adapter], &hr, 659719f82d3SEliot Blennerhassett sizeof(rESP_HPI_MIXER_OPEN[adapter])); 660719f82d3SEliot Blennerhassett 661719f82d3SEliot Blennerhassett for (i = 0; i < HPI_MAX_STREAMS; i++) { 662719f82d3SEliot Blennerhassett hpi_init_response(&hr, HPI_OBJ_OSTREAM, 663719f82d3SEliot Blennerhassett HPI_OSTREAM_OPEN, 664719f82d3SEliot Blennerhassett HPI_ERROR_INVALID_OBJ); 665719f82d3SEliot Blennerhassett memcpy(&rESP_HPI_OSTREAM_OPEN[adapter][i], 666719f82d3SEliot Blennerhassett &hr, 667719f82d3SEliot Blennerhassett sizeof(rESP_HPI_OSTREAM_OPEN[adapter] 668719f82d3SEliot Blennerhassett [i])); 669719f82d3SEliot Blennerhassett hpi_init_response(&hr, HPI_OBJ_ISTREAM, 670719f82d3SEliot Blennerhassett HPI_ISTREAM_OPEN, 671719f82d3SEliot Blennerhassett HPI_ERROR_INVALID_OBJ); 672719f82d3SEliot Blennerhassett memcpy(&rESP_HPI_ISTREAM_OPEN[adapter][i], 673719f82d3SEliot Blennerhassett &hr, 674719f82d3SEliot Blennerhassett sizeof(rESP_HPI_ISTREAM_OPEN[adapter] 675719f82d3SEliot Blennerhassett [i])); 676719f82d3SEliot Blennerhassett } 677719f82d3SEliot Blennerhassett } 678719f82d3SEliot Blennerhassett } else if (adapter_index < HPI_MAX_ADAPTERS) { 679719f82d3SEliot Blennerhassett rESP_HPI_ADAPTER_OPEN[adapter_index].h.error = 680719f82d3SEliot Blennerhassett HPI_ERROR_BAD_ADAPTER; 681719f82d3SEliot Blennerhassett rESP_HPI_MIXER_OPEN[adapter_index].h.error = 682719f82d3SEliot Blennerhassett HPI_ERROR_INVALID_OBJ; 683719f82d3SEliot Blennerhassett for (i = 0; i < HPI_MAX_STREAMS; i++) { 684719f82d3SEliot Blennerhassett rESP_HPI_OSTREAM_OPEN[adapter_index][i].h.error = 685719f82d3SEliot Blennerhassett HPI_ERROR_INVALID_OBJ; 686719f82d3SEliot Blennerhassett rESP_HPI_ISTREAM_OPEN[adapter_index][i].h.error = 687719f82d3SEliot Blennerhassett HPI_ERROR_INVALID_OBJ; 688719f82d3SEliot Blennerhassett } 689719f82d3SEliot Blennerhassett } 690719f82d3SEliot Blennerhassett } 691719f82d3SEliot Blennerhassett 692719f82d3SEliot Blennerhassett static u16 HPIMSGX__init(struct hpi_message *phm, 693719f82d3SEliot Blennerhassett /* HPI_SUBSYS_CREATE_ADAPTER structure with */ 694719f82d3SEliot Blennerhassett /* resource list or NULL=find all */ 695719f82d3SEliot Blennerhassett struct hpi_response *phr 696719f82d3SEliot Blennerhassett /* response from HPI_ADAPTER_GET_INFO */ 697719f82d3SEliot Blennerhassett ) 698719f82d3SEliot Blennerhassett { 699719f82d3SEliot Blennerhassett hpi_handler_func *entry_point_func; 700719f82d3SEliot Blennerhassett struct hpi_response hr; 701719f82d3SEliot Blennerhassett 702719f82d3SEliot Blennerhassett /* Init response here so we can pass in previous adapter list */ 703719f82d3SEliot Blennerhassett hpi_init_response(&hr, phm->object, phm->function, 704719f82d3SEliot Blennerhassett HPI_ERROR_INVALID_OBJ); 705719f82d3SEliot Blennerhassett 706719f82d3SEliot Blennerhassett entry_point_func = 707719f82d3SEliot Blennerhassett hpi_lookup_entry_point_function(phm->u.s.resource.r.pci); 708719f82d3SEliot Blennerhassett 709719f82d3SEliot Blennerhassett if (entry_point_func) { 710719f82d3SEliot Blennerhassett HPI_DEBUG_MESSAGE(DEBUG, phm); 711719f82d3SEliot Blennerhassett entry_point_func(phm, &hr); 712719f82d3SEliot Blennerhassett } else { 713719f82d3SEliot Blennerhassett phr->error = HPI_ERROR_PROCESSING_MESSAGE; 714719f82d3SEliot Blennerhassett return phr->error; 715719f82d3SEliot Blennerhassett } 716719f82d3SEliot Blennerhassett if (hr.error == 0) { 71725985edcSLucas De Marchi /* the adapter was created successfully 718719f82d3SEliot Blennerhassett save the mapping for future use */ 719719f82d3SEliot Blennerhassett hpi_entry_points[hr.u.s.adapter_index] = entry_point_func; 720719f82d3SEliot Blennerhassett /* prepare adapter (pre-open streams etc.) */ 721719f82d3SEliot Blennerhassett HPI_DEBUG_LOG(DEBUG, 722719f82d3SEliot Blennerhassett "HPI_SUBSYS_CREATE_ADAPTER successful," 723719f82d3SEliot Blennerhassett " preparing adapter\n"); 724719f82d3SEliot Blennerhassett adapter_prepare(hr.u.s.adapter_index); 725719f82d3SEliot Blennerhassett } 726719f82d3SEliot Blennerhassett memcpy(phr, &hr, hr.size); 727719f82d3SEliot Blennerhassett return phr->error; 728719f82d3SEliot Blennerhassett } 729719f82d3SEliot Blennerhassett 730719f82d3SEliot Blennerhassett static void HPIMSGX__cleanup(u16 adapter_index, void *h_owner) 731719f82d3SEliot Blennerhassett { 732719f82d3SEliot Blennerhassett int i, adapter, adapter_limit; 733719f82d3SEliot Blennerhassett 734719f82d3SEliot Blennerhassett if (!h_owner) 735719f82d3SEliot Blennerhassett return; 736719f82d3SEliot Blennerhassett 737719f82d3SEliot Blennerhassett if (adapter_index == HPIMSGX_ALLADAPTERS) { 738719f82d3SEliot Blennerhassett adapter = 0; 739719f82d3SEliot Blennerhassett adapter_limit = HPI_MAX_ADAPTERS; 740719f82d3SEliot Blennerhassett } else { 741719f82d3SEliot Blennerhassett adapter = adapter_index; 742719f82d3SEliot Blennerhassett adapter_limit = adapter + 1; 743719f82d3SEliot Blennerhassett } 744719f82d3SEliot Blennerhassett 745719f82d3SEliot Blennerhassett for (; adapter < adapter_limit; adapter++) { 746719f82d3SEliot Blennerhassett /* printk(KERN_INFO "Cleanup adapter #%d\n",wAdapter); */ 747719f82d3SEliot Blennerhassett for (i = 0; i < HPI_MAX_STREAMS; i++) { 748719f82d3SEliot Blennerhassett if (h_owner == 749719f82d3SEliot Blennerhassett outstream_user_open[adapter][i].h_owner) { 750719f82d3SEliot Blennerhassett struct hpi_message hm; 751719f82d3SEliot Blennerhassett struct hpi_response hr; 752719f82d3SEliot Blennerhassett 753719f82d3SEliot Blennerhassett HPI_DEBUG_LOG(DEBUG, 7543285ea10SEliot Blennerhassett "Close adapter %d ostream %d\n", 755719f82d3SEliot Blennerhassett adapter, i); 756719f82d3SEliot Blennerhassett 757719f82d3SEliot Blennerhassett hpi_init_message_response(&hm, &hr, 758719f82d3SEliot Blennerhassett HPI_OBJ_OSTREAM, HPI_OSTREAM_RESET); 759719f82d3SEliot Blennerhassett hm.adapter_index = (u16)adapter; 760719f82d3SEliot Blennerhassett hm.obj_index = (u16)i; 761719f82d3SEliot Blennerhassett hw_entry_point(&hm, &hr); 762719f82d3SEliot Blennerhassett 763719f82d3SEliot Blennerhassett hm.function = HPI_OSTREAM_HOSTBUFFER_FREE; 764719f82d3SEliot Blennerhassett hw_entry_point(&hm, &hr); 765719f82d3SEliot Blennerhassett 766719f82d3SEliot Blennerhassett hm.function = HPI_OSTREAM_GROUP_RESET; 767719f82d3SEliot Blennerhassett hw_entry_point(&hm, &hr); 768719f82d3SEliot Blennerhassett 769719f82d3SEliot Blennerhassett outstream_user_open[adapter][i].open_flag = 0; 770719f82d3SEliot Blennerhassett outstream_user_open[adapter][i].h_owner = 771719f82d3SEliot Blennerhassett NULL; 772719f82d3SEliot Blennerhassett } 773719f82d3SEliot Blennerhassett if (h_owner == instream_user_open[adapter][i].h_owner) { 774719f82d3SEliot Blennerhassett struct hpi_message hm; 775719f82d3SEliot Blennerhassett struct hpi_response hr; 776719f82d3SEliot Blennerhassett 777719f82d3SEliot Blennerhassett HPI_DEBUG_LOG(DEBUG, 7783285ea10SEliot Blennerhassett "Close adapter %d istream %d\n", 779719f82d3SEliot Blennerhassett adapter, i); 780719f82d3SEliot Blennerhassett 781719f82d3SEliot Blennerhassett hpi_init_message_response(&hm, &hr, 782719f82d3SEliot Blennerhassett HPI_OBJ_ISTREAM, HPI_ISTREAM_RESET); 783719f82d3SEliot Blennerhassett hm.adapter_index = (u16)adapter; 784719f82d3SEliot Blennerhassett hm.obj_index = (u16)i; 785719f82d3SEliot Blennerhassett hw_entry_point(&hm, &hr); 786719f82d3SEliot Blennerhassett 787719f82d3SEliot Blennerhassett hm.function = HPI_ISTREAM_HOSTBUFFER_FREE; 788719f82d3SEliot Blennerhassett hw_entry_point(&hm, &hr); 789719f82d3SEliot Blennerhassett 790719f82d3SEliot Blennerhassett hm.function = HPI_ISTREAM_GROUP_RESET; 791719f82d3SEliot Blennerhassett hw_entry_point(&hm, &hr); 792719f82d3SEliot Blennerhassett 793719f82d3SEliot Blennerhassett instream_user_open[adapter][i].open_flag = 0; 794719f82d3SEliot Blennerhassett instream_user_open[adapter][i].h_owner = NULL; 795719f82d3SEliot Blennerhassett } 796719f82d3SEliot Blennerhassett } 797719f82d3SEliot Blennerhassett } 798719f82d3SEliot Blennerhassett } 799