diff options
Diffstat (limited to 'sound/pci/asihpi/hpi6000.c')
-rw-r--r-- | sound/pci/asihpi/hpi6000.c | 332 |
1 files changed, 150 insertions, 182 deletions
diff --git a/sound/pci/asihpi/hpi6000.c b/sound/pci/asihpi/hpi6000.c index f7e374ec4414..df4aed5295dd 100644 --- a/sound/pci/asihpi/hpi6000.c +++ b/sound/pci/asihpi/hpi6000.c | |||
@@ -43,16 +43,17 @@ | |||
43 | #define HPI_HIF_ERROR_MASK 0x4000 | 43 | #define HPI_HIF_ERROR_MASK 0x4000 |
44 | 44 | ||
45 | /* HPI6000 specific error codes */ | 45 | /* HPI6000 specific error codes */ |
46 | #define HPI6000_ERROR_BASE 900 /* not actually used anywhere */ | ||
46 | 47 | ||
47 | #define HPI6000_ERROR_BASE 900 | 48 | /* operational/messaging errors */ |
48 | #define HPI6000_ERROR_MSG_RESP_IDLE_TIMEOUT 901 | 49 | #define HPI6000_ERROR_MSG_RESP_IDLE_TIMEOUT 901 |
49 | #define HPI6000_ERROR_MSG_RESP_SEND_MSG_ACK 902 | 50 | |
50 | #define HPI6000_ERROR_MSG_RESP_GET_RESP_ACK 903 | 51 | #define HPI6000_ERROR_MSG_RESP_GET_RESP_ACK 903 |
51 | #define HPI6000_ERROR_MSG_GET_ADR 904 | 52 | #define HPI6000_ERROR_MSG_GET_ADR 904 |
52 | #define HPI6000_ERROR_RESP_GET_ADR 905 | 53 | #define HPI6000_ERROR_RESP_GET_ADR 905 |
53 | #define HPI6000_ERROR_MSG_RESP_BLOCKWRITE32 906 | 54 | #define HPI6000_ERROR_MSG_RESP_BLOCKWRITE32 906 |
54 | #define HPI6000_ERROR_MSG_RESP_BLOCKREAD32 907 | 55 | #define HPI6000_ERROR_MSG_RESP_BLOCKREAD32 907 |
55 | #define HPI6000_ERROR_MSG_INVALID_DSP_INDEX 908 | 56 | |
56 | #define HPI6000_ERROR_CONTROL_CACHE_PARAMS 909 | 57 | #define HPI6000_ERROR_CONTROL_CACHE_PARAMS 909 |
57 | 58 | ||
58 | #define HPI6000_ERROR_SEND_DATA_IDLE_TIMEOUT 911 | 59 | #define HPI6000_ERROR_SEND_DATA_IDLE_TIMEOUT 911 |
@@ -62,7 +63,6 @@ | |||
62 | #define HPI6000_ERROR_SEND_DATA_CMD 915 | 63 | #define HPI6000_ERROR_SEND_DATA_CMD 915 |
63 | #define HPI6000_ERROR_SEND_DATA_WRITE 916 | 64 | #define HPI6000_ERROR_SEND_DATA_WRITE 916 |
64 | #define HPI6000_ERROR_SEND_DATA_IDLECMD 917 | 65 | #define HPI6000_ERROR_SEND_DATA_IDLECMD 917 |
65 | #define HPI6000_ERROR_SEND_DATA_VERIFY 918 | ||
66 | 66 | ||
67 | #define HPI6000_ERROR_GET_DATA_IDLE_TIMEOUT 921 | 67 | #define HPI6000_ERROR_GET_DATA_IDLE_TIMEOUT 921 |
68 | #define HPI6000_ERROR_GET_DATA_ACK 922 | 68 | #define HPI6000_ERROR_GET_DATA_ACK 922 |
@@ -76,9 +76,8 @@ | |||
76 | 76 | ||
77 | #define HPI6000_ERROR_MSG_RESP_GETRESPCMD 961 | 77 | #define HPI6000_ERROR_MSG_RESP_GETRESPCMD 961 |
78 | #define HPI6000_ERROR_MSG_RESP_IDLECMD 962 | 78 | #define HPI6000_ERROR_MSG_RESP_IDLECMD 962 |
79 | #define HPI6000_ERROR_MSG_RESP_BLOCKVERIFY32 963 | ||
80 | 79 | ||
81 | /* adapter init errors */ | 80 | /* Initialisation/bootload errors */ |
82 | #define HPI6000_ERROR_UNHANDLED_SUBSYS_ID 930 | 81 | #define HPI6000_ERROR_UNHANDLED_SUBSYS_ID 930 |
83 | 82 | ||
84 | /* can't access PCI2040 */ | 83 | /* can't access PCI2040 */ |
@@ -201,8 +200,8 @@ static void hpi_read_block(struct dsp_obj *pdo, u32 address, u32 *pdata, | |||
201 | static void subsys_create_adapter(struct hpi_message *phm, | 200 | static void subsys_create_adapter(struct hpi_message *phm, |
202 | struct hpi_response *phr); | 201 | struct hpi_response *phr); |
203 | 202 | ||
204 | static void subsys_delete_adapter(struct hpi_message *phm, | 203 | static void adapter_delete(struct hpi_adapter_obj *pao, |
205 | struct hpi_response *phr); | 204 | struct hpi_message *phm, struct hpi_response *phr); |
206 | 205 | ||
207 | static void adapter_get_asserts(struct hpi_adapter_obj *pao, | 206 | static void adapter_get_asserts(struct hpi_adapter_obj *pao, |
208 | struct hpi_message *phm, struct hpi_response *phr); | 207 | struct hpi_message *phm, struct hpi_response *phr); |
@@ -210,6 +209,8 @@ static void adapter_get_asserts(struct hpi_adapter_obj *pao, | |||
210 | static short create_adapter_obj(struct hpi_adapter_obj *pao, | 209 | static short create_adapter_obj(struct hpi_adapter_obj *pao, |
211 | u32 *pos_error_code); | 210 | u32 *pos_error_code); |
212 | 211 | ||
212 | static void delete_adapter_obj(struct hpi_adapter_obj *pao); | ||
213 | |||
213 | /* local globals */ | 214 | /* local globals */ |
214 | 215 | ||
215 | static u16 gw_pci_read_asserts; /* used to count PCI2040 errors */ | 216 | static u16 gw_pci_read_asserts; /* used to count PCI2040 errors */ |
@@ -217,23 +218,10 @@ static u16 gw_pci_write_asserts; /* used to count PCI2040 errors */ | |||
217 | 218 | ||
218 | static void subsys_message(struct hpi_message *phm, struct hpi_response *phr) | 219 | static void subsys_message(struct hpi_message *phm, struct hpi_response *phr) |
219 | { | 220 | { |
220 | |||
221 | switch (phm->function) { | 221 | switch (phm->function) { |
222 | case HPI_SUBSYS_OPEN: | ||
223 | case HPI_SUBSYS_CLOSE: | ||
224 | case HPI_SUBSYS_GET_INFO: | ||
225 | case HPI_SUBSYS_DRIVER_UNLOAD: | ||
226 | case HPI_SUBSYS_DRIVER_LOAD: | ||
227 | case HPI_SUBSYS_FIND_ADAPTERS: | ||
228 | /* messages that should not get here */ | ||
229 | phr->error = HPI_ERROR_UNIMPLEMENTED; | ||
230 | break; | ||
231 | case HPI_SUBSYS_CREATE_ADAPTER: | 222 | case HPI_SUBSYS_CREATE_ADAPTER: |
232 | subsys_create_adapter(phm, phr); | 223 | subsys_create_adapter(phm, phr); |
233 | break; | 224 | break; |
234 | case HPI_SUBSYS_DELETE_ADAPTER: | ||
235 | subsys_delete_adapter(phm, phr); | ||
236 | break; | ||
237 | default: | 225 | default: |
238 | phr->error = HPI_ERROR_INVALID_FUNC; | 226 | phr->error = HPI_ERROR_INVALID_FUNC; |
239 | break; | 227 | break; |
@@ -243,7 +231,6 @@ static void subsys_message(struct hpi_message *phm, struct hpi_response *phr) | |||
243 | static void control_message(struct hpi_adapter_obj *pao, | 231 | static void control_message(struct hpi_adapter_obj *pao, |
244 | struct hpi_message *phm, struct hpi_response *phr) | 232 | struct hpi_message *phm, struct hpi_response *phr) |
245 | { | 233 | { |
246 | |||
247 | switch (phm->function) { | 234 | switch (phm->function) { |
248 | case HPI_CONTROL_GET_STATE: | 235 | case HPI_CONTROL_GET_STATE: |
249 | if (pao->has_control_cache) { | 236 | if (pao->has_control_cache) { |
@@ -251,7 +238,13 @@ static void control_message(struct hpi_adapter_obj *pao, | |||
251 | err = hpi6000_update_control_cache(pao, phm); | 238 | err = hpi6000_update_control_cache(pao, phm); |
252 | 239 | ||
253 | if (err) { | 240 | if (err) { |
254 | phr->error = err; | 241 | if (err >= HPI_ERROR_BACKEND_BASE) { |
242 | phr->error = | ||
243 | HPI_ERROR_CONTROL_CACHING; | ||
244 | phr->specific_error = err; | ||
245 | } else { | ||
246 | phr->error = err; | ||
247 | } | ||
255 | break; | 248 | break; |
256 | } | 249 | } |
257 | 250 | ||
@@ -262,16 +255,15 @@ static void control_message(struct hpi_adapter_obj *pao, | |||
262 | } | 255 | } |
263 | hw_message(pao, phm, phr); | 256 | hw_message(pao, phm, phr); |
264 | break; | 257 | break; |
265 | case HPI_CONTROL_GET_INFO: | ||
266 | hw_message(pao, phm, phr); | ||
267 | break; | ||
268 | case HPI_CONTROL_SET_STATE: | 258 | case HPI_CONTROL_SET_STATE: |
269 | hw_message(pao, phm, phr); | 259 | hw_message(pao, phm, phr); |
270 | hpi_sync_control_cache(((struct hpi_hw_obj *)pao->priv)-> | 260 | hpi_cmn_control_cache_sync_to_msg(((struct hpi_hw_obj *)pao-> |
271 | p_cache, phm, phr); | 261 | priv)->p_cache, phm, phr); |
272 | break; | 262 | break; |
263 | |||
264 | case HPI_CONTROL_GET_INFO: | ||
273 | default: | 265 | default: |
274 | phr->error = HPI_ERROR_INVALID_FUNC; | 266 | hw_message(pao, phm, phr); |
275 | break; | 267 | break; |
276 | } | 268 | } |
277 | } | 269 | } |
@@ -280,26 +272,16 @@ static void adapter_message(struct hpi_adapter_obj *pao, | |||
280 | struct hpi_message *phm, struct hpi_response *phr) | 272 | struct hpi_message *phm, struct hpi_response *phr) |
281 | { | 273 | { |
282 | switch (phm->function) { | 274 | switch (phm->function) { |
283 | case HPI_ADAPTER_GET_INFO: | ||
284 | hw_message(pao, phm, phr); | ||
285 | break; | ||
286 | case HPI_ADAPTER_GET_ASSERT: | 275 | case HPI_ADAPTER_GET_ASSERT: |
287 | adapter_get_asserts(pao, phm, phr); | 276 | adapter_get_asserts(pao, phm, phr); |
288 | break; | 277 | break; |
289 | case HPI_ADAPTER_OPEN: | 278 | |
290 | case HPI_ADAPTER_CLOSE: | 279 | case HPI_ADAPTER_DELETE: |
291 | case HPI_ADAPTER_TEST_ASSERT: | 280 | adapter_delete(pao, phm, phr); |
292 | case HPI_ADAPTER_SELFTEST: | ||
293 | case HPI_ADAPTER_GET_MODE: | ||
294 | case HPI_ADAPTER_SET_MODE: | ||
295 | case HPI_ADAPTER_FIND_OBJECT: | ||
296 | case HPI_ADAPTER_GET_PROPERTY: | ||
297 | case HPI_ADAPTER_SET_PROPERTY: | ||
298 | case HPI_ADAPTER_ENUM_PROPERTY: | ||
299 | hw_message(pao, phm, phr); | ||
300 | break; | 281 | break; |
282 | |||
301 | default: | 283 | default: |
302 | phr->error = HPI_ERROR_INVALID_FUNC; | 284 | hw_message(pao, phm, phr); |
303 | break; | 285 | break; |
304 | } | 286 | } |
305 | } | 287 | } |
@@ -311,7 +293,7 @@ static void outstream_message(struct hpi_adapter_obj *pao, | |||
311 | case HPI_OSTREAM_HOSTBUFFER_ALLOC: | 293 | case HPI_OSTREAM_HOSTBUFFER_ALLOC: |
312 | case HPI_OSTREAM_HOSTBUFFER_FREE: | 294 | case HPI_OSTREAM_HOSTBUFFER_FREE: |
313 | /* Don't let these messages go to the HW function because | 295 | /* Don't let these messages go to the HW function because |
314 | * they're called without allocating the spinlock. | 296 | * they're called without locking the spinlock. |
315 | * For the HPI6000 adapters the HW would return | 297 | * For the HPI6000 adapters the HW would return |
316 | * HPI_ERROR_INVALID_FUNC anyway. | 298 | * HPI_ERROR_INVALID_FUNC anyway. |
317 | */ | 299 | */ |
@@ -331,7 +313,7 @@ static void instream_message(struct hpi_adapter_obj *pao, | |||
331 | case HPI_ISTREAM_HOSTBUFFER_ALLOC: | 313 | case HPI_ISTREAM_HOSTBUFFER_ALLOC: |
332 | case HPI_ISTREAM_HOSTBUFFER_FREE: | 314 | case HPI_ISTREAM_HOSTBUFFER_FREE: |
333 | /* Don't let these messages go to the HW function because | 315 | /* Don't let these messages go to the HW function because |
334 | * they're called without allocating the spinlock. | 316 | * they're called without locking the spinlock. |
335 | * For the HPI6000 adapters the HW would return | 317 | * For the HPI6000 adapters the HW would return |
336 | * HPI_ERROR_INVALID_FUNC anyway. | 318 | * HPI_ERROR_INVALID_FUNC anyway. |
337 | */ | 319 | */ |
@@ -352,26 +334,22 @@ void HPI_6000(struct hpi_message *phm, struct hpi_response *phr) | |||
352 | { | 334 | { |
353 | struct hpi_adapter_obj *pao = NULL; | 335 | struct hpi_adapter_obj *pao = NULL; |
354 | 336 | ||
355 | /* subsytem messages get executed by every HPI. */ | ||
356 | /* All other messages are ignored unless the adapter index matches */ | ||
357 | /* an adapter in the HPI */ | ||
358 | HPI_DEBUG_LOG(DEBUG, "O %d,F %x\n", phm->object, phm->function); | ||
359 | |||
360 | /* if Dsp has crashed then do not communicate with it any more */ | ||
361 | if (phm->object != HPI_OBJ_SUBSYSTEM) { | 337 | if (phm->object != HPI_OBJ_SUBSYSTEM) { |
362 | pao = hpi_find_adapter(phm->adapter_index); | 338 | pao = hpi_find_adapter(phm->adapter_index); |
363 | if (!pao) { | 339 | if (!pao) { |
364 | HPI_DEBUG_LOG(DEBUG, | 340 | hpi_init_response(phr, phm->object, phm->function, |
365 | " %d,%d refused, for another HPI?\n", | 341 | HPI_ERROR_BAD_ADAPTER_NUMBER); |
366 | phm->object, phm->function); | 342 | HPI_DEBUG_LOG(DEBUG, "invalid adapter index: %d \n", |
343 | phm->adapter_index); | ||
367 | return; | 344 | return; |
368 | } | 345 | } |
369 | 346 | ||
347 | /* Don't even try to communicate with crashed DSP */ | ||
370 | if (pao->dsp_crashed >= 10) { | 348 | if (pao->dsp_crashed >= 10) { |
371 | hpi_init_response(phr, phm->object, phm->function, | 349 | hpi_init_response(phr, phm->object, phm->function, |
372 | HPI_ERROR_DSP_HARDWARE); | 350 | HPI_ERROR_DSP_HARDWARE); |
373 | HPI_DEBUG_LOG(DEBUG, " %d,%d dsp crashed.\n", | 351 | HPI_DEBUG_LOG(DEBUG, "adapter %d dsp crashed\n", |
374 | phm->object, phm->function); | 352 | phm->adapter_index); |
375 | return; | 353 | return; |
376 | } | 354 | } |
377 | } | 355 | } |
@@ -433,39 +411,34 @@ static void subsys_create_adapter(struct hpi_message *phm, | |||
433 | struct hpi_adapter_obj ao; | 411 | struct hpi_adapter_obj ao; |
434 | struct hpi_adapter_obj *pao; | 412 | struct hpi_adapter_obj *pao; |
435 | u32 os_error_code; | 413 | u32 os_error_code; |
436 | short error = 0; | 414 | u16 err = 0; |
437 | u32 dsp_index = 0; | 415 | u32 dsp_index = 0; |
438 | 416 | ||
439 | HPI_DEBUG_LOG(VERBOSE, "subsys_create_adapter\n"); | 417 | HPI_DEBUG_LOG(VERBOSE, "subsys_create_adapter\n"); |
440 | 418 | ||
441 | memset(&ao, 0, sizeof(ao)); | 419 | memset(&ao, 0, sizeof(ao)); |
442 | 420 | ||
443 | /* this HPI only creates adapters for TI/PCI2040 based devices */ | ||
444 | if (phm->u.s.resource.bus_type != HPI_BUS_PCI) | ||
445 | return; | ||
446 | if (phm->u.s.resource.r.pci->vendor_id != HPI_PCI_VENDOR_ID_TI) | ||
447 | return; | ||
448 | if (phm->u.s.resource.r.pci->device_id != HPI_PCI_DEV_ID_PCI2040) | ||
449 | return; | ||
450 | |||
451 | ao.priv = kzalloc(sizeof(struct hpi_hw_obj), GFP_KERNEL); | 421 | ao.priv = kzalloc(sizeof(struct hpi_hw_obj), GFP_KERNEL); |
452 | if (!ao.priv) { | 422 | if (!ao.priv) { |
453 | HPI_DEBUG_LOG(ERROR, "cant get mem for adapter object\n"); | 423 | HPI_DEBUG_LOG(ERROR, "can't get mem for adapter object\n"); |
454 | phr->error = HPI_ERROR_MEMORY_ALLOC; | 424 | phr->error = HPI_ERROR_MEMORY_ALLOC; |
455 | return; | 425 | return; |
456 | } | 426 | } |
457 | 427 | ||
458 | /* create the adapter object based on the resource information */ | 428 | /* create the adapter object based on the resource information */ |
459 | /*? memcpy(&ao.Pci,&phm->u.s.Resource.r.Pci,sizeof(ao.Pci)); */ | ||
460 | ao.pci = *phm->u.s.resource.r.pci; | 429 | ao.pci = *phm->u.s.resource.r.pci; |
461 | 430 | ||
462 | error = create_adapter_obj(&ao, &os_error_code); | 431 | err = create_adapter_obj(&ao, &os_error_code); |
463 | if (!error) | 432 | if (err) { |
464 | error = hpi_add_adapter(&ao); | 433 | delete_adapter_obj(&ao); |
465 | if (error) { | 434 | if (err >= HPI_ERROR_BACKEND_BASE) { |
435 | phr->error = HPI_ERROR_DSP_BOOTLOAD; | ||
436 | phr->specific_error = err; | ||
437 | } else { | ||
438 | phr->error = err; | ||
439 | } | ||
440 | |||
466 | phr->u.s.data = os_error_code; | 441 | phr->u.s.data = os_error_code; |
467 | kfree(ao.priv); | ||
468 | phr->error = error; | ||
469 | return; | 442 | return; |
470 | } | 443 | } |
471 | /* need to update paParentAdapter */ | 444 | /* need to update paParentAdapter */ |
@@ -473,7 +446,7 @@ static void subsys_create_adapter(struct hpi_message *phm, | |||
473 | if (!pao) { | 446 | if (!pao) { |
474 | /* We just added this adapter, why can't we find it!? */ | 447 | /* We just added this adapter, why can't we find it!? */ |
475 | HPI_DEBUG_LOG(ERROR, "lost adapter after boot\n"); | 448 | HPI_DEBUG_LOG(ERROR, "lost adapter after boot\n"); |
476 | phr->error = 950; | 449 | phr->error = HPI_ERROR_BAD_ADAPTER; |
477 | return; | 450 | return; |
478 | } | 451 | } |
479 | 452 | ||
@@ -482,30 +455,16 @@ static void subsys_create_adapter(struct hpi_message *phm, | |||
482 | phw->ado[dsp_index].pa_parent_adapter = pao; | 455 | phw->ado[dsp_index].pa_parent_adapter = pao; |
483 | } | 456 | } |
484 | 457 | ||
485 | phr->u.s.aw_adapter_list[ao.index] = ao.adapter_type; | 458 | phr->u.s.adapter_type = ao.adapter_type; |
486 | phr->u.s.adapter_index = ao.index; | 459 | phr->u.s.adapter_index = ao.index; |
487 | phr->u.s.num_adapters++; | ||
488 | phr->error = 0; | 460 | phr->error = 0; |
489 | } | 461 | } |
490 | 462 | ||
491 | static void subsys_delete_adapter(struct hpi_message *phm, | 463 | static void adapter_delete(struct hpi_adapter_obj *pao, |
492 | struct hpi_response *phr) | 464 | struct hpi_message *phm, struct hpi_response *phr) |
493 | { | 465 | { |
494 | struct hpi_adapter_obj *pao = NULL; | 466 | delete_adapter_obj(pao); |
495 | struct hpi_hw_obj *phw; | ||
496 | |||
497 | pao = hpi_find_adapter(phm->adapter_index); | ||
498 | if (!pao) | ||
499 | return; | ||
500 | |||
501 | phw = (struct hpi_hw_obj *)pao->priv; | ||
502 | |||
503 | if (pao->has_control_cache) | ||
504 | hpi_free_control_cache(phw->p_cache); | ||
505 | |||
506 | hpi_delete_adapter(pao); | 467 | hpi_delete_adapter(pao); |
507 | kfree(phw); | ||
508 | |||
509 | phr->error = 0; | 468 | phr->error = 0; |
510 | } | 469 | } |
511 | 470 | ||
@@ -519,9 +478,6 @@ static short create_adapter_obj(struct hpi_adapter_obj *pao, | |||
519 | u32 control_cache_count = 0; | 478 | u32 control_cache_count = 0; |
520 | struct hpi_hw_obj *phw = (struct hpi_hw_obj *)pao->priv; | 479 | struct hpi_hw_obj *phw = (struct hpi_hw_obj *)pao->priv; |
521 | 480 | ||
522 | /* init error reporting */ | ||
523 | pao->dsp_crashed = 0; | ||
524 | |||
525 | /* The PCI2040 has the following address map */ | 481 | /* The PCI2040 has the following address map */ |
526 | /* BAR0 - 4K = HPI control and status registers on PCI2040 (HPI CSR) */ | 482 | /* BAR0 - 4K = HPI control and status registers on PCI2040 (HPI CSR) */ |
527 | /* BAR1 - 32K = HPI registers on DSP */ | 483 | /* BAR1 - 32K = HPI registers on DSP */ |
@@ -575,36 +531,36 @@ static short create_adapter_obj(struct hpi_adapter_obj *pao, | |||
575 | /* get info about the adapter by asking the adapter */ | 531 | /* get info about the adapter by asking the adapter */ |
576 | /* send a HPI_ADAPTER_GET_INFO message */ | 532 | /* send a HPI_ADAPTER_GET_INFO message */ |
577 | { | 533 | { |
578 | struct hpi_message hM; | 534 | struct hpi_message hm; |
579 | struct hpi_response hR0; /* response from DSP 0 */ | 535 | struct hpi_response hr0; /* response from DSP 0 */ |
580 | struct hpi_response hR1; /* response from DSP 1 */ | 536 | struct hpi_response hr1; /* response from DSP 1 */ |
581 | u16 error = 0; | 537 | u16 error = 0; |
582 | 538 | ||
583 | HPI_DEBUG_LOG(VERBOSE, "send ADAPTER_GET_INFO\n"); | 539 | HPI_DEBUG_LOG(VERBOSE, "send ADAPTER_GET_INFO\n"); |
584 | memset(&hM, 0, sizeof(hM)); | 540 | memset(&hm, 0, sizeof(hm)); |
585 | hM.type = HPI_TYPE_MESSAGE; | 541 | hm.type = HPI_TYPE_MESSAGE; |
586 | hM.size = sizeof(struct hpi_message); | 542 | hm.size = sizeof(struct hpi_message); |
587 | hM.object = HPI_OBJ_ADAPTER; | 543 | hm.object = HPI_OBJ_ADAPTER; |
588 | hM.function = HPI_ADAPTER_GET_INFO; | 544 | hm.function = HPI_ADAPTER_GET_INFO; |
589 | hM.adapter_index = 0; | 545 | hm.adapter_index = 0; |
590 | memset(&hR0, 0, sizeof(hR0)); | 546 | memset(&hr0, 0, sizeof(hr0)); |
591 | memset(&hR1, 0, sizeof(hR1)); | 547 | memset(&hr1, 0, sizeof(hr1)); |
592 | hR0.size = sizeof(hR0); | 548 | hr0.size = sizeof(hr0); |
593 | hR1.size = sizeof(hR1); | 549 | hr1.size = sizeof(hr1); |
594 | 550 | ||
595 | error = hpi6000_message_response_sequence(pao, 0, &hM, &hR0); | 551 | error = hpi6000_message_response_sequence(pao, 0, &hm, &hr0); |
596 | if (hR0.error) { | 552 | if (hr0.error) { |
597 | HPI_DEBUG_LOG(DEBUG, "message error %d\n", hR0.error); | 553 | HPI_DEBUG_LOG(DEBUG, "message error %d\n", hr0.error); |
598 | return hR0.error; | 554 | return hr0.error; |
599 | } | 555 | } |
600 | if (phw->num_dsp == 2) { | 556 | if (phw->num_dsp == 2) { |
601 | error = hpi6000_message_response_sequence(pao, 1, &hM, | 557 | error = hpi6000_message_response_sequence(pao, 1, &hm, |
602 | &hR1); | 558 | &hr1); |
603 | if (error) | 559 | if (error) |
604 | return error; | 560 | return error; |
605 | } | 561 | } |
606 | pao->adapter_type = hR0.u.a.adapter_type; | 562 | pao->adapter_type = hr0.u.ax.info.adapter_type; |
607 | pao->index = hR0.u.a.adapter_index; | 563 | pao->index = hr0.u.ax.info.adapter_index; |
608 | } | 564 | } |
609 | 565 | ||
610 | memset(&phw->control_cache[0], 0, | 566 | memset(&phw->control_cache[0], 0, |
@@ -618,20 +574,37 @@ static short create_adapter_obj(struct hpi_adapter_obj *pao, | |||
618 | control_cache_count = | 574 | control_cache_count = |
619 | hpi_read_word(&phw->ado[0], | 575 | hpi_read_word(&phw->ado[0], |
620 | HPI_HIF_ADDR(control_cache_count)); | 576 | HPI_HIF_ADDR(control_cache_count)); |
621 | pao->has_control_cache = 1; | ||
622 | 577 | ||
623 | phw->p_cache = | 578 | phw->p_cache = |
624 | hpi_alloc_control_cache(control_cache_count, | 579 | hpi_alloc_control_cache(control_cache_count, |
625 | control_cache_size, (struct hpi_control_cache_info *) | 580 | control_cache_size, (unsigned char *) |
626 | &phw->control_cache[0] | 581 | &phw->control_cache[0] |
627 | ); | 582 | ); |
628 | } else | 583 | if (phw->p_cache) |
629 | pao->has_control_cache = 0; | 584 | pao->has_control_cache = 1; |
585 | } | ||
630 | 586 | ||
631 | HPI_DEBUG_LOG(DEBUG, "get adapter info ASI%04X index %d\n", | 587 | HPI_DEBUG_LOG(DEBUG, "get adapter info ASI%04X index %d\n", |
632 | pao->adapter_type, pao->index); | 588 | pao->adapter_type, pao->index); |
633 | pao->open = 0; /* upon creation the adapter is closed */ | 589 | pao->open = 0; /* upon creation the adapter is closed */ |
634 | return 0; | 590 | |
591 | if (phw->p_cache) | ||
592 | phw->p_cache->adap_idx = pao->index; | ||
593 | |||
594 | return hpi_add_adapter(pao); | ||
595 | } | ||
596 | |||
597 | static void delete_adapter_obj(struct hpi_adapter_obj *pao) | ||
598 | { | ||
599 | struct hpi_hw_obj *phw = (struct hpi_hw_obj *)pao->priv; | ||
600 | |||
601 | if (pao->has_control_cache) | ||
602 | hpi_free_control_cache(phw->p_cache); | ||
603 | |||
604 | /* reset DSPs on adapter */ | ||
605 | iowrite32(0x0003000F, phw->dw2040_HPICSR + HPI_RESET); | ||
606 | |||
607 | kfree(phw); | ||
635 | } | 608 | } |
636 | 609 | ||
637 | /************************************************************************/ | 610 | /************************************************************************/ |
@@ -643,11 +616,13 @@ static void adapter_get_asserts(struct hpi_adapter_obj *pao, | |||
643 | #ifndef HIDE_PCI_ASSERTS | 616 | #ifndef HIDE_PCI_ASSERTS |
644 | /* if we have PCI2040 asserts then collect them */ | 617 | /* if we have PCI2040 asserts then collect them */ |
645 | if ((gw_pci_read_asserts > 0) || (gw_pci_write_asserts > 0)) { | 618 | if ((gw_pci_read_asserts > 0) || (gw_pci_write_asserts > 0)) { |
646 | phr->u.a.serial_number = | 619 | phr->u.ax.assert.p1 = |
647 | gw_pci_read_asserts * 100 + gw_pci_write_asserts; | 620 | gw_pci_read_asserts * 100 + gw_pci_write_asserts; |
648 | phr->u.a.adapter_index = 1; /* assert count */ | 621 | phr->u.ax.assert.p2 = 0; |
649 | phr->u.a.adapter_type = -1; /* "dsp index" */ | 622 | phr->u.ax.assert.count = 1; /* assert count */ |
650 | strcpy(phr->u.a.sz_adapter_assert, "PCI2040 error"); | 623 | phr->u.ax.assert.dsp_index = -1; /* "dsp index" */ |
624 | strcpy(phr->u.ax.assert.sz_message, "PCI2040 error"); | ||
625 | phr->u.ax.assert.dsp_msg_addr = 0; | ||
651 | gw_pci_read_asserts = 0; | 626 | gw_pci_read_asserts = 0; |
652 | gw_pci_write_asserts = 0; | 627 | gw_pci_write_asserts = 0; |
653 | phr->error = 0; | 628 | phr->error = 0; |
@@ -684,10 +659,10 @@ static short hpi6000_adapter_boot_load_dsp(struct hpi_adapter_obj *pao, | |||
684 | 659 | ||
685 | /* NOTE don't use wAdapterType in this routine. It is not setup yet */ | 660 | /* NOTE don't use wAdapterType in this routine. It is not setup yet */ |
686 | 661 | ||
687 | switch (pao->pci.subsys_device_id) { | 662 | switch (pao->pci.pci_dev->subsystem_device) { |
688 | case 0x5100: | 663 | case 0x5100: |
689 | case 0x5110: /* ASI5100 revB or higher with C6711D */ | 664 | case 0x5110: /* ASI5100 revB or higher with C6711D */ |
690 | case 0x5200: /* ASI5200 PC_ie version of ASI5100 */ | 665 | case 0x5200: /* ASI5200 PCIe version of ASI5100 */ |
691 | case 0x6100: | 666 | case 0x6100: |
692 | case 0x6200: | 667 | case 0x6200: |
693 | boot_load_family = HPI_ADAPTER_FAMILY_ASI(0x6200); | 668 | boot_load_family = HPI_ADAPTER_FAMILY_ASI(0x6200); |
@@ -707,8 +682,9 @@ static short hpi6000_adapter_boot_load_dsp(struct hpi_adapter_obj *pao, | |||
707 | * note that bits 4..15 are read-only and so should always return zero, | 682 | * note that bits 4..15 are read-only and so should always return zero, |
708 | * even though we wrote 1 to them | 683 | * even though we wrote 1 to them |
709 | */ | 684 | */ |
710 | for (i = 0; i < 1000; i++) | 685 | hpios_delay_micro_seconds(1000); |
711 | delay = ioread32(phw->dw2040_HPICSR + HPI_RESET); | 686 | delay = ioread32(phw->dw2040_HPICSR + HPI_RESET); |
687 | |||
712 | if (delay != dw2040_reset) { | 688 | if (delay != dw2040_reset) { |
713 | HPI_DEBUG_LOG(ERROR, "INIT_PCI2040 %x %x\n", dw2040_reset, | 689 | HPI_DEBUG_LOG(ERROR, "INIT_PCI2040 %x %x\n", dw2040_reset, |
714 | delay); | 690 | delay); |
@@ -741,8 +717,7 @@ static short hpi6000_adapter_boot_load_dsp(struct hpi_adapter_obj *pao, | |||
741 | dw2040_reset = dw2040_reset & (~0x00000008); | 717 | dw2040_reset = dw2040_reset & (~0x00000008); |
742 | iowrite32(dw2040_reset, phw->dw2040_HPICSR + HPI_RESET); | 718 | iowrite32(dw2040_reset, phw->dw2040_HPICSR + HPI_RESET); |
743 | /*delay to allow DSP to get going */ | 719 | /*delay to allow DSP to get going */ |
744 | for (i = 0; i < 100; i++) | 720 | hpios_delay_micro_seconds(100); |
745 | delay = ioread32(phw->dw2040_HPICSR + HPI_RESET); | ||
746 | 721 | ||
747 | /* loop through all DSPs, downloading DSP code */ | 722 | /* loop through all DSPs, downloading DSP code */ |
748 | for (dsp_index = 0; dsp_index < phw->num_dsp; dsp_index++) { | 723 | for (dsp_index = 0; dsp_index < phw->num_dsp; dsp_index++) { |
@@ -781,27 +756,27 @@ static short hpi6000_adapter_boot_load_dsp(struct hpi_adapter_obj *pao, | |||
781 | */ | 756 | */ |
782 | /* bypass PLL */ | 757 | /* bypass PLL */ |
783 | hpi_write_word(pdo, 0x01B7C100, 0x0000); | 758 | hpi_write_word(pdo, 0x01B7C100, 0x0000); |
784 | for (i = 0; i < 100; i++) | 759 | hpios_delay_micro_seconds(100); |
785 | delay = ioread32(phw->dw2040_HPICSR + | ||
786 | HPI_RESET); | ||
787 | 760 | ||
788 | /* ** use default of PLL x7 ** */ | 761 | /* ** use default of PLL x7 ** */ |
789 | /* EMIF = 225/3=75MHz */ | 762 | /* EMIF = 225/3=75MHz */ |
790 | hpi_write_word(pdo, 0x01B7C120, 0x8002); | 763 | hpi_write_word(pdo, 0x01B7C120, 0x8002); |
764 | hpios_delay_micro_seconds(100); | ||
765 | |||
791 | /* peri = 225/2 */ | 766 | /* peri = 225/2 */ |
792 | hpi_write_word(pdo, 0x01B7C11C, 0x8001); | 767 | hpi_write_word(pdo, 0x01B7C11C, 0x8001); |
768 | hpios_delay_micro_seconds(100); | ||
769 | |||
793 | /* cpu = 225/1 */ | 770 | /* cpu = 225/1 */ |
794 | hpi_write_word(pdo, 0x01B7C118, 0x8000); | 771 | hpi_write_word(pdo, 0x01B7C118, 0x8000); |
795 | /* ~200us delay */ | 772 | |
796 | for (i = 0; i < 2000; i++) | 773 | /* ~2ms delay */ |
797 | delay = ioread32(phw->dw2040_HPICSR + | 774 | hpios_delay_micro_seconds(2000); |
798 | HPI_RESET); | 775 | |
799 | /* PLL not bypassed */ | 776 | /* PLL not bypassed */ |
800 | hpi_write_word(pdo, 0x01B7C100, 0x0001); | 777 | hpi_write_word(pdo, 0x01B7C100, 0x0001); |
801 | /* ~200us delay */ | 778 | /* ~2ms delay */ |
802 | for (i = 0; i < 2000; i++) | 779 | hpios_delay_micro_seconds(2000); |
803 | delay = ioread32(phw->dw2040_HPICSR + | ||
804 | HPI_RESET); | ||
805 | } | 780 | } |
806 | 781 | ||
807 | /* test r/w to internal DSP memory | 782 | /* test r/w to internal DSP memory |
@@ -925,9 +900,7 @@ static short hpi6000_adapter_boot_load_dsp(struct hpi_adapter_obj *pao, | |||
925 | } | 900 | } |
926 | 901 | ||
927 | /* delay a little to allow SDRAM and DSP to "get going" */ | 902 | /* delay a little to allow SDRAM and DSP to "get going" */ |
928 | 903 | hpios_delay_micro_seconds(1000); | |
929 | for (i = 0; i < 1000; i++) | ||
930 | delay = ioread32(phw->dw2040_HPICSR + HPI_RESET); | ||
931 | 904 | ||
932 | /* test access to SDRAM */ | 905 | /* test access to SDRAM */ |
933 | { | 906 | { |
@@ -974,7 +947,7 @@ static short hpi6000_adapter_boot_load_dsp(struct hpi_adapter_obj *pao, | |||
974 | 947 | ||
975 | /* write the DSP code down into the DSPs memory */ | 948 | /* write the DSP code down into the DSPs memory */ |
976 | /*HpiDspCode_Open(nBootLoadFamily,&DspCode,pdwOsErrorCode); */ | 949 | /*HpiDspCode_Open(nBootLoadFamily,&DspCode,pdwOsErrorCode); */ |
977 | dsp_code.ps_dev = pao->pci.p_os_data; | 950 | dsp_code.ps_dev = pao->pci.pci_dev; |
978 | 951 | ||
979 | error = hpi_dsp_code_open(boot_load_family, &dsp_code, | 952 | error = hpi_dsp_code_open(boot_load_family, &dsp_code, |
980 | pos_error_code); | 953 | pos_error_code); |
@@ -1071,8 +1044,7 @@ static short hpi6000_adapter_boot_load_dsp(struct hpi_adapter_obj *pao, | |||
1071 | 1044 | ||
1072 | /* step 3. Start code by sending interrupt */ | 1045 | /* step 3. Start code by sending interrupt */ |
1073 | iowrite32(0x00030003, pdo->prHPI_control); | 1046 | iowrite32(0x00030003, pdo->prHPI_control); |
1074 | for (i = 0; i < 10000; i++) | 1047 | hpios_delay_micro_seconds(10000); |
1075 | delay = ioread32(phw->dw2040_HPICSR + HPI_RESET); | ||
1076 | 1048 | ||
1077 | /* wait for a non-zero value in hostcmd - | 1049 | /* wait for a non-zero value in hostcmd - |
1078 | * indicating initialization is complete | 1050 | * indicating initialization is complete |
@@ -1099,7 +1071,7 @@ static short hpi6000_adapter_boot_load_dsp(struct hpi_adapter_obj *pao, | |||
1099 | * locks up with a bluescreen (NOT GPF or pagefault). | 1071 | * locks up with a bluescreen (NOT GPF or pagefault). |
1100 | */ | 1072 | */ |
1101 | else | 1073 | else |
1102 | hpios_delay_micro_seconds(1000); | 1074 | hpios_delay_micro_seconds(10000); |
1103 | } | 1075 | } |
1104 | if (timeout == 0) | 1076 | if (timeout == 0) |
1105 | return HPI6000_ERROR_INIT_NOACK; | 1077 | return HPI6000_ERROR_INIT_NOACK; |
@@ -1130,14 +1102,14 @@ static short hpi6000_adapter_boot_load_dsp(struct hpi_adapter_obj *pao, | |||
1130 | mask = 0xFFFFFF00L; | 1102 | mask = 0xFFFFFF00L; |
1131 | /* ASI5100 uses AX6 code, */ | 1103 | /* ASI5100 uses AX6 code, */ |
1132 | /* but has no PLD r/w register to test */ | 1104 | /* but has no PLD r/w register to test */ |
1133 | if (HPI_ADAPTER_FAMILY_ASI(pao->pci. | 1105 | if (HPI_ADAPTER_FAMILY_ASI(pao->pci.pci_dev-> |
1134 | subsys_device_id) == | 1106 | subsystem_device) == |
1135 | HPI_ADAPTER_FAMILY_ASI(0x5100)) | 1107 | HPI_ADAPTER_FAMILY_ASI(0x5100)) |
1136 | mask = 0x00000000L; | 1108 | mask = 0x00000000L; |
1137 | /* ASI5200 uses AX6 code, */ | 1109 | /* ASI5200 uses AX6 code, */ |
1138 | /* but has no PLD r/w register to test */ | 1110 | /* but has no PLD r/w register to test */ |
1139 | if (HPI_ADAPTER_FAMILY_ASI(pao->pci. | 1111 | if (HPI_ADAPTER_FAMILY_ASI(pao->pci.pci_dev-> |
1140 | subsys_device_id) == | 1112 | subsystem_device) == |
1141 | HPI_ADAPTER_FAMILY_ASI(0x5200)) | 1113 | HPI_ADAPTER_FAMILY_ASI(0x5200)) |
1142 | mask = 0x00000000L; | 1114 | mask = 0x00000000L; |
1143 | break; | 1115 | break; |
@@ -1202,7 +1174,7 @@ static u32 hpi_read_word(struct dsp_obj *pdo, u32 address) | |||
1202 | u32 data = 0; | 1174 | u32 data = 0; |
1203 | 1175 | ||
1204 | if (hpi_set_address(pdo, address)) | 1176 | if (hpi_set_address(pdo, address)) |
1205 | return 0; /*? no way to return error */ | 1177 | return 0; /*? No way to return error */ |
1206 | 1178 | ||
1207 | /* take care of errata in revB DSP (2.0.1) */ | 1179 | /* take care of errata in revB DSP (2.0.1) */ |
1208 | data = ioread32(pdo->prHPI_data); | 1180 | data = ioread32(pdo->prHPI_data); |
@@ -1338,10 +1310,6 @@ static short hpi6000_message_response_sequence(struct hpi_adapter_obj *pao, | |||
1338 | u32 *p_data; | 1310 | u32 *p_data; |
1339 | u16 error = 0; | 1311 | u16 error = 0; |
1340 | 1312 | ||
1341 | /* does the DSP we are referencing exist? */ | ||
1342 | if (dsp_index >= phw->num_dsp) | ||
1343 | return HPI6000_ERROR_MSG_INVALID_DSP_INDEX; | ||
1344 | |||
1345 | ack = hpi6000_wait_dsp_ack(pao, dsp_index, HPI_HIF_IDLE); | 1313 | ack = hpi6000_wait_dsp_ack(pao, dsp_index, HPI_HIF_IDLE); |
1346 | if (ack & HPI_HIF_ERROR_MASK) { | 1314 | if (ack & HPI_HIF_ERROR_MASK) { |
1347 | pao->dsp_crashed++; | 1315 | pao->dsp_crashed++; |
@@ -1349,9 +1317,7 @@ static short hpi6000_message_response_sequence(struct hpi_adapter_obj *pao, | |||
1349 | } | 1317 | } |
1350 | pao->dsp_crashed = 0; | 1318 | pao->dsp_crashed = 0; |
1351 | 1319 | ||
1352 | /* send the message */ | 1320 | /* get the message address and size */ |
1353 | |||
1354 | /* get the address and size */ | ||
1355 | if (phw->message_buffer_address_on_dsp == 0) { | 1321 | if (phw->message_buffer_address_on_dsp == 0) { |
1356 | timeout = TIMEOUT; | 1322 | timeout = TIMEOUT; |
1357 | do { | 1323 | do { |
@@ -1366,10 +1332,9 @@ static short hpi6000_message_response_sequence(struct hpi_adapter_obj *pao, | |||
1366 | } else | 1332 | } else |
1367 | address = phw->message_buffer_address_on_dsp; | 1333 | address = phw->message_buffer_address_on_dsp; |
1368 | 1334 | ||
1369 | /* dwLength = sizeof(struct hpi_message); */ | ||
1370 | length = phm->size; | 1335 | length = phm->size; |
1371 | 1336 | ||
1372 | /* send it */ | 1337 | /* send the message */ |
1373 | p_data = (u32 *)phm; | 1338 | p_data = (u32 *)phm; |
1374 | if (hpi6000_dsp_block_write32(pao, dsp_index, address, p_data, | 1339 | if (hpi6000_dsp_block_write32(pao, dsp_index, address, p_data, |
1375 | (u16)length / 4)) | 1340 | (u16)length / 4)) |
@@ -1383,7 +1348,7 @@ static short hpi6000_message_response_sequence(struct hpi_adapter_obj *pao, | |||
1383 | if (ack & HPI_HIF_ERROR_MASK) | 1348 | if (ack & HPI_HIF_ERROR_MASK) |
1384 | return HPI6000_ERROR_MSG_RESP_GET_RESP_ACK; | 1349 | return HPI6000_ERROR_MSG_RESP_GET_RESP_ACK; |
1385 | 1350 | ||
1386 | /* get the address and size */ | 1351 | /* get the response address */ |
1387 | if (phw->response_buffer_address_on_dsp == 0) { | 1352 | if (phw->response_buffer_address_on_dsp == 0) { |
1388 | timeout = TIMEOUT; | 1353 | timeout = TIMEOUT; |
1389 | do { | 1354 | do { |
@@ -1407,7 +1372,7 @@ static short hpi6000_message_response_sequence(struct hpi_adapter_obj *pao, | |||
1407 | if (!timeout) | 1372 | if (!timeout) |
1408 | length = sizeof(struct hpi_response); | 1373 | length = sizeof(struct hpi_response); |
1409 | 1374 | ||
1410 | /* get it */ | 1375 | /* get the response */ |
1411 | p_data = (u32 *)phr; | 1376 | p_data = (u32 *)phr; |
1412 | if (hpi6000_dsp_block_read32(pao, dsp_index, address, p_data, | 1377 | if (hpi6000_dsp_block_read32(pao, dsp_index, address, p_data, |
1413 | (u16)length / 4)) | 1378 | (u16)length / 4)) |
@@ -1803,17 +1768,11 @@ static void hw_message(struct hpi_adapter_obj *pao, struct hpi_message *phm, | |||
1803 | hpios_dsplock_lock(pao); | 1768 | hpios_dsplock_lock(pao); |
1804 | error = hpi6000_message_response_sequence(pao, dsp_index, phm, phr); | 1769 | error = hpi6000_message_response_sequence(pao, dsp_index, phm, phr); |
1805 | 1770 | ||
1806 | /* maybe an error response */ | 1771 | if (error) /* something failed in the HPI/DSP interface */ |
1807 | if (error) { | ||
1808 | /* something failed in the HPI/DSP interface */ | ||
1809 | phr->error = error; | ||
1810 | /* just the header of the response is valid */ | ||
1811 | phr->size = sizeof(struct hpi_response_header); | ||
1812 | goto err; | 1772 | goto err; |
1813 | } | ||
1814 | 1773 | ||
1815 | if (phr->error != 0) /* something failed in the DSP */ | 1774 | if (phr->error) /* something failed in the DSP */ |
1816 | goto err; | 1775 | goto out; |
1817 | 1776 | ||
1818 | switch (phm->function) { | 1777 | switch (phm->function) { |
1819 | case HPI_OSTREAM_WRITE: | 1778 | case HPI_OSTREAM_WRITE: |
@@ -1825,21 +1784,30 @@ static void hw_message(struct hpi_adapter_obj *pao, struct hpi_message *phm, | |||
1825 | error = hpi6000_get_data(pao, dsp_index, phm, phr); | 1784 | error = hpi6000_get_data(pao, dsp_index, phm, phr); |
1826 | break; | 1785 | break; |
1827 | case HPI_ADAPTER_GET_ASSERT: | 1786 | case HPI_ADAPTER_GET_ASSERT: |
1828 | phr->u.a.adapter_index = 0; /* dsp 0 default */ | 1787 | phr->u.ax.assert.dsp_index = 0; /* dsp 0 default */ |
1829 | if (num_dsp == 2) { | 1788 | if (num_dsp == 2) { |
1830 | if (!phr->u.a.adapter_type) { | 1789 | if (!phr->u.ax.assert.count) { |
1831 | /* no assert from dsp 0, check dsp 1 */ | 1790 | /* no assert from dsp 0, check dsp 1 */ |
1832 | error = hpi6000_message_response_sequence(pao, | 1791 | error = hpi6000_message_response_sequence(pao, |
1833 | 1, phm, phr); | 1792 | 1, phm, phr); |
1834 | phr->u.a.adapter_index = 1; | 1793 | phr->u.ax.assert.dsp_index = 1; |
1835 | } | 1794 | } |
1836 | } | 1795 | } |
1837 | } | 1796 | } |
1838 | 1797 | ||
1839 | if (error) | ||
1840 | phr->error = error; | ||
1841 | |||
1842 | err: | 1798 | err: |
1799 | if (error) { | ||
1800 | if (error >= HPI_ERROR_BACKEND_BASE) { | ||
1801 | phr->error = HPI_ERROR_DSP_COMMUNICATION; | ||
1802 | phr->specific_error = error; | ||
1803 | } else { | ||
1804 | phr->error = error; | ||
1805 | } | ||
1806 | |||
1807 | /* just the header of the response is valid */ | ||
1808 | phr->size = sizeof(struct hpi_response_header); | ||
1809 | } | ||
1810 | out: | ||
1843 | hpios_dsplock_unlock(pao); | 1811 | hpios_dsplock_unlock(pao); |
1844 | return; | 1812 | return; |
1845 | } | 1813 | } |