1719f82d3SEliot Blennerhassett /****************************************************************************** 2719f82d3SEliot Blennerhassett 3719f82d3SEliot Blennerhassett AudioScience HPI driver 4719f82d3SEliot Blennerhassett Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com> 5719f82d3SEliot Blennerhassett 6719f82d3SEliot Blennerhassett This program is free software; you can redistribute it and/or modify 7719f82d3SEliot Blennerhassett it under the terms of version 2 of the GNU General Public License as 8719f82d3SEliot Blennerhassett published by the Free Software Foundation; 9719f82d3SEliot Blennerhassett 10719f82d3SEliot Blennerhassett This program is distributed in the hope that it will be useful, 11719f82d3SEliot Blennerhassett but WITHOUT ANY WARRANTY; without even the implied warranty of 12719f82d3SEliot Blennerhassett MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13719f82d3SEliot Blennerhassett GNU General Public License for more details. 14719f82d3SEliot Blennerhassett 15719f82d3SEliot Blennerhassett You should have received a copy of the GNU General Public License 16719f82d3SEliot Blennerhassett along with this program; if not, write to the Free Software 17719f82d3SEliot Blennerhassett Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18719f82d3SEliot Blennerhassett 19719f82d3SEliot Blennerhassett Extended Message Function With Response Cacheing 20719f82d3SEliot Blennerhassett 21719f82d3SEliot Blennerhassett (C) Copyright AudioScience Inc. 2002 22719f82d3SEliot Blennerhassett *****************************************************************************/ 23719f82d3SEliot Blennerhassett #define SOURCEFILE_NAME "hpimsgx.c" 24719f82d3SEliot Blennerhassett #include "hpi_internal.h" 25719f82d3SEliot Blennerhassett #include "hpimsginit.h" 26*3285ea10SEliot Blennerhassett #include "hpicmn.h" 27719f82d3SEliot Blennerhassett #include "hpimsgx.h" 28719f82d3SEliot Blennerhassett #include "hpidebug.h" 29719f82d3SEliot Blennerhassett 30719f82d3SEliot Blennerhassett static struct pci_device_id asihpi_pci_tbl[] = { 31719f82d3SEliot Blennerhassett #include "hpipcida.h" 32719f82d3SEliot Blennerhassett }; 33719f82d3SEliot Blennerhassett 34719f82d3SEliot Blennerhassett static struct hpios_spinlock msgx_lock; 35719f82d3SEliot Blennerhassett 36719f82d3SEliot Blennerhassett static hpi_handler_func *hpi_entry_points[HPI_MAX_ADAPTERS]; 37719f82d3SEliot Blennerhassett 38719f82d3SEliot Blennerhassett static hpi_handler_func *hpi_lookup_entry_point_function(const struct hpi_pci 39719f82d3SEliot Blennerhassett *pci_info) 40719f82d3SEliot Blennerhassett { 41719f82d3SEliot Blennerhassett 42719f82d3SEliot Blennerhassett int i; 43719f82d3SEliot Blennerhassett 44719f82d3SEliot Blennerhassett for (i = 0; asihpi_pci_tbl[i].vendor != 0; i++) { 45719f82d3SEliot Blennerhassett if (asihpi_pci_tbl[i].vendor != PCI_ANY_ID 46*3285ea10SEliot Blennerhassett && asihpi_pci_tbl[i].vendor != 47*3285ea10SEliot Blennerhassett pci_info->pci_dev->vendor) 48719f82d3SEliot Blennerhassett continue; 49719f82d3SEliot Blennerhassett if (asihpi_pci_tbl[i].device != PCI_ANY_ID 50*3285ea10SEliot Blennerhassett && asihpi_pci_tbl[i].device != 51*3285ea10SEliot Blennerhassett pci_info->pci_dev->device) 52719f82d3SEliot Blennerhassett continue; 53719f82d3SEliot Blennerhassett if (asihpi_pci_tbl[i].subvendor != PCI_ANY_ID 54719f82d3SEliot Blennerhassett && asihpi_pci_tbl[i].subvendor != 55*3285ea10SEliot Blennerhassett pci_info->pci_dev->subsystem_vendor) 56719f82d3SEliot Blennerhassett continue; 57719f82d3SEliot Blennerhassett if (asihpi_pci_tbl[i].subdevice != PCI_ANY_ID 58719f82d3SEliot Blennerhassett && asihpi_pci_tbl[i].subdevice != 59*3285ea10SEliot Blennerhassett pci_info->pci_dev->subsystem_device) 60719f82d3SEliot Blennerhassett continue; 61719f82d3SEliot Blennerhassett 62*3285ea10SEliot Blennerhassett /* HPI_DEBUG_LOG(DEBUG, " %x,%lx\n", i, 63*3285ea10SEliot Blennerhassett asihpi_pci_tbl[i].driver_data); */ 64719f82d3SEliot Blennerhassett return (hpi_handler_func *) asihpi_pci_tbl[i].driver_data; 65719f82d3SEliot Blennerhassett } 66719f82d3SEliot Blennerhassett 67719f82d3SEliot Blennerhassett return NULL; 68719f82d3SEliot Blennerhassett } 69719f82d3SEliot Blennerhassett 70719f82d3SEliot Blennerhassett static inline void hw_entry_point(struct hpi_message *phm, 71719f82d3SEliot Blennerhassett struct hpi_response *phr) 72719f82d3SEliot Blennerhassett { 73*3285ea10SEliot Blennerhassett if ((phm->adapter_index < HPI_MAX_ADAPTERS) 74*3285ea10SEliot Blennerhassett && hpi_entry_points[phm->adapter_index]) 75*3285ea10SEliot Blennerhassett hpi_entry_points[phm->adapter_index] (phm, phr); 76*3285ea10SEliot Blennerhassett else 77719f82d3SEliot Blennerhassett hpi_init_response(phr, phm->object, phm->function, 78719f82d3SEliot Blennerhassett HPI_ERROR_PROCESSING_MESSAGE); 79719f82d3SEliot Blennerhassett } 80719f82d3SEliot Blennerhassett 81719f82d3SEliot Blennerhassett static void adapter_open(struct hpi_message *phm, struct hpi_response *phr); 82719f82d3SEliot Blennerhassett static void adapter_close(struct hpi_message *phm, struct hpi_response *phr); 83719f82d3SEliot Blennerhassett 84719f82d3SEliot Blennerhassett static void mixer_open(struct hpi_message *phm, struct hpi_response *phr); 85719f82d3SEliot Blennerhassett static void mixer_close(struct hpi_message *phm, struct hpi_response *phr); 86719f82d3SEliot Blennerhassett 87719f82d3SEliot Blennerhassett static void outstream_open(struct hpi_message *phm, struct hpi_response *phr, 88719f82d3SEliot Blennerhassett void *h_owner); 89719f82d3SEliot Blennerhassett static void outstream_close(struct hpi_message *phm, struct hpi_response *phr, 90719f82d3SEliot Blennerhassett void *h_owner); 91719f82d3SEliot Blennerhassett static void instream_open(struct hpi_message *phm, struct hpi_response *phr, 92719f82d3SEliot Blennerhassett void *h_owner); 93719f82d3SEliot Blennerhassett static void instream_close(struct hpi_message *phm, struct hpi_response *phr, 94719f82d3SEliot Blennerhassett void *h_owner); 95719f82d3SEliot Blennerhassett 96719f82d3SEliot Blennerhassett static void HPIMSGX__reset(u16 adapter_index); 97*3285ea10SEliot Blennerhassett 98719f82d3SEliot Blennerhassett static u16 HPIMSGX__init(struct hpi_message *phm, struct hpi_response *phr); 99719f82d3SEliot Blennerhassett static void HPIMSGX__cleanup(u16 adapter_index, void *h_owner); 100719f82d3SEliot Blennerhassett 101719f82d3SEliot Blennerhassett #ifndef DISABLE_PRAGMA_PACK1 102719f82d3SEliot Blennerhassett #pragma pack(push, 1) 103719f82d3SEliot Blennerhassett #endif 104719f82d3SEliot Blennerhassett 105719f82d3SEliot Blennerhassett struct hpi_subsys_response { 106719f82d3SEliot Blennerhassett struct hpi_response_header h; 107719f82d3SEliot Blennerhassett struct hpi_subsys_res s; 108719f82d3SEliot Blennerhassett }; 109719f82d3SEliot Blennerhassett 110719f82d3SEliot Blennerhassett struct hpi_adapter_response { 111719f82d3SEliot Blennerhassett struct hpi_response_header h; 112719f82d3SEliot Blennerhassett struct hpi_adapter_res a; 113719f82d3SEliot Blennerhassett }; 114719f82d3SEliot Blennerhassett 115719f82d3SEliot Blennerhassett struct hpi_mixer_response { 116719f82d3SEliot Blennerhassett struct hpi_response_header h; 117719f82d3SEliot Blennerhassett struct hpi_mixer_res m; 118719f82d3SEliot Blennerhassett }; 119719f82d3SEliot Blennerhassett 120719f82d3SEliot Blennerhassett struct hpi_stream_response { 121719f82d3SEliot Blennerhassett struct hpi_response_header h; 122719f82d3SEliot Blennerhassett struct hpi_stream_res d; 123719f82d3SEliot Blennerhassett }; 124719f82d3SEliot Blennerhassett 125719f82d3SEliot Blennerhassett struct adapter_info { 126719f82d3SEliot Blennerhassett u16 type; 127719f82d3SEliot Blennerhassett u16 num_instreams; 128719f82d3SEliot Blennerhassett u16 num_outstreams; 129719f82d3SEliot Blennerhassett }; 130719f82d3SEliot Blennerhassett 131719f82d3SEliot Blennerhassett struct asi_open_state { 132719f82d3SEliot Blennerhassett int open_flag; 133719f82d3SEliot Blennerhassett void *h_owner; 134719f82d3SEliot Blennerhassett }; 135719f82d3SEliot Blennerhassett 136719f82d3SEliot Blennerhassett #ifndef DISABLE_PRAGMA_PACK1 137719f82d3SEliot Blennerhassett #pragma pack(pop) 138719f82d3SEliot Blennerhassett #endif 139719f82d3SEliot Blennerhassett 140719f82d3SEliot Blennerhassett /* Globals */ 141719f82d3SEliot Blennerhassett static struct hpi_adapter_response rESP_HPI_ADAPTER_OPEN[HPI_MAX_ADAPTERS]; 142719f82d3SEliot Blennerhassett 143719f82d3SEliot Blennerhassett static struct hpi_stream_response 144719f82d3SEliot Blennerhassett rESP_HPI_OSTREAM_OPEN[HPI_MAX_ADAPTERS][HPI_MAX_STREAMS]; 145719f82d3SEliot Blennerhassett 146719f82d3SEliot Blennerhassett static struct hpi_stream_response 147719f82d3SEliot Blennerhassett rESP_HPI_ISTREAM_OPEN[HPI_MAX_ADAPTERS][HPI_MAX_STREAMS]; 148719f82d3SEliot Blennerhassett 149719f82d3SEliot Blennerhassett static struct hpi_mixer_response rESP_HPI_MIXER_OPEN[HPI_MAX_ADAPTERS]; 150719f82d3SEliot Blennerhassett 151719f82d3SEliot Blennerhassett static struct adapter_info aDAPTER_INFO[HPI_MAX_ADAPTERS]; 152719f82d3SEliot Blennerhassett 153719f82d3SEliot Blennerhassett /* use these to keep track of opens from user mode apps/DLLs */ 154719f82d3SEliot Blennerhassett static struct asi_open_state 155719f82d3SEliot Blennerhassett outstream_user_open[HPI_MAX_ADAPTERS][HPI_MAX_STREAMS]; 156719f82d3SEliot Blennerhassett 157719f82d3SEliot Blennerhassett static struct asi_open_state 158719f82d3SEliot Blennerhassett instream_user_open[HPI_MAX_ADAPTERS][HPI_MAX_STREAMS]; 159719f82d3SEliot Blennerhassett 160719f82d3SEliot Blennerhassett static void subsys_message(struct hpi_message *phm, struct hpi_response *phr, 161719f82d3SEliot Blennerhassett void *h_owner) 162719f82d3SEliot Blennerhassett { 163*3285ea10SEliot Blennerhassett if (phm->adapter_index != HPI_ADAPTER_INDEX_INVALID) 164*3285ea10SEliot Blennerhassett HPI_DEBUG_LOG(WARNING, 165*3285ea10SEliot Blennerhassett "suspicious adapter index %d in subsys message 0x%x.\n", 166*3285ea10SEliot Blennerhassett phm->adapter_index, phm->function); 167*3285ea10SEliot Blennerhassett 168719f82d3SEliot Blennerhassett switch (phm->function) { 169719f82d3SEliot Blennerhassett case HPI_SUBSYS_GET_VERSION: 170719f82d3SEliot Blennerhassett hpi_init_response(phr, HPI_OBJ_SUBSYSTEM, 171719f82d3SEliot Blennerhassett HPI_SUBSYS_GET_VERSION, 0); 172719f82d3SEliot Blennerhassett phr->u.s.version = HPI_VER >> 8; /* return major.minor */ 173719f82d3SEliot Blennerhassett phr->u.s.data = HPI_VER; /* return major.minor.release */ 174719f82d3SEliot Blennerhassett break; 175719f82d3SEliot Blennerhassett case HPI_SUBSYS_OPEN: 176719f82d3SEliot Blennerhassett /*do not propagate the message down the chain */ 177719f82d3SEliot Blennerhassett hpi_init_response(phr, HPI_OBJ_SUBSYSTEM, HPI_SUBSYS_OPEN, 0); 178719f82d3SEliot Blennerhassett break; 179719f82d3SEliot Blennerhassett case HPI_SUBSYS_CLOSE: 180719f82d3SEliot Blennerhassett /*do not propagate the message down the chain */ 181719f82d3SEliot Blennerhassett hpi_init_response(phr, HPI_OBJ_SUBSYSTEM, HPI_SUBSYS_CLOSE, 182719f82d3SEliot Blennerhassett 0); 183719f82d3SEliot Blennerhassett HPIMSGX__cleanup(HPIMSGX_ALLADAPTERS, h_owner); 184719f82d3SEliot Blennerhassett break; 185719f82d3SEliot Blennerhassett case HPI_SUBSYS_DRIVER_LOAD: 186719f82d3SEliot Blennerhassett /* Initialize this module's internal state */ 187719f82d3SEliot Blennerhassett hpios_msgxlock_init(&msgx_lock); 188719f82d3SEliot Blennerhassett memset(&hpi_entry_points, 0, sizeof(hpi_entry_points)); 189719f82d3SEliot Blennerhassett hpios_locked_mem_init(); 190719f82d3SEliot Blennerhassett /* Init subsys_findadapters response to no-adapters */ 191719f82d3SEliot Blennerhassett HPIMSGX__reset(HPIMSGX_ALLADAPTERS); 192719f82d3SEliot Blennerhassett hpi_init_response(phr, HPI_OBJ_SUBSYSTEM, 193719f82d3SEliot Blennerhassett HPI_SUBSYS_DRIVER_LOAD, 0); 194719f82d3SEliot Blennerhassett /* individual HPIs dont implement driver load */ 195719f82d3SEliot Blennerhassett HPI_COMMON(phm, phr); 196719f82d3SEliot Blennerhassett break; 197719f82d3SEliot Blennerhassett case HPI_SUBSYS_DRIVER_UNLOAD: 198719f82d3SEliot Blennerhassett HPI_COMMON(phm, phr); 199719f82d3SEliot Blennerhassett HPIMSGX__cleanup(HPIMSGX_ALLADAPTERS, h_owner); 200719f82d3SEliot Blennerhassett hpios_locked_mem_free_all(); 201719f82d3SEliot Blennerhassett hpi_init_response(phr, HPI_OBJ_SUBSYSTEM, 202719f82d3SEliot Blennerhassett HPI_SUBSYS_DRIVER_UNLOAD, 0); 203719f82d3SEliot Blennerhassett return; 204719f82d3SEliot Blennerhassett 205*3285ea10SEliot Blennerhassett case HPI_SUBSYS_GET_NUM_ADAPTERS: 206*3285ea10SEliot Blennerhassett case HPI_SUBSYS_GET_ADAPTER: 207719f82d3SEliot Blennerhassett HPI_COMMON(phm, phr); 208719f82d3SEliot Blennerhassett break; 209719f82d3SEliot Blennerhassett 210719f82d3SEliot Blennerhassett case HPI_SUBSYS_CREATE_ADAPTER: 211719f82d3SEliot Blennerhassett HPIMSGX__init(phm, phr); 212719f82d3SEliot Blennerhassett break; 213*3285ea10SEliot Blennerhassett 214719f82d3SEliot Blennerhassett case HPI_SUBSYS_DELETE_ADAPTER: 215*3285ea10SEliot Blennerhassett HPIMSGX__cleanup(phm->obj_index, h_owner); 216719f82d3SEliot Blennerhassett { 217719f82d3SEliot Blennerhassett struct hpi_message hm; 218719f82d3SEliot Blennerhassett struct hpi_response hr; 219719f82d3SEliot Blennerhassett hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER, 220719f82d3SEliot Blennerhassett HPI_ADAPTER_CLOSE); 221*3285ea10SEliot Blennerhassett hm.adapter_index = phm->obj_index; 222719f82d3SEliot Blennerhassett hw_entry_point(&hm, &hr); 223719f82d3SEliot Blennerhassett } 224*3285ea10SEliot Blennerhassett if ((phm->obj_index < HPI_MAX_ADAPTERS) 225*3285ea10SEliot Blennerhassett && hpi_entry_points[phm->obj_index]) { 226*3285ea10SEliot Blennerhassett hpi_entry_points[phm->obj_index] (phm, phr); 227*3285ea10SEliot Blennerhassett hpi_entry_points[phm->obj_index] = NULL; 228*3285ea10SEliot Blennerhassett } else 229*3285ea10SEliot Blennerhassett phr->error = HPI_ERROR_INVALID_OBJ_INDEX; 230*3285ea10SEliot Blennerhassett 231719f82d3SEliot Blennerhassett break; 232719f82d3SEliot Blennerhassett default: 233*3285ea10SEliot Blennerhassett /* Must explicitly send subsys messages to individual backends */ 234*3285ea10SEliot Blennerhassett hpi_init_response(phr, HPI_OBJ_SUBSYSTEM, phm->function, 235*3285ea10SEliot Blennerhassett HPI_ERROR_INVALID_FUNC); 236719f82d3SEliot Blennerhassett break; 237719f82d3SEliot Blennerhassett } 238719f82d3SEliot Blennerhassett } 239719f82d3SEliot Blennerhassett 240719f82d3SEliot Blennerhassett static void adapter_message(struct hpi_message *phm, struct hpi_response *phr, 241719f82d3SEliot Blennerhassett void *h_owner) 242719f82d3SEliot Blennerhassett { 243719f82d3SEliot Blennerhassett switch (phm->function) { 244719f82d3SEliot Blennerhassett case HPI_ADAPTER_OPEN: 245719f82d3SEliot Blennerhassett adapter_open(phm, phr); 246719f82d3SEliot Blennerhassett break; 247719f82d3SEliot Blennerhassett case HPI_ADAPTER_CLOSE: 248719f82d3SEliot Blennerhassett adapter_close(phm, phr); 249719f82d3SEliot Blennerhassett break; 250719f82d3SEliot Blennerhassett default: 251719f82d3SEliot Blennerhassett hw_entry_point(phm, phr); 252719f82d3SEliot Blennerhassett break; 253719f82d3SEliot Blennerhassett } 254719f82d3SEliot Blennerhassett } 255719f82d3SEliot Blennerhassett 256719f82d3SEliot Blennerhassett static void mixer_message(struct hpi_message *phm, struct hpi_response *phr) 257719f82d3SEliot Blennerhassett { 258719f82d3SEliot Blennerhassett switch (phm->function) { 259719f82d3SEliot Blennerhassett case HPI_MIXER_OPEN: 260719f82d3SEliot Blennerhassett mixer_open(phm, phr); 261719f82d3SEliot Blennerhassett break; 262719f82d3SEliot Blennerhassett case HPI_MIXER_CLOSE: 263719f82d3SEliot Blennerhassett mixer_close(phm, phr); 264719f82d3SEliot Blennerhassett break; 265719f82d3SEliot Blennerhassett default: 266719f82d3SEliot Blennerhassett hw_entry_point(phm, phr); 267719f82d3SEliot Blennerhassett break; 268719f82d3SEliot Blennerhassett } 269719f82d3SEliot Blennerhassett } 270719f82d3SEliot Blennerhassett 271719f82d3SEliot Blennerhassett static void outstream_message(struct hpi_message *phm, 272719f82d3SEliot Blennerhassett struct hpi_response *phr, void *h_owner) 273719f82d3SEliot Blennerhassett { 274719f82d3SEliot Blennerhassett if (phm->obj_index >= aDAPTER_INFO[phm->adapter_index].num_outstreams) { 275719f82d3SEliot Blennerhassett hpi_init_response(phr, HPI_OBJ_OSTREAM, phm->function, 276719f82d3SEliot Blennerhassett HPI_ERROR_INVALID_OBJ_INDEX); 277719f82d3SEliot Blennerhassett return; 278719f82d3SEliot Blennerhassett } 279719f82d3SEliot Blennerhassett 280719f82d3SEliot Blennerhassett switch (phm->function) { 281719f82d3SEliot Blennerhassett case HPI_OSTREAM_OPEN: 282719f82d3SEliot Blennerhassett outstream_open(phm, phr, h_owner); 283719f82d3SEliot Blennerhassett break; 284719f82d3SEliot Blennerhassett case HPI_OSTREAM_CLOSE: 285719f82d3SEliot Blennerhassett outstream_close(phm, phr, h_owner); 286719f82d3SEliot Blennerhassett break; 287719f82d3SEliot Blennerhassett default: 288719f82d3SEliot Blennerhassett hw_entry_point(phm, phr); 289719f82d3SEliot Blennerhassett break; 290719f82d3SEliot Blennerhassett } 291719f82d3SEliot Blennerhassett } 292719f82d3SEliot Blennerhassett 293719f82d3SEliot Blennerhassett static void instream_message(struct hpi_message *phm, 294719f82d3SEliot Blennerhassett struct hpi_response *phr, void *h_owner) 295719f82d3SEliot Blennerhassett { 296719f82d3SEliot Blennerhassett if (phm->obj_index >= aDAPTER_INFO[phm->adapter_index].num_instreams) { 297719f82d3SEliot Blennerhassett hpi_init_response(phr, HPI_OBJ_ISTREAM, phm->function, 298719f82d3SEliot Blennerhassett HPI_ERROR_INVALID_OBJ_INDEX); 299719f82d3SEliot Blennerhassett return; 300719f82d3SEliot Blennerhassett } 301719f82d3SEliot Blennerhassett 302719f82d3SEliot Blennerhassett switch (phm->function) { 303719f82d3SEliot Blennerhassett case HPI_ISTREAM_OPEN: 304719f82d3SEliot Blennerhassett instream_open(phm, phr, h_owner); 305719f82d3SEliot Blennerhassett break; 306719f82d3SEliot Blennerhassett case HPI_ISTREAM_CLOSE: 307719f82d3SEliot Blennerhassett instream_close(phm, phr, h_owner); 308719f82d3SEliot Blennerhassett break; 309719f82d3SEliot Blennerhassett default: 310719f82d3SEliot Blennerhassett hw_entry_point(phm, phr); 311719f82d3SEliot Blennerhassett break; 312719f82d3SEliot Blennerhassett } 313719f82d3SEliot Blennerhassett } 314719f82d3SEliot Blennerhassett 315719f82d3SEliot Blennerhassett /* NOTE: HPI_Message() must be defined in the driver as a wrapper for 316719f82d3SEliot Blennerhassett * HPI_MessageEx so that functions in hpifunc.c compile. 317719f82d3SEliot Blennerhassett */ 318719f82d3SEliot Blennerhassett void hpi_send_recv_ex(struct hpi_message *phm, struct hpi_response *phr, 319719f82d3SEliot Blennerhassett void *h_owner) 320719f82d3SEliot Blennerhassett { 321719f82d3SEliot Blennerhassett HPI_DEBUG_MESSAGE(DEBUG, phm); 322719f82d3SEliot Blennerhassett 323719f82d3SEliot Blennerhassett if (phm->type != HPI_TYPE_MESSAGE) { 324719f82d3SEliot Blennerhassett hpi_init_response(phr, phm->object, phm->function, 325719f82d3SEliot Blennerhassett HPI_ERROR_INVALID_TYPE); 326719f82d3SEliot Blennerhassett return; 327719f82d3SEliot Blennerhassett } 328719f82d3SEliot Blennerhassett 329719f82d3SEliot Blennerhassett if (phm->adapter_index >= HPI_MAX_ADAPTERS 330719f82d3SEliot Blennerhassett && phm->adapter_index != HPIMSGX_ALLADAPTERS) { 331719f82d3SEliot Blennerhassett hpi_init_response(phr, phm->object, phm->function, 332719f82d3SEliot Blennerhassett HPI_ERROR_BAD_ADAPTER_NUMBER); 333719f82d3SEliot Blennerhassett return; 334719f82d3SEliot Blennerhassett } 335719f82d3SEliot Blennerhassett 336719f82d3SEliot Blennerhassett switch (phm->object) { 337719f82d3SEliot Blennerhassett case HPI_OBJ_SUBSYSTEM: 338719f82d3SEliot Blennerhassett subsys_message(phm, phr, h_owner); 339719f82d3SEliot Blennerhassett break; 340719f82d3SEliot Blennerhassett 341719f82d3SEliot Blennerhassett case HPI_OBJ_ADAPTER: 342719f82d3SEliot Blennerhassett adapter_message(phm, phr, h_owner); 343719f82d3SEliot Blennerhassett break; 344719f82d3SEliot Blennerhassett 345719f82d3SEliot Blennerhassett case HPI_OBJ_MIXER: 346719f82d3SEliot Blennerhassett mixer_message(phm, phr); 347719f82d3SEliot Blennerhassett break; 348719f82d3SEliot Blennerhassett 349719f82d3SEliot Blennerhassett case HPI_OBJ_OSTREAM: 350719f82d3SEliot Blennerhassett outstream_message(phm, phr, h_owner); 351719f82d3SEliot Blennerhassett break; 352719f82d3SEliot Blennerhassett 353719f82d3SEliot Blennerhassett case HPI_OBJ_ISTREAM: 354719f82d3SEliot Blennerhassett instream_message(phm, phr, h_owner); 355719f82d3SEliot Blennerhassett break; 356719f82d3SEliot Blennerhassett 357719f82d3SEliot Blennerhassett default: 358719f82d3SEliot Blennerhassett hw_entry_point(phm, phr); 359719f82d3SEliot Blennerhassett break; 360719f82d3SEliot Blennerhassett } 361719f82d3SEliot Blennerhassett HPI_DEBUG_RESPONSE(phr); 362719f82d3SEliot Blennerhassett 363719f82d3SEliot Blennerhassett } 364719f82d3SEliot Blennerhassett 365719f82d3SEliot Blennerhassett static void adapter_open(struct hpi_message *phm, struct hpi_response *phr) 366719f82d3SEliot Blennerhassett { 367719f82d3SEliot Blennerhassett HPI_DEBUG_LOG(VERBOSE, "adapter_open\n"); 368719f82d3SEliot Blennerhassett memcpy(phr, &rESP_HPI_ADAPTER_OPEN[phm->adapter_index], 369719f82d3SEliot Blennerhassett sizeof(rESP_HPI_ADAPTER_OPEN[0])); 370719f82d3SEliot Blennerhassett } 371719f82d3SEliot Blennerhassett 372719f82d3SEliot Blennerhassett static void adapter_close(struct hpi_message *phm, struct hpi_response *phr) 373719f82d3SEliot Blennerhassett { 374719f82d3SEliot Blennerhassett HPI_DEBUG_LOG(VERBOSE, "adapter_close\n"); 375719f82d3SEliot Blennerhassett hpi_init_response(phr, HPI_OBJ_ADAPTER, HPI_ADAPTER_CLOSE, 0); 376719f82d3SEliot Blennerhassett } 377719f82d3SEliot Blennerhassett 378719f82d3SEliot Blennerhassett static void mixer_open(struct hpi_message *phm, struct hpi_response *phr) 379719f82d3SEliot Blennerhassett { 380719f82d3SEliot Blennerhassett memcpy(phr, &rESP_HPI_MIXER_OPEN[phm->adapter_index], 381719f82d3SEliot Blennerhassett sizeof(rESP_HPI_MIXER_OPEN[0])); 382719f82d3SEliot Blennerhassett } 383719f82d3SEliot Blennerhassett 384719f82d3SEliot Blennerhassett static void mixer_close(struct hpi_message *phm, struct hpi_response *phr) 385719f82d3SEliot Blennerhassett { 386719f82d3SEliot Blennerhassett hpi_init_response(phr, HPI_OBJ_MIXER, HPI_MIXER_CLOSE, 0); 387719f82d3SEliot Blennerhassett } 388719f82d3SEliot Blennerhassett 389719f82d3SEliot Blennerhassett static void instream_open(struct hpi_message *phm, struct hpi_response *phr, 390719f82d3SEliot Blennerhassett void *h_owner) 391719f82d3SEliot Blennerhassett { 392719f82d3SEliot Blennerhassett 393719f82d3SEliot Blennerhassett struct hpi_message hm; 394719f82d3SEliot Blennerhassett struct hpi_response hr; 395719f82d3SEliot Blennerhassett 396719f82d3SEliot Blennerhassett hpi_init_response(phr, HPI_OBJ_ISTREAM, HPI_ISTREAM_OPEN, 0); 397719f82d3SEliot Blennerhassett 398719f82d3SEliot Blennerhassett hpios_msgxlock_lock(&msgx_lock); 399719f82d3SEliot Blennerhassett 400719f82d3SEliot Blennerhassett if (instream_user_open[phm->adapter_index][phm->obj_index].open_flag) 401719f82d3SEliot Blennerhassett phr->error = HPI_ERROR_OBJ_ALREADY_OPEN; 402719f82d3SEliot Blennerhassett else if (rESP_HPI_ISTREAM_OPEN[phm->adapter_index] 403719f82d3SEliot Blennerhassett [phm->obj_index].h.error) 404719f82d3SEliot Blennerhassett memcpy(phr, 405719f82d3SEliot Blennerhassett &rESP_HPI_ISTREAM_OPEN[phm->adapter_index][phm-> 406719f82d3SEliot Blennerhassett obj_index], 407719f82d3SEliot Blennerhassett sizeof(rESP_HPI_ISTREAM_OPEN[0][0])); 408719f82d3SEliot Blennerhassett else { 409719f82d3SEliot Blennerhassett instream_user_open[phm->adapter_index][phm-> 410719f82d3SEliot Blennerhassett obj_index].open_flag = 1; 411*3285ea10SEliot Blennerhassett hpios_msgxlock_unlock(&msgx_lock); 412719f82d3SEliot Blennerhassett 413719f82d3SEliot Blennerhassett /* issue a reset */ 414719f82d3SEliot Blennerhassett hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM, 415719f82d3SEliot Blennerhassett HPI_ISTREAM_RESET); 416719f82d3SEliot Blennerhassett hm.adapter_index = phm->adapter_index; 417719f82d3SEliot Blennerhassett hm.obj_index = phm->obj_index; 418719f82d3SEliot Blennerhassett hw_entry_point(&hm, &hr); 419719f82d3SEliot Blennerhassett 420719f82d3SEliot Blennerhassett hpios_msgxlock_lock(&msgx_lock); 421719f82d3SEliot Blennerhassett if (hr.error) { 422719f82d3SEliot Blennerhassett instream_user_open[phm->adapter_index][phm-> 423719f82d3SEliot Blennerhassett obj_index].open_flag = 0; 424719f82d3SEliot Blennerhassett phr->error = hr.error; 425719f82d3SEliot Blennerhassett } else { 426719f82d3SEliot Blennerhassett instream_user_open[phm->adapter_index][phm-> 427719f82d3SEliot Blennerhassett obj_index].open_flag = 1; 428719f82d3SEliot Blennerhassett instream_user_open[phm->adapter_index][phm-> 429719f82d3SEliot Blennerhassett obj_index].h_owner = h_owner; 430719f82d3SEliot Blennerhassett memcpy(phr, 431719f82d3SEliot Blennerhassett &rESP_HPI_ISTREAM_OPEN[phm->adapter_index] 432719f82d3SEliot Blennerhassett [phm->obj_index], 433719f82d3SEliot Blennerhassett sizeof(rESP_HPI_ISTREAM_OPEN[0][0])); 434719f82d3SEliot Blennerhassett } 435719f82d3SEliot Blennerhassett } 436*3285ea10SEliot Blennerhassett hpios_msgxlock_unlock(&msgx_lock); 437719f82d3SEliot Blennerhassett } 438719f82d3SEliot Blennerhassett 439719f82d3SEliot Blennerhassett static void instream_close(struct hpi_message *phm, struct hpi_response *phr, 440719f82d3SEliot Blennerhassett void *h_owner) 441719f82d3SEliot Blennerhassett { 442719f82d3SEliot Blennerhassett 443719f82d3SEliot Blennerhassett struct hpi_message hm; 444719f82d3SEliot Blennerhassett struct hpi_response hr; 445719f82d3SEliot Blennerhassett 446719f82d3SEliot Blennerhassett hpi_init_response(phr, HPI_OBJ_ISTREAM, HPI_ISTREAM_CLOSE, 0); 447719f82d3SEliot Blennerhassett 448719f82d3SEliot Blennerhassett hpios_msgxlock_lock(&msgx_lock); 449719f82d3SEliot Blennerhassett if (h_owner == 450719f82d3SEliot Blennerhassett instream_user_open[phm->adapter_index][phm-> 451719f82d3SEliot Blennerhassett obj_index].h_owner) { 452719f82d3SEliot Blennerhassett /* HPI_DEBUG_LOG(INFO,"closing adapter %d " 453719f82d3SEliot Blennerhassett "instream %d owned by %p\n", 454719f82d3SEliot Blennerhassett phm->wAdapterIndex, phm->wObjIndex, hOwner); */ 455719f82d3SEliot Blennerhassett instream_user_open[phm->adapter_index][phm-> 456719f82d3SEliot Blennerhassett obj_index].h_owner = NULL; 457*3285ea10SEliot Blennerhassett hpios_msgxlock_unlock(&msgx_lock); 458719f82d3SEliot Blennerhassett /* issue a reset */ 459719f82d3SEliot Blennerhassett hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM, 460719f82d3SEliot Blennerhassett HPI_ISTREAM_RESET); 461719f82d3SEliot Blennerhassett hm.adapter_index = phm->adapter_index; 462719f82d3SEliot Blennerhassett hm.obj_index = phm->obj_index; 463719f82d3SEliot Blennerhassett hw_entry_point(&hm, &hr); 464719f82d3SEliot Blennerhassett hpios_msgxlock_lock(&msgx_lock); 465719f82d3SEliot Blennerhassett if (hr.error) { 466719f82d3SEliot Blennerhassett instream_user_open[phm->adapter_index][phm-> 467719f82d3SEliot Blennerhassett obj_index].h_owner = h_owner; 468719f82d3SEliot Blennerhassett phr->error = hr.error; 469719f82d3SEliot Blennerhassett } else { 470719f82d3SEliot Blennerhassett instream_user_open[phm->adapter_index][phm-> 471719f82d3SEliot Blennerhassett obj_index].open_flag = 0; 472719f82d3SEliot Blennerhassett instream_user_open[phm->adapter_index][phm-> 473719f82d3SEliot Blennerhassett obj_index].h_owner = NULL; 474719f82d3SEliot Blennerhassett } 475719f82d3SEliot Blennerhassett } else { 476719f82d3SEliot Blennerhassett HPI_DEBUG_LOG(WARNING, 477719f82d3SEliot Blennerhassett "%p trying to close %d instream %d owned by %p\n", 478719f82d3SEliot Blennerhassett h_owner, phm->adapter_index, phm->obj_index, 479719f82d3SEliot Blennerhassett instream_user_open[phm->adapter_index][phm-> 480719f82d3SEliot Blennerhassett obj_index].h_owner); 481719f82d3SEliot Blennerhassett phr->error = HPI_ERROR_OBJ_NOT_OPEN; 482719f82d3SEliot Blennerhassett } 483*3285ea10SEliot Blennerhassett hpios_msgxlock_unlock(&msgx_lock); 484719f82d3SEliot Blennerhassett } 485719f82d3SEliot Blennerhassett 486719f82d3SEliot Blennerhassett static void outstream_open(struct hpi_message *phm, struct hpi_response *phr, 487719f82d3SEliot Blennerhassett void *h_owner) 488719f82d3SEliot Blennerhassett { 489719f82d3SEliot Blennerhassett 490719f82d3SEliot Blennerhassett struct hpi_message hm; 491719f82d3SEliot Blennerhassett struct hpi_response hr; 492719f82d3SEliot Blennerhassett 493719f82d3SEliot Blennerhassett hpi_init_response(phr, HPI_OBJ_OSTREAM, HPI_OSTREAM_OPEN, 0); 494719f82d3SEliot Blennerhassett 495719f82d3SEliot Blennerhassett hpios_msgxlock_lock(&msgx_lock); 496719f82d3SEliot Blennerhassett 497719f82d3SEliot Blennerhassett if (outstream_user_open[phm->adapter_index][phm->obj_index].open_flag) 498719f82d3SEliot Blennerhassett phr->error = HPI_ERROR_OBJ_ALREADY_OPEN; 499719f82d3SEliot Blennerhassett else if (rESP_HPI_OSTREAM_OPEN[phm->adapter_index] 500719f82d3SEliot Blennerhassett [phm->obj_index].h.error) 501719f82d3SEliot Blennerhassett memcpy(phr, 502719f82d3SEliot Blennerhassett &rESP_HPI_OSTREAM_OPEN[phm->adapter_index][phm-> 503719f82d3SEliot Blennerhassett obj_index], 504719f82d3SEliot Blennerhassett sizeof(rESP_HPI_OSTREAM_OPEN[0][0])); 505719f82d3SEliot Blennerhassett else { 506719f82d3SEliot Blennerhassett outstream_user_open[phm->adapter_index][phm-> 507719f82d3SEliot Blennerhassett obj_index].open_flag = 1; 508*3285ea10SEliot Blennerhassett hpios_msgxlock_unlock(&msgx_lock); 509719f82d3SEliot Blennerhassett 510719f82d3SEliot Blennerhassett /* issue a reset */ 511719f82d3SEliot Blennerhassett hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM, 512719f82d3SEliot Blennerhassett HPI_OSTREAM_RESET); 513719f82d3SEliot Blennerhassett hm.adapter_index = phm->adapter_index; 514719f82d3SEliot Blennerhassett hm.obj_index = phm->obj_index; 515719f82d3SEliot Blennerhassett hw_entry_point(&hm, &hr); 516719f82d3SEliot Blennerhassett 517719f82d3SEliot Blennerhassett hpios_msgxlock_lock(&msgx_lock); 518719f82d3SEliot Blennerhassett if (hr.error) { 519719f82d3SEliot Blennerhassett outstream_user_open[phm->adapter_index][phm-> 520719f82d3SEliot Blennerhassett obj_index].open_flag = 0; 521719f82d3SEliot Blennerhassett phr->error = hr.error; 522719f82d3SEliot Blennerhassett } else { 523719f82d3SEliot Blennerhassett outstream_user_open[phm->adapter_index][phm-> 524719f82d3SEliot Blennerhassett obj_index].open_flag = 1; 525719f82d3SEliot Blennerhassett outstream_user_open[phm->adapter_index][phm-> 526719f82d3SEliot Blennerhassett obj_index].h_owner = h_owner; 527719f82d3SEliot Blennerhassett memcpy(phr, 528719f82d3SEliot Blennerhassett &rESP_HPI_OSTREAM_OPEN[phm->adapter_index] 529719f82d3SEliot Blennerhassett [phm->obj_index], 530719f82d3SEliot Blennerhassett sizeof(rESP_HPI_OSTREAM_OPEN[0][0])); 531719f82d3SEliot Blennerhassett } 532719f82d3SEliot Blennerhassett } 533*3285ea10SEliot Blennerhassett hpios_msgxlock_unlock(&msgx_lock); 534719f82d3SEliot Blennerhassett } 535719f82d3SEliot Blennerhassett 536719f82d3SEliot Blennerhassett static void outstream_close(struct hpi_message *phm, struct hpi_response *phr, 537719f82d3SEliot Blennerhassett void *h_owner) 538719f82d3SEliot Blennerhassett { 539719f82d3SEliot Blennerhassett 540719f82d3SEliot Blennerhassett struct hpi_message hm; 541719f82d3SEliot Blennerhassett struct hpi_response hr; 542719f82d3SEliot Blennerhassett 543719f82d3SEliot Blennerhassett hpi_init_response(phr, HPI_OBJ_OSTREAM, HPI_OSTREAM_CLOSE, 0); 544719f82d3SEliot Blennerhassett 545719f82d3SEliot Blennerhassett hpios_msgxlock_lock(&msgx_lock); 546719f82d3SEliot Blennerhassett 547719f82d3SEliot Blennerhassett if (h_owner == 548719f82d3SEliot Blennerhassett outstream_user_open[phm->adapter_index][phm-> 549719f82d3SEliot Blennerhassett obj_index].h_owner) { 550719f82d3SEliot Blennerhassett /* HPI_DEBUG_LOG(INFO,"closing adapter %d " 551719f82d3SEliot Blennerhassett "outstream %d owned by %p\n", 552719f82d3SEliot Blennerhassett phm->wAdapterIndex, phm->wObjIndex, hOwner); */ 553719f82d3SEliot Blennerhassett outstream_user_open[phm->adapter_index][phm-> 554719f82d3SEliot Blennerhassett obj_index].h_owner = NULL; 555*3285ea10SEliot Blennerhassett hpios_msgxlock_unlock(&msgx_lock); 556719f82d3SEliot Blennerhassett /* issue a reset */ 557719f82d3SEliot Blennerhassett hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM, 558719f82d3SEliot Blennerhassett HPI_OSTREAM_RESET); 559719f82d3SEliot Blennerhassett hm.adapter_index = phm->adapter_index; 560719f82d3SEliot Blennerhassett hm.obj_index = phm->obj_index; 561719f82d3SEliot Blennerhassett hw_entry_point(&hm, &hr); 562719f82d3SEliot Blennerhassett hpios_msgxlock_lock(&msgx_lock); 563719f82d3SEliot Blennerhassett if (hr.error) { 564719f82d3SEliot Blennerhassett outstream_user_open[phm->adapter_index][phm-> 565719f82d3SEliot Blennerhassett obj_index].h_owner = h_owner; 566719f82d3SEliot Blennerhassett phr->error = hr.error; 567719f82d3SEliot Blennerhassett } else { 568719f82d3SEliot Blennerhassett outstream_user_open[phm->adapter_index][phm-> 569719f82d3SEliot Blennerhassett obj_index].open_flag = 0; 570719f82d3SEliot Blennerhassett outstream_user_open[phm->adapter_index][phm-> 571719f82d3SEliot Blennerhassett obj_index].h_owner = NULL; 572719f82d3SEliot Blennerhassett } 573719f82d3SEliot Blennerhassett } else { 574719f82d3SEliot Blennerhassett HPI_DEBUG_LOG(WARNING, 575719f82d3SEliot Blennerhassett "%p trying to close %d outstream %d owned by %p\n", 576719f82d3SEliot Blennerhassett h_owner, phm->adapter_index, phm->obj_index, 577719f82d3SEliot Blennerhassett outstream_user_open[phm->adapter_index][phm-> 578719f82d3SEliot Blennerhassett obj_index].h_owner); 579719f82d3SEliot Blennerhassett phr->error = HPI_ERROR_OBJ_NOT_OPEN; 580719f82d3SEliot Blennerhassett } 581*3285ea10SEliot Blennerhassett hpios_msgxlock_unlock(&msgx_lock); 582719f82d3SEliot Blennerhassett } 583719f82d3SEliot Blennerhassett 584719f82d3SEliot Blennerhassett static u16 adapter_prepare(u16 adapter) 585719f82d3SEliot Blennerhassett { 586719f82d3SEliot Blennerhassett struct hpi_message hm; 587719f82d3SEliot Blennerhassett struct hpi_response hr; 588719f82d3SEliot Blennerhassett 589719f82d3SEliot Blennerhassett /* Open the adapter and streams */ 590719f82d3SEliot Blennerhassett u16 i; 591719f82d3SEliot Blennerhassett 592719f82d3SEliot Blennerhassett /* call to HPI_ADAPTER_OPEN */ 593719f82d3SEliot Blennerhassett hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER, 594719f82d3SEliot Blennerhassett HPI_ADAPTER_OPEN); 595719f82d3SEliot Blennerhassett hm.adapter_index = adapter; 596719f82d3SEliot Blennerhassett hw_entry_point(&hm, &hr); 597719f82d3SEliot Blennerhassett memcpy(&rESP_HPI_ADAPTER_OPEN[adapter], &hr, 598719f82d3SEliot Blennerhassett sizeof(rESP_HPI_ADAPTER_OPEN[0])); 599719f82d3SEliot Blennerhassett if (hr.error) 600719f82d3SEliot Blennerhassett return hr.error; 601719f82d3SEliot Blennerhassett 602719f82d3SEliot Blennerhassett /* call to HPI_ADAPTER_GET_INFO */ 603719f82d3SEliot Blennerhassett hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER, 604719f82d3SEliot Blennerhassett HPI_ADAPTER_GET_INFO); 605719f82d3SEliot Blennerhassett hm.adapter_index = adapter; 606719f82d3SEliot Blennerhassett hw_entry_point(&hm, &hr); 607719f82d3SEliot Blennerhassett if (hr.error) 608719f82d3SEliot Blennerhassett return hr.error; 609719f82d3SEliot Blennerhassett 610*3285ea10SEliot Blennerhassett aDAPTER_INFO[adapter].num_outstreams = hr.u.ax.info.num_outstreams; 611*3285ea10SEliot Blennerhassett aDAPTER_INFO[adapter].num_instreams = hr.u.ax.info.num_instreams; 612*3285ea10SEliot Blennerhassett aDAPTER_INFO[adapter].type = hr.u.ax.info.adapter_type; 613719f82d3SEliot Blennerhassett 614719f82d3SEliot Blennerhassett /* call to HPI_OSTREAM_OPEN */ 615719f82d3SEliot Blennerhassett for (i = 0; i < aDAPTER_INFO[adapter].num_outstreams; i++) { 616719f82d3SEliot Blennerhassett hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM, 617719f82d3SEliot Blennerhassett HPI_OSTREAM_OPEN); 618719f82d3SEliot Blennerhassett hm.adapter_index = adapter; 619719f82d3SEliot Blennerhassett hm.obj_index = i; 620719f82d3SEliot Blennerhassett hw_entry_point(&hm, &hr); 621719f82d3SEliot Blennerhassett memcpy(&rESP_HPI_OSTREAM_OPEN[adapter][i], &hr, 622719f82d3SEliot Blennerhassett sizeof(rESP_HPI_OSTREAM_OPEN[0][0])); 623719f82d3SEliot Blennerhassett outstream_user_open[adapter][i].open_flag = 0; 624719f82d3SEliot Blennerhassett outstream_user_open[adapter][i].h_owner = NULL; 625719f82d3SEliot Blennerhassett } 626719f82d3SEliot Blennerhassett 627719f82d3SEliot Blennerhassett /* call to HPI_ISTREAM_OPEN */ 628719f82d3SEliot Blennerhassett for (i = 0; i < aDAPTER_INFO[adapter].num_instreams; i++) { 629719f82d3SEliot Blennerhassett hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM, 630719f82d3SEliot Blennerhassett HPI_ISTREAM_OPEN); 631719f82d3SEliot Blennerhassett hm.adapter_index = adapter; 632719f82d3SEliot Blennerhassett hm.obj_index = i; 633719f82d3SEliot Blennerhassett hw_entry_point(&hm, &hr); 634719f82d3SEliot Blennerhassett memcpy(&rESP_HPI_ISTREAM_OPEN[adapter][i], &hr, 635719f82d3SEliot Blennerhassett sizeof(rESP_HPI_ISTREAM_OPEN[0][0])); 636719f82d3SEliot Blennerhassett instream_user_open[adapter][i].open_flag = 0; 637719f82d3SEliot Blennerhassett instream_user_open[adapter][i].h_owner = NULL; 638719f82d3SEliot Blennerhassett } 639719f82d3SEliot Blennerhassett 640719f82d3SEliot Blennerhassett /* call to HPI_MIXER_OPEN */ 641719f82d3SEliot Blennerhassett hpi_init_message_response(&hm, &hr, HPI_OBJ_MIXER, HPI_MIXER_OPEN); 642719f82d3SEliot Blennerhassett hm.adapter_index = adapter; 643719f82d3SEliot Blennerhassett hw_entry_point(&hm, &hr); 644719f82d3SEliot Blennerhassett memcpy(&rESP_HPI_MIXER_OPEN[adapter], &hr, 645719f82d3SEliot Blennerhassett sizeof(rESP_HPI_MIXER_OPEN[0])); 646719f82d3SEliot Blennerhassett 647*3285ea10SEliot Blennerhassett return 0; 648719f82d3SEliot Blennerhassett } 649719f82d3SEliot Blennerhassett 650719f82d3SEliot Blennerhassett static void HPIMSGX__reset(u16 adapter_index) 651719f82d3SEliot Blennerhassett { 652719f82d3SEliot Blennerhassett int i; 653719f82d3SEliot Blennerhassett u16 adapter; 654719f82d3SEliot Blennerhassett struct hpi_response hr; 655719f82d3SEliot Blennerhassett 656719f82d3SEliot Blennerhassett if (adapter_index == HPIMSGX_ALLADAPTERS) { 657719f82d3SEliot Blennerhassett for (adapter = 0; adapter < HPI_MAX_ADAPTERS; adapter++) { 658719f82d3SEliot Blennerhassett 659719f82d3SEliot Blennerhassett hpi_init_response(&hr, HPI_OBJ_ADAPTER, 660719f82d3SEliot Blennerhassett HPI_ADAPTER_OPEN, HPI_ERROR_BAD_ADAPTER); 661719f82d3SEliot Blennerhassett memcpy(&rESP_HPI_ADAPTER_OPEN[adapter], &hr, 662719f82d3SEliot Blennerhassett sizeof(rESP_HPI_ADAPTER_OPEN[adapter])); 663719f82d3SEliot Blennerhassett 664719f82d3SEliot Blennerhassett hpi_init_response(&hr, HPI_OBJ_MIXER, HPI_MIXER_OPEN, 665719f82d3SEliot Blennerhassett HPI_ERROR_INVALID_OBJ); 666719f82d3SEliot Blennerhassett memcpy(&rESP_HPI_MIXER_OPEN[adapter], &hr, 667719f82d3SEliot Blennerhassett sizeof(rESP_HPI_MIXER_OPEN[adapter])); 668719f82d3SEliot Blennerhassett 669719f82d3SEliot Blennerhassett for (i = 0; i < HPI_MAX_STREAMS; i++) { 670719f82d3SEliot Blennerhassett hpi_init_response(&hr, HPI_OBJ_OSTREAM, 671719f82d3SEliot Blennerhassett HPI_OSTREAM_OPEN, 672719f82d3SEliot Blennerhassett HPI_ERROR_INVALID_OBJ); 673719f82d3SEliot Blennerhassett memcpy(&rESP_HPI_OSTREAM_OPEN[adapter][i], 674719f82d3SEliot Blennerhassett &hr, 675719f82d3SEliot Blennerhassett sizeof(rESP_HPI_OSTREAM_OPEN[adapter] 676719f82d3SEliot Blennerhassett [i])); 677719f82d3SEliot Blennerhassett hpi_init_response(&hr, HPI_OBJ_ISTREAM, 678719f82d3SEliot Blennerhassett HPI_ISTREAM_OPEN, 679719f82d3SEliot Blennerhassett HPI_ERROR_INVALID_OBJ); 680719f82d3SEliot Blennerhassett memcpy(&rESP_HPI_ISTREAM_OPEN[adapter][i], 681719f82d3SEliot Blennerhassett &hr, 682719f82d3SEliot Blennerhassett sizeof(rESP_HPI_ISTREAM_OPEN[adapter] 683719f82d3SEliot Blennerhassett [i])); 684719f82d3SEliot Blennerhassett } 685719f82d3SEliot Blennerhassett } 686719f82d3SEliot Blennerhassett } else if (adapter_index < HPI_MAX_ADAPTERS) { 687719f82d3SEliot Blennerhassett rESP_HPI_ADAPTER_OPEN[adapter_index].h.error = 688719f82d3SEliot Blennerhassett HPI_ERROR_BAD_ADAPTER; 689719f82d3SEliot Blennerhassett rESP_HPI_MIXER_OPEN[adapter_index].h.error = 690719f82d3SEliot Blennerhassett HPI_ERROR_INVALID_OBJ; 691719f82d3SEliot Blennerhassett for (i = 0; i < HPI_MAX_STREAMS; i++) { 692719f82d3SEliot Blennerhassett rESP_HPI_OSTREAM_OPEN[adapter_index][i].h.error = 693719f82d3SEliot Blennerhassett HPI_ERROR_INVALID_OBJ; 694719f82d3SEliot Blennerhassett rESP_HPI_ISTREAM_OPEN[adapter_index][i].h.error = 695719f82d3SEliot Blennerhassett HPI_ERROR_INVALID_OBJ; 696719f82d3SEliot Blennerhassett } 697719f82d3SEliot Blennerhassett } 698719f82d3SEliot Blennerhassett } 699719f82d3SEliot Blennerhassett 700719f82d3SEliot Blennerhassett static u16 HPIMSGX__init(struct hpi_message *phm, 701719f82d3SEliot Blennerhassett /* HPI_SUBSYS_CREATE_ADAPTER structure with */ 702719f82d3SEliot Blennerhassett /* resource list or NULL=find all */ 703719f82d3SEliot Blennerhassett struct hpi_response *phr 704719f82d3SEliot Blennerhassett /* response from HPI_ADAPTER_GET_INFO */ 705719f82d3SEliot Blennerhassett ) 706719f82d3SEliot Blennerhassett { 707719f82d3SEliot Blennerhassett hpi_handler_func *entry_point_func; 708719f82d3SEliot Blennerhassett struct hpi_response hr; 709719f82d3SEliot Blennerhassett 710719f82d3SEliot Blennerhassett /* Init response here so we can pass in previous adapter list */ 711719f82d3SEliot Blennerhassett hpi_init_response(&hr, phm->object, phm->function, 712719f82d3SEliot Blennerhassett HPI_ERROR_INVALID_OBJ); 713719f82d3SEliot Blennerhassett 714719f82d3SEliot Blennerhassett entry_point_func = 715719f82d3SEliot Blennerhassett hpi_lookup_entry_point_function(phm->u.s.resource.r.pci); 716719f82d3SEliot Blennerhassett 717719f82d3SEliot Blennerhassett if (entry_point_func) { 718719f82d3SEliot Blennerhassett HPI_DEBUG_MESSAGE(DEBUG, phm); 719719f82d3SEliot Blennerhassett entry_point_func(phm, &hr); 720719f82d3SEliot Blennerhassett } else { 721719f82d3SEliot Blennerhassett phr->error = HPI_ERROR_PROCESSING_MESSAGE; 722719f82d3SEliot Blennerhassett return phr->error; 723719f82d3SEliot Blennerhassett } 724719f82d3SEliot Blennerhassett if (hr.error == 0) { 725719f82d3SEliot Blennerhassett /* the adapter was created succesfully 726719f82d3SEliot Blennerhassett save the mapping for future use */ 727719f82d3SEliot Blennerhassett hpi_entry_points[hr.u.s.adapter_index] = entry_point_func; 728719f82d3SEliot Blennerhassett /* prepare adapter (pre-open streams etc.) */ 729719f82d3SEliot Blennerhassett HPI_DEBUG_LOG(DEBUG, 730719f82d3SEliot Blennerhassett "HPI_SUBSYS_CREATE_ADAPTER successful," 731719f82d3SEliot Blennerhassett " preparing adapter\n"); 732719f82d3SEliot Blennerhassett adapter_prepare(hr.u.s.adapter_index); 733719f82d3SEliot Blennerhassett } 734719f82d3SEliot Blennerhassett memcpy(phr, &hr, hr.size); 735719f82d3SEliot Blennerhassett return phr->error; 736719f82d3SEliot Blennerhassett } 737719f82d3SEliot Blennerhassett 738719f82d3SEliot Blennerhassett static void HPIMSGX__cleanup(u16 adapter_index, void *h_owner) 739719f82d3SEliot Blennerhassett { 740719f82d3SEliot Blennerhassett int i, adapter, adapter_limit; 741719f82d3SEliot Blennerhassett 742719f82d3SEliot Blennerhassett if (!h_owner) 743719f82d3SEliot Blennerhassett return; 744719f82d3SEliot Blennerhassett 745719f82d3SEliot Blennerhassett if (adapter_index == HPIMSGX_ALLADAPTERS) { 746719f82d3SEliot Blennerhassett adapter = 0; 747719f82d3SEliot Blennerhassett adapter_limit = HPI_MAX_ADAPTERS; 748719f82d3SEliot Blennerhassett } else { 749719f82d3SEliot Blennerhassett adapter = adapter_index; 750719f82d3SEliot Blennerhassett adapter_limit = adapter + 1; 751719f82d3SEliot Blennerhassett } 752719f82d3SEliot Blennerhassett 753719f82d3SEliot Blennerhassett for (; adapter < adapter_limit; adapter++) { 754719f82d3SEliot Blennerhassett /* printk(KERN_INFO "Cleanup adapter #%d\n",wAdapter); */ 755719f82d3SEliot Blennerhassett for (i = 0; i < HPI_MAX_STREAMS; i++) { 756719f82d3SEliot Blennerhassett if (h_owner == 757719f82d3SEliot Blennerhassett outstream_user_open[adapter][i].h_owner) { 758719f82d3SEliot Blennerhassett struct hpi_message hm; 759719f82d3SEliot Blennerhassett struct hpi_response hr; 760719f82d3SEliot Blennerhassett 761719f82d3SEliot Blennerhassett HPI_DEBUG_LOG(DEBUG, 762*3285ea10SEliot Blennerhassett "Close adapter %d ostream %d\n", 763719f82d3SEliot Blennerhassett adapter, i); 764719f82d3SEliot Blennerhassett 765719f82d3SEliot Blennerhassett hpi_init_message_response(&hm, &hr, 766719f82d3SEliot Blennerhassett HPI_OBJ_OSTREAM, HPI_OSTREAM_RESET); 767719f82d3SEliot Blennerhassett hm.adapter_index = (u16)adapter; 768719f82d3SEliot Blennerhassett hm.obj_index = (u16)i; 769719f82d3SEliot Blennerhassett hw_entry_point(&hm, &hr); 770719f82d3SEliot Blennerhassett 771719f82d3SEliot Blennerhassett hm.function = HPI_OSTREAM_HOSTBUFFER_FREE; 772719f82d3SEliot Blennerhassett hw_entry_point(&hm, &hr); 773719f82d3SEliot Blennerhassett 774719f82d3SEliot Blennerhassett hm.function = HPI_OSTREAM_GROUP_RESET; 775719f82d3SEliot Blennerhassett hw_entry_point(&hm, &hr); 776719f82d3SEliot Blennerhassett 777719f82d3SEliot Blennerhassett outstream_user_open[adapter][i].open_flag = 0; 778719f82d3SEliot Blennerhassett outstream_user_open[adapter][i].h_owner = 779719f82d3SEliot Blennerhassett NULL; 780719f82d3SEliot Blennerhassett } 781719f82d3SEliot Blennerhassett if (h_owner == instream_user_open[adapter][i].h_owner) { 782719f82d3SEliot Blennerhassett struct hpi_message hm; 783719f82d3SEliot Blennerhassett struct hpi_response hr; 784719f82d3SEliot Blennerhassett 785719f82d3SEliot Blennerhassett HPI_DEBUG_LOG(DEBUG, 786*3285ea10SEliot Blennerhassett "Close adapter %d istream %d\n", 787719f82d3SEliot Blennerhassett adapter, i); 788719f82d3SEliot Blennerhassett 789719f82d3SEliot Blennerhassett hpi_init_message_response(&hm, &hr, 790719f82d3SEliot Blennerhassett HPI_OBJ_ISTREAM, HPI_ISTREAM_RESET); 791719f82d3SEliot Blennerhassett hm.adapter_index = (u16)adapter; 792719f82d3SEliot Blennerhassett hm.obj_index = (u16)i; 793719f82d3SEliot Blennerhassett hw_entry_point(&hm, &hr); 794719f82d3SEliot Blennerhassett 795719f82d3SEliot Blennerhassett hm.function = HPI_ISTREAM_HOSTBUFFER_FREE; 796719f82d3SEliot Blennerhassett hw_entry_point(&hm, &hr); 797719f82d3SEliot Blennerhassett 798719f82d3SEliot Blennerhassett hm.function = HPI_ISTREAM_GROUP_RESET; 799719f82d3SEliot Blennerhassett hw_entry_point(&hm, &hr); 800719f82d3SEliot Blennerhassett 801719f82d3SEliot Blennerhassett instream_user_open[adapter][i].open_flag = 0; 802719f82d3SEliot Blennerhassett instream_user_open[adapter][i].h_owner = NULL; 803719f82d3SEliot Blennerhassett } 804719f82d3SEliot Blennerhassett } 805719f82d3SEliot Blennerhassett } 806719f82d3SEliot Blennerhassett } 807