void hpi_debug_message(struct hpi_message *phm, char *sz_fileline) { if (phm) { if ((phm->object <= HPI_OBJ_MAXINDEX) && phm->object) { u16 index = 0; u16 attrib = 0; int is_control = 0; index = phm->obj_index; switch (phm->object) { case HPI_OBJ_ADAPTER: case HPI_OBJ_PROFILE: break; case HPI_OBJ_MIXER: if (phm->function == HPI_MIXER_GET_CONTROL_BY_INDEX) index = phm->u.m.control_index; break; case HPI_OBJ_OSTREAM: case HPI_OBJ_ISTREAM: break; case HPI_OBJ_CONTROLEX: case HPI_OBJ_CONTROL: if (phm->version == 1) attrib = HPI_CTL_ATTR(UNIVERSAL, 1); else attrib = phm->u.c.attribute; is_control = 1; break; default: break; } if (is_control && (attrib & 0xFF00)) { int control_type = (attrib & 0xFF00) >> 8; int attr_index = HPI_CTL_ATTR_INDEX(attrib); /* note the KERN facility level is in szFileline already */ printk("%s adapter %d %s " "ctrl_index x%04x %s %d\n", sz_fileline, phm->adapter_index, hpi_function_string(phm->function), index, get_treenode_elem (&hpi_control_type_strings, control_type, char *), attr_index); } else
/** CheckControlCache checks the cache and fills the struct hpi_response * accordingly. It returns one if a cache hit occurred, zero otherwise. */ short hpi_check_control_cache(struct hpi_control_cache *p_cache, struct hpi_message *phm, struct hpi_response *phr) { short found = 1; struct hpi_control_cache_info *pI; struct hpi_control_cache_single *pC; size_t response_size; if (!find_control(phm->obj_index, p_cache, &pI)) { HPI_DEBUG_LOG(VERBOSE, "HPICMN find_control() failed for adap %d\n", phm->adapter_index); return 0; } phr->error = 0; phr->specific_error = 0; phr->version = 0; /* set the default response size */ response_size = sizeof(struct hpi_response_header) + sizeof(struct hpi_control_res); /* pC is the default cached control strucure. May be cast to something else in the following switch statement. */ pC = (struct hpi_control_cache_single *)pI; switch (pI->control_type) { case HPI_CONTROL_METER: if (phm->u.c.attribute == HPI_METER_PEAK) { phr->u.c.an_log_value[0] = pC->u.meter.an_log_peak[0]; phr->u.c.an_log_value[1] = pC->u.meter.an_log_peak[1]; } else if (phm->u.c.attribute == HPI_METER_RMS) { if (pC->u.meter.an_logRMS[0] == HPI_CACHE_INVALID_SHORT) { phr->error = HPI_ERROR_INVALID_CONTROL_ATTRIBUTE; phr->u.c.an_log_value[0] = HPI_METER_MINIMUM; phr->u.c.an_log_value[1] = HPI_METER_MINIMUM; } else { phr->u.c.an_log_value[0] = pC->u.meter.an_logRMS[0]; phr->u.c.an_log_value[1] = pC->u.meter.an_logRMS[1]; } } else found = 0; break; case HPI_CONTROL_VOLUME: if (phm->u.c.attribute == HPI_VOLUME_GAIN) { phr->u.c.an_log_value[0] = pC->u.vol.an_log[0]; phr->u.c.an_log_value[1] = pC->u.vol.an_log[1]; } else if (phm->u.c.attribute == HPI_VOLUME_MUTE) { if (pC->u.vol.flags & HPI_VOLUME_FLAG_HAS_MUTE) { if (pC->u.vol.flags & HPI_VOLUME_FLAG_MUTED) phr->u.c.param1 = HPI_BITMASK_ALL_CHANNELS; else phr->u.c.param1 = 0; } else { phr->error = HPI_ERROR_INVALID_CONTROL_ATTRIBUTE; phr->u.c.param1 = 0; } } else { found = 0; } break; case HPI_CONTROL_MULTIPLEXER: if (phm->u.c.attribute == HPI_MULTIPLEXER_SOURCE) { phr->u.c.param1 = pC->u.mux.source_node_type; phr->u.c.param2 = pC->u.mux.source_node_index; } else { found = 0; } break; case HPI_CONTROL_CHANNEL_MODE: if (phm->u.c.attribute == HPI_CHANNEL_MODE_MODE) phr->u.c.param1 = pC->u.mode.mode; else found = 0; break; case HPI_CONTROL_LEVEL: if (phm->u.c.attribute == HPI_LEVEL_GAIN) { phr->u.c.an_log_value[0] = pC->u.level.an_log[0]; phr->u.c.an_log_value[1] = pC->u.level.an_log[1]; } else found = 0; break; case HPI_CONTROL_TUNER: if (phm->u.c.attribute == HPI_TUNER_FREQ) phr->u.c.param1 = pC->u.tuner.freq_ink_hz; else if (phm->u.c.attribute == HPI_TUNER_BAND) phr->u.c.param1 = pC->u.tuner.band; else if (phm->u.c.attribute == HPI_TUNER_LEVEL_AVG) if (pC->u.tuner.s_level_avg == HPI_CACHE_INVALID_SHORT) { phr->u.cu.tuner.s_level = 0; phr->error = HPI_ERROR_INVALID_CONTROL_ATTRIBUTE; } else phr->u.cu.tuner.s_level = pC->u.tuner.s_level_avg; else found = 0; break; case HPI_CONTROL_AESEBU_RECEIVER: if (phm->u.c.attribute == HPI_AESEBURX_ERRORSTATUS) phr->u.c.param1 = pC->u.aes3rx.error_status; else if (phm->u.c.attribute == HPI_AESEBURX_FORMAT) phr->u.c.param1 = pC->u.aes3rx.format; else found = 0; break; case HPI_CONTROL_AESEBU_TRANSMITTER: if (phm->u.c.attribute == HPI_AESEBUTX_FORMAT) phr->u.c.param1 = pC->u.aes3tx.format; else found = 0; break; case HPI_CONTROL_TONEDETECTOR: if (phm->u.c.attribute == HPI_TONEDETECTOR_STATE) phr->u.c.param1 = pC->u.tone.state; else found = 0; break; case HPI_CONTROL_SILENCEDETECTOR: if (phm->u.c.attribute == HPI_SILENCEDETECTOR_STATE) { phr->u.c.param1 = pC->u.silence.state; } else found = 0; break; case HPI_CONTROL_MICROPHONE: if (phm->u.c.attribute == HPI_MICROPHONE_PHANTOM_POWER) phr->u.c.param1 = pC->u.microphone.phantom_state; else found = 0; break; case HPI_CONTROL_SAMPLECLOCK: if (phm->u.c.attribute == HPI_SAMPLECLOCK_SOURCE) phr->u.c.param1 = pC->u.clk.source; else if (phm->u.c.attribute == HPI_SAMPLECLOCK_SOURCE_INDEX) { if (pC->u.clk.source_index == HPI_CACHE_INVALID_UINT16) { phr->u.c.param1 = 0; phr->error = HPI_ERROR_INVALID_CONTROL_ATTRIBUTE; } else phr->u.c.param1 = pC->u.clk.source_index; } else if (phm->u.c.attribute == HPI_SAMPLECLOCK_SAMPLERATE) phr->u.c.param1 = pC->u.clk.sample_rate; else found = 0; break; case HPI_CONTROL_PAD:{ struct hpi_control_cache_pad *p_pad; p_pad = (struct hpi_control_cache_pad *)pI; if (!(p_pad->field_valid_flags & (1 << HPI_CTL_ATTR_INDEX(phm->u.c. attribute)))) { phr->error = HPI_ERROR_INVALID_CONTROL_ATTRIBUTE; break; } if (phm->u.c.attribute == HPI_PAD_PROGRAM_ID) phr->u.c.param1 = p_pad->pI; else if (phm->u.c.attribute == HPI_PAD_PROGRAM_TYPE) phr->u.c.param1 = p_pad->pTY; else { unsigned int index = HPI_CTL_ATTR_INDEX(phm->u.c. attribute) - 1; unsigned int offset = phm->u.c.param1; unsigned int pad_string_len, field_size; char *pad_string; unsigned int tocopy; if (index > ARRAY_SIZE(pad_desc) - 1) { phr->error = HPI_ERROR_INVALID_CONTROL_ATTRIBUTE; break; } pad_string = ((char *)p_pad) + pad_desc[index].offset; field_size = pad_desc[index].field_size; /* Ensure null terminator */ pad_string[field_size - 1] = 0; pad_string_len = strlen(pad_string) + 1; if (offset > pad_string_len) { phr->error = HPI_ERROR_INVALID_CONTROL_VALUE; break; } tocopy = pad_string_len - offset; if (tocopy > sizeof(phr->u.cu.chars8.sz_data)) tocopy = sizeof(phr->u.cu.chars8. sz_data); memcpy(phr->u.cu.chars8.sz_data, &pad_string[offset], tocopy); phr->u.cu.chars8.remaining_chars = pad_string_len - offset - tocopy; } } break; default: found = 0; break; } HPI_DEBUG_LOG(VERBOSE, "%s Adap %d, Ctl %d, Type %d, Attr %d\n", found ? "Cached" : "Uncached", phm->adapter_index, pI->control_index, pI->control_type, phm->u.c.attribute); if (found) { phr->size = (u16)response_size; phr->type = HPI_TYPE_RESPONSE; phr->object = phm->object; phr->function = phm->function; } return found; }
/** CheckControlCache checks the cache and fills the struct hpi_response * accordingly. It returns one if a cache hit occurred, zero otherwise. */ short hpi_check_control_cache(struct hpi_control_cache *p_cache, struct hpi_message *phm, struct hpi_response *phr) { short found = 1; u16 control_index; struct hpi_control_cache_info *pI; struct hpi_control_cache_single *pC; struct hpi_control_cache_pad *p_pad; if (!find_control(phm, p_cache, &pI, &control_index)) return 0; phr->error = 0; /* pC is the default cached control strucure. May be cast to something else in the following switch statement. */ pC = (struct hpi_control_cache_single *)pI; p_pad = (struct hpi_control_cache_pad *)pI; switch (pI->control_type) { case HPI_CONTROL_METER: if (phm->u.c.attribute == HPI_METER_PEAK) { phr->u.c.an_log_value[0] = pC->u.p.an_log_peak[0]; phr->u.c.an_log_value[1] = pC->u.p.an_log_peak[1]; } else if (phm->u.c.attribute == HPI_METER_RMS) { phr->u.c.an_log_value[0] = pC->u.p.an_logRMS[0]; phr->u.c.an_log_value[1] = pC->u.p.an_logRMS[1]; } else found = 0; break; case HPI_CONTROL_VOLUME: if (phm->u.c.attribute == HPI_VOLUME_GAIN) { phr->u.c.an_log_value[0] = pC->u.v.an_log[0]; phr->u.c.an_log_value[1] = pC->u.v.an_log[1]; } else found = 0; break; case HPI_CONTROL_MULTIPLEXER: if (phm->u.c.attribute == HPI_MULTIPLEXER_SOURCE) { phr->u.c.param1 = pC->u.x.source_node_type; phr->u.c.param2 = pC->u.x.source_node_index; } else { found = 0; } break; case HPI_CONTROL_CHANNEL_MODE: if (phm->u.c.attribute == HPI_CHANNEL_MODE_MODE) phr->u.c.param1 = pC->u.m.mode; else found = 0; break; case HPI_CONTROL_LEVEL: if (phm->u.c.attribute == HPI_LEVEL_GAIN) { phr->u.c.an_log_value[0] = pC->u.l.an_log[0]; phr->u.c.an_log_value[1] = pC->u.l.an_log[1]; } else found = 0; break; case HPI_CONTROL_TUNER: if (phm->u.c.attribute == HPI_TUNER_FREQ) phr->u.c.param1 = pC->u.t.freq_ink_hz; else if (phm->u.c.attribute == HPI_TUNER_BAND) phr->u.c.param1 = pC->u.t.band; else if ((phm->u.c.attribute == HPI_TUNER_LEVEL) && (phm->u.c.param1 == HPI_TUNER_LEVEL_AVERAGE)) phr->u.c.param1 = pC->u.t.level; else found = 0; break; case HPI_CONTROL_AESEBU_RECEIVER: if (phm->u.c.attribute == HPI_AESEBURX_ERRORSTATUS) phr->u.c.param1 = pC->u.aes3rx.error_status; else if (phm->u.c.attribute == HPI_AESEBURX_FORMAT) phr->u.c.param1 = pC->u.aes3rx.source; else found = 0; break; case HPI_CONTROL_AESEBU_TRANSMITTER: if (phm->u.c.attribute == HPI_AESEBUTX_FORMAT) phr->u.c.param1 = pC->u.aes3tx.format; else found = 0; break; case HPI_CONTROL_TONEDETECTOR: if (phm->u.c.attribute == HPI_TONEDETECTOR_STATE) phr->u.c.param1 = pC->u.tone.state; else found = 0; break; case HPI_CONTROL_SILENCEDETECTOR: if (phm->u.c.attribute == HPI_SILENCEDETECTOR_STATE) { phr->u.c.param1 = pC->u.silence.state; phr->u.c.param2 = pC->u.silence.count; } else found = 0; break; case HPI_CONTROL_MICROPHONE: if (phm->u.c.attribute == HPI_MICROPHONE_PHANTOM_POWER) phr->u.c.param1 = pC->u.phantom_power.state; else found = 0; break; case HPI_CONTROL_SAMPLECLOCK: if (phm->u.c.attribute == HPI_SAMPLECLOCK_SOURCE) phr->u.c.param1 = pC->u.clk.source; else if (phm->u.c.attribute == HPI_SAMPLECLOCK_SOURCE_INDEX) { if (pC->u.clk.source_index == HPI_ERROR_ILLEGAL_CACHE_VALUE) { phr->u.c.param1 = 0; phr->error = HPI_ERROR_INVALID_OPERATION; } else phr->u.c.param1 = pC->u.clk.source_index; } else if (phm->u.c.attribute == HPI_SAMPLECLOCK_SAMPLERATE) phr->u.c.param1 = pC->u.clk.sample_rate; else found = 0; break; case HPI_CONTROL_PAD: if (!(p_pad->field_valid_flags & (1 << HPI_CTL_ATTR_INDEX(phm->u.c. attribute)))) { phr->error = HPI_ERROR_INVALID_CONTROL_ATTRIBUTE; break; } if (phm->u.c.attribute == HPI_PAD_PROGRAM_ID) phr->u.c.param1 = p_pad->pI; else if (phm->u.c.attribute == HPI_PAD_PROGRAM_TYPE) phr->u.c.param1 = p_pad->pTY; else { unsigned int index = HPI_CTL_ATTR_INDEX(phm->u.c.attribute) - 1; unsigned int offset = phm->u.c.param1; unsigned int pad_string_len, field_size; char *pad_string; unsigned int tocopy; HPI_DEBUG_LOG(VERBOSE, "PADS HPI_PADS_ %d\n", phm->u.c.attribute); if (index > ARRAY_SIZE(pad_desc) - 1) { phr->error = HPI_ERROR_INVALID_CONTROL_ATTRIBUTE; break; } pad_string = ((char *)p_pad) + pad_desc[index].offset; field_size = pad_desc[index].field_size; /* Ensure null terminator */ pad_string[field_size - 1] = 0; pad_string_len = strlen(pad_string) + 1; if (offset > pad_string_len) { phr->error = HPI_ERROR_INVALID_CONTROL_VALUE; break; } tocopy = pad_string_len - offset; if (tocopy > sizeof(phr->u.cu.chars8.sz_data)) tocopy = sizeof(phr->u.cu.chars8.sz_data); HPI_DEBUG_LOG(VERBOSE, "PADS memcpy(%d), offset %d \n", tocopy, offset); memcpy(phr->u.cu.chars8.sz_data, &pad_string[offset], tocopy); phr->u.cu.chars8.remaining_chars = pad_string_len - offset - tocopy; } break; default: found = 0; break; } if (found) HPI_DEBUG_LOG(VERBOSE, "cached adap %d, ctl %d, type %d, attr %d\n", phm->adapter_index, pI->control_index, pI->control_type, phm->u.c.attribute); else HPI_DEBUG_LOG(VERBOSE, "uncached adap %d, ctl %d, ctl type %d\n", phm->adapter_index, pI->control_index, pI->control_type); if (found) phr->size = sizeof(struct hpi_response_header) + sizeof(struct hpi_control_res); return found; }