~ubuntu-branches/ubuntu/natty/linux-backports-modules-2.6.38/natty-proposed

« back to all changes in this revision

Viewing changes to updates/compat-wireless-2.6.37/drivers/staging/ath6kl/bmi/src/bmi.c

  • Committer: Bazaar Package Importer
  • Author(s): Tim Gardner, Tim Gardner
  • Date: 2011-06-08 10:44:09 UTC
  • Revision ID: james.westby@ubuntu.com-20110608104409-fnl8carkdo15bwsz
Tags: 2.6.38-10.6
[ Tim Gardner ]

Shorten compat-wireless package name to cw to accomodate
CDROM file name length restrictions.

Show diffs side-by-side

added added

removed removed

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