OLD | NEW |
(Empty) | |
| 1 //------------------------------------------------------------------------------ |
| 2 // <copyright file="bmi.c" company="Atheros"> |
| 3 // Copyright (c) 2004-2008 Atheros Corporation. All rights reserved. |
| 4 // |
| 5 // This program is free software; you can redistribute it and/or modify |
| 6 // it under the terms of the GNU General Public License version 2 as |
| 7 // published by the Free Software Foundation; |
| 8 // |
| 9 // Software distributed under the License is distributed on an "AS |
| 10 // IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or |
| 11 // implied. See the License for the specific language governing |
| 12 // rights and limitations under the License. |
| 13 // |
| 14 // |
| 15 //------------------------------------------------------------------------------ |
| 16 //============================================================================== |
| 17 // |
| 18 // Author(s): ="Atheros" |
| 19 //============================================================================== |
| 20 |
| 21 #include "hif.h" |
| 22 #include "bmi.h" |
| 23 #include "htc_api.h" |
| 24 #include "bmi_internal.h" |
| 25 |
| 26 #ifdef DEBUG |
| 27 static ATH_DEBUG_MASK_DESCRIPTION bmi_debug_desc[] = { |
| 28 { ATH_DEBUG_BMI , "BMI Tracing"}, |
| 29 }; |
| 30 |
| 31 ATH_DEBUG_INSTANTIATE_MODULE_VAR(bmi, |
| 32 "bmi", |
| 33 "Boot Manager Interface", |
| 34 ATH_DEBUG_MASK_DEFAULTS, |
| 35 ATH_DEBUG_DESCRIPTION_COUNT(bmi_debug_desc), |
| 36 bmi_debug_desc); |
| 37 |
| 38 #endif |
| 39 |
| 40 /* |
| 41 Although we had envisioned BMI to run on top of HTC, this is not how the |
| 42 final implementation ended up. On the Target side, BMI is a part of the BSP |
| 43 and does not use the HTC protocol nor even DMA -- it is intentionally kept |
| 44 very simple. |
| 45 */ |
| 46 |
| 47 static A_BOOL pendingEventsFuncCheck = FALSE; |
| 48 static A_UINT32 *pBMICmdCredits; |
| 49 static A_UCHAR *pBMICmdBuf; |
| 50 #define MAX_BMI_CMDBUF_SZ (BMI_DATASZ_MAX + \ |
| 51 sizeof(A_UINT32) /* cmd */ + \ |
| 52 sizeof(A_UINT32) /* addr */ + \ |
| 53 sizeof(A_UINT32))/* length */ |
| 54 #define BMI_COMMAND_FITS(sz) ((sz) <= MAX_BMI_CMDBUF_SZ) |
| 55 |
| 56 /* APIs visible to the driver */ |
| 57 void |
| 58 BMIInit(void) |
| 59 { |
| 60 bmiDone = FALSE; |
| 61 pendingEventsFuncCheck = FALSE; |
| 62 |
| 63 /* |
| 64 * On some platforms, it's not possible to DMA to a static variable |
| 65 * in a device driver (e.g. Linux loadable driver module). |
| 66 * So we need to A_MALLOC space for "command credits" and for commands. |
| 67 * |
| 68 * Note: implicitly relies on A_MALLOC to provide a buffer that is |
| 69 * suitable for DMA (or PIO). This buffer will be passed down the |
| 70 * bus stack. |
| 71 */ |
| 72 if (!pBMICmdCredits) { |
| 73 pBMICmdCredits = (A_UINT32 *)A_MALLOC_NOWAIT(4); |
| 74 A_ASSERT(pBMICmdCredits); |
| 75 } |
| 76 |
| 77 if (!pBMICmdBuf) { |
| 78 pBMICmdBuf = (A_UCHAR *)A_MALLOC_NOWAIT(MAX_BMI_CMDBUF_SZ); |
| 79 A_ASSERT(pBMICmdBuf); |
| 80 } |
| 81 |
| 82 A_REGISTER_MODULE_DEBUG_INFO(bmi); |
| 83 } |
| 84 |
| 85 A_STATUS |
| 86 BMIDone(HIF_DEVICE *device) |
| 87 { |
| 88 A_STATUS status; |
| 89 A_UINT32 cid; |
| 90 |
| 91 if (bmiDone) { |
| 92 AR_DEBUG_PRINTF (ATH_DEBUG_BMI, ("BMIDone skipped\n")); |
| 93 return A_OK; |
| 94 } |
| 95 |
| 96 AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Done: Enter (device: 0x%p)\n", device))
; |
| 97 bmiDone = TRUE; |
| 98 cid = BMI_DONE; |
| 99 |
| 100 status = bmiBufferSend(device, (A_UCHAR *)&cid, sizeof(cid)); |
| 101 if (status != A_OK) { |
| 102 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n")); |
| 103 return A_ERROR; |
| 104 } |
| 105 |
| 106 if (pBMICmdCredits) { |
| 107 A_FREE(pBMICmdCredits); |
| 108 pBMICmdCredits = NULL; |
| 109 } |
| 110 |
| 111 if (pBMICmdBuf) { |
| 112 A_FREE(pBMICmdBuf); |
| 113 pBMICmdBuf = NULL; |
| 114 } |
| 115 |
| 116 AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Done: Exit\n")); |
| 117 |
| 118 return A_OK; |
| 119 } |
| 120 |
| 121 A_STATUS |
| 122 BMIGetTargetInfo(HIF_DEVICE *device, struct bmi_target_info *targ_info) |
| 123 { |
| 124 A_STATUS status; |
| 125 A_UINT32 cid; |
| 126 |
| 127 if (bmiDone) { |
| 128 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n")); |
| 129 return A_ERROR; |
| 130 } |
| 131 |
| 132 AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Get Target Info: Enter (device: 0x%p)\n
", device)); |
| 133 cid = BMI_GET_TARGET_INFO; |
| 134 |
| 135 status = bmiBufferSend(device, (A_UCHAR *)&cid, sizeof(cid)); |
| 136 if (status != A_OK) { |
| 137 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n")); |
| 138 return A_ERROR; |
| 139 } |
| 140 |
| 141 status = bmiBufferReceive(device, (A_UCHAR *)&targ_info->target_ver, |
| 142 sizeof(targ_info->target_ver), T
RUE); |
| 143 if (status != A_OK) { |
| 144 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read Target Version from the
device\n")); |
| 145 return A_ERROR; |
| 146 } |
| 147 |
| 148 if (targ_info->target_ver == TARGET_VERSION_SENTINAL) { |
| 149 /* Determine how many bytes are in the Target's targ_info */ |
| 150 status = bmiBufferReceive(device, (A_UCHAR *)&targ_info->target_info_byt
e_count, |
| 151 sizeof(targ_info->target_info_byte_c
ount), TRUE); |
| 152 if (status != A_OK) { |
| 153 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read Target Info Byte Cou
nt from the device\n")); |
| 154 return A_ERROR; |
| 155 } |
| 156 |
| 157 /* |
| 158 * The Target's targ_info doesn't match the Host's targ_info. |
| 159 * We need to do some backwards compatibility work to make this OK. |
| 160 */ |
| 161 A_ASSERT(targ_info->target_info_byte_count == sizeof(*targ_info)); |
| 162 |
| 163 /* Read the remainder of the targ_info */ |
| 164 status = bmiBufferReceive(device, |
| 165 ((A_UCHAR *)targ_info)+sizeof(targ_info->target_info_byt
e_count), |
| 166 sizeof(*targ_info)-sizeof(targ_info->target_info_byte_co
unt), TRUE); |
| 167 if (status != A_OK) { |
| 168 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read Target Info (%d byte
s) from the device\n", |
| 169 targ_info->targe
t_info_byte_count)); |
| 170 return A_ERROR; |
| 171 } |
| 172 } else { |
| 173 /* |
| 174 * Target must be an AR6001 whose firmware does not |
| 175 * support BMI_GET_TARGET_INFO. Construct the data |
| 176 * that it would have sent. |
| 177 */ |
| 178 targ_info->target_info_byte_count=sizeof(*targ_info); |
| 179 targ_info->target_type=TARGET_TYPE_AR6001; |
| 180 } |
| 181 |
| 182 AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Get Target Info: Exit (ver: 0x%x type:
0x%x)\n", |
| 183 targ_info->targe
t_ver, targ_info->target_type)); |
| 184 |
| 185 return A_OK; |
| 186 } |
| 187 |
| 188 A_STATUS |
| 189 BMIReadMemory(HIF_DEVICE *device, |
| 190 A_UINT32 address, |
| 191 A_UCHAR *buffer, |
| 192 A_UINT32 length) |
| 193 { |
| 194 A_UINT32 cid; |
| 195 A_STATUS status; |
| 196 A_UINT32 offset; |
| 197 A_UINT32 remaining, rxlen; |
| 198 |
| 199 A_ASSERT(BMI_COMMAND_FITS(BMI_DATASZ_MAX + sizeof(cid) + sizeof(address) + s
izeof(length))); |
| 200 memset (pBMICmdBuf, 0, BMI_DATASZ_MAX + sizeof(cid) + sizeof(address) + size
of(length)); |
| 201 |
| 202 if (bmiDone) { |
| 203 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n")); |
| 204 return A_ERROR; |
| 205 } |
| 206 |
| 207 AR_DEBUG_PRINTF(ATH_DEBUG_BMI, |
| 208 ("BMI Read Memory: Enter (device: 0x%p, address: 0x%x, l
ength: %d)\n", |
| 209 device, address, length)); |
| 210 |
| 211 cid = BMI_READ_MEMORY; |
| 212 |
| 213 remaining = length; |
| 214 |
| 215 while (remaining) |
| 216 { |
| 217 rxlen = (remaining < BMI_DATASZ_MAX) ? remaining : BMI_DATASZ_MAX; |
| 218 offset = 0; |
| 219 A_MEMCPY(&(pBMICmdBuf[offset]), &cid, sizeof(cid)); |
| 220 offset += sizeof(cid); |
| 221 A_MEMCPY(&(pBMICmdBuf[offset]), &address, sizeof(address)); |
| 222 offset += sizeof(address); |
| 223 A_MEMCPY(&(pBMICmdBuf[offset]), &rxlen, sizeof(rxlen)); |
| 224 offset += sizeof(length); |
| 225 |
| 226 status = bmiBufferSend(device, pBMICmdBuf, offset); |
| 227 if (status != A_OK) { |
| 228 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n")); |
| 229 return A_ERROR; |
| 230 } |
| 231 status = bmiBufferReceive(device, pBMICmdBuf, rxlen, TRUE); |
| 232 if (status != A_OK) { |
| 233 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read from the device\n"))
; |
| 234 return A_ERROR; |
| 235 } |
| 236 A_MEMCPY(&buffer[length - remaining], pBMICmdBuf, rxlen); |
| 237 remaining -= rxlen; address += rxlen; |
| 238 } |
| 239 |
| 240 AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Read Memory: Exit\n")); |
| 241 return A_OK; |
| 242 } |
| 243 |
| 244 A_STATUS |
| 245 BMIWriteMemory(HIF_DEVICE *device, |
| 246 A_UINT32 address, |
| 247 A_UCHAR *buffer, |
| 248 A_UINT32 length) |
| 249 { |
| 250 A_UINT32 cid; |
| 251 A_STATUS status; |
| 252 A_UINT32 offset; |
| 253 A_UINT32 remaining, txlen; |
| 254 const A_UINT32 header = sizeof(cid) + sizeof(address) + sizeof(length); |
| 255 |
| 256 A_ASSERT(BMI_COMMAND_FITS(BMI_DATASZ_MAX + header)); |
| 257 memset (pBMICmdBuf, 0, BMI_DATASZ_MAX + header); |
| 258 |
| 259 if (bmiDone) { |
| 260 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n")); |
| 261 return A_ERROR; |
| 262 } |
| 263 |
| 264 AR_DEBUG_PRINTF(ATH_DEBUG_BMI, |
| 265 ("BMI Write Memory: Enter (device: 0x%p, address: 0x%x, length: %d)\n", |
| 266 device, address, length)); |
| 267 |
| 268 cid = BMI_WRITE_MEMORY; |
| 269 |
| 270 remaining = length; |
| 271 while (remaining) |
| 272 { |
| 273 txlen = (remaining < (BMI_DATASZ_MAX - header)) ? |
| 274 remaining : (BMI_DATASZ_MAX - header); |
| 275 offset = 0; |
| 276 A_MEMCPY(&(pBMICmdBuf[offset]), &cid, sizeof(cid)); |
| 277 offset += sizeof(cid); |
| 278 A_MEMCPY(&(pBMICmdBuf[offset]), &address, sizeof(address)); |
| 279 offset += sizeof(address); |
| 280 A_MEMCPY(&(pBMICmdBuf[offset]), &txlen, sizeof(txlen)); |
| 281 offset += sizeof(txlen); |
| 282 A_MEMCPY(&(pBMICmdBuf[offset]), &buffer[length - remaining], txlen); |
| 283 offset += txlen; |
| 284 status = bmiBufferSend(device, pBMICmdBuf, offset); |
| 285 if (status != A_OK) { |
| 286 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n")); |
| 287 return A_ERROR; |
| 288 } |
| 289 remaining -= txlen; address += txlen; |
| 290 } |
| 291 |
| 292 AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Write Memory: Exit\n")); |
| 293 |
| 294 return A_OK; |
| 295 } |
| 296 |
| 297 A_STATUS |
| 298 BMIExecute(HIF_DEVICE *device, |
| 299 A_UINT32 address, |
| 300 A_UINT32 *param) |
| 301 { |
| 302 A_UINT32 cid; |
| 303 A_STATUS status; |
| 304 A_UINT32 offset; |
| 305 |
| 306 A_ASSERT(BMI_COMMAND_FITS(sizeof(cid) + sizeof(address) + sizeof(param))); |
| 307 memset (pBMICmdBuf, 0, sizeof(cid) + sizeof(address) + sizeof(param)); |
| 308 |
| 309 if (bmiDone) { |
| 310 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n")); |
| 311 return A_ERROR; |
| 312 } |
| 313 |
| 314 AR_DEBUG_PRINTF(ATH_DEBUG_BMI, |
| 315 ("BMI Execute: Enter (device: 0x%p, address: 0x%x, param: %d)\n", |
| 316 device, address, *param)); |
| 317 |
| 318 cid = BMI_EXECUTE; |
| 319 |
| 320 offset = 0; |
| 321 A_MEMCPY(&(pBMICmdBuf[offset]), &cid, sizeof(cid)); |
| 322 offset += sizeof(cid); |
| 323 A_MEMCPY(&(pBMICmdBuf[offset]), &address, sizeof(address)); |
| 324 offset += sizeof(address); |
| 325 A_MEMCPY(&(pBMICmdBuf[offset]), param, sizeof(*param)); |
| 326 offset += sizeof(*param); |
| 327 status = bmiBufferSend(device, pBMICmdBuf, offset); |
| 328 if (status != A_OK) { |
| 329 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n")); |
| 330 return A_ERROR; |
| 331 } |
| 332 |
| 333 status = bmiBufferReceive(device, pBMICmdBuf, sizeof(*param), FALSE); |
| 334 if (status != A_OK) { |
| 335 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read from the device\n")); |
| 336 return A_ERROR; |
| 337 } |
| 338 |
| 339 A_MEMCPY(param, pBMICmdBuf, sizeof(*param)); |
| 340 |
| 341 AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Execute: Exit (param: %d)\n", *param)); |
| 342 return A_OK; |
| 343 } |
| 344 |
| 345 A_STATUS |
| 346 BMISetAppStart(HIF_DEVICE *device, |
| 347 A_UINT32 address) |
| 348 { |
| 349 A_UINT32 cid; |
| 350 A_STATUS status; |
| 351 A_UINT32 offset; |
| 352 |
| 353 A_ASSERT(BMI_COMMAND_FITS(sizeof(cid) + sizeof(address))); |
| 354 memset (pBMICmdBuf, 0, sizeof(cid) + sizeof(address)); |
| 355 |
| 356 if (bmiDone) { |
| 357 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n")); |
| 358 return A_ERROR; |
| 359 } |
| 360 |
| 361 AR_DEBUG_PRINTF(ATH_DEBUG_BMI, |
| 362 ("BMI Set App Start: Enter (device: 0x%p, address: 0x%x)\n", |
| 363 device, address)); |
| 364 |
| 365 cid = BMI_SET_APP_START; |
| 366 |
| 367 offset = 0; |
| 368 A_MEMCPY(&(pBMICmdBuf[offset]), &cid, sizeof(cid)); |
| 369 offset += sizeof(cid); |
| 370 A_MEMCPY(&(pBMICmdBuf[offset]), &address, sizeof(address)); |
| 371 offset += sizeof(address); |
| 372 status = bmiBufferSend(device, pBMICmdBuf, offset); |
| 373 if (status != A_OK) { |
| 374 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n")); |
| 375 return A_ERROR; |
| 376 } |
| 377 |
| 378 AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Set App Start: Exit\n")); |
| 379 return A_OK; |
| 380 } |
| 381 |
| 382 A_STATUS |
| 383 BMIReadSOCRegister(HIF_DEVICE *device, |
| 384 A_UINT32 address, |
| 385 A_UINT32 *param) |
| 386 { |
| 387 A_UINT32 cid; |
| 388 A_STATUS status; |
| 389 A_UINT32 offset; |
| 390 |
| 391 A_ASSERT(BMI_COMMAND_FITS(sizeof(cid) + sizeof(address))); |
| 392 memset (pBMICmdBuf, 0, sizeof(cid) + sizeof(address)); |
| 393 |
| 394 if (bmiDone) { |
| 395 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n")); |
| 396 return A_ERROR; |
| 397 } |
| 398 |
| 399 AR_DEBUG_PRINTF(ATH_DEBUG_BMI, |
| 400 ("BMI Read SOC Register: Enter (device: 0x%p, address: 0x%x)\n", |
| 401 device, address)); |
| 402 |
| 403 cid = BMI_READ_SOC_REGISTER; |
| 404 |
| 405 offset = 0; |
| 406 A_MEMCPY(&(pBMICmdBuf[offset]), &cid, sizeof(cid)); |
| 407 offset += sizeof(cid); |
| 408 A_MEMCPY(&(pBMICmdBuf[offset]), &address, sizeof(address)); |
| 409 offset += sizeof(address); |
| 410 |
| 411 status = bmiBufferSend(device, pBMICmdBuf, offset); |
| 412 if (status != A_OK) { |
| 413 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n")); |
| 414 return A_ERROR; |
| 415 } |
| 416 |
| 417 status = bmiBufferReceive(device, pBMICmdBuf, sizeof(*param), TRUE); |
| 418 if (status != A_OK) { |
| 419 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read from the device\n")); |
| 420 return A_ERROR; |
| 421 } |
| 422 A_MEMCPY(param, pBMICmdBuf, sizeof(*param)); |
| 423 |
| 424 AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Read SOC Register: Exit (value: %d)\n",
*param)); |
| 425 return A_OK; |
| 426 } |
| 427 |
| 428 A_STATUS |
| 429 BMIWriteSOCRegister(HIF_DEVICE *device, |
| 430 A_UINT32 address, |
| 431 A_UINT32 param) |
| 432 { |
| 433 A_UINT32 cid; |
| 434 A_STATUS status; |
| 435 A_UINT32 offset; |
| 436 |
| 437 A_ASSERT(BMI_COMMAND_FITS(sizeof(cid) + sizeof(address) + sizeof(param))); |
| 438 memset (pBMICmdBuf, 0, sizeof(cid) + sizeof(address) + sizeof(param)); |
| 439 |
| 440 if (bmiDone) { |
| 441 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n")); |
| 442 return A_ERROR; |
| 443 } |
| 444 |
| 445 AR_DEBUG_PRINTF(ATH_DEBUG_BMI, |
| 446 ("BMI Write SOC Register: Enter (device: 0x%p, address: 0x%x, param: %d)\n"
, |
| 447 device, address, param)); |
| 448 |
| 449 cid = BMI_WRITE_SOC_REGISTER; |
| 450 |
| 451 offset = 0; |
| 452 A_MEMCPY(&(pBMICmdBuf[offset]), &cid, sizeof(cid)); |
| 453 offset += sizeof(cid); |
| 454 A_MEMCPY(&(pBMICmdBuf[offset]), &address, sizeof(address)); |
| 455 offset += sizeof(address); |
| 456 A_MEMCPY(&(pBMICmdBuf[offset]), ¶m, sizeof(param)); |
| 457 offset += sizeof(param); |
| 458 status = bmiBufferSend(device, pBMICmdBuf, offset); |
| 459 if (status != A_OK) { |
| 460 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n")); |
| 461 return A_ERROR; |
| 462 } |
| 463 |
| 464 AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Read SOC Register: Exit\n")); |
| 465 return A_OK; |
| 466 } |
| 467 |
| 468 A_STATUS |
| 469 BMIrompatchInstall(HIF_DEVICE *device, |
| 470 A_UINT32 ROM_addr, |
| 471 A_UINT32 RAM_addr, |
| 472 A_UINT32 nbytes, |
| 473 A_UINT32 do_activate, |
| 474 A_UINT32 *rompatch_id) |
| 475 { |
| 476 A_UINT32 cid; |
| 477 A_STATUS status; |
| 478 A_UINT32 offset; |
| 479 |
| 480 A_ASSERT(BMI_COMMAND_FITS(sizeof(cid) + sizeof(ROM_addr) + sizeof(RAM_addr)
+ |
| 481 sizeof(nbytes) + sizeof(do_activate))); |
| 482 memset(pBMICmdBuf, 0, sizeof(cid) + sizeof(ROM_addr) + sizeof(RAM_addr) + |
| 483 sizeof(nbytes) + sizeof(do_activate)); |
| 484 |
| 485 if (bmiDone) { |
| 486 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n")); |
| 487 return A_ERROR; |
| 488 } |
| 489 |
| 490 AR_DEBUG_PRINTF(ATH_DEBUG_BMI, |
| 491 ("BMI rompatch Install: Enter (device: 0x%p, ROMaddr: 0x%x, RAMaddr: 0x
%x length: %d activate: %d)\n", |
| 492 device, ROM_addr, RAM_addr, nbytes, do_activate)); |
| 493 |
| 494 cid = BMI_ROMPATCH_INSTALL; |
| 495 |
| 496 offset = 0; |
| 497 A_MEMCPY(&(pBMICmdBuf[offset]), &cid, sizeof(cid)); |
| 498 offset += sizeof(cid); |
| 499 A_MEMCPY(&(pBMICmdBuf[offset]), &ROM_addr, sizeof(ROM_addr)); |
| 500 offset += sizeof(ROM_addr); |
| 501 A_MEMCPY(&(pBMICmdBuf[offset]), &RAM_addr, sizeof(RAM_addr)); |
| 502 offset += sizeof(RAM_addr); |
| 503 A_MEMCPY(&(pBMICmdBuf[offset]), &nbytes, sizeof(nbytes)); |
| 504 offset += sizeof(nbytes); |
| 505 A_MEMCPY(&(pBMICmdBuf[offset]), &do_activate, sizeof(do_activate)); |
| 506 offset += sizeof(do_activate); |
| 507 status = bmiBufferSend(device, pBMICmdBuf, offset); |
| 508 if (status != A_OK) { |
| 509 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n")); |
| 510 return A_ERROR; |
| 511 } |
| 512 |
| 513 status = bmiBufferReceive(device, pBMICmdBuf, sizeof(*rompatch_id), TRUE); |
| 514 if (status != A_OK) { |
| 515 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read from the device\n")); |
| 516 return A_ERROR; |
| 517 } |
| 518 A_MEMCPY(rompatch_id, pBMICmdBuf, sizeof(*rompatch_id)); |
| 519 |
| 520 AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI rompatch Install: (rompatch_id=%d)\n",
*rompatch_id)); |
| 521 return A_OK; |
| 522 } |
| 523 |
| 524 A_STATUS |
| 525 BMIrompatchUninstall(HIF_DEVICE *device, |
| 526 A_UINT32 rompatch_id) |
| 527 { |
| 528 A_UINT32 cid; |
| 529 A_STATUS status; |
| 530 A_UINT32 offset; |
| 531 |
| 532 A_ASSERT(BMI_COMMAND_FITS(sizeof(cid) + sizeof(rompatch_id))); |
| 533 memset (pBMICmdBuf, 0, sizeof(cid) + sizeof(rompatch_id)); |
| 534 |
| 535 if (bmiDone) { |
| 536 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n")); |
| 537 return A_ERROR; |
| 538 } |
| 539 |
| 540 AR_DEBUG_PRINTF(ATH_DEBUG_BMI, |
| 541 ("BMI rompatch Uninstall: Enter (device: 0x%p, rompatch_id: %d)\n", |
| 542 device,
rompatch_id)); |
| 543 |
| 544 cid = BMI_ROMPATCH_UNINSTALL; |
| 545 |
| 546 offset = 0; |
| 547 A_MEMCPY(&(pBMICmdBuf[offset]), &cid, sizeof(cid)); |
| 548 offset += sizeof(cid); |
| 549 A_MEMCPY(&(pBMICmdBuf[offset]), &rompatch_id, sizeof(rompatch_id)); |
| 550 offset += sizeof(rompatch_id); |
| 551 status = bmiBufferSend(device, pBMICmdBuf, offset); |
| 552 if (status != A_OK) { |
| 553 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n")); |
| 554 return A_ERROR; |
| 555 } |
| 556 |
| 557 AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI rompatch UNinstall: (rompatch_id=0x%x)\
n", rompatch_id)); |
| 558 return A_OK; |
| 559 } |
| 560 |
| 561 static A_STATUS |
| 562 _BMIrompatchChangeActivation(HIF_DEVICE *device, |
| 563 A_UINT32 rompatch_count, |
| 564 A_UINT32 *rompatch_list, |
| 565 A_UINT32 do_activate) |
| 566 { |
| 567 A_UINT32 cid; |
| 568 A_STATUS status; |
| 569 A_UINT32 offset; |
| 570 A_UINT32 length; |
| 571 |
| 572 A_ASSERT(BMI_COMMAND_FITS(BMI_DATASZ_MAX + sizeof(cid) + sizeof(rompatch_cou
nt))); |
| 573 memset(pBMICmdBuf, 0, BMI_DATASZ_MAX + sizeof(cid) + sizeof(rompatch_count))
; |
| 574 |
| 575 if (bmiDone) { |
| 576 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n")); |
| 577 return A_ERROR; |
| 578 } |
| 579 |
| 580 AR_DEBUG_PRINTF(ATH_DEBUG_BMI, |
| 581 ("BMI Change rompatch Activation: Enter (device: 0x%p, count: %d)\n", |
| 582 device, rompatch_count)); |
| 583 |
| 584 cid = do_activate ? BMI_ROMPATCH_ACTIVATE : BMI_ROMPATCH_DEACTIVATE; |
| 585 |
| 586 offset = 0; |
| 587 A_MEMCPY(&(pBMICmdBuf[offset]), &cid, sizeof(cid)); |
| 588 offset += sizeof(cid); |
| 589 A_MEMCPY(&(pBMICmdBuf[offset]), &rompatch_count, sizeof(rompatch_count)); |
| 590 offset += sizeof(rompatch_count); |
| 591 length = rompatch_count * sizeof(*rompatch_list); |
| 592 A_MEMCPY(&(pBMICmdBuf[offset]), rompatch_list, length); |
| 593 offset += length; |
| 594 status = bmiBufferSend(device, pBMICmdBuf, offset); |
| 595 if (status != A_OK) { |
| 596 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n")); |
| 597 return A_ERROR; |
| 598 } |
| 599 |
| 600 AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Change rompatch Activation: Exit\n")); |
| 601 |
| 602 return A_OK; |
| 603 } |
| 604 |
| 605 A_STATUS |
| 606 BMIrompatchActivate(HIF_DEVICE *device, |
| 607 A_UINT32 rompatch_count, |
| 608 A_UINT32 *rompatch_list) |
| 609 { |
| 610 return _BMIrompatchChangeActivation(device, rompatch_count, rompatch_list, 1
); |
| 611 } |
| 612 |
| 613 A_STATUS |
| 614 BMIrompatchDeactivate(HIF_DEVICE *device, |
| 615 A_UINT32 rompatch_count, |
| 616 A_UINT32 *rompatch_list) |
| 617 { |
| 618 return _BMIrompatchChangeActivation(device, rompatch_count, rompatch_list, 0
); |
| 619 } |
| 620 |
| 621 A_STATUS |
| 622 BMILZData(HIF_DEVICE *device, |
| 623 A_UCHAR *buffer, |
| 624 A_UINT32 length) |
| 625 { |
| 626 A_UINT32 cid; |
| 627 A_STATUS status; |
| 628 A_UINT32 offset; |
| 629 A_UINT32 remaining, txlen; |
| 630 const A_UINT32 header = sizeof(cid) + sizeof(length); |
| 631 |
| 632 A_ASSERT(BMI_COMMAND_FITS(BMI_DATASZ_MAX+header)); |
| 633 memset (pBMICmdBuf, 0, BMI_DATASZ_MAX+header); |
| 634 |
| 635 if (bmiDone) { |
| 636 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n")); |
| 637 return A_ERROR; |
| 638 } |
| 639 |
| 640 AR_DEBUG_PRINTF(ATH_DEBUG_BMI, |
| 641 ("BMI Send LZ Data: Enter (device: 0x%p, length: %d)\n", |
| 642 device, length)); |
| 643 |
| 644 cid = BMI_LZ_DATA; |
| 645 |
| 646 remaining = length; |
| 647 while (remaining) |
| 648 { |
| 649 txlen = (remaining < (BMI_DATASZ_MAX - header)) ? |
| 650 remaining : (BMI_DATASZ_MAX - header); |
| 651 offset = 0; |
| 652 A_MEMCPY(&(pBMICmdBuf[offset]), &cid, sizeof(cid)); |
| 653 offset += sizeof(cid); |
| 654 A_MEMCPY(&(pBMICmdBuf[offset]), &txlen, sizeof(txlen)); |
| 655 offset += sizeof(txlen); |
| 656 A_MEMCPY(&(pBMICmdBuf[offset]), &buffer[length - remaining], txlen); |
| 657 offset += txlen; |
| 658 status = bmiBufferSend(device, pBMICmdBuf, offset); |
| 659 if (status != A_OK) { |
| 660 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n")); |
| 661 return A_ERROR; |
| 662 } |
| 663 remaining -= txlen; |
| 664 } |
| 665 |
| 666 AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI LZ Data: Exit\n")); |
| 667 |
| 668 return A_OK; |
| 669 } |
| 670 |
| 671 A_STATUS |
| 672 BMILZStreamStart(HIF_DEVICE *device, |
| 673 A_UINT32 address) |
| 674 { |
| 675 A_UINT32 cid; |
| 676 A_STATUS status; |
| 677 A_UINT32 offset; |
| 678 |
| 679 A_ASSERT(BMI_COMMAND_FITS(sizeof(cid) + sizeof(address))); |
| 680 memset (pBMICmdBuf, 0, sizeof(cid) + sizeof(address)); |
| 681 |
| 682 if (bmiDone) { |
| 683 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n")); |
| 684 return A_ERROR; |
| 685 } |
| 686 |
| 687 AR_DEBUG_PRINTF(ATH_DEBUG_BMI, |
| 688 ("BMI LZ Stream Start: Enter (device: 0x%p, address: 0x%x)\n", |
| 689 device, address)); |
| 690 |
| 691 cid = BMI_LZ_STREAM_START; |
| 692 offset = 0; |
| 693 A_MEMCPY(&(pBMICmdBuf[offset]), &cid, sizeof(cid)); |
| 694 offset += sizeof(cid); |
| 695 A_MEMCPY(&(pBMICmdBuf[offset]), &address, sizeof(address)); |
| 696 offset += sizeof(address); |
| 697 status = bmiBufferSend(device, pBMICmdBuf, offset); |
| 698 if (status != A_OK) { |
| 699 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to Start LZ Stream to the device
\n")); |
| 700 return A_ERROR; |
| 701 } |
| 702 |
| 703 AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI LZ Stream Start: Exit\n")); |
| 704 |
| 705 return A_OK; |
| 706 } |
| 707 |
| 708 /* BMI Access routines */ |
| 709 A_STATUS |
| 710 bmiBufferSend(HIF_DEVICE *device, |
| 711 A_UCHAR *buffer, |
| 712 A_UINT32 length) |
| 713 { |
| 714 A_STATUS status; |
| 715 A_UINT32 timeout; |
| 716 A_UINT32 address; |
| 717 A_UINT32 mboxAddress[HTC_MAILBOX_NUM_MAX]; |
| 718 |
| 719 HIFConfigureDevice(device, HIF_DEVICE_GET_MBOX_ADDR, |
| 720 &mboxAddress[0], sizeof(mboxAddress)); |
| 721 |
| 722 *pBMICmdCredits = 0; |
| 723 timeout = BMI_COMMUNICATION_TIMEOUT; |
| 724 |
| 725 while(timeout-- && !(*pBMICmdCredits)) { |
| 726 /* Read the counter register to get the command credits */ |
| 727 address = COUNT_DEC_ADDRESS + (HTC_MAILBOX_NUM_MAX + ENDPOINT1) * 4; |
| 728 /* hit the credit counter with a 4-byte access, the first byte read will
hit the counter and cause |
| 729 * a decrement, while the remaining 3 bytes has no effect. The rational
e behind this is to |
| 730 * make all HIF accesses 4-byte aligned */ |
| 731 status = HIFReadWrite(device, address, (A_UINT8 *)pBMICmdCredits, 4, |
| 732 HIF_RD_SYNC_BYTE_INC, NULL); |
| 733 if (status != A_OK) { |
| 734 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to decrement the command cre
dit count register\n")); |
| 735 return A_ERROR; |
| 736 } |
| 737 /* the counter is only 8=bits, ignore anything in the upper 3 bytes */ |
| 738 (*pBMICmdCredits) &= 0xFF; |
| 739 } |
| 740 |
| 741 if (*pBMICmdCredits) { |
| 742 address = mboxAddress[ENDPOINT1]; |
| 743 status = HIFReadWrite(device, address, buffer, length, |
| 744 HIF_WR_SYNC_BYTE_INC, NULL); |
| 745 if (status != A_OK) { |
| 746 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to send the BMI data to the
device\n")); |
| 747 return A_ERROR; |
| 748 } |
| 749 } else { |
| 750 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMI Communication timeout - bmiBufferSe
nd\n")); |
| 751 return A_ERROR; |
| 752 } |
| 753 |
| 754 return status; |
| 755 } |
| 756 |
| 757 A_STATUS |
| 758 bmiBufferReceive(HIF_DEVICE *device, |
| 759 A_UCHAR *buffer, |
| 760 A_UINT32 length, |
| 761 A_BOOL want_timeout) |
| 762 { |
| 763 A_STATUS status; |
| 764 A_UINT32 address; |
| 765 A_UINT32 mboxAddress[HTC_MAILBOX_NUM_MAX]; |
| 766 HIF_PENDING_EVENTS_INFO hifPendingEvents; |
| 767 static HIF_PENDING_EVENTS_FUNC getPendingEventsFunc = NULL; |
| 768 |
| 769 if (!pendingEventsFuncCheck) { |
| 770 /* see if the HIF layer implements an alternative function to get pe
nding events |
| 771 * do this only once! */ |
| 772 HIFConfigureDevice(device, |
| 773 HIF_DEVICE_GET_PENDING_EVENTS_FUNC, |
| 774 &getPendingEventsFunc, |
| 775 sizeof(getPendingEventsFunc)); |
| 776 pendingEventsFuncCheck = TRUE; |
| 777 } |
| 778 |
| 779 HIFConfigureDevice(device, HIF_DEVICE_GET_MBOX_ADDR, |
| 780 &mboxAddress[0], sizeof(mboxAddress)); |
| 781 |
| 782 /* |
| 783 * During normal bootup, small reads may be required. |
| 784 * Rather than issue an HIF Read and then wait as the Target |
| 785 * adds successive bytes to the FIFO, we wait here until |
| 786 * we know that response data is available. |
| 787 * |
| 788 * This allows us to cleanly timeout on an unexpected |
| 789 * Target failure rather than risk problems at the HIF level. In |
| 790 * particular, this avoids SDIO timeouts and possibly garbage |
| 791 * data on some host controllers. And on an interconnect |
| 792 * such as Compact Flash (as well as some SDIO masters) which |
| 793 * does not provide any indication on data timeout, it avoids |
| 794 * a potential hang or garbage response. |
| 795 * |
| 796 * Synchronization is more difficult for reads larger than the |
| 797 * size of the MBOX FIFO (128B), because the Target is unable |
| 798 * to push the 129th byte of data until AFTER the Host posts an |
| 799 * HIF Read and removes some FIFO data. So for large reads the |
| 800 * Host proceeds to post an HIF Read BEFORE all the data is |
| 801 * actually available to read. Fortunately, large BMI reads do |
| 802 * not occur in practice -- they're supported for debug/development. |
| 803 * |
| 804 * So Host/Target BMI synchronization is divided into these cases: |
| 805 * CASE 1: length < 4 |
| 806 * Should not happen |
| 807 * |
| 808 * CASE 2: 4 <= length <= 128 |
| 809 * Wait for first 4 bytes to be in FIFO |
| 810 * If CONSERVATIVE_BMI_READ is enabled, also wait for |
| 811 * a BMI command credit, which indicates that the ENTIRE |
| 812 * response is available in the the FIFO |
| 813 * |
| 814 * CASE 3: length > 128 |
| 815 * Wait for the first 4 bytes to be in FIFO |
| 816 * |
| 817 * For most uses, a small timeout should be sufficient and we will |
| 818 * usually see a response quickly; but there may be some unusual |
| 819 * (debug) cases of BMI_EXECUTE where we want an larger timeout. |
| 820 * For now, we use an unbounded busy loop while waiting for |
| 821 * BMI_EXECUTE. |
| 822 * |
| 823 * If BMI_EXECUTE ever needs to support longer-latency execution, |
| 824 * especially in production, this code needs to be enhanced to sleep |
| 825 * and yield. Also note that BMI_COMMUNICATION_TIMEOUT is currently |
| 826 * a function of Host processor speed. |
| 827 */ |
| 828 if (length >= 4) { /* NB: Currently, always true */ |
| 829 /* |
| 830 * NB: word_available is declared static for esoteric reasons |
| 831 * having to do with protection on some OSes. |
| 832 */ |
| 833 static A_UINT32 word_available; |
| 834 A_UINT32 timeout; |
| 835 |
| 836 word_available = 0; |
| 837 timeout = BMI_COMMUNICATION_TIMEOUT; |
| 838 while((!want_timeout || timeout--) && !word_available) { |
| 839 |
| 840 if (getPendingEventsFunc != NULL) { |
| 841 status = getPendingEventsFunc(device, |
| 842 &hifPendingEvents, |
| 843 NULL); |
| 844 if (status != A_OK) { |
| 845 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BMI: Failed to get pending e
vents \n")); |
| 846 break; |
| 847 } |
| 848 |
| 849 if (hifPendingEvents.AvailableRecvBytes >= sizeof(A_UINT32)) { |
| 850 word_available = 1; |
| 851 } |
| 852 continue; |
| 853 } |
| 854 |
| 855 status = HIFReadWrite(device, RX_LOOKAHEAD_VALID_ADDRESS, (A_UINT8 *
)&word_available, |
| 856 sizeof(word_available), HIF_RD_SYNC_BYTE_INC, NULL); |
| 857 if (status != A_OK) { |
| 858 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read RX_LOOKAHEAD_VAL
ID register\n")); |
| 859 return A_ERROR; |
| 860 } |
| 861 /* We did a 4-byte read to the same register; all we really want is
one bit */ |
| 862 word_available &= (1 << ENDPOINT1); |
| 863 } |
| 864 |
| 865 if (!word_available) { |
| 866 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMI Communication timeout - bmiBuff
erReceive FIFO empty\n")); |
| 867 return A_ERROR; |
| 868 } |
| 869 } |
| 870 |
| 871 #define CONSERVATIVE_BMI_READ 0 |
| 872 #if CONSERVATIVE_BMI_READ |
| 873 /* |
| 874 * This is an extra-conservative CREDIT check. It guarantees |
| 875 * that ALL data is available in the FIFO before we start to |
| 876 * read from the interconnect. |
| 877 * |
| 878 * This credit check is useless when firmware chooses to |
| 879 * allow multiple outstanding BMI Command Credits, since the next |
| 880 * credit will already be present. To restrict the Target to one |
| 881 * BMI Command Credit, see HI_OPTION_BMI_CRED_LIMIT. |
| 882 * |
| 883 * And for large reads (when HI_OPTION_BMI_CRED_LIMIT is set) |
| 884 * we cannot wait for the next credit because the Target's FIFO |
| 885 * will not hold the entire response. So we need the Host to |
| 886 * start to empty the FIFO sooner. (And again, large reads are |
| 887 * not used in practice; they are for debug/development only.) |
| 888 * |
| 889 * For a more conservative Host implementation (which would be |
| 890 * safer for a Compact Flash interconnect): |
| 891 * Set CONSERVATIVE_BMI_READ (above) to 1 |
| 892 * Set HI_OPTION_BMI_CRED_LIMIT and |
| 893 * reduce BMI_DATASZ_MAX to 32 or 64 |
| 894 */ |
| 895 if ((length > 4) && (length < 128)) { /* check against MBOX FIFO size */ |
| 896 A_UINT32 timeout; |
| 897 |
| 898 *pBMICmdCredits = 0; |
| 899 timeout = BMI_COMMUNICATION_TIMEOUT; |
| 900 while((!want_timeout || timeout--) && !(*pBMICmdCredits) { |
| 901 /* Read the counter register to get the command credits */ |
| 902 address = COUNT_ADDRESS + (HTC_MAILBOX_NUM_MAX + ENDPOINT1) * 1; |
| 903 /* read the counter using a 4-byte read. Since the counter is NOT a
uto-decrementing, |
| 904 * we can read this counter multiple times using a non-incrementing
address mode. |
| 905 * The rationale here is to make all HIF accesses a multiple of 4 by
tes */ |
| 906 status = HIFReadWrite(device, address, (A_UINT8 *)pBMICmdCredits, si
zeof(*pBMICmdCredits), |
| 907 HIF_RD_SYNC_BYTE_FIX, NULL); |
| 908 if (status != A_OK) { |
| 909 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read the command cred
it count register\n")); |
| 910 return A_ERROR; |
| 911 } |
| 912 /* we did a 4-byte read to the same count register so mask off u
pper bytes */ |
| 913 (*pBMICmdCredits) &= 0xFF; |
| 914 } |
| 915 |
| 916 if (!(*pBMICmdCredits)) { |
| 917 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMI Communication timeout- bmiBuffe
rReceive no credit\n")); |
| 918 return A_ERROR; |
| 919 } |
| 920 } |
| 921 #endif |
| 922 |
| 923 address = mboxAddress[ENDPOINT1]; |
| 924 status = HIFReadWrite(device, address, buffer, length, HIF_RD_SYNC_BYTE_INC,
NULL); |
| 925 if (status != A_OK) { |
| 926 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read the BMI data from the de
vice\n")); |
| 927 return A_ERROR; |
| 928 } |
| 929 |
| 930 return A_OK; |
| 931 } |
| 932 |
| 933 A_STATUS |
| 934 BMIFastDownload(HIF_DEVICE *device, A_UINT32 address, A_UCHAR *buffer, A_UINT32
length) |
| 935 { |
| 936 A_STATUS status = A_ERROR; |
| 937 A_UINT32 lastWord = 0; |
| 938 A_UINT32 lastWordOffset = length & ~0x3; |
| 939 A_UINT32 unalignedBytes = length & 0x3; |
| 940 |
| 941 status = BMILZStreamStart (device, address); |
| 942 if (A_FAILED(status)) { |
| 943 return A_ERROR; |
| 944 } |
| 945 |
| 946 if (unalignedBytes) { |
| 947 /* copy the last word into a zero padded buffer */ |
| 948 A_MEMCPY(&lastWord, &buffer[lastWordOffset], unalignedBytes); |
| 949 } |
| 950 |
| 951 status = BMILZData(device, buffer, lastWordOffset); |
| 952 |
| 953 if (A_FAILED(status)) { |
| 954 return A_ERROR; |
| 955 } |
| 956 |
| 957 if (unalignedBytes) { |
| 958 status = BMILZData(device, (A_UINT8 *)&lastWord, 4); |
| 959 } |
| 960 |
| 961 if (A_SUCCESS(status)) { |
| 962 // |
| 963 // Close compressed stream and open a new (fake) one. This serves mainl
y to flush Target caches. |
| 964 // |
| 965 status = BMILZStreamStart (device, 0x00); |
| 966 if (A_FAILED(status)) { |
| 967 return A_ERROR; |
| 968 } |
| 969 } |
| 970 return status; |
| 971 } |
| 972 |
| 973 A_STATUS |
| 974 BMIRawWrite(HIF_DEVICE *device, A_UCHAR *buffer, A_UINT32 length) |
| 975 { |
| 976 return bmiBufferSend(device, buffer, length); |
| 977 } |
| 978 |
| 979 A_STATUS |
| 980 BMIRawRead(HIF_DEVICE *device, A_UCHAR *buffer, A_UINT32 length, A_BOOL want_tim
eout) |
| 981 { |
| 982 return bmiBufferReceive(device, buffer, length, want_timeout); |
| 983 } |
OLD | NEW |