0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #define SOURCEFILE_NAME "hpimsgx.c"
0013 #include "hpi_internal.h"
0014 #include "hpi_version.h"
0015 #include "hpimsginit.h"
0016 #include "hpicmn.h"
0017 #include "hpimsgx.h"
0018 #include "hpidebug.h"
0019
0020 static const struct pci_device_id asihpi_pci_tbl[] = {
0021 #include "hpipcida.h"
0022 };
0023
0024 static struct hpios_spinlock msgx_lock;
0025
0026 static hpi_handler_func *hpi_entry_points[HPI_MAX_ADAPTERS];
0027 static int logging_enabled = 1;
0028
0029 static hpi_handler_func *hpi_lookup_entry_point_function(const struct hpi_pci
0030 *pci_info)
0031 {
0032
0033 int i;
0034
0035 for (i = 0; asihpi_pci_tbl[i].vendor != 0; i++) {
0036 if (asihpi_pci_tbl[i].vendor != PCI_ANY_ID
0037 && asihpi_pci_tbl[i].vendor !=
0038 pci_info->pci_dev->vendor)
0039 continue;
0040 if (asihpi_pci_tbl[i].device != PCI_ANY_ID
0041 && asihpi_pci_tbl[i].device !=
0042 pci_info->pci_dev->device)
0043 continue;
0044 if (asihpi_pci_tbl[i].subvendor != PCI_ANY_ID
0045 && asihpi_pci_tbl[i].subvendor !=
0046 pci_info->pci_dev->subsystem_vendor)
0047 continue;
0048 if (asihpi_pci_tbl[i].subdevice != PCI_ANY_ID
0049 && asihpi_pci_tbl[i].subdevice !=
0050 pci_info->pci_dev->subsystem_device)
0051 continue;
0052
0053
0054
0055 return (hpi_handler_func *) asihpi_pci_tbl[i].driver_data;
0056 }
0057
0058 return NULL;
0059 }
0060
0061 static inline void hw_entry_point(struct hpi_message *phm,
0062 struct hpi_response *phr)
0063 {
0064 if ((phm->adapter_index < HPI_MAX_ADAPTERS)
0065 && hpi_entry_points[phm->adapter_index])
0066 hpi_entry_points[phm->adapter_index] (phm, phr);
0067 else
0068 hpi_init_response(phr, phm->object, phm->function,
0069 HPI_ERROR_PROCESSING_MESSAGE);
0070 }
0071
0072 static void adapter_open(struct hpi_message *phm, struct hpi_response *phr);
0073 static void adapter_close(struct hpi_message *phm, struct hpi_response *phr);
0074
0075 static void mixer_open(struct hpi_message *phm, struct hpi_response *phr);
0076 static void mixer_close(struct hpi_message *phm, struct hpi_response *phr);
0077
0078 static void outstream_open(struct hpi_message *phm, struct hpi_response *phr,
0079 void *h_owner);
0080 static void outstream_close(struct hpi_message *phm, struct hpi_response *phr,
0081 void *h_owner);
0082 static void instream_open(struct hpi_message *phm, struct hpi_response *phr,
0083 void *h_owner);
0084 static void instream_close(struct hpi_message *phm, struct hpi_response *phr,
0085 void *h_owner);
0086
0087 static void HPIMSGX__reset(u16 adapter_index);
0088
0089 static u16 HPIMSGX__init(struct hpi_message *phm, struct hpi_response *phr);
0090 static void HPIMSGX__cleanup(u16 adapter_index, void *h_owner);
0091
0092 #ifndef DISABLE_PRAGMA_PACK1
0093 #pragma pack(push, 1)
0094 #endif
0095
0096 struct hpi_subsys_response {
0097 struct hpi_response_header h;
0098 struct hpi_subsys_res s;
0099 };
0100
0101 struct hpi_adapter_response {
0102 struct hpi_response_header h;
0103 struct hpi_adapter_res a;
0104 };
0105
0106 struct hpi_mixer_response {
0107 struct hpi_response_header h;
0108 struct hpi_mixer_res m;
0109 };
0110
0111 struct hpi_stream_response {
0112 struct hpi_response_header h;
0113 struct hpi_stream_res d;
0114 };
0115
0116 struct adapter_info {
0117 u16 type;
0118 u16 num_instreams;
0119 u16 num_outstreams;
0120 };
0121
0122 struct asi_open_state {
0123 int open_flag;
0124 void *h_owner;
0125 };
0126
0127 #ifndef DISABLE_PRAGMA_PACK1
0128 #pragma pack(pop)
0129 #endif
0130
0131
0132 static struct hpi_adapter_response rESP_HPI_ADAPTER_OPEN[HPI_MAX_ADAPTERS];
0133
0134 static struct hpi_stream_response
0135 rESP_HPI_OSTREAM_OPEN[HPI_MAX_ADAPTERS][HPI_MAX_STREAMS];
0136
0137 static struct hpi_stream_response
0138 rESP_HPI_ISTREAM_OPEN[HPI_MAX_ADAPTERS][HPI_MAX_STREAMS];
0139
0140 static struct hpi_mixer_response rESP_HPI_MIXER_OPEN[HPI_MAX_ADAPTERS];
0141
0142 static struct adapter_info aDAPTER_INFO[HPI_MAX_ADAPTERS];
0143
0144
0145 static struct asi_open_state
0146 outstream_user_open[HPI_MAX_ADAPTERS][HPI_MAX_STREAMS];
0147
0148 static struct asi_open_state
0149 instream_user_open[HPI_MAX_ADAPTERS][HPI_MAX_STREAMS];
0150
0151 static void subsys_message(struct hpi_message *phm, struct hpi_response *phr,
0152 void *h_owner)
0153 {
0154 if (phm->adapter_index != HPI_ADAPTER_INDEX_INVALID)
0155 HPI_DEBUG_LOG(WARNING,
0156 "suspicious adapter index %d in subsys message 0x%x.\n",
0157 phm->adapter_index, phm->function);
0158
0159 switch (phm->function) {
0160 case HPI_SUBSYS_GET_VERSION:
0161 hpi_init_response(phr, HPI_OBJ_SUBSYSTEM,
0162 HPI_SUBSYS_GET_VERSION, 0);
0163 phr->u.s.version = HPI_VER >> 8;
0164 phr->u.s.data = HPI_VER;
0165 break;
0166 case HPI_SUBSYS_OPEN:
0167
0168 hpi_init_response(phr, HPI_OBJ_SUBSYSTEM, HPI_SUBSYS_OPEN, 0);
0169 break;
0170 case HPI_SUBSYS_CLOSE:
0171
0172 hpi_init_response(phr, HPI_OBJ_SUBSYSTEM, HPI_SUBSYS_CLOSE,
0173 0);
0174 HPIMSGX__cleanup(HPIMSGX_ALLADAPTERS, h_owner);
0175 break;
0176 case HPI_SUBSYS_DRIVER_LOAD:
0177
0178 hpios_msgxlock_init(&msgx_lock);
0179 memset(&hpi_entry_points, 0, sizeof(hpi_entry_points));
0180
0181 HPIMSGX__reset(HPIMSGX_ALLADAPTERS);
0182 hpi_init_response(phr, HPI_OBJ_SUBSYSTEM,
0183 HPI_SUBSYS_DRIVER_LOAD, 0);
0184
0185 HPI_COMMON(phm, phr);
0186 break;
0187 case HPI_SUBSYS_DRIVER_UNLOAD:
0188 HPI_COMMON(phm, phr);
0189 HPIMSGX__cleanup(HPIMSGX_ALLADAPTERS, h_owner);
0190 hpi_init_response(phr, HPI_OBJ_SUBSYSTEM,
0191 HPI_SUBSYS_DRIVER_UNLOAD, 0);
0192 return;
0193
0194 case HPI_SUBSYS_GET_NUM_ADAPTERS:
0195 case HPI_SUBSYS_GET_ADAPTER:
0196 HPI_COMMON(phm, phr);
0197 break;
0198
0199 case HPI_SUBSYS_CREATE_ADAPTER:
0200 HPIMSGX__init(phm, phr);
0201 break;
0202
0203 default:
0204
0205 hpi_init_response(phr, HPI_OBJ_SUBSYSTEM, phm->function,
0206 HPI_ERROR_INVALID_FUNC);
0207 break;
0208 }
0209 }
0210
0211 static void adapter_message(struct hpi_message *phm, struct hpi_response *phr,
0212 void *h_owner)
0213 {
0214 switch (phm->function) {
0215 case HPI_ADAPTER_OPEN:
0216 adapter_open(phm, phr);
0217 break;
0218 case HPI_ADAPTER_CLOSE:
0219 adapter_close(phm, phr);
0220 break;
0221 case HPI_ADAPTER_DELETE:
0222 HPIMSGX__cleanup(phm->adapter_index, h_owner);
0223 {
0224 struct hpi_message hm;
0225 struct hpi_response hr;
0226 hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER,
0227 HPI_ADAPTER_CLOSE);
0228 hm.adapter_index = phm->adapter_index;
0229 hw_entry_point(&hm, &hr);
0230 }
0231 hw_entry_point(phm, phr);
0232 break;
0233
0234 default:
0235 hw_entry_point(phm, phr);
0236 break;
0237 }
0238 }
0239
0240 static void mixer_message(struct hpi_message *phm, struct hpi_response *phr)
0241 {
0242 switch (phm->function) {
0243 case HPI_MIXER_OPEN:
0244 mixer_open(phm, phr);
0245 break;
0246 case HPI_MIXER_CLOSE:
0247 mixer_close(phm, phr);
0248 break;
0249 default:
0250 hw_entry_point(phm, phr);
0251 break;
0252 }
0253 }
0254
0255 static void outstream_message(struct hpi_message *phm,
0256 struct hpi_response *phr, void *h_owner)
0257 {
0258 if (phm->obj_index >= aDAPTER_INFO[phm->adapter_index].num_outstreams) {
0259 hpi_init_response(phr, HPI_OBJ_OSTREAM, phm->function,
0260 HPI_ERROR_INVALID_OBJ_INDEX);
0261 return;
0262 }
0263
0264 switch (phm->function) {
0265 case HPI_OSTREAM_OPEN:
0266 outstream_open(phm, phr, h_owner);
0267 break;
0268 case HPI_OSTREAM_CLOSE:
0269 outstream_close(phm, phr, h_owner);
0270 break;
0271 default:
0272 hw_entry_point(phm, phr);
0273 break;
0274 }
0275 }
0276
0277 static void instream_message(struct hpi_message *phm,
0278 struct hpi_response *phr, void *h_owner)
0279 {
0280 if (phm->obj_index >= aDAPTER_INFO[phm->adapter_index].num_instreams) {
0281 hpi_init_response(phr, HPI_OBJ_ISTREAM, phm->function,
0282 HPI_ERROR_INVALID_OBJ_INDEX);
0283 return;
0284 }
0285
0286 switch (phm->function) {
0287 case HPI_ISTREAM_OPEN:
0288 instream_open(phm, phr, h_owner);
0289 break;
0290 case HPI_ISTREAM_CLOSE:
0291 instream_close(phm, phr, h_owner);
0292 break;
0293 default:
0294 hw_entry_point(phm, phr);
0295 break;
0296 }
0297 }
0298
0299
0300
0301
0302 void hpi_send_recv_ex(struct hpi_message *phm, struct hpi_response *phr,
0303 void *h_owner)
0304 {
0305
0306 if (logging_enabled)
0307 HPI_DEBUG_MESSAGE(DEBUG, phm);
0308
0309 if (phm->type != HPI_TYPE_REQUEST) {
0310 hpi_init_response(phr, phm->object, phm->function,
0311 HPI_ERROR_INVALID_TYPE);
0312 return;
0313 }
0314
0315 if (phm->adapter_index >= HPI_MAX_ADAPTERS
0316 && phm->adapter_index != HPIMSGX_ALLADAPTERS) {
0317 hpi_init_response(phr, phm->object, phm->function,
0318 HPI_ERROR_BAD_ADAPTER_NUMBER);
0319 return;
0320 }
0321
0322 switch (phm->object) {
0323 case HPI_OBJ_SUBSYSTEM:
0324 subsys_message(phm, phr, h_owner);
0325 break;
0326
0327 case HPI_OBJ_ADAPTER:
0328 adapter_message(phm, phr, h_owner);
0329 break;
0330
0331 case HPI_OBJ_MIXER:
0332 mixer_message(phm, phr);
0333 break;
0334
0335 case HPI_OBJ_OSTREAM:
0336 outstream_message(phm, phr, h_owner);
0337 break;
0338
0339 case HPI_OBJ_ISTREAM:
0340 instream_message(phm, phr, h_owner);
0341 break;
0342
0343 default:
0344 hw_entry_point(phm, phr);
0345 break;
0346 }
0347
0348 if (logging_enabled)
0349 HPI_DEBUG_RESPONSE(phr);
0350
0351 if (phr->error >= HPI_ERROR_DSP_COMMUNICATION) {
0352 hpi_debug_level_set(HPI_DEBUG_LEVEL_ERROR);
0353 logging_enabled = 0;
0354 }
0355 }
0356
0357 static void adapter_open(struct hpi_message *phm, struct hpi_response *phr)
0358 {
0359 HPI_DEBUG_LOG(VERBOSE, "adapter_open\n");
0360 memcpy(phr, &rESP_HPI_ADAPTER_OPEN[phm->adapter_index],
0361 sizeof(rESP_HPI_ADAPTER_OPEN[0]));
0362 }
0363
0364 static void adapter_close(struct hpi_message *phm, struct hpi_response *phr)
0365 {
0366 HPI_DEBUG_LOG(VERBOSE, "adapter_close\n");
0367 hpi_init_response(phr, HPI_OBJ_ADAPTER, HPI_ADAPTER_CLOSE, 0);
0368 }
0369
0370 static void mixer_open(struct hpi_message *phm, struct hpi_response *phr)
0371 {
0372 memcpy(phr, &rESP_HPI_MIXER_OPEN[phm->adapter_index],
0373 sizeof(rESP_HPI_MIXER_OPEN[0]));
0374 }
0375
0376 static void mixer_close(struct hpi_message *phm, struct hpi_response *phr)
0377 {
0378 hpi_init_response(phr, HPI_OBJ_MIXER, HPI_MIXER_CLOSE, 0);
0379 }
0380
0381 static void instream_open(struct hpi_message *phm, struct hpi_response *phr,
0382 void *h_owner)
0383 {
0384
0385 struct hpi_message hm;
0386 struct hpi_response hr;
0387
0388 hpi_init_response(phr, HPI_OBJ_ISTREAM, HPI_ISTREAM_OPEN, 0);
0389
0390 hpios_msgxlock_lock(&msgx_lock);
0391
0392 if (instream_user_open[phm->adapter_index][phm->obj_index].open_flag)
0393 phr->error = HPI_ERROR_OBJ_ALREADY_OPEN;
0394 else if (rESP_HPI_ISTREAM_OPEN[phm->adapter_index]
0395 [phm->obj_index].h.error)
0396 memcpy(phr,
0397 &rESP_HPI_ISTREAM_OPEN[phm->adapter_index][phm->
0398 obj_index],
0399 sizeof(rESP_HPI_ISTREAM_OPEN[0][0]));
0400 else {
0401 instream_user_open[phm->adapter_index][phm->
0402 obj_index].open_flag = 1;
0403 hpios_msgxlock_unlock(&msgx_lock);
0404
0405
0406 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
0407 HPI_ISTREAM_RESET);
0408 hm.adapter_index = phm->adapter_index;
0409 hm.obj_index = phm->obj_index;
0410 hw_entry_point(&hm, &hr);
0411
0412 hpios_msgxlock_lock(&msgx_lock);
0413 if (hr.error) {
0414 instream_user_open[phm->adapter_index][phm->
0415 obj_index].open_flag = 0;
0416 phr->error = hr.error;
0417 } else {
0418 instream_user_open[phm->adapter_index][phm->
0419 obj_index].open_flag = 1;
0420 instream_user_open[phm->adapter_index][phm->
0421 obj_index].h_owner = h_owner;
0422 memcpy(phr,
0423 &rESP_HPI_ISTREAM_OPEN[phm->adapter_index]
0424 [phm->obj_index],
0425 sizeof(rESP_HPI_ISTREAM_OPEN[0][0]));
0426 }
0427 }
0428 hpios_msgxlock_unlock(&msgx_lock);
0429 }
0430
0431 static void instream_close(struct hpi_message *phm, struct hpi_response *phr,
0432 void *h_owner)
0433 {
0434
0435 struct hpi_message hm;
0436 struct hpi_response hr;
0437
0438 hpi_init_response(phr, HPI_OBJ_ISTREAM, HPI_ISTREAM_CLOSE, 0);
0439
0440 hpios_msgxlock_lock(&msgx_lock);
0441 if (h_owner ==
0442 instream_user_open[phm->adapter_index][phm->
0443 obj_index].h_owner) {
0444
0445
0446
0447 instream_user_open[phm->adapter_index][phm->
0448 obj_index].h_owner = NULL;
0449 hpios_msgxlock_unlock(&msgx_lock);
0450
0451 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
0452 HPI_ISTREAM_RESET);
0453 hm.adapter_index = phm->adapter_index;
0454 hm.obj_index = phm->obj_index;
0455 hw_entry_point(&hm, &hr);
0456 hpios_msgxlock_lock(&msgx_lock);
0457 if (hr.error) {
0458 instream_user_open[phm->adapter_index][phm->
0459 obj_index].h_owner = h_owner;
0460 phr->error = hr.error;
0461 } else {
0462 instream_user_open[phm->adapter_index][phm->
0463 obj_index].open_flag = 0;
0464 instream_user_open[phm->adapter_index][phm->
0465 obj_index].h_owner = NULL;
0466 }
0467 } else {
0468 HPI_DEBUG_LOG(WARNING,
0469 "%p trying to close %d instream %d owned by %p\n",
0470 h_owner, phm->adapter_index, phm->obj_index,
0471 instream_user_open[phm->adapter_index][phm->
0472 obj_index].h_owner);
0473 phr->error = HPI_ERROR_OBJ_NOT_OPEN;
0474 }
0475 hpios_msgxlock_unlock(&msgx_lock);
0476 }
0477
0478 static void outstream_open(struct hpi_message *phm, struct hpi_response *phr,
0479 void *h_owner)
0480 {
0481
0482 struct hpi_message hm;
0483 struct hpi_response hr;
0484
0485 hpi_init_response(phr, HPI_OBJ_OSTREAM, HPI_OSTREAM_OPEN, 0);
0486
0487 hpios_msgxlock_lock(&msgx_lock);
0488
0489 if (outstream_user_open[phm->adapter_index][phm->obj_index].open_flag)
0490 phr->error = HPI_ERROR_OBJ_ALREADY_OPEN;
0491 else if (rESP_HPI_OSTREAM_OPEN[phm->adapter_index]
0492 [phm->obj_index].h.error)
0493 memcpy(phr,
0494 &rESP_HPI_OSTREAM_OPEN[phm->adapter_index][phm->
0495 obj_index],
0496 sizeof(rESP_HPI_OSTREAM_OPEN[0][0]));
0497 else {
0498 outstream_user_open[phm->adapter_index][phm->
0499 obj_index].open_flag = 1;
0500 hpios_msgxlock_unlock(&msgx_lock);
0501
0502
0503 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
0504 HPI_OSTREAM_RESET);
0505 hm.adapter_index = phm->adapter_index;
0506 hm.obj_index = phm->obj_index;
0507 hw_entry_point(&hm, &hr);
0508
0509 hpios_msgxlock_lock(&msgx_lock);
0510 if (hr.error) {
0511 outstream_user_open[phm->adapter_index][phm->
0512 obj_index].open_flag = 0;
0513 phr->error = hr.error;
0514 } else {
0515 outstream_user_open[phm->adapter_index][phm->
0516 obj_index].open_flag = 1;
0517 outstream_user_open[phm->adapter_index][phm->
0518 obj_index].h_owner = h_owner;
0519 memcpy(phr,
0520 &rESP_HPI_OSTREAM_OPEN[phm->adapter_index]
0521 [phm->obj_index],
0522 sizeof(rESP_HPI_OSTREAM_OPEN[0][0]));
0523 }
0524 }
0525 hpios_msgxlock_unlock(&msgx_lock);
0526 }
0527
0528 static void outstream_close(struct hpi_message *phm, struct hpi_response *phr,
0529 void *h_owner)
0530 {
0531
0532 struct hpi_message hm;
0533 struct hpi_response hr;
0534
0535 hpi_init_response(phr, HPI_OBJ_OSTREAM, HPI_OSTREAM_CLOSE, 0);
0536
0537 hpios_msgxlock_lock(&msgx_lock);
0538
0539 if (h_owner ==
0540 outstream_user_open[phm->adapter_index][phm->
0541 obj_index].h_owner) {
0542
0543
0544
0545 outstream_user_open[phm->adapter_index][phm->
0546 obj_index].h_owner = NULL;
0547 hpios_msgxlock_unlock(&msgx_lock);
0548
0549 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
0550 HPI_OSTREAM_RESET);
0551 hm.adapter_index = phm->adapter_index;
0552 hm.obj_index = phm->obj_index;
0553 hw_entry_point(&hm, &hr);
0554 hpios_msgxlock_lock(&msgx_lock);
0555 if (hr.error) {
0556 outstream_user_open[phm->adapter_index][phm->
0557 obj_index].h_owner = h_owner;
0558 phr->error = hr.error;
0559 } else {
0560 outstream_user_open[phm->adapter_index][phm->
0561 obj_index].open_flag = 0;
0562 outstream_user_open[phm->adapter_index][phm->
0563 obj_index].h_owner = NULL;
0564 }
0565 } else {
0566 HPI_DEBUG_LOG(WARNING,
0567 "%p trying to close %d outstream %d owned by %p\n",
0568 h_owner, phm->adapter_index, phm->obj_index,
0569 outstream_user_open[phm->adapter_index][phm->
0570 obj_index].h_owner);
0571 phr->error = HPI_ERROR_OBJ_NOT_OPEN;
0572 }
0573 hpios_msgxlock_unlock(&msgx_lock);
0574 }
0575
0576 static u16 adapter_prepare(u16 adapter)
0577 {
0578 struct hpi_message hm;
0579 struct hpi_response hr;
0580
0581
0582 u16 i;
0583
0584
0585 hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER,
0586 HPI_ADAPTER_OPEN);
0587 hm.adapter_index = adapter;
0588 hw_entry_point(&hm, &hr);
0589 memcpy(&rESP_HPI_ADAPTER_OPEN[adapter], &hr,
0590 sizeof(rESP_HPI_ADAPTER_OPEN[0]));
0591 if (hr.error)
0592 return hr.error;
0593
0594
0595 hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER,
0596 HPI_ADAPTER_GET_INFO);
0597 hm.adapter_index = adapter;
0598 hw_entry_point(&hm, &hr);
0599 if (hr.error)
0600 return hr.error;
0601
0602 aDAPTER_INFO[adapter].num_outstreams = hr.u.ax.info.num_outstreams;
0603 aDAPTER_INFO[adapter].num_instreams = hr.u.ax.info.num_instreams;
0604 aDAPTER_INFO[adapter].type = hr.u.ax.info.adapter_type;
0605
0606
0607 for (i = 0; i < aDAPTER_INFO[adapter].num_outstreams; i++) {
0608 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
0609 HPI_OSTREAM_OPEN);
0610 hm.adapter_index = adapter;
0611 hm.obj_index = i;
0612 hw_entry_point(&hm, &hr);
0613 memcpy(&rESP_HPI_OSTREAM_OPEN[adapter][i], &hr,
0614 sizeof(rESP_HPI_OSTREAM_OPEN[0][0]));
0615 outstream_user_open[adapter][i].open_flag = 0;
0616 outstream_user_open[adapter][i].h_owner = NULL;
0617 }
0618
0619
0620 for (i = 0; i < aDAPTER_INFO[adapter].num_instreams; i++) {
0621 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
0622 HPI_ISTREAM_OPEN);
0623 hm.adapter_index = adapter;
0624 hm.obj_index = i;
0625 hw_entry_point(&hm, &hr);
0626 memcpy(&rESP_HPI_ISTREAM_OPEN[adapter][i], &hr,
0627 sizeof(rESP_HPI_ISTREAM_OPEN[0][0]));
0628 instream_user_open[adapter][i].open_flag = 0;
0629 instream_user_open[adapter][i].h_owner = NULL;
0630 }
0631
0632
0633 hpi_init_message_response(&hm, &hr, HPI_OBJ_MIXER, HPI_MIXER_OPEN);
0634 hm.adapter_index = adapter;
0635 hw_entry_point(&hm, &hr);
0636 memcpy(&rESP_HPI_MIXER_OPEN[adapter], &hr,
0637 sizeof(rESP_HPI_MIXER_OPEN[0]));
0638
0639 return 0;
0640 }
0641
0642 static void HPIMSGX__reset(u16 adapter_index)
0643 {
0644 int i;
0645 u16 adapter;
0646 struct hpi_response hr;
0647
0648 if (adapter_index == HPIMSGX_ALLADAPTERS) {
0649 for (adapter = 0; adapter < HPI_MAX_ADAPTERS; adapter++) {
0650
0651 hpi_init_response(&hr, HPI_OBJ_ADAPTER,
0652 HPI_ADAPTER_OPEN, HPI_ERROR_BAD_ADAPTER);
0653 memcpy(&rESP_HPI_ADAPTER_OPEN[adapter], &hr,
0654 sizeof(rESP_HPI_ADAPTER_OPEN[adapter]));
0655
0656 hpi_init_response(&hr, HPI_OBJ_MIXER, HPI_MIXER_OPEN,
0657 HPI_ERROR_INVALID_OBJ);
0658 memcpy(&rESP_HPI_MIXER_OPEN[adapter], &hr,
0659 sizeof(rESP_HPI_MIXER_OPEN[adapter]));
0660
0661 for (i = 0; i < HPI_MAX_STREAMS; i++) {
0662 hpi_init_response(&hr, HPI_OBJ_OSTREAM,
0663 HPI_OSTREAM_OPEN,
0664 HPI_ERROR_INVALID_OBJ);
0665 memcpy(&rESP_HPI_OSTREAM_OPEN[adapter][i],
0666 &hr,
0667 sizeof(rESP_HPI_OSTREAM_OPEN[adapter]
0668 [i]));
0669 hpi_init_response(&hr, HPI_OBJ_ISTREAM,
0670 HPI_ISTREAM_OPEN,
0671 HPI_ERROR_INVALID_OBJ);
0672 memcpy(&rESP_HPI_ISTREAM_OPEN[adapter][i],
0673 &hr,
0674 sizeof(rESP_HPI_ISTREAM_OPEN[adapter]
0675 [i]));
0676 }
0677 }
0678 } else if (adapter_index < HPI_MAX_ADAPTERS) {
0679 rESP_HPI_ADAPTER_OPEN[adapter_index].h.error =
0680 HPI_ERROR_BAD_ADAPTER;
0681 rESP_HPI_MIXER_OPEN[adapter_index].h.error =
0682 HPI_ERROR_INVALID_OBJ;
0683 for (i = 0; i < HPI_MAX_STREAMS; i++) {
0684 rESP_HPI_OSTREAM_OPEN[adapter_index][i].h.error =
0685 HPI_ERROR_INVALID_OBJ;
0686 rESP_HPI_ISTREAM_OPEN[adapter_index][i].h.error =
0687 HPI_ERROR_INVALID_OBJ;
0688 }
0689 }
0690 }
0691
0692 static u16 HPIMSGX__init(struct hpi_message *phm,
0693
0694
0695 struct hpi_response *phr
0696
0697 )
0698 {
0699 hpi_handler_func *entry_point_func;
0700 struct hpi_response hr;
0701
0702
0703 hpi_init_response(&hr, phm->object, phm->function,
0704 HPI_ERROR_INVALID_OBJ);
0705
0706 entry_point_func =
0707 hpi_lookup_entry_point_function(phm->u.s.resource.r.pci);
0708
0709 if (entry_point_func) {
0710 HPI_DEBUG_MESSAGE(DEBUG, phm);
0711 entry_point_func(phm, &hr);
0712 } else {
0713 phr->error = HPI_ERROR_PROCESSING_MESSAGE;
0714 return phr->error;
0715 }
0716 if (hr.error == 0) {
0717
0718
0719 hpi_entry_points[hr.u.s.adapter_index] = entry_point_func;
0720
0721 HPI_DEBUG_LOG(DEBUG,
0722 "HPI_SUBSYS_CREATE_ADAPTER successful,"
0723 " preparing adapter\n");
0724 adapter_prepare(hr.u.s.adapter_index);
0725 }
0726 memcpy(phr, &hr, hr.size);
0727 return phr->error;
0728 }
0729
0730 static void HPIMSGX__cleanup(u16 adapter_index, void *h_owner)
0731 {
0732 int i, adapter, adapter_limit;
0733
0734 if (!h_owner)
0735 return;
0736
0737 if (adapter_index == HPIMSGX_ALLADAPTERS) {
0738 adapter = 0;
0739 adapter_limit = HPI_MAX_ADAPTERS;
0740 } else {
0741 adapter = adapter_index;
0742 adapter_limit = adapter + 1;
0743 }
0744
0745 for (; adapter < adapter_limit; adapter++) {
0746
0747 for (i = 0; i < HPI_MAX_STREAMS; i++) {
0748 if (h_owner ==
0749 outstream_user_open[adapter][i].h_owner) {
0750 struct hpi_message hm;
0751 struct hpi_response hr;
0752
0753 HPI_DEBUG_LOG(DEBUG,
0754 "Close adapter %d ostream %d\n",
0755 adapter, i);
0756
0757 hpi_init_message_response(&hm, &hr,
0758 HPI_OBJ_OSTREAM, HPI_OSTREAM_RESET);
0759 hm.adapter_index = (u16)adapter;
0760 hm.obj_index = (u16)i;
0761 hw_entry_point(&hm, &hr);
0762
0763 hm.function = HPI_OSTREAM_HOSTBUFFER_FREE;
0764 hw_entry_point(&hm, &hr);
0765
0766 hm.function = HPI_OSTREAM_GROUP_RESET;
0767 hw_entry_point(&hm, &hr);
0768
0769 outstream_user_open[adapter][i].open_flag = 0;
0770 outstream_user_open[adapter][i].h_owner =
0771 NULL;
0772 }
0773 if (h_owner == instream_user_open[adapter][i].h_owner) {
0774 struct hpi_message hm;
0775 struct hpi_response hr;
0776
0777 HPI_DEBUG_LOG(DEBUG,
0778 "Close adapter %d istream %d\n",
0779 adapter, i);
0780
0781 hpi_init_message_response(&hm, &hr,
0782 HPI_OBJ_ISTREAM, HPI_ISTREAM_RESET);
0783 hm.adapter_index = (u16)adapter;
0784 hm.obj_index = (u16)i;
0785 hw_entry_point(&hm, &hr);
0786
0787 hm.function = HPI_ISTREAM_HOSTBUFFER_FREE;
0788 hw_entry_point(&hm, &hr);
0789
0790 hm.function = HPI_ISTREAM_GROUP_RESET;
0791 hw_entry_point(&hm, &hr);
0792
0793 instream_user_open[adapter][i].open_flag = 0;
0794 instream_user_open[adapter][i].h_owner = NULL;
0795 }
0796 }
0797 }
0798 }