| 1 | /*************************************************************************** |
|---|
| 2 | * (c)2007-2011 Broadcom Corporation |
|---|
| 3 | * |
|---|
| 4 | * This program is the proprietary software of Broadcom Corporation and/or its licensors, |
|---|
| 5 | * and may only be used, duplicated, modified or distributed pursuant to the terms and |
|---|
| 6 | * conditions of a separate, written license agreement executed between you and Broadcom |
|---|
| 7 | * (an "Authorized License"). Except as set forth in an Authorized License, Broadcom grants |
|---|
| 8 | * no license (express or implied), right to use, or waiver of any kind with respect to the |
|---|
| 9 | * Software, and Broadcom expressly reserves all rights in and to the Software and all |
|---|
| 10 | * intellectual property rights therein. IF YOU HAVE NO AUTHORIZED LICENSE, THEN YOU |
|---|
| 11 | * HAVE NO RIGHT TO USE THIS SOFTWARE IN ANY WAY, AND SHOULD IMMEDIATELY |
|---|
| 12 | * NOTIFY BROADCOM AND DISCONTINUE ALL USE OF THE SOFTWARE. |
|---|
| 13 | * |
|---|
| 14 | * Except as expressly set forth in the Authorized License, |
|---|
| 15 | * |
|---|
| 16 | * 1. This program, including its structure, sequence and organization, constitutes the valuable trade |
|---|
| 17 | * secrets of Broadcom, and you shall use all reasonable efforts to protect the confidentiality thereof, |
|---|
| 18 | * and to use this information only in connection with your use of Broadcom integrated circuit products. |
|---|
| 19 | * |
|---|
| 20 | * 2. TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS" |
|---|
| 21 | * AND WITH ALL FAULTS AND BROADCOM MAKES NO PROMISES, REPRESENTATIONS OR |
|---|
| 22 | * WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH RESPECT TO |
|---|
| 23 | * THE SOFTWARE. BROADCOM SPECIFICALLY DISCLAIMS ANY AND ALL IMPLIED WARRANTIES |
|---|
| 24 | * OF TITLE, MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE, |
|---|
| 25 | * LACK OF VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION |
|---|
| 26 | * OR CORRESPONDENCE TO DESCRIPTION. YOU ASSUME THE ENTIRE RISK ARISING OUT OF |
|---|
| 27 | * USE OR PERFORMANCE OF THE SOFTWARE. |
|---|
| 28 | * |
|---|
| 29 | * 3. TO THE MAXIMUM EXTENT PERMITTED BY LAW, IN NO EVENT SHALL BROADCOM OR ITS |
|---|
| 30 | * LICENSORS BE LIABLE FOR (i) CONSEQUENTIAL, INCIDENTAL, SPECIAL, INDIRECT, OR |
|---|
| 31 | * EXEMPLARY DAMAGES WHATSOEVER ARISING OUT OF OR IN ANY WAY RELATING TO YOUR |
|---|
| 32 | * USE OF OR INABILITY TO USE THE SOFTWARE EVEN IF BROADCOM HAS BEEN ADVISED OF |
|---|
| 33 | * THE POSSIBILITY OF SUCH DAMAGES; OR (ii) ANY AMOUNT IN EXCESS OF THE AMOUNT |
|---|
| 34 | * ACTUALLY PAID FOR THE SOFTWARE ITSELF OR U.S. $1, WHICHEVER IS GREATER. THESE |
|---|
| 35 | * LIMITATIONS SHALL APPLY NOTWITHSTANDING ANY FAILURE OF ESSENTIAL PURPOSE OF |
|---|
| 36 | * ANY LIMITED REMEDY. |
|---|
| 37 | * |
|---|
| 38 | * $brcm_Workfile: nexus_demux.c $ |
|---|
| 39 | * $brcm_Revision: 68 $ |
|---|
| 40 | * $brcm_Date: 12/9/11 11:13a $ |
|---|
| 41 | * |
|---|
| 42 | * Module Description: |
|---|
| 43 | * |
|---|
| 44 | * Revision History: |
|---|
| 45 | * |
|---|
| 46 | * $brcm_Log: /nexus/modules/transport/7400/src/nexus_demux.c $ |
|---|
| 47 | * |
|---|
| 48 | * 68 12/9/11 11:13a gmullen |
|---|
| 49 | * SW7425-1871: Add build checks for parts that don't have message |
|---|
| 50 | * filtering hw |
|---|
| 51 | * |
|---|
| 52 | * 67 12/5/11 10:21a erickson |
|---|
| 53 | * SW7425-1871: use BXPT_NUM_MESSAGE_CAPABLE_PID_CHANNELS |
|---|
| 54 | * |
|---|
| 55 | * 66 11/23/11 3:54p nickh |
|---|
| 56 | * SW7420-2143: Fix audio issue when re-inserting cable card |
|---|
| 57 | * |
|---|
| 58 | * 65 11/17/11 12:19p nickh |
|---|
| 59 | * SW7420-2143: Fix cable card crash when all pass filtering |
|---|
| 60 | * |
|---|
| 61 | * 64 11/4/11 11:48a erickson |
|---|
| 62 | * SW7231-391: add ERR |
|---|
| 63 | * |
|---|
| 64 | * 63 10/31/11 7:54p bandrews |
|---|
| 65 | * SW7231-391: cleanup from merge to main |
|---|
| 66 | * |
|---|
| 67 | * 62 10/31/11 7:47p bandrews |
|---|
| 68 | * SW7231-391: merge to main |
|---|
| 69 | * |
|---|
| 70 | * SW7420-2078/1 10/25/11 5:22p bandrews |
|---|
| 71 | * SW7231-391: update parser band and timebase implementations to use |
|---|
| 72 | * handles everywhere, even for legacy enum usage |
|---|
| 73 | * |
|---|
| 74 | * 61 10/17/11 11:38a gmullen |
|---|
| 75 | * SW7425-1383: Merged to main |
|---|
| 76 | * |
|---|
| 77 | * 60 10/13/11 3:32p erickson |
|---|
| 78 | * SW7420-1120: improve code for platforms without parser bands |
|---|
| 79 | * |
|---|
| 80 | * SW7425-1383/2 10/14/11 4:09p gmullen |
|---|
| 81 | * SW7425-1383: Updated per David's suggestions |
|---|
| 82 | * |
|---|
| 83 | * SW7425-1383/1 10/11/11 3:45p gmullen |
|---|
| 84 | * SW7425-1383: Added API to return the chip-specific allPass PID channel |
|---|
| 85 | * number |
|---|
| 86 | * |
|---|
| 87 | * 59 9/29/11 9:52a erickson |
|---|
| 88 | * SW7358-150: refine comparison NEXUS_PidChannelSettings when opening |
|---|
| 89 | * duplicate pids to only those settings which must match |
|---|
| 90 | * |
|---|
| 91 | * 58 9/29/11 9:45a erickson |
|---|
| 92 | * SW7358-141: "and" the enable flags for all SW pid channel handles that |
|---|
| 93 | * share the same HW pid channel. |
|---|
| 94 | * |
|---|
| 95 | * 57 9/6/11 3:53p dlwin |
|---|
| 96 | * SW7344-192: Change for Coverity: 35340 |
|---|
| 97 | * |
|---|
| 98 | * 56 9/6/11 10:59a jtna |
|---|
| 99 | * SW7425-1215: add const to NEXUS_PidChannel_SetRemapSettings() |
|---|
| 100 | * |
|---|
| 101 | * 55 9/2/11 2:54p jtna |
|---|
| 102 | * SW7425-1215: add NEXUS_PidChannel_SetRemapSettings() and related |
|---|
| 103 | * changes |
|---|
| 104 | * |
|---|
| 105 | * 54 9/2/11 12:40p erickson |
|---|
| 106 | * SW7420-1995: unregister handles from objdb when doing automatic close |
|---|
| 107 | * |
|---|
| 108 | * 53 7/1/11 10:16a erickson |
|---|
| 109 | * SW7425-725: disable SPID when opening a pid channel |
|---|
| 110 | * |
|---|
| 111 | * 52 6/16/11 4:17p erickson |
|---|
| 112 | * SW7425-725: clear pid remap when closing pid channel |
|---|
| 113 | * |
|---|
| 114 | * 51 3/10/11 8:59a gmohile |
|---|
| 115 | * SW7422-101 : Fix build error for platform without parser band |
|---|
| 116 | * |
|---|
| 117 | * 50 3/8/11 6:08p vsilyaev |
|---|
| 118 | * SW7422-101: Updated logic of handling continuityCountEnabled, so per |
|---|
| 119 | * band and per pid settings are combined with logical AND |
|---|
| 120 | * |
|---|
| 121 | * 49 2/11/11 10:23a gmohile |
|---|
| 122 | * SW7420-1120 : Fix platform with no parser band |
|---|
| 123 | * |
|---|
| 124 | * 48 2/10/11 11:02a erickson |
|---|
| 125 | * SW7420-1120: refactor NEXUS_PidChannel_Open so it returns separate |
|---|
| 126 | * handles even if underlying HW pid channel is shared |
|---|
| 127 | * |
|---|
| 128 | * 47 1/28/11 8:55a erickson |
|---|
| 129 | * SW7420-1440: add internal hooks so that NEXUS_PidChannel_Close can |
|---|
| 130 | * close playpump pidchannels (but not playback pidchannels) |
|---|
| 131 | * |
|---|
| 132 | * 46 1/3/11 1:56p erickson |
|---|
| 133 | * SW7422-101: add NEXUS_PidChannelSettings.continuityCountEnabled |
|---|
| 134 | * |
|---|
| 135 | * 45 1/27/10 4:34p erickson |
|---|
| 136 | * SW7400-2651: add NEXUS_PidChannelSettings.remap for SPID pid remapping |
|---|
| 137 | * |
|---|
| 138 | * 44 1/6/10 4:32p erickson |
|---|
| 139 | * SW3548-2696: enable IB5P for 3548 |
|---|
| 140 | * |
|---|
| 141 | * 43 12/14/09 11:10a erickson |
|---|
| 142 | * SW7335-638: fix pid channel refcnt if |
|---|
| 143 | * NEXUS_PidChannelSettings.pidChannelIndex is specified |
|---|
| 144 | * |
|---|
| 145 | * 42 12/11/09 3:32p erickson |
|---|
| 146 | * SW7550-112: merge 7550 code. add support for sw message filtering. |
|---|
| 147 | * allow for no HW message filtering using standard XPT define. |
|---|
| 148 | * |
|---|
| 149 | * Refsw_7550/1 11/19/09 12:36p nitinb |
|---|
| 150 | * SW7550-63: change NEXUS_NUM_MESSAGE_CAPABLE_PID_CHANNELS to 48 for |
|---|
| 151 | * 7550 |
|---|
| 152 | * |
|---|
| 153 | * 41 12/9/09 3:20p gmohile |
|---|
| 154 | * SW7408-1 : Fix conditional compile for parser band support |
|---|
| 155 | * |
|---|
| 156 | * 40 12/1/09 6:24p randyjew |
|---|
| 157 | * SW7468-6: Add 7468 support |
|---|
| 158 | * |
|---|
| 159 | * 39 11/19/09 4:25p gmohile |
|---|
| 160 | * SW7408-1 : Add 7408 support |
|---|
| 161 | * |
|---|
| 162 | * 38 11/11/09 2:40p erickson |
|---|
| 163 | * SW7400-2601: add NEXUS_PidChannelSettings.enabled, default to true |
|---|
| 164 | * |
|---|
| 165 | * 37 10/19/09 11:26a erickson |
|---|
| 166 | * SW7400-2559: add NEXUS_PidChannelSettings.dssHdFilter |
|---|
| 167 | * |
|---|
| 168 | * 36 10/19/09 10:42a erickson |
|---|
| 169 | * SW7400-2559: add NEXUS_PID_CHANNEL_OPEN macros for more |
|---|
| 170 | * NEXUS_PidChannel_Open options |
|---|
| 171 | * |
|---|
| 172 | * 35 10/1/09 5:03p erickson |
|---|
| 173 | * SW7405-3087: add playpump cc check, add cc error counting per pid |
|---|
| 174 | * |
|---|
| 175 | * 34 8/14/09 7:16p jrubio |
|---|
| 176 | * PR55232: Input Band Max 7 for 7342 |
|---|
| 177 | * |
|---|
| 178 | * 33 6/11/09 4:30p jtna |
|---|
| 179 | * PR55817: allow refcnt on pidChannelIndex opened more than once |
|---|
| 180 | * |
|---|
| 181 | * 32 6/8/09 7:17a erickson |
|---|
| 182 | * PR55717: support platforms with no input bands |
|---|
| 183 | * |
|---|
| 184 | * 31 2/24/09 5:30p anilmm |
|---|
| 185 | * PR52416: Check for parser band allpass should include check for |
|---|
| 186 | * cablecard enable as well |
|---|
| 187 | * |
|---|
| 188 | * 30 12/3/08 1:18p erickson |
|---|
| 189 | * PR45405: rename rave member to pidChannelIndex to avoid |
|---|
| 190 | * misunderstanding |
|---|
| 191 | * |
|---|
| 192 | * 29 12/1/08 12:49p erickson |
|---|
| 193 | * PR49676: set unused status params to invalid values to flush out app |
|---|
| 194 | * bugs |
|---|
| 195 | * |
|---|
| 196 | * 28 11/24/08 10:28a erickson |
|---|
| 197 | * PR48846: fix refcnt logic |
|---|
| 198 | * |
|---|
| 199 | * 27 11/12/08 1:26p jgarrett |
|---|
| 200 | * PR 48830: Adding NEXUS_PidChannel_SetEnabled |
|---|
| 201 | * |
|---|
| 202 | * 26 8/14/08 5:25p katrep |
|---|
| 203 | * PR45674: Fix compiiler warning in kernel mode non debug builds |
|---|
| 204 | * |
|---|
| 205 | * 25 8/7/08 11:11a piyushg |
|---|
| 206 | * PR45008: Fix compile error due to change in XPT PI function |
|---|
| 207 | * definition. |
|---|
| 208 | * |
|---|
| 209 | * 24 7/23/08 2:22p erickson |
|---|
| 210 | * PR45008: NEXUS_PidChannel_AddSplicePidChannel must support a pid |
|---|
| 211 | * channel attached to multiple rave contexts |
|---|
| 212 | * |
|---|
| 213 | * 23 7/21/08 1:27p erickson |
|---|
| 214 | * PR45008: add pid splicing API |
|---|
| 215 | * |
|---|
| 216 | * 22 6/18/08 1:19p erickson |
|---|
| 217 | * PR43730: fix warning |
|---|
| 218 | * |
|---|
| 219 | * 21 6/16/08 11:53a erickson |
|---|
| 220 | * PR42973: fix all pass changes. only use parserBand if playpumpIndex == |
|---|
| 221 | * -1. |
|---|
| 222 | * |
|---|
| 223 | * 20 6/13/08 7:19p erickson |
|---|
| 224 | * PR42973: merge all pass changes |
|---|
| 225 | * |
|---|
| 226 | * 19 5/28/08 7:45p jrubio |
|---|
| 227 | * PR43085: fix PLAYPUMP=0 compile |
|---|
| 228 | * |
|---|
| 229 | * 18 5/15/08 1:01p erickson |
|---|
| 230 | * PR42706: coverity fix |
|---|
| 231 | * |
|---|
| 232 | * 17 5/2/08 9:18a erickson |
|---|
| 233 | * PR42339: refcnt check needed a little more |
|---|
| 234 | * |
|---|
| 235 | * 16 5/1/08 2:56p erickson |
|---|
| 236 | * PR42391: refcnt pid channels after checking both live and playback |
|---|
| 237 | * criteria. also, removed duplicate storage to prevent future bugs. |
|---|
| 238 | * |
|---|
| 239 | * 15 4/28/08 11:53a erickson |
|---|
| 240 | * PR42197: remove NEXUS_ParserBand_ePlayback enums |
|---|
| 241 | * |
|---|
| 242 | * 14 4/21/08 3:10p erickson |
|---|
| 243 | * PR41987: add optional NEXUS_PidChannelSettings.pidChannelIndex for |
|---|
| 244 | * user-specified pid channel index |
|---|
| 245 | * |
|---|
| 246 | * 13 4/18/08 4:03p vsilyaev |
|---|
| 247 | * PR 41868: Added security API to playpump and recpump |
|---|
| 248 | * |
|---|
| 249 | * 12 4/10/08 1:58p erickson |
|---|
| 250 | * PR40079: added PidChannel ScramblingCheck |
|---|
| 251 | * |
|---|
| 252 | * 11 4/4/08 11:52a erickson |
|---|
| 253 | * PR40079: prevent infinite loop. this algo must be reworked. |
|---|
| 254 | * |
|---|
| 255 | * 10 4/4/08 11:26a erickson |
|---|
| 256 | * PR40079: fix for non-3563 |
|---|
| 257 | * |
|---|
| 258 | * 9 4/4/08 11:18a erickson |
|---|
| 259 | * PR40079: impl NEXUS_PidChannel_GetScramblingStatus |
|---|
| 260 | * |
|---|
| 261 | * 8 3/27/08 11:27a erickson |
|---|
| 262 | * PR40978: remove chip-specific parallelInput check. allow XPT PI to fail |
|---|
| 263 | * or WRN. |
|---|
| 264 | * |
|---|
| 265 | * 7 3/27/08 10:37a erickson |
|---|
| 266 | * PR40851: if parser band is DSS, it should override some input band |
|---|
| 267 | * settings. if not DSS, don't override. |
|---|
| 268 | * |
|---|
| 269 | * 6 3/4/08 3:31p erickson |
|---|
| 270 | * PR40080: add transport error callbacks |
|---|
| 271 | * |
|---|
| 272 | * 5 2/22/08 5:03p erickson |
|---|
| 273 | * PR39868: clean up static analysis warnings |
|---|
| 274 | * |
|---|
| 275 | * 4 2/22/08 10:51a erickson |
|---|
| 276 | * PR39868: added more parser band asserts |
|---|
| 277 | * |
|---|
| 278 | * 3 2/20/08 10:33a erickson |
|---|
| 279 | * PR39743: fix buffer overrun fix |
|---|
| 280 | * |
|---|
| 281 | * 2 2/19/08 3:47p erickson |
|---|
| 282 | * PR39743: fix possible buffer overrun |
|---|
| 283 | * |
|---|
| 284 | * 1 1/18/08 2:20p jgarrett |
|---|
| 285 | * PR 38808: Merging to main branch |
|---|
| 286 | * |
|---|
| 287 | **************************************************************************/ |
|---|
| 288 | #include "nexus_transport_module.h" |
|---|
| 289 | #include "bxpt_spid.h" |
|---|
| 290 | #include "nexus_playpump_impl.h" |
|---|
| 291 | #include "nexus_class_verification.h" |
|---|
| 292 | |
|---|
| 293 | BDBG_MODULE(nexus_demux); |
|---|
| 294 | |
|---|
| 295 | static NEXUS_Error NEXUS_PidChannel_P_SetEnabled( NEXUS_PidChannelHandle pidChannel, bool enabled ); |
|---|
| 296 | |
|---|
| 297 | void NEXUS_InputBand_GetSettings(NEXUS_InputBand inputBand, NEXUS_InputBandSettings *pSettings) |
|---|
| 298 | { |
|---|
| 299 | #if NEXUS_NUM_INPUT_BANDS |
|---|
| 300 | BERR_Code rc=0; |
|---|
| 301 | /* this code assumes Nexus holds the default state, not the PI or HW */ |
|---|
| 302 | if (inputBand >= NEXUS_NUM_INPUT_BANDS) { |
|---|
| 303 | rc=BERR_TRACE(NEXUS_INVALID_PARAMETER); |
|---|
| 304 | return; |
|---|
| 305 | } |
|---|
| 306 | *pSettings = pTransport->inputBand[inputBand].settings; |
|---|
| 307 | #else |
|---|
| 308 | BSTD_UNUSED(inputBand); |
|---|
| 309 | BKNI_Memset(pSettings, 0, sizeof(*pSettings)); |
|---|
| 310 | #endif |
|---|
| 311 | } |
|---|
| 312 | |
|---|
| 313 | NEXUS_Error NEXUS_InputBand_SetSettings(NEXUS_InputBand inputBand, const NEXUS_InputBandSettings *pSettings) |
|---|
| 314 | { |
|---|
| 315 | #if NEXUS_NUM_INPUT_BANDS |
|---|
| 316 | BERR_Code rc; |
|---|
| 317 | BXPT_InputBandConfig config; |
|---|
| 318 | |
|---|
| 319 | NEXUS_ASSERT_MODULE(); /* make sure init was called */ |
|---|
| 320 | if (inputBand >= NEXUS_NUM_INPUT_BANDS) { |
|---|
| 321 | return BERR_TRACE(NEXUS_INVALID_PARAMETER); |
|---|
| 322 | } |
|---|
| 323 | |
|---|
| 324 | BXPT_GetInputBandConfig(pTransport->xpt, inputBand, &config); |
|---|
| 325 | config.ClockPolSel = pSettings->clockActiveHigh?BXPT_Polarity_eActiveHigh:BXPT_Polarity_eActiveLow; |
|---|
| 326 | config.LsbFirst = pSettings->dataLsbFirst; |
|---|
| 327 | config.DataPolSel = pSettings->dataActiveHigh?BXPT_Polarity_eActiveHigh:BXPT_Polarity_eActiveLow; |
|---|
| 328 | config.ForceValid = !pSettings->validEnabled; |
|---|
| 329 | config.ValidPolSel = pSettings->validActiveHigh?BXPT_Polarity_eActiveHigh:BXPT_Polarity_eActiveLow; |
|---|
| 330 | config.UseSyncAsValid = pSettings->useSyncAsValid; |
|---|
| 331 | config.SyncPolSel = pSettings->syncActiveHigh?BXPT_Polarity_eActiveHigh:BXPT_Polarity_eActiveLow; |
|---|
| 332 | config.EnableErrorInput = pSettings->errorEnabled; |
|---|
| 333 | config.ErrorPolSel = pSettings->errorActiveHigh?BXPT_Polarity_eActiveHigh:BXPT_Polarity_eActiveLow; |
|---|
| 334 | config.ParallelInputSel = pSettings->parallelInput; |
|---|
| 335 | if (NEXUS_IS_DSS_MODE(pTransport->inputBand[inputBand].transportType)) { |
|---|
| 336 | /* If parser band was configured for DSS, we need to override the input band settings */ |
|---|
| 337 | config.IbPktLength = 130; |
|---|
| 338 | config.SyncDetectEn = false; |
|---|
| 339 | } |
|---|
| 340 | else { |
|---|
| 341 | config.IbPktLength = pSettings->packetLength; |
|---|
| 342 | config.SyncDetectEn = pSettings->useInternalSync; |
|---|
| 343 | } |
|---|
| 344 | rc = BXPT_SetInputBandConfig(pTransport->xpt, inputBand, &config); |
|---|
| 345 | if (rc) {return BERR_TRACE(rc);} |
|---|
| 346 | |
|---|
| 347 | pTransport->inputBand[inputBand].settings = *pSettings; |
|---|
| 348 | |
|---|
| 349 | return BERR_SUCCESS; |
|---|
| 350 | #else |
|---|
| 351 | BSTD_UNUSED(inputBand); |
|---|
| 352 | BSTD_UNUSED(pSettings); |
|---|
| 353 | return BERR_TRACE(NEXUS_NOT_SUPPORTED); |
|---|
| 354 | #endif |
|---|
| 355 | } |
|---|
| 356 | |
|---|
| 357 | NEXUS_Error NEXUS_InputBand_P_SetTransportType(NEXUS_InputBand inputBand, NEXUS_TransportType transportType) |
|---|
| 358 | { |
|---|
| 359 | #if NEXUS_NUM_INPUT_BANDS |
|---|
| 360 | if (inputBand >= NEXUS_NUM_INPUT_BANDS) { |
|---|
| 361 | return BERR_TRACE(NEXUS_INVALID_PARAMETER); |
|---|
| 362 | } |
|---|
| 363 | pTransport->inputBand[inputBand].transportType = transportType; |
|---|
| 364 | return NEXUS_InputBand_SetSettings(inputBand, &pTransport->inputBand[inputBand].settings); |
|---|
| 365 | #else |
|---|
| 366 | BSTD_UNUSED(inputBand); |
|---|
| 367 | BSTD_UNUSED(transportType); |
|---|
| 368 | return BERR_TRACE(NEXUS_NOT_SUPPORTED); |
|---|
| 369 | #endif |
|---|
| 370 | } |
|---|
| 371 | |
|---|
| 372 | #include "bchp_xpt_fe.h" |
|---|
| 373 | NEXUS_Error NEXUS_InputBand_GetStatus(NEXUS_InputBand inputBand, NEXUS_InputBandStatus *pStatus) |
|---|
| 374 | { |
|---|
| 375 | #if NEXUS_NUM_INPUT_BANDS |
|---|
| 376 | BKNI_Memset(pStatus, 0, sizeof(*pStatus)); |
|---|
| 377 | switch (inputBand-NEXUS_InputBand_e0) { |
|---|
| 378 | case 0: pStatus->syncCount = BREG_Read32(g_pCoreHandles->reg, BCHP_XPT_FE_IB0_SYNC_COUNT); break; |
|---|
| 379 | case 1: pStatus->syncCount = BREG_Read32(g_pCoreHandles->reg, BCHP_XPT_FE_IB1_SYNC_COUNT); break; |
|---|
| 380 | #if NEXUS_NUM_INPUT_BANDS > 2 |
|---|
| 381 | case 2: pStatus->syncCount = BREG_Read32(g_pCoreHandles->reg, BCHP_XPT_FE_IB2_SYNC_COUNT); break; |
|---|
| 382 | case 3: pStatus->syncCount = BREG_Read32(g_pCoreHandles->reg, BCHP_XPT_FE_IB3_SYNC_COUNT); break; |
|---|
| 383 | #endif |
|---|
| 384 | #if NEXUS_NUM_INPUT_BANDS > 4 |
|---|
| 385 | case 4: pStatus->syncCount = BREG_Read32(g_pCoreHandles->reg, BCHP_XPT_FE_IB4_SYNC_COUNT); break; |
|---|
| 386 | #endif |
|---|
| 387 | #if NEXUS_NUM_INPUT_BANDS > 5 |
|---|
| 388 | #ifndef BCHP_XPT_FE_IB5_SYNC_COUNT |
|---|
| 389 | #define BCHP_XPT_FE_IB5_SYNC_COUNT BCHP_XPT_FE_IB5P_SYNC_COUNT |
|---|
| 390 | #endif |
|---|
| 391 | case 5: pStatus->syncCount = BREG_Read32(g_pCoreHandles->reg, BCHP_XPT_FE_IB5_SYNC_COUNT); break; |
|---|
| 392 | #endif |
|---|
| 393 | #if NEXUS_NUM_INPUT_BANDS > 6 |
|---|
| 394 | case 6: pStatus->syncCount = BREG_Read32(g_pCoreHandles->reg, BCHP_XPT_FE_IB6_SYNC_COUNT); break; |
|---|
| 395 | #endif |
|---|
| 396 | #if NEXUS_NUM_INPUT_BANDS > 7 |
|---|
| 397 | case 7: pStatus->syncCount = BREG_Read32(g_pCoreHandles->reg, BCHP_XPT_FE_IB7_SYNC_COUNT); break; |
|---|
| 398 | #endif |
|---|
| 399 | } |
|---|
| 400 | return 0; |
|---|
| 401 | #else |
|---|
| 402 | BSTD_UNUSED(inputBand); |
|---|
| 403 | BSTD_UNUSED(pStatus); |
|---|
| 404 | return BERR_TRACE(NEXUS_NOT_SUPPORTED); |
|---|
| 405 | #endif |
|---|
| 406 | } |
|---|
| 407 | |
|---|
| 408 | void NEXUS_PidChannel_GetDefaultSettings(NEXUS_PidChannelSettings *pSettings) |
|---|
| 409 | { |
|---|
| 410 | BKNI_Memset(pSettings, 0, sizeof(*pSettings)); |
|---|
| 411 | pSettings->pidChannelIndex = NEXUS_PID_CHANNEL_OPEN_ANY; |
|---|
| 412 | pSettings->enabled = true; |
|---|
| 413 | pSettings->continuityCountEnabled = true; |
|---|
| 414 | pSettings->remap.continuityCountEnabled = true; |
|---|
| 415 | } |
|---|
| 416 | |
|---|
| 417 | NEXUS_PidChannelHandle NEXUS_PidChannel_Open(NEXUS_ParserBand parserBand, uint16_t pid, |
|---|
| 418 | const NEXUS_PidChannelSettings *pSettings) |
|---|
| 419 | { |
|---|
| 420 | #if NEXUS_NUM_PARSER_BANDS |
|---|
| 421 | NEXUS_ParserBandHandle handle = NEXUS_ParserBand_Resolve_priv(parserBand); |
|---|
| 422 | if (handle) |
|---|
| 423 | { |
|---|
| 424 | return NEXUS_PidChannel_P_Open(handle, NULL, pid, pSettings, |
|---|
| 425 | handle->settings.continuityCountEnabled |
|---|
| 426 | ); |
|---|
| 427 | } |
|---|
| 428 | else { |
|---|
| 429 | BDBG_ERR(("unable to resolve %#x", parserBand)); |
|---|
| 430 | (void)BERR_TRACE(NEXUS_INVALID_PARAMETER); |
|---|
| 431 | return NULL; |
|---|
| 432 | } |
|---|
| 433 | #else |
|---|
| 434 | BSTD_UNUSED(parserBand); |
|---|
| 435 | BSTD_UNUSED(pid); |
|---|
| 436 | BSTD_UNUSED(pSettings); |
|---|
| 437 | BERR_TRACE(NEXUS_NOT_SUPPORTED); |
|---|
| 438 | return NULL; |
|---|
| 439 | #endif |
|---|
| 440 | } |
|---|
| 441 | |
|---|
| 442 | NEXUS_PidChannelHandle NEXUS_PidChannel_P_Open(NEXUS_ParserBandHandle parserBand, NEXUS_PlaypumpHandle playpump, uint16_t pid, |
|---|
| 443 | const NEXUS_PidChannelSettings *pSettings, bool bandContinuityCountEnabled) |
|---|
| 444 | { |
|---|
| 445 | NEXUS_PidChannelHandle duplicatePidChannel = NULL; |
|---|
| 446 | NEXUS_PidChannelHandle pidChannel; |
|---|
| 447 | unsigned index; /* hw index */ |
|---|
| 448 | BERR_Code rc; |
|---|
| 449 | NEXUS_PidChannelSettings settings; |
|---|
| 450 | |
|---|
| 451 | NEXUS_ASSERT_MODULE(); |
|---|
| 452 | |
|---|
| 453 | if (!pSettings) { |
|---|
| 454 | NEXUS_PidChannel_GetDefaultSettings(&settings); |
|---|
| 455 | pSettings = &settings; |
|---|
| 456 | } |
|---|
| 457 | |
|---|
| 458 | if (playpump) { |
|---|
| 459 | parserBand = NULL; /* parserBand is invalid if playpump is set. */ |
|---|
| 460 | } |
|---|
| 461 | else { |
|---|
| 462 | #if NEXUS_NUM_PARSER_BANDS |
|---|
| 463 | BDBG_OBJECT_ASSERT(parserBand, NEXUS_ParserBandImpl); |
|---|
| 464 | #else |
|---|
| 465 | BERR_TRACE(NEXUS_NOT_SUPPORTED); |
|---|
| 466 | return NULL; |
|---|
| 467 | #endif |
|---|
| 468 | } |
|---|
| 469 | |
|---|
| 470 | /* user specifies the HW pid channel */ |
|---|
| 471 | if (pSettings->pidChannelIndex >= 0) { |
|---|
| 472 | index = (unsigned)pSettings->pidChannelIndex; |
|---|
| 473 | if (index >= NEXUS_NUM_PID_CHANNELS) { |
|---|
| 474 | BDBG_ERR(("Invalid pid channel index %d", index)); |
|---|
| 475 | return NULL; |
|---|
| 476 | } |
|---|
| 477 | |
|---|
| 478 | /* if already opened */ |
|---|
| 479 | for (pidChannel = BLST_S_FIRST(&pTransport->pidChannels); pidChannel; pidChannel = BLST_S_NEXT(pidChannel, link)) { |
|---|
| 480 | if (pidChannel->status.pidChannelIndex == (unsigned)pSettings->pidChannelIndex) { |
|---|
| 481 | /* must be the same pid */ |
|---|
| 482 | if (pidChannel->status.pid != pid) { |
|---|
| 483 | BDBG_ERR(("Cannot open the same pidChannelIndex (%d) with different pids (0x%x and 0x%x)", pSettings->pidChannelIndex, pidChannel->status.pid, pid)); |
|---|
| 484 | return NULL; |
|---|
| 485 | } |
|---|
| 486 | if (!duplicatePidChannel) { |
|---|
| 487 | duplicatePidChannel = pidChannel; |
|---|
| 488 | } |
|---|
| 489 | } |
|---|
| 490 | } |
|---|
| 491 | } |
|---|
| 492 | else { |
|---|
| 493 | /* nexus assigns the HW pid channel */ |
|---|
| 494 | unsigned firstPidChannel; |
|---|
| 495 | unsigned totalPidChannels; |
|---|
| 496 | |
|---|
| 497 | /* first, see if the same HW pid channel is already opened */ |
|---|
| 498 | for (pidChannel = BLST_S_FIRST(&pTransport->pidChannels); pidChannel; pidChannel = BLST_S_NEXT(pidChannel, link)) { |
|---|
| 499 | #if B_HAS_DSS |
|---|
| 500 | /* a different ENABLE_HD_FILTER value allows for a duplicate pid channel */ |
|---|
| 501 | if ((pidChannel->settings.dssHdFilter == NEXUS_PidChannelDssHdFilter_eDisabled) != (pSettings->dssHdFilter == NEXUS_PidChannelDssHdFilter_eDisabled)) { |
|---|
| 502 | continue; |
|---|
| 503 | } |
|---|
| 504 | #endif |
|---|
| 505 | |
|---|
| 506 | /* playback */ |
|---|
| 507 | if (playpump && |
|---|
| 508 | pidChannel->status.playback && |
|---|
| 509 | pidChannel->status.playbackIndex == playpump->index && |
|---|
| 510 | pidChannel->status.pid == pid) |
|---|
| 511 | { |
|---|
| 512 | break; |
|---|
| 513 | } |
|---|
| 514 | #if NEXUS_NUM_PARSER_BANDS |
|---|
| 515 | /* live */ |
|---|
| 516 | if (!playpump && |
|---|
| 517 | !pidChannel->status.playback && |
|---|
| 518 | pidChannel->parserBand == parserBand && |
|---|
| 519 | (pidChannel->status.pid == pid |
|---|
| 520 | || (parserBand->settings.allPass |
|---|
| 521 | && parserBand->settings.cableCard == NEXUS_CableCardType_eNone ) )) |
|---|
| 522 | { |
|---|
| 523 | break; |
|---|
| 524 | } |
|---|
| 525 | #endif |
|---|
| 526 | } |
|---|
| 527 | if (pidChannel) { |
|---|
| 528 | /* we can/must reuse the HW pid channel */ |
|---|
| 529 | duplicatePidChannel = pidChannel; |
|---|
| 530 | index = duplicatePidChannel->status.pidChannelIndex; |
|---|
| 531 | goto alloc; |
|---|
| 532 | } |
|---|
| 533 | |
|---|
| 534 | /* we're not already using it, so find an available HW pid channel. */ |
|---|
| 535 | |
|---|
| 536 | /* first, handle allpass special case */ |
|---|
| 537 | #if NEXUS_NUM_PARSER_BANDS |
|---|
| 538 | if (!playpump && parserBand->settings.allPass |
|---|
| 539 | && parserBand->settings.cableCard == NEXUS_CableCardType_eNone) |
|---|
| 540 | { |
|---|
| 541 | /* allPass is a special mode where HW pid channel must == parser band. */ |
|---|
| 542 | /* ignore duplicatePidChannel. this is a test scenario anyway. */ |
|---|
| 543 | NEXUS_ParserBand_GetAllPassPidChannelIndex((NEXUS_ParserBand)parserBand, &index); |
|---|
| 544 | goto alloc; |
|---|
| 545 | } |
|---|
| 546 | #endif |
|---|
| 547 | |
|---|
| 548 | /* otherwise, we must search. bound the search based on the capabilities desired. */ |
|---|
| 549 | /* Some parts, such as the 7550, don't have message filtering hardware. BXPT_NUM_MESSAGE_CAPABLE_PID_CHANNELS |
|---|
| 550 | won't be defined for those chips. */ |
|---|
| 551 | #ifdef BXPT_NUM_MESSAGE_CAPABLE_PID_CHANNELS |
|---|
| 552 | BDBG_CASSERT(BXPT_NUM_MESSAGE_CAPABLE_PID_CHANNELS <= NEXUS_NUM_PID_CHANNELS); |
|---|
| 553 | #endif |
|---|
| 554 | switch (pSettings->pidChannelIndex) { |
|---|
| 555 | case NEXUS_PID_CHANNEL_OPEN_ANY: |
|---|
| 556 | firstPidChannel = 0; |
|---|
| 557 | totalPidChannels = NEXUS_NUM_PID_CHANNELS; |
|---|
| 558 | break; |
|---|
| 559 | |
|---|
| 560 | #ifdef BXPT_NUM_MESSAGE_CAPABLE_PID_CHANNELS |
|---|
| 561 | case NEXUS_PID_CHANNEL_OPEN_MESSAGE_CAPABLE: |
|---|
| 562 | firstPidChannel = 0; |
|---|
| 563 | totalPidChannels = BXPT_NUM_MESSAGE_CAPABLE_PID_CHANNELS; |
|---|
| 564 | break; |
|---|
| 565 | case NEXUS_PID_CHANNEL_OPEN_NOT_MESSAGE_CAPABLE: |
|---|
| 566 | firstPidChannel = BXPT_NUM_MESSAGE_CAPABLE_PID_CHANNELS; |
|---|
| 567 | totalPidChannels = NEXUS_NUM_PID_CHANNELS; |
|---|
| 568 | break; |
|---|
| 569 | #else |
|---|
| 570 | case NEXUS_PID_CHANNEL_OPEN_MESSAGE_CAPABLE: |
|---|
| 571 | BDBG_ERR(( "Message filtering not support in hw.")); |
|---|
| 572 | BERR_TRACE(NEXUS_NOT_SUPPORTED); |
|---|
| 573 | return NULL; |
|---|
| 574 | case NEXUS_PID_CHANNEL_OPEN_NOT_MESSAGE_CAPABLE: |
|---|
| 575 | firstPidChannel = 0; |
|---|
| 576 | totalPidChannels = NEXUS_NUM_PID_CHANNELS; |
|---|
| 577 | break; |
|---|
| 578 | #endif |
|---|
| 579 | |
|---|
| 580 | default: |
|---|
| 581 | BDBG_ERR(("invalid pidChannelIndex %d", pSettings->pidChannelIndex)); |
|---|
| 582 | return NULL; |
|---|
| 583 | } |
|---|
| 584 | |
|---|
| 585 | for (index=firstPidChannel;index<totalPidChannels;index++) { |
|---|
| 586 | if (pTransport->hwPidChannelRefCnt[index] == 0) break; |
|---|
| 587 | } |
|---|
| 588 | if (index == totalPidChannels) { |
|---|
| 589 | BDBG_ERR(("No more pid channels available in range %d..%d", firstPidChannel, totalPidChannels-1)); |
|---|
| 590 | return NULL; |
|---|
| 591 | } |
|---|
| 592 | } |
|---|
| 593 | |
|---|
| 594 | alloc: |
|---|
| 595 | /* Don't call BXPT_AllocPidChannel because we need the option of selecting the index. |
|---|
| 596 | BXPT_ConfigurePidChannel will reserve it just the same. */ |
|---|
| 597 | BDBG_MSG(("Allocated PID channel %d for PID 0x%04x", index, pid)); |
|---|
| 598 | |
|---|
| 599 | #if NEXUS_NUM_PARSER_BANDS |
|---|
| 600 | /* If the parser we want is in allPass mode, make sure the correct PID channel is used. Similar code in |
|---|
| 601 | NEXUS_ParserBand_SetSettings() will cover the possiblity that the parser is configured after the PID channel. */ |
|---|
| 602 | if (!playpump && parserBand->settings.allPass && parserBand->settings.cableCard == NEXUS_CableCardType_eNone) { |
|---|
| 603 | unsigned AllPassPidChannel; |
|---|
| 604 | NEXUS_ParserBand_GetAllPassPidChannelIndex((NEXUS_ParserBand)parserBand, &AllPassPidChannel); |
|---|
| 605 | if (index != AllPassPidChannel ) |
|---|
| 606 | { |
|---|
| 607 | BDBG_ERR(("Incorrect PID channel used for allPass on parser band %u. See NEXUS_ParserBand_GetAllPassPidChannelIndex()", parserBand)); |
|---|
| 608 | return NULL; |
|---|
| 609 | } |
|---|
| 610 | } |
|---|
| 611 | #endif |
|---|
| 612 | |
|---|
| 613 | if (duplicatePidChannel) { |
|---|
| 614 | /* test if new dup pid channel has conflicting settings. can't just memcmp settings because some don't apply. |
|---|
| 615 | ignore requireMessageBuffer and pidChannelIndex. we already know the HW pid channel index matches. |
|---|
| 616 | enabled doesn't have to match. it will be and-ed with others. |
|---|
| 617 | others must match. |
|---|
| 618 | */ |
|---|
| 619 | if (pSettings->dssHdFilter != duplicatePidChannel->settings.dssHdFilter || |
|---|
| 620 | pSettings->continuityCountEnabled != duplicatePidChannel->settings.continuityCountEnabled || |
|---|
| 621 | pSettings->generateContinuityCount != duplicatePidChannel->settings.generateContinuityCount || |
|---|
| 622 | BKNI_Memcmp(&pSettings->remap, &duplicatePidChannel->settings.remap, sizeof(pSettings->remap))) |
|---|
| 623 | { |
|---|
| 624 | BDBG_ERR(("Cannot open duplicate pid channel with different settings")); |
|---|
| 625 | return NULL; |
|---|
| 626 | } |
|---|
| 627 | } |
|---|
| 628 | |
|---|
| 629 | pidChannel = BKNI_Malloc(sizeof(*pidChannel)); |
|---|
| 630 | if (!pidChannel) { |
|---|
| 631 | BERR_TRACE(NEXUS_OUT_OF_SYSTEM_MEMORY); |
|---|
| 632 | return NULL; |
|---|
| 633 | } |
|---|
| 634 | BKNI_Memset(pidChannel, 0, sizeof(*pidChannel)); |
|---|
| 635 | BDBG_OBJECT_SET(pidChannel, NEXUS_PidChannel); |
|---|
| 636 | pidChannel->playpump = playpump; |
|---|
| 637 | pidChannel->settings = *pSettings; |
|---|
| 638 | pidChannel->status.pid = pid; |
|---|
| 639 | pidChannel->status.pidChannelIndex = index; |
|---|
| 640 | pTransport->hwPidChannelRefCnt[index]++; |
|---|
| 641 | BKNI_EnterCriticalSection(); |
|---|
| 642 | BLST_S_INSERT_HEAD(&pTransport->pidChannels, pidChannel, link); |
|---|
| 643 | BKNI_LeaveCriticalSection(); |
|---|
| 644 | |
|---|
| 645 | pidChannel->status.parserBand = NEXUS_ParserBand_eInvalid; /* DEPRECATED: invalid value */ |
|---|
| 646 | pidChannel->status.playback = playpump != NULL; |
|---|
| 647 | |
|---|
| 648 | if (pidChannel->status.playback) |
|---|
| 649 | { |
|---|
| 650 | pidChannel->parserBand = NULL; |
|---|
| 651 | pidChannel->status.playbackIndex = playpump->index; |
|---|
| 652 | } |
|---|
| 653 | else |
|---|
| 654 | { |
|---|
| 655 | pidChannel->parserBand = parserBand; |
|---|
| 656 | pidChannel->status.playbackIndex = 0xffff; /* invalid value */ |
|---|
| 657 | /* must inc parserBand refcnt here. if it fails later, NEXUS_PidChannel_P_Close will decrement */ |
|---|
| 658 | #if NEXUS_NUM_PARSER_BANDS |
|---|
| 659 | parserBand->refcnt++; |
|---|
| 660 | /* status.transportType gets overwritten by Playpump if it packetizes */ |
|---|
| 661 | pidChannel->status.transportType = pidChannel->status.originalTransportType = parserBand->settings.transportType; |
|---|
| 662 | #endif |
|---|
| 663 | } |
|---|
| 664 | |
|---|
| 665 | pidChannel->status.remappedPid = pid; |
|---|
| 666 | pidChannel->status.continuityCountErrors = 0; |
|---|
| 667 | |
|---|
| 668 | if (pTransport->hwPidChannelRefCnt[index] == 1) { |
|---|
| 669 | /* Configure it */ |
|---|
| 670 | if (pSettings->remap.enabled) { |
|---|
| 671 | /* the old pid goes in */ |
|---|
| 672 | rc = BXPT_Spid_ConfigureChannel(pTransport->xpt, pidChannel->status.pidChannelIndex, pid, BXPT_Spid_eChannelMode_Remap); |
|---|
| 673 | if (rc) {rc=BERR_TRACE(rc); goto fail1;} |
|---|
| 674 | |
|---|
| 675 | /* the new pid comes out */ |
|---|
| 676 | rc = BXPT_ConfigurePidChannel(pTransport->xpt, pidChannel->status.pidChannelIndex, pSettings->remap.pid, playpump?BXPT_PB_PARSER(playpump->index):parserBand->hwIndex); |
|---|
| 677 | if (rc) {rc=BERR_TRACE(rc); goto fail1;} |
|---|
| 678 | |
|---|
| 679 | pidChannel->status.remappedPid = pSettings->remap.pid; /* this should be the new pid */ |
|---|
| 680 | } |
|---|
| 681 | else { |
|---|
| 682 | (void)BXPT_Spid_ConfigureChannel(pTransport->xpt, pidChannel->status.pidChannelIndex, 0, BXPT_Spid_eChannelMode_Disable); |
|---|
| 683 | |
|---|
| 684 | rc = BXPT_ConfigurePidChannel(pTransport->xpt, pidChannel->status.pidChannelIndex, pid, playpump?BXPT_PB_PARSER(playpump->index):parserBand->hwIndex); |
|---|
| 685 | if (rc) {rc=BERR_TRACE(rc); goto fail1;} |
|---|
| 686 | } |
|---|
| 687 | |
|---|
| 688 | #if B_HAS_DSS |
|---|
| 689 | rc = BXPT_DirecTv_ConfigHdFiltering(pTransport->xpt, pidChannel->status.pidChannelIndex, |
|---|
| 690 | pSettings->dssHdFilter != NEXUS_PidChannelDssHdFilter_eDisabled, |
|---|
| 691 | ((pSettings->dssHdFilter == NEXUS_PidChannelDssHdFilter_eAux) ? BXPT_HdFilterMode_eAuxOnly : BXPT_HdFilterMode_eNonAuxOnly)); |
|---|
| 692 | if (rc) {rc=BERR_TRACE(rc); goto fail1;} |
|---|
| 693 | #endif |
|---|
| 694 | #if NEXUS_PARSER_BAND_CC_CHECK |
|---|
| 695 | if (NEXUS_GetEnv("cont_count_ignore")) { |
|---|
| 696 | bandContinuityCountEnabled = false; |
|---|
| 697 | } |
|---|
| 698 | #endif |
|---|
| 699 | |
|---|
| 700 | #if !NEXUS_PARSER_BAND_CC_CHECK |
|---|
| 701 | { |
|---|
| 702 | BXPT_PidChannel_CC_Config cfg; |
|---|
| 703 | BXPT_GetPidChannel_CC_Config(pTransport->xpt, pidChannel->status.pidChannelIndex, &cfg); |
|---|
| 704 | cfg.Primary_CC_CheckEnable = pSettings->continuityCountEnabled && bandContinuityCountEnabled; |
|---|
| 705 | cfg.Secondary_CC_CheckEnable = pSettings->remap.continuityCountEnabled && bandContinuityCountEnabled; |
|---|
| 706 | cfg.Generate_CC_Enable = pSettings->generateContinuityCount; |
|---|
| 707 | rc = BXPT_SetPidChannel_CC_Config(pTransport->xpt, pidChannel->status.pidChannelIndex, &cfg); |
|---|
| 708 | if (rc) {rc=BERR_TRACE(rc); goto fail1;} |
|---|
| 709 | } |
|---|
| 710 | #endif |
|---|
| 711 | } |
|---|
| 712 | |
|---|
| 713 | /* must call NEXUS_PidChannel_SetEnabled because it may disable dups */ |
|---|
| 714 | rc = NEXUS_PidChannel_P_SetEnabled(pidChannel, pSettings->enabled); |
|---|
| 715 | if (rc) {rc=BERR_TRACE(rc); goto fail1;} |
|---|
| 716 | |
|---|
| 717 | pidChannel->status.enabled = pSettings->enabled; |
|---|
| 718 | |
|---|
| 719 | if (!playpump) { |
|---|
| 720 | #if NEXUS_NUM_PARSER_BANDS |
|---|
| 721 | NEXUS_ParserBand_P_SetEnable(parserBand); |
|---|
| 722 | parserBand->pidChannels++; |
|---|
| 723 | #endif |
|---|
| 724 | } |
|---|
| 725 | return pidChannel; |
|---|
| 726 | |
|---|
| 727 | fail1: |
|---|
| 728 | if (pidChannel) { |
|---|
| 729 | NEXUS_PidChannel_P_Close(pidChannel); |
|---|
| 730 | } |
|---|
| 731 | return NULL; |
|---|
| 732 | } |
|---|
| 733 | |
|---|
| 734 | void NEXUS_PidChannel_Close(NEXUS_PidChannelHandle pidChannel) |
|---|
| 735 | { |
|---|
| 736 | BDBG_OBJECT_ASSERT(pidChannel, NEXUS_PidChannel); |
|---|
| 737 | if (pidChannel->playpump) { |
|---|
| 738 | NEXUS_Playpump_ClosePidChannel(pidChannel->playpump, pidChannel); |
|---|
| 739 | } |
|---|
| 740 | else { |
|---|
| 741 | NEXUS_PidChannel_P_Close(pidChannel); |
|---|
| 742 | } |
|---|
| 743 | } |
|---|
| 744 | |
|---|
| 745 | void NEXUS_PidChannel_P_Close(NEXUS_PidChannelHandle pidChannel) |
|---|
| 746 | { |
|---|
| 747 | unsigned index; /* hw index */ |
|---|
| 748 | |
|---|
| 749 | BDBG_OBJECT_ASSERT(pidChannel, NEXUS_PidChannel); |
|---|
| 750 | |
|---|
| 751 | if (!pidChannel->status.playback) { |
|---|
| 752 | #if NEXUS_NUM_PARSER_BANDS |
|---|
| 753 | if (pidChannel->parserBand) |
|---|
| 754 | { |
|---|
| 755 | pidChannel->parserBand->pidChannels--; |
|---|
| 756 | BDBG_ASSERT(pidChannel->parserBand->refcnt); |
|---|
| 757 | pidChannel->parserBand->refcnt--; |
|---|
| 758 | NEXUS_ParserBand_P_SetEnable(pidChannel->parserBand); |
|---|
| 759 | } |
|---|
| 760 | #endif |
|---|
| 761 | } |
|---|
| 762 | |
|---|
| 763 | NEXUS_PidChannel_StopScramblingCheck(pidChannel); |
|---|
| 764 | |
|---|
| 765 | if (pidChannel->settings.remap.enabled) { |
|---|
| 766 | (void)BXPT_Spid_ConfigureChannel(pTransport->xpt, pidChannel->status.pidChannelIndex, 0, BXPT_Spid_eChannelMode_Disable); |
|---|
| 767 | } |
|---|
| 768 | |
|---|
| 769 | index = pidChannel->status.pidChannelIndex; |
|---|
| 770 | BDBG_ASSERT(pTransport->hwPidChannelRefCnt[index]); |
|---|
| 771 | pTransport->hwPidChannelRefCnt[index]--; |
|---|
| 772 | BDBG_MSG(("dec pidchannel refcnt(%d) on pidchannel %d", pTransport->hwPidChannelRefCnt[index], index)); |
|---|
| 773 | if (pTransport->hwPidChannelRefCnt[index] == 0) { |
|---|
| 774 | BXPT_DisablePidChannel(pTransport->xpt, index); |
|---|
| 775 | BXPT_FreePidChannel(pTransport->xpt, index); |
|---|
| 776 | } |
|---|
| 777 | |
|---|
| 778 | BKNI_EnterCriticalSection(); |
|---|
| 779 | BLST_S_REMOVE(&pTransport->pidChannels, pidChannel, NEXUS_PidChannel, link); |
|---|
| 780 | BKNI_LeaveCriticalSection(); |
|---|
| 781 | |
|---|
| 782 | /* recalc "enabled" for remaining dups. find first dup and reapply its state. it will recalc for all. */ |
|---|
| 783 | if (pTransport->hwPidChannelRefCnt[index] > 0) { |
|---|
| 784 | NEXUS_PidChannelHandle other; |
|---|
| 785 | for (other = BLST_S_FIRST(&pTransport->pidChannels); other; other = BLST_S_NEXT(other, link)) { |
|---|
| 786 | if (other->status.pidChannelIndex == pidChannel->status.pidChannelIndex) { |
|---|
| 787 | NEXUS_PidChannel_P_SetEnabled(other, other->settings.enabled); |
|---|
| 788 | break; |
|---|
| 789 | } |
|---|
| 790 | } |
|---|
| 791 | } |
|---|
| 792 | |
|---|
| 793 | BDBG_OBJECT_DESTROY(pidChannel, NEXUS_PidChannel); |
|---|
| 794 | BKNI_Free(pidChannel); |
|---|
| 795 | } |
|---|
| 796 | |
|---|
| 797 | void NEXUS_PidChannel_CloseAll(NEXUS_ParserBand parserBand) |
|---|
| 798 | { |
|---|
| 799 | NEXUS_ParserBandHandle handle; |
|---|
| 800 | NEXUS_PidChannelHandle pidChannel; |
|---|
| 801 | |
|---|
| 802 | handle = NEXUS_ParserBand_Resolve_priv(parserBand); |
|---|
| 803 | |
|---|
| 804 | for (pidChannel = BLST_S_FIRST(&pTransport->pidChannels); pidChannel;) { |
|---|
| 805 | NEXUS_PidChannelHandle next = BLST_S_NEXT(pidChannel, link); |
|---|
| 806 | |
|---|
| 807 | if (!pidChannel->status.playback && pidChannel->parserBand == handle) { |
|---|
| 808 | nexus_unregister_NEXUS_PidChannelHandle(nexus_transport_client(), pidChannel, false); |
|---|
| 809 | NEXUS_PidChannel_Close(pidChannel); |
|---|
| 810 | } |
|---|
| 811 | pidChannel = next; |
|---|
| 812 | } |
|---|
| 813 | } |
|---|
| 814 | |
|---|
| 815 | NEXUS_Error NEXUS_PidChannel_GetStatus(NEXUS_PidChannelHandle pidChannel, NEXUS_PidChannelStatus *pStatus) |
|---|
| 816 | { |
|---|
| 817 | BDBG_OBJECT_ASSERT(pidChannel, NEXUS_PidChannel); |
|---|
| 818 | /* no need to check pidChannel->refcnt. if zero, we should have already asserted */ |
|---|
| 819 | *pStatus = pidChannel->status; |
|---|
| 820 | return 0; |
|---|
| 821 | } |
|---|
| 822 | |
|---|
| 823 | void NEXUS_PidChannel_ConsumerStarted(NEXUS_PidChannelHandle pidChannel) |
|---|
| 824 | { |
|---|
| 825 | BDBG_OBJECT_ASSERT(pidChannel, NEXUS_PidChannel); |
|---|
| 826 | if (pidChannel->status.playback) { |
|---|
| 827 | NEXUS_PlaypumpHandle playpump; |
|---|
| 828 | |
|---|
| 829 | BDBG_MSG(("NEXUS_PidChannel_ConsumerStarted on playback %d", pidChannel->status.playbackIndex)); |
|---|
| 830 | #if NEXUS_NUM_PLAYPUMPS |
|---|
| 831 | if (pidChannel->status.playbackIndex < NEXUS_NUM_PLAYPUMPS) { |
|---|
| 832 | playpump = pTransport->playpump[pidChannel->status.playbackIndex].playpump; |
|---|
| 833 | } |
|---|
| 834 | else |
|---|
| 835 | #endif |
|---|
| 836 | { |
|---|
| 837 | playpump = NULL; |
|---|
| 838 | } |
|---|
| 839 | if (playpump) { |
|---|
| 840 | NEXUS_Playpump_P_ConsumerStarted(playpump); |
|---|
| 841 | } else { |
|---|
| 842 | BDBG_ERR(("NEXUS_PidChannel_ConsumerStarted: %#lx invalid state", (unsigned long)pidChannel)); |
|---|
| 843 | } |
|---|
| 844 | } |
|---|
| 845 | } |
|---|
| 846 | |
|---|
| 847 | /** |
|---|
| 848 | TODO: consider adding pTransport->rave[].splicePidChannel list to keep track. for now, this is a seldomly used API, so we'll let XPT keep track. |
|---|
| 849 | also consider adding pidChannel->ravelist to avoid the look up. for now, it's acceptable. |
|---|
| 850 | **/ |
|---|
| 851 | NEXUS_Error NEXUS_PidChannel_AddSplicePidChannel( NEXUS_PidChannelHandle pidChannel, NEXUS_PidChannelHandle splicePidChannel ) |
|---|
| 852 | { |
|---|
| 853 | NEXUS_Error rc; |
|---|
| 854 | NEXUS_RaveHandle rave; |
|---|
| 855 | unsigned i,j; |
|---|
| 856 | bool found = false; |
|---|
| 857 | |
|---|
| 858 | for (j=0;j<NEXUS_NUM_RAVE_CHANNELS;j++) { |
|---|
| 859 | for (i=0;i<NEXUS_NUM_RAVE_CONTEXTS;i++) { |
|---|
| 860 | rave = &pTransport->rave[j].context[i]; |
|---|
| 861 | if (rave->pidChannelIndex == pidChannel->status.pidChannelIndex && rave->raveHandle) { |
|---|
| 862 | rc = BXPT_Rave_PushPidChannel(rave->raveHandle, pidChannel->status.pidChannelIndex, splicePidChannel->status.pidChannelIndex); |
|---|
| 863 | if (rc) return BERR_TRACE(rc); |
|---|
| 864 | found = true; |
|---|
| 865 | } |
|---|
| 866 | } |
|---|
| 867 | } |
|---|
| 868 | |
|---|
| 869 | if (!found) { |
|---|
| 870 | BDBG_ERR(("Unable to look up RAVE context. The NEXUS_PidChannel must be currently decoding to allow pid splicing.")); |
|---|
| 871 | return BERR_TRACE(NEXUS_UNKNOWN); |
|---|
| 872 | } |
|---|
| 873 | return 0; |
|---|
| 874 | } |
|---|
| 875 | |
|---|
| 876 | NEXUS_Error NEXUS_PidChannel_RemoveSplicePidChannel( NEXUS_PidChannelHandle pidChannel, NEXUS_PidChannelHandle splicePidChannel ) |
|---|
| 877 | { |
|---|
| 878 | NEXUS_Error rc; |
|---|
| 879 | NEXUS_RaveHandle rave; |
|---|
| 880 | unsigned i,j; |
|---|
| 881 | bool found = false; |
|---|
| 882 | |
|---|
| 883 | for (j=0;j<NEXUS_NUM_RAVE_CHANNELS;j++) { |
|---|
| 884 | for (i=0;i<NEXUS_NUM_RAVE_CONTEXTS;i++) { |
|---|
| 885 | rave = &pTransport->rave[j].context[i]; |
|---|
| 886 | if (rave->pidChannelIndex == pidChannel->status.pidChannelIndex && rave->raveHandle) { |
|---|
| 887 | rc = BXPT_Rave_RemovePidChannel(rave->raveHandle, splicePidChannel->status.pidChannelIndex); |
|---|
| 888 | if (rc) return BERR_TRACE(rc); |
|---|
| 889 | found = true; |
|---|
| 890 | } |
|---|
| 891 | } |
|---|
| 892 | } |
|---|
| 893 | |
|---|
| 894 | if (!found) { |
|---|
| 895 | BDBG_ERR(("Unable to look up RAVE context. The NEXUS_PidChannel must be currently decoding to allow pid splicing.")); |
|---|
| 896 | return BERR_TRACE(NEXUS_UNKNOWN); |
|---|
| 897 | } |
|---|
| 898 | return 0; |
|---|
| 899 | } |
|---|
| 900 | |
|---|
| 901 | void NEXUS_PidChannel_RemoveAllSplicePidChannels( NEXUS_PidChannelHandle pidChannel ) |
|---|
| 902 | { |
|---|
| 903 | NEXUS_Error rc; |
|---|
| 904 | NEXUS_RaveHandle rave; |
|---|
| 905 | unsigned i,j; |
|---|
| 906 | bool found = false; |
|---|
| 907 | |
|---|
| 908 | for (j=0;j<NEXUS_NUM_RAVE_CHANNELS;j++) { |
|---|
| 909 | for (i=0;i<NEXUS_NUM_RAVE_CONTEXTS;i++) { |
|---|
| 910 | rave = &pTransport->rave[j].context[i]; |
|---|
| 911 | if (rave->pidChannelIndex == pidChannel->status.pidChannelIndex && rave->raveHandle) { |
|---|
| 912 | rc = BXPT_Rave_ClearQueue(rave->raveHandle); |
|---|
| 913 | if (rc) rc = BERR_TRACE(rc); |
|---|
| 914 | found = true; |
|---|
| 915 | } |
|---|
| 916 | } |
|---|
| 917 | } |
|---|
| 918 | |
|---|
| 919 | if (!found) { |
|---|
| 920 | BDBG_ERR(("Unable to look up RAVE context. The NEXUS_PidChannel must be currently decoding to allow pid splicing.")); |
|---|
| 921 | rc = BERR_TRACE(NEXUS_UNKNOWN); |
|---|
| 922 | } |
|---|
| 923 | } |
|---|
| 924 | |
|---|
| 925 | /* public function can filter out change */ |
|---|
| 926 | NEXUS_Error NEXUS_PidChannel_SetEnabled( NEXUS_PidChannelHandle pidChannel, bool enabled ) |
|---|
| 927 | { |
|---|
| 928 | BDBG_OBJECT_ASSERT(pidChannel, NEXUS_PidChannel); |
|---|
| 929 | if (pidChannel->settings.enabled == enabled) { |
|---|
| 930 | return 0; |
|---|
| 931 | } |
|---|
| 932 | pidChannel->settings.enabled = enabled; |
|---|
| 933 | return NEXUS_PidChannel_P_SetEnabled(pidChannel, enabled); |
|---|
| 934 | } |
|---|
| 935 | |
|---|
| 936 | /* private function may be called with no settings.enabled change, but status may change */ |
|---|
| 937 | static NEXUS_Error NEXUS_PidChannel_P_SetEnabled( NEXUS_PidChannelHandle pidChannel, bool enabled ) |
|---|
| 938 | { |
|---|
| 939 | NEXUS_PidChannelHandle other; |
|---|
| 940 | unsigned index = pidChannel->status.pidChannelIndex; |
|---|
| 941 | |
|---|
| 942 | /* must "and" with all other SW pid channel handles for this HW pid channel (short circuit if !enabled). |
|---|
| 943 | pidChannel->settings.enabled stores SW state for each handle. |
|---|
| 944 | pidChannel->status.enabled stores HW state (must be the same for all dups). */ |
|---|
| 945 | if (pTransport->hwPidChannelRefCnt[index] > 1) { |
|---|
| 946 | for (other = BLST_S_FIRST(&pTransport->pidChannels); other && enabled; other = BLST_S_NEXT(other, link)) { |
|---|
| 947 | BDBG_OBJECT_ASSERT(other, NEXUS_PidChannel); |
|---|
| 948 | if (other->status.pidChannelIndex == index) { |
|---|
| 949 | enabled &= other->settings.enabled; |
|---|
| 950 | } |
|---|
| 951 | } |
|---|
| 952 | } |
|---|
| 953 | |
|---|
| 954 | if ( pidChannel->status.enabled != enabled ) |
|---|
| 955 | { |
|---|
| 956 | BERR_Code errCode; |
|---|
| 957 | |
|---|
| 958 | if ( enabled ) |
|---|
| 959 | { |
|---|
| 960 | BDBG_MSG(("Enabling pid channel %u", index)); |
|---|
| 961 | errCode = BXPT_EnablePidChannel(pTransport->xpt, index); |
|---|
| 962 | if ( errCode ) |
|---|
| 963 | { |
|---|
| 964 | return BERR_TRACE(errCode); |
|---|
| 965 | } |
|---|
| 966 | } |
|---|
| 967 | else |
|---|
| 968 | { |
|---|
| 969 | BDBG_MSG(("Disabling pid channel %u", index)); |
|---|
| 970 | errCode = BXPT_DisablePidChannel(pTransport->xpt, index); |
|---|
| 971 | if ( errCode ) |
|---|
| 972 | { |
|---|
| 973 | return BERR_TRACE(errCode); |
|---|
| 974 | } |
|---|
| 975 | } |
|---|
| 976 | |
|---|
| 977 | /* update all status */ |
|---|
| 978 | if (pTransport->hwPidChannelRefCnt[index] > 1) { |
|---|
| 979 | for (other = BLST_S_FIRST(&pTransport->pidChannels); other; other = BLST_S_NEXT(other, link)) { |
|---|
| 980 | if (other->status.pidChannelIndex == index) { |
|---|
| 981 | other->status.enabled = enabled; |
|---|
| 982 | } |
|---|
| 983 | } |
|---|
| 984 | } |
|---|
| 985 | else { |
|---|
| 986 | /* avoid search */ |
|---|
| 987 | pidChannel->status.enabled = enabled; |
|---|
| 988 | } |
|---|
| 989 | } |
|---|
| 990 | |
|---|
| 991 | return NEXUS_SUCCESS; |
|---|
| 992 | } |
|---|
| 993 | |
|---|
| 994 | NEXUS_Error NEXUS_PidChannel_SetRemapSettings( |
|---|
| 995 | NEXUS_PidChannelHandle pidChannel, |
|---|
| 996 | const NEXUS_PidChannelRemapSettings *pSettings) |
|---|
| 997 | { |
|---|
| 998 | /* SW7344-192, Coverity: 35340 */ |
|---|
| 999 | BERR_Code rc = NEXUS_SUCCESS; |
|---|
| 1000 | bool bandContinuityCountEnabled = pidChannel->settings.continuityCountEnabled; |
|---|
| 1001 | bool wasEnabled = false; |
|---|
| 1002 | |
|---|
| 1003 | NEXUS_ASSERT_MODULE(); |
|---|
| 1004 | BDBG_OBJECT_ASSERT(pidChannel, NEXUS_PidChannel); |
|---|
| 1005 | BDBG_ASSERT(pSettings); |
|---|
| 1006 | |
|---|
| 1007 | if (pidChannel->status.enabled) { |
|---|
| 1008 | rc = NEXUS_PidChannel_P_SetEnabled(pidChannel, false); |
|---|
| 1009 | if (rc) {rc=BERR_TRACE(rc); goto fail;} |
|---|
| 1010 | wasEnabled = true; |
|---|
| 1011 | } |
|---|
| 1012 | |
|---|
| 1013 | if (pSettings->enabled) { |
|---|
| 1014 | /* the old pid goes in */ |
|---|
| 1015 | rc = BXPT_Spid_ConfigureChannel(pTransport->xpt, pidChannel->status.pidChannelIndex, pidChannel->status.pid, BXPT_Spid_eChannelMode_Remap); |
|---|
| 1016 | if (rc) {rc=BERR_TRACE(rc); goto fail;} |
|---|
| 1017 | |
|---|
| 1018 | if (pidChannel->parserBand) |
|---|
| 1019 | { |
|---|
| 1020 | /* the new pid comes out */ |
|---|
| 1021 | rc = BXPT_ConfigurePidChannel(pTransport->xpt, pidChannel->status.pidChannelIndex, pSettings->pid, pidChannel->parserBand->hwIndex); |
|---|
| 1022 | if (rc) {rc=BERR_TRACE(rc); goto fail;} |
|---|
| 1023 | } |
|---|
| 1024 | |
|---|
| 1025 | pidChannel->status.remappedPid = pSettings->pid; /* this should be the new pid */ |
|---|
| 1026 | |
|---|
| 1027 | #if NEXUS_PARSER_BAND_CC_CHECK |
|---|
| 1028 | if (NEXUS_GetEnv("cont_count_ignore")) { |
|---|
| 1029 | bandContinuityCountEnabled = false; |
|---|
| 1030 | } |
|---|
| 1031 | #endif |
|---|
| 1032 | #if (!NEXUS_PARSER_BAND_CC_CHECK) |
|---|
| 1033 | { |
|---|
| 1034 | BXPT_PidChannel_CC_Config cfg; |
|---|
| 1035 | BXPT_GetPidChannel_CC_Config(pTransport->xpt,pidChannel->status.pidChannelIndex, &cfg); |
|---|
| 1036 | cfg.Secondary_CC_CheckEnable = pSettings->continuityCountEnabled && bandContinuityCountEnabled; |
|---|
| 1037 | rc = BXPT_SetPidChannel_CC_Config(pTransport->xpt, pidChannel->status.pidChannelIndex, &cfg); |
|---|
| 1038 | if (rc) {rc=BERR_TRACE(rc); goto fail;} |
|---|
| 1039 | } |
|---|
| 1040 | #endif |
|---|
| 1041 | pidChannel->settings.remap = *pSettings; |
|---|
| 1042 | } |
|---|
| 1043 | else { |
|---|
| 1044 | if (pidChannel->settings.remap.pid) { |
|---|
| 1045 | (void)BXPT_Spid_ConfigureChannel(pTransport->xpt, pidChannel->status.pidChannelIndex, 0, BXPT_Spid_eChannelMode_Disable); |
|---|
| 1046 | } |
|---|
| 1047 | } |
|---|
| 1048 | |
|---|
| 1049 | fail: |
|---|
| 1050 | if (wasEnabled) { |
|---|
| 1051 | /* even on failure condition, we want to reenable */ |
|---|
| 1052 | (void)NEXUS_PidChannel_P_SetEnabled(pidChannel, true); |
|---|
| 1053 | } |
|---|
| 1054 | return rc; |
|---|
| 1055 | } |
|---|
| 1056 | |
|---|
| 1057 | NEXUS_Error NEXUS_PidChannel_ResetStatus( NEXUS_PidChannelHandle pidChannel ) |
|---|
| 1058 | { |
|---|
| 1059 | BDBG_OBJECT_ASSERT(pidChannel, NEXUS_PidChannel); |
|---|
| 1060 | pidChannel->status.continuityCountErrors = 0; |
|---|
| 1061 | return 0; |
|---|
| 1062 | } |
|---|
| 1063 | |
|---|