staging/ft1000-usb: fix problems found by sparse
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / drivers / staging / ft1000 / ft1000-usb / ft1000_download.c
blobba07d5d85045fac3e36c5468eb00cfce15708499
1 //=====================================================
2 // CopyRight (C) 2007 Qualcomm Inc. All Rights Reserved.
3 //
4 //
5 // This file is part of Express Card USB Driver
6 //
7 // $Id:
8 //====================================================
9 // 20090926; aelias; removed compiler warnings; ubuntu 9.04; 2.6.28-15-generic
11 #include <linux/init.h>
12 #include <linux/kernel.h>
13 #include <linux/module.h>
14 #include <linux/netdevice.h>
15 #include <linux/etherdevice.h>
16 #include <linux/usb.h>
17 #include <linux/vmalloc.h>
18 #include "ft1000_usb.h"
20 #define FIFO_DNLD 1
22 #define DWNLD_HANDSHAKE_LOC 0x02
23 #define DWNLD_TYPE_LOC 0x04
24 #define DWNLD_SIZE_MSW_LOC 0x06
25 #define DWNLD_SIZE_LSW_LOC 0x08
26 #define DWNLD_PS_HDR_LOC 0x0A
28 #define MAX_DSP_WAIT_LOOPS 40
29 #define DSP_WAIT_SLEEP_TIME 1000 /* 1 millisecond */
30 #define DSP_WAIT_DISPATCH_LVL 50 /* 50 usec */
32 #define HANDSHAKE_TIMEOUT_VALUE 0xF1F1
33 #define HANDSHAKE_RESET_VALUE 0xFEFE /* When DSP requests startover */
34 #define HANDSHAKE_RESET_VALUE_USB 0xFE7E /* When DSP requests startover */
35 #define HANDSHAKE_DSP_BL_READY 0xFEFE /* At start DSP writes this when bootloader ready */
36 #define HANDSHAKE_DSP_BL_READY_USB 0xFE7E /* At start DSP writes this when bootloader ready */
37 #define HANDSHAKE_DRIVER_READY 0xFFFF /* Driver writes after receiving 0xFEFE */
38 #define HANDSHAKE_SEND_DATA 0x0000 /* DSP writes this when ready for more data */
40 #define HANDSHAKE_REQUEST 0x0001 /* Request from DSP */
41 #define HANDSHAKE_RESPONSE 0x0000 /* Satisfied DSP request */
43 #define REQUEST_CODE_LENGTH 0x0000
44 #define REQUEST_RUN_ADDRESS 0x0001
45 #define REQUEST_CODE_SEGMENT 0x0002 /* In WORD count */
46 #define REQUEST_DONE_BL 0x0003
47 #define REQUEST_DONE_CL 0x0004
48 #define REQUEST_VERSION_INFO 0x0005
49 #define REQUEST_CODE_BY_VERSION 0x0006
50 #define REQUEST_MAILBOX_DATA 0x0007
51 #define REQUEST_FILE_CHECKSUM 0x0008
53 #define STATE_START_DWNLD 0x01
54 #define STATE_BOOT_DWNLD 0x02
55 #define STATE_CODE_DWNLD 0x03
56 #define STATE_DONE_DWNLD 0x04
57 #define STATE_SECTION_PROV 0x05
58 #define STATE_DONE_PROV 0x06
59 #define STATE_DONE_FILE 0x07
61 #define MAX_LENGTH 0x7f0
63 // Temporary download mechanism for Magnemite
64 #define DWNLD_MAG_TYPE_LOC 0x00
65 #define DWNLD_MAG_LEN_LOC 0x01
66 #define DWNLD_MAG_ADDR_LOC 0x02
67 #define DWNLD_MAG_CHKSUM_LOC 0x03
68 #define DWNLD_MAG_VAL_LOC 0x04
70 #define HANDSHAKE_MAG_DSP_BL_READY 0xFEFE0000 /* At start DSP writes this when bootloader ready */
71 #define HANDSHAKE_MAG_DSP_ENTRY 0x01000000 /* Dsp writes this to request for entry address */
72 #define HANDSHAKE_MAG_DSP_DATA 0x02000000 /* Dsp writes this to request for data block */
73 #define HANDSHAKE_MAG_DSP_DONE 0x03000000 /* Dsp writes this to indicate download done */
75 #define HANDSHAKE_MAG_DRV_READY 0xFFFF0000 /* Driver writes this to indicate ready to download */
76 #define HANDSHAKE_MAG_DRV_DATA 0x02FECDAB /* Driver writes this to indicate data available to DSP */
77 #define HANDSHAKE_MAG_DRV_ENTRY 0x01FECDAB /* Driver writes this to indicate entry point to DSP */
79 #define HANDSHAKE_MAG_TIMEOUT_VALUE 0xF1F1
82 // New Magnemite downloader
83 #define DWNLD_MAG1_HANDSHAKE_LOC 0x00
84 #define DWNLD_MAG1_TYPE_LOC 0x01
85 #define DWNLD_MAG1_SIZE_LOC 0x02
86 #define DWNLD_MAG1_PS_HDR_LOC 0x03
88 #pragma pack (push, pack_save, 1)
89 typedef struct _DSP_FILE_HDR {
90 long build_date;
91 long dsp_coff_date;
92 long loader_code_address;
93 long loader_code_size;
94 long loader_code_end;
95 long dsp_code_address;
96 long dsp_code_size;
97 long dsp_code_end;
98 long reserved[8];
99 } DSP_FILE_HDR, *PDSP_FILE_HDR;
101 typedef struct _DSP_FILE_HDR_5 {
102 long version_id; // Version ID of this image format.
103 long package_id; // Package ID of code release.
104 long build_date; // Date/time stamp when file was built.
105 long commands_offset; // Offset to attached commands in Pseudo Hdr format.
106 long loader_offset; // Offset to bootloader code.
107 long loader_code_address; // Start address of bootloader.
108 long loader_code_end; // Where bootloader code ends.
109 long loader_code_size;
110 long version_data_offset; // Offset were scrambled version data begins.
111 long version_data_size; // Size, in words, of scrambled version data.
112 long nDspImages; // Number of DSP images in file.
113 } DSP_FILE_HDR_5, * PDSP_FILE_HDR_5;
115 typedef struct _DSP_IMAGE_INFO {
116 long coff_date; // Date/time when DSP Coff image was built.
117 long begin_offset; // Offset in file where image begins.
118 long end_offset; // Offset in file where image begins.
119 long run_address; // On chip Start address of DSP code.
120 long image_size; // Size of image.
121 long version; // Embedded version # of DSP code.
122 } DSP_IMAGE_INFO, *PDSP_IMAGE_INFO;
124 typedef struct _DSP_IMAGE_INFO_V6 {
125 long coff_date; // Date/time when DSP Coff image was built.
126 long begin_offset; // Offset in file where image begins.
127 long end_offset; // Offset in file where image begins.
128 long run_address; // On chip Start address of DSP code.
129 long image_size; // Size of image.
130 long version; // Embedded version # of DSP code.
131 unsigned short checksum; // DSP File checksum
132 unsigned short pad1;
133 } DSP_IMAGE_INFO_V6, *PDSP_IMAGE_INFO_V6;
136 //---------------------------------------------------------------------------
137 // Function: getfw
139 // Parameters: char *fn - input DSP image file name
140 // int *pimgsz - output DSP image file size
141 // Returns: DSP image buffer
143 // Description: Read the DSP image file into a char buffer
145 // Notes:
147 //---------------------------------------------------------------------------
148 char *getfw (char *fn, size_t *pimgsz)
150 struct file *fd;
151 mm_segment_t fs = get_fs();
152 loff_t pos;
153 char *pfwimg;
154 int fwimgsz;
156 set_fs(get_ds());
158 fd = filp_open(fn, 0, 0);
159 if ( IS_ERR(fd) )
161 DEBUG("FT1000:%s:can not open dsp image\n", __FUNCTION__);
162 set_fs(fs);
163 return NULL;
166 fwimgsz = i_size_read(fd->f_dentry->d_inode);
167 *pimgsz = fwimgsz;
169 if (fwimgsz <= 0)
171 DEBUG("FT1000:%s:invalid file size\n", __FUNCTION__);
172 filp_close(fd, current->files);
173 set_fs(fs);
174 return NULL;
176 pfwimg = (char*)vmalloc ( fwimgsz );
177 if (pfwimg == NULL) {
178 DEBUG("FT1000:%s:can not allocate memory for dsp image\n", __FUNCTION__);
179 filp_close(fd, current->files);
180 set_fs(fs);
181 return NULL;
183 pos = 0;
184 if (vfs_read(fd, (void __user __force*)pfwimg, fwimgsz, &pos) != fwimgsz) {
185 vfree(pfwimg);
186 DEBUG("FT1000:%s:failed to read firmware image\n",__FUNCTION__);
187 filp_close(fd, current->files);
188 set_fs(fs);
189 return NULL;
192 filp_close(fd, current->files);
193 set_fs(fs);
195 return pfwimg;
198 //---------------------------------------------------------------------------
199 // Function: check_usb_db
201 // Parameters: struct ft1000_device - device structure
203 // Returns: 0 - success
205 // Description: This function checks if the doorbell register is cleared
207 // Notes:
209 //---------------------------------------------------------------------------
210 static ULONG check_usb_db (struct ft1000_device *ft1000dev)
212 int loopcnt;
213 USHORT temp;
214 ULONG status;
216 loopcnt = 0;
217 while (loopcnt < 10)
220 status = ft1000_read_register (ft1000dev, &temp, FT1000_REG_DOORBELL);
221 DEBUG("check_usb_db: read FT1000_REG_DOORBELL value is %x\n", temp);
222 if (temp & 0x0080)
224 DEBUG("FT1000:Got checkusb doorbell\n");
225 status = ft1000_write_register (ft1000dev, 0x0080, FT1000_REG_DOORBELL);
226 #if FIFO_DNLD
227 status = ft1000_write_register (ft1000dev, 0x0100, FT1000_REG_DOORBELL);
228 #endif
229 status = ft1000_write_register (ft1000dev, 0x8000, FT1000_REG_DOORBELL);
230 break;
232 else
234 loopcnt++;
235 msleep (10);
238 } //end of while
241 loopcnt = 0;
242 while (loopcnt < 20)
245 status = ft1000_read_register (ft1000dev, &temp, FT1000_REG_DOORBELL);
246 DEBUG("FT1000:check_usb_db:Doorbell = 0x%x\n", temp);
247 if (temp & 0x8000)
249 loopcnt++;
250 msleep (10);
252 else
254 DEBUG("check_usb_db: door bell is cleared, return 0\n");
255 return 0;
257 #if 0
258 // Check if Card is present
259 status = ft1000_read_register (ft1000dev, &temp, FT1000_REG_SUP_IMASK);
260 if (temp == 0x0000) {
261 break;
264 status = ft1000_read_register (ft1000dev, &temp, FT1000_REG_ASIC_ID);
265 if (temp == 0xffff) {
266 break;
268 #endif
271 return HANDSHAKE_MAG_TIMEOUT_VALUE;
275 //---------------------------------------------------------------------------
276 // Function: get_handshake
278 // Parameters: struct ft1000_device - device structure
279 // USHORT expected_value - the handshake value expected
281 // Returns: handshakevalue - success
282 // HANDSHAKE_TIMEOUT_VALUE - failure
284 // Description: This function gets the handshake and compare with the expected value
286 // Notes:
288 //---------------------------------------------------------------------------
289 static USHORT get_handshake(struct ft1000_device *ft1000dev, USHORT expected_value)
291 USHORT handshake;
292 int loopcnt;
293 ULONG status=0;
294 PFT1000_INFO pft1000info = netdev_priv(ft1000dev->net);
296 loopcnt = 0;
297 while (loopcnt < 100)
300 #if FIFO_DNLD
301 // Need to clear downloader doorbell if Hartley ASIC
302 status = ft1000_write_register (ft1000dev, FT1000_DB_DNLD_RX, FT1000_REG_DOORBELL);
303 //DEBUG("FT1000:get_handshake:doorbell = 0x%x\n", temp);
304 if (pft1000info->fcodeldr)
306 DEBUG(" get_handshake: fcodeldr is %d\n", pft1000info->fcodeldr);
307 pft1000info->fcodeldr = 0;
308 status = check_usb_db(ft1000dev);
309 if (status != STATUS_SUCCESS)
311 DEBUG("get_handshake: check_usb_db failed\n");
312 status = STATUS_FAILURE;
313 break;
315 status = ft1000_write_register (ft1000dev, FT1000_DB_DNLD_RX, FT1000_REG_DOORBELL);
318 status = ft1000_read_dpram16 (ft1000dev, DWNLD_MAG1_HANDSHAKE_LOC, (PUCHAR)&handshake, 1);
319 //DEBUG("get_handshake: handshake is %x\n", tempx);
320 handshake = ntohs(handshake);
321 //DEBUG("get_handshake: after swap, handshake is %x\n", handshake);
322 #else
323 // Need to clear downloader doorbell if Hartley ASIC
324 status = ft1000_read_register (ft1000dev, &temp, FT1000_REG_DOORBELL);
325 //DEBUG("FT1000:get_handshake:doorbell = 0x%x\n", temp);
326 if (temp)
328 if (temp & FT1000_DB_DNLD_RX)
330 //DEBUG("get_handshake: write FT1000_DB_DNLD_RX to doorbell register\n");
331 status = ft1000_write_register(ft1000dev, FT1000_DB_DNLD_RX, FT1000_REG_DOORBELL);
334 if (pft1000info->fcodeldr)
336 DEBUG(" get_handshake: fcodeldr is %d\n", pft1000info->fcodeldr);
337 pft1000info->fcodeldr = 0;
338 status = check_usb_db(ft1000dev);
339 if (status != STATUS_SUCCESS)
341 DEBUG("get_handshake: check_usb_db failed\n");
342 status = STATUS_FAILURE;
343 break;
346 status = ft1000_read_register (ft1000dev, &temp, FT1000_REG_DOORBELL);
347 //DEBUG("FT1000:get_handshake:doorbell = 0x%x\n", temp);
348 if (temp)
350 if (temp & FT1000_DB_DNLD_RX)
351 status = ft1000_write_register(ft1000dev,FT1000_DB_DNLD_RX, FT1000_REG_DOORBELL);
355 status = ft1000_read_dpram16 (ft1000dev, DWNLD_MAG1_HANDSHAKE_LOC, (PUCHAR)&handshake, 1);
356 //DEBUG("get_handshake: handshake is %x\n", tempx);
357 handshake = ntohs(handshake);
358 //DEBUG("get_handshake: after swap, handshake is %x\n", handshake);
360 } //end of if temp
361 #endif
364 if (status)
365 return HANDSHAKE_TIMEOUT_VALUE;
367 //DEBUG("get_handshake: handshake= %x\n", handshake);
368 if ((handshake == expected_value) || (handshake == HANDSHAKE_RESET_VALUE_USB))
370 //DEBUG("get_handshake: return handshake %x\n", handshake);
371 return handshake;
373 else
375 loopcnt++;
376 msleep (10);
378 //DEBUG("HANDSHKE LOOP: %d\n", loopcnt);
382 //DEBUG("get_handshake: return handshake time out\n");
383 return HANDSHAKE_TIMEOUT_VALUE;
386 //---------------------------------------------------------------------------
387 // Function: put_handshake
389 // Parameters: struct ft1000_device - device structure
390 // USHORT handshake_value - handshake to be written
392 // Returns: none
394 // Description: This function write the handshake value to the handshake location
395 // in DPRAM
397 // Notes:
399 //---------------------------------------------------------------------------
400 static void put_handshake(struct ft1000_device *ft1000dev,USHORT handshake_value)
402 ULONG tempx;
403 USHORT tempword;
404 int i;
405 ULONG status;
409 tempx = (ULONG)handshake_value;
410 tempx = ntohl(tempx);
412 tempword = (USHORT)(tempx & 0xffff);
413 status = ft1000_write_dpram16 (ft1000dev, DWNLD_MAG1_HANDSHAKE_LOC, tempword, 0);
414 tempword = (USHORT)(tempx >> 16);
415 status = ft1000_write_dpram16 (ft1000dev, DWNLD_MAG1_HANDSHAKE_LOC, tempword, 1);
416 status = ft1000_write_register(ft1000dev, FT1000_DB_DNLD_TX, FT1000_REG_DOORBELL);
417 #if FIFO_DNLD
418 for (i=0; i<1000; i++);
419 #else
420 for (i=0; i<10; i++)
422 status = ft1000_read_register (ft1000dev, &tempword, FT1000_REG_DOORBELL);
423 if ((tempword & FT1000_DB_DNLD_TX) == 0)
424 break;
426 if (i==10)
428 DEBUG("FT1000:put_handshake could not clear Tx doorbell\n");
429 status = ft1000_read_register (ft1000dev, &tempword, FT1000_REG_DOORBELL);
430 DEBUG("FT1000:put_handshake:doorbell = 0x%x\n",tempword);
432 #endif
436 static USHORT get_handshake_usb(struct ft1000_device *ft1000dev, USHORT expected_value)
438 USHORT handshake;
439 int loopcnt;
440 USHORT temp;
441 ULONG status=0;
443 PFT1000_INFO pft1000info = netdev_priv(ft1000dev->net);
444 loopcnt = 0;
445 handshake = 0;
446 while (loopcnt < 100)
448 if (pft1000info->usbboot == 2) {
449 status = ft1000_read_dpram32 (ft1000dev, 0, (PUCHAR)&(pft1000info->tempbuf[0]), 64);
450 for (temp=0; temp<16; temp++)
451 DEBUG("tempbuf %d = 0x%x\n", temp, pft1000info->tempbuf[temp]);
452 status = ft1000_read_dpram16 (ft1000dev, DWNLD_MAG1_HANDSHAKE_LOC, (PUCHAR)&handshake, 1);
453 DEBUG("handshake from read_dpram16 = 0x%x\n", handshake);
454 if (pft1000info->dspalive == pft1000info->tempbuf[6])
455 handshake = 0;
456 else {
457 handshake = pft1000info->tempbuf[1];
458 pft1000info->dspalive = pft1000info->tempbuf[6];
461 else {
462 status = ft1000_read_dpram16 (ft1000dev, DWNLD_MAG1_HANDSHAKE_LOC, (PUCHAR)&handshake, 1);
464 loopcnt++;
465 msleep(10);
466 handshake = ntohs(handshake);
467 if ((handshake == expected_value) || (handshake == HANDSHAKE_RESET_VALUE_USB))
469 return handshake;
473 return HANDSHAKE_TIMEOUT_VALUE;
476 static void put_handshake_usb(struct ft1000_device *ft1000dev,USHORT handshake_value)
478 int i;
480 for (i=0; i<1000; i++);
483 //---------------------------------------------------------------------------
484 // Function: get_request_type
486 // Parameters: struct ft1000_device - device structure
488 // Returns: request type - success
490 // Description: This function returns the request type
492 // Notes:
494 //---------------------------------------------------------------------------
495 static USHORT get_request_type(struct ft1000_device *ft1000dev)
497 USHORT request_type;
498 ULONG status;
499 USHORT tempword;
500 ULONG tempx;
501 PFT1000_INFO pft1000info = netdev_priv(ft1000dev->net);
503 if ( pft1000info->bootmode == 1)
505 status = fix_ft1000_read_dpram32 (ft1000dev, DWNLD_MAG1_TYPE_LOC, (PUCHAR)&tempx);
506 tempx = ntohl(tempx);
508 else
510 #if FIFO_DNLD
511 tempx = 0;
512 #else
513 status = ft1000_read_dpram16 (ft1000dev, DWNLD_MAG1_TYPE_LOC, (PUCHAR)&tempword, 0);
514 tempx = tempword;
515 #endif
516 status = ft1000_read_dpram16 (ft1000dev, DWNLD_MAG1_TYPE_LOC, (PUCHAR)&tempword, 1);
517 tempx |= (tempword << 16);
518 tempx = ntohl(tempx);
520 request_type = (USHORT)tempx;
522 //DEBUG("get_request_type: request_type is %x\n", request_type);
523 return request_type;
527 static USHORT get_request_type_usb(struct ft1000_device *ft1000dev)
529 USHORT request_type;
530 ULONG status;
531 USHORT tempword;
532 ULONG tempx;
533 PFT1000_INFO pft1000info = netdev_priv(ft1000dev->net);
534 if ( pft1000info->bootmode == 1)
536 status = fix_ft1000_read_dpram32 (ft1000dev, DWNLD_MAG1_TYPE_LOC, (PUCHAR)&tempx);
537 tempx = ntohl(tempx);
539 else
541 if (pft1000info->usbboot == 2) {
542 tempx = pft1000info->tempbuf[2];
543 tempword = pft1000info->tempbuf[3];
545 else {
546 tempx = 0;
547 status = ft1000_read_dpram16 (ft1000dev, DWNLD_MAG1_TYPE_LOC, (PUCHAR)&tempword, 1);
549 tempx |= (tempword << 16);
550 tempx = ntohl(tempx);
552 request_type = (USHORT)tempx;
554 //DEBUG("get_request_type: request_type is %x\n", request_type);
555 return request_type;
559 //---------------------------------------------------------------------------
560 // Function: get_request_value
562 // Parameters: struct ft1000_device - device structure
564 // Returns: request value - success
566 // Description: This function returns the request value
568 // Notes:
570 //---------------------------------------------------------------------------
571 static long get_request_value(struct ft1000_device *ft1000dev)
573 ULONG value;
574 USHORT tempword;
575 ULONG status;
576 PFT1000_INFO pft1000info = netdev_priv(ft1000dev->net);
579 if ( pft1000info->bootmode == 1)
581 status = fix_ft1000_read_dpram32(ft1000dev, DWNLD_MAG1_SIZE_LOC, (PUCHAR)&value);
582 value = ntohl(value);
584 else
586 status = ft1000_read_dpram16(ft1000dev, DWNLD_MAG1_SIZE_LOC, (PUCHAR)&tempword, 0);
587 value = tempword;
588 status = ft1000_read_dpram16(ft1000dev, DWNLD_MAG1_SIZE_LOC, (PUCHAR)&tempword, 1);
589 value |= (tempword << 16);
590 value = ntohl(value);
594 //DEBUG("get_request_value: value is %x\n", value);
595 return value;
599 #if 0
600 static long get_request_value_usb(struct ft1000_device *ft1000dev)
602 ULONG value;
603 USHORT tempword;
604 ULONG status;
605 PFT1000_INFO pft1000info = netdev_priv(ft1000dev->net);
607 if (pft1000info->usbboot == 2) {
608 value = pft1000info->tempbuf[4];
609 tempword = pft1000info->tempbuf[5];
611 else {
612 value = 0;
613 status = ft1000_read_dpram16(ft1000dev, DWNLD_MAG1_SIZE_LOC, (PUCHAR)&tempword, 1);
616 value |= (tempword << 16);
617 value = ntohl(value);
619 #if FIFO_DNLD
620 if (pft1000info->usbboot == 1)
621 pft1000info->usbboot = 2;
622 #endif
624 //DEBUG("get_request_value_usb: value is %x\n", value);
625 return value;
628 #endif
630 //---------------------------------------------------------------------------
631 // Function: put_request_value
633 // Parameters: struct ft1000_device - device structure
634 // long lvalue - value to be put into DPRAM location DWNLD_MAG1_SIZE_LOC
636 // Returns: none
638 // Description: This function writes a value to DWNLD_MAG1_SIZE_LOC
640 // Notes:
642 //---------------------------------------------------------------------------
643 static void put_request_value(struct ft1000_device *ft1000dev, long lvalue)
645 ULONG tempx;
646 ULONG status;
648 tempx = ntohl(lvalue);
649 status = fix_ft1000_write_dpram32(ft1000dev, DWNLD_MAG1_SIZE_LOC, (PUCHAR)&tempx);
653 //DEBUG("put_request_value: value is %x\n", lvalue);
659 //---------------------------------------------------------------------------
660 // Function: hdr_checksum
662 // Parameters: PPSEUDO_HDR pHdr - Pseudo header pointer
664 // Returns: checksum - success
666 // Description: This function returns the checksum of the pseudo header
668 // Notes:
670 //---------------------------------------------------------------------------
671 static USHORT hdr_checksum(PPSEUDO_HDR pHdr)
673 USHORT *usPtr = (USHORT *)pHdr;
674 USHORT chksum;
677 chksum = ((((((usPtr[0] ^ usPtr[1]) ^ usPtr[2]) ^ usPtr[3]) ^
678 usPtr[4]) ^ usPtr[5]) ^ usPtr[6]);
680 return chksum;
684 //---------------------------------------------------------------------------
685 // Function: write_blk
687 // Parameters: struct ft1000_device - device structure
688 // USHORT **pUsFile - DSP image file pointer in USHORT
689 // UCHAR **pUcFile - DSP image file pointer in UCHAR
690 // long word_length - lenght of the buffer to be written
691 // to DPRAM
693 // Returns: STATUS_SUCCESS - success
694 // STATUS_FAILURE - failure
696 // Description: This function writes a block of DSP image to DPRAM
698 // Notes:
700 //---------------------------------------------------------------------------
701 static ULONG write_blk (struct ft1000_device *ft1000dev, USHORT **pUsFile, UCHAR **pUcFile, long word_length)
703 ULONG Status = STATUS_SUCCESS;
704 USHORT dpram;
705 long temp_word_length;
706 int loopcnt, i, j;
707 USHORT *pTempFile;
708 USHORT tempword;
709 USHORT tempbuffer[64];
710 USHORT resultbuffer[64];
711 PFT1000_INFO pft1000info = netdev_priv(ft1000dev->net);
713 //DEBUG("FT1000:download:start word_length = %d\n",(int)word_length);
714 dpram = (USHORT)DWNLD_MAG1_PS_HDR_LOC;
715 tempword = *(*pUsFile);
716 (*pUsFile)++;
717 Status = ft1000_write_dpram16(ft1000dev, dpram, tempword, 0);
718 tempword = *(*pUsFile);
719 (*pUsFile)++;
720 Status = ft1000_write_dpram16(ft1000dev, dpram++, tempword, 1);
722 *pUcFile = *pUcFile + 4;
723 word_length--;
724 tempword = (USHORT)word_length;
725 word_length = (word_length / 16) + 1;
726 pTempFile = *pUsFile;
727 temp_word_length = word_length;
728 for (; word_length > 0; word_length--) /* In words */
730 loopcnt = 0;
732 for (i=0; i<32; i++)
734 if (tempword != 0)
736 tempbuffer[i++] = *(*pUsFile);
737 (*pUsFile)++;
738 tempbuffer[i] = *(*pUsFile);
739 (*pUsFile)++;
740 *pUcFile = *pUcFile + 4;
741 loopcnt++;
742 tempword--;
744 else
746 tempbuffer[i++] = 0;
747 tempbuffer[i] = 0;
751 //DEBUG("write_blk: loopcnt is %d\n", loopcnt);
752 //DEBUG("write_blk: bootmode = %d\n", bootmode);
753 //DEBUG("write_blk: dpram = %x\n", dpram);
754 if (pft1000info->bootmode == 0)
756 if (dpram >= 0x3F4)
757 Status = ft1000_write_dpram32 (ft1000dev, dpram, (PUCHAR)&tempbuffer[0], 8);
758 else
759 Status = ft1000_write_dpram32 (ft1000dev, dpram, (PUCHAR)&tempbuffer[0], 64);
761 else
763 for (j=0; j<10; j++)
765 Status = ft1000_write_dpram32 (ft1000dev, dpram, (PUCHAR)&tempbuffer[0], 64);
766 if (Status == STATUS_SUCCESS)
768 // Work around for ASIC bit stuffing problem.
769 if ( (tempbuffer[31] & 0xfe00) == 0xfe00)
771 Status = ft1000_write_dpram32(ft1000dev, dpram+12, (PUCHAR)&tempbuffer[24], 64);
773 // Let's check the data written
774 Status = ft1000_read_dpram32 (ft1000dev, dpram, (PUCHAR)&resultbuffer[0], 64);
775 if ( (tempbuffer[31] & 0xfe00) == 0xfe00)
777 for (i=0; i<28; i++)
779 if (resultbuffer[i] != tempbuffer[i])
781 //NdisMSleep (100);
782 DEBUG("FT1000:download:DPRAM write failed 1 during bootloading\n");
783 msleep(10);
784 Status = STATUS_FAILURE;
785 break;
788 Status = ft1000_read_dpram32 (ft1000dev, dpram+12, (PUCHAR)&resultbuffer[0], 64);
789 for (i=0; i<16; i++)
791 if (resultbuffer[i] != tempbuffer[i+24])
793 //NdisMSleep (100);
794 DEBUG("FT1000:download:DPRAM write failed 2 during bootloading\n");
795 msleep(10);
796 Status = STATUS_FAILURE;
797 break;
801 else
803 for (i=0; i<32; i++)
805 if (resultbuffer[i] != tempbuffer[i])
807 //NdisMSleep (100);
808 DEBUG("FT1000:download:DPRAM write failed 3 during bootloading\n");
809 msleep(10);
810 Status = STATUS_FAILURE;
811 break;
816 if (Status == STATUS_SUCCESS)
817 break;
822 if (Status != STATUS_SUCCESS)
824 DEBUG("FT1000:download:Write failed tempbuffer[31] = 0x%x\n", tempbuffer[31]);
825 break;
829 dpram = dpram + loopcnt;
832 return Status;
835 static void usb_dnld_complete (struct urb *urb)
837 //DEBUG("****** usb_dnld_complete\n");
840 //---------------------------------------------------------------------------
841 // Function: write_blk_fifo
843 // Parameters: struct ft1000_device - device structure
844 // USHORT **pUsFile - DSP image file pointer in USHORT
845 // UCHAR **pUcFile - DSP image file pointer in UCHAR
846 // long word_length - lenght of the buffer to be written
847 // to DPRAM
849 // Returns: STATUS_SUCCESS - success
850 // STATUS_FAILURE - failure
852 // Description: This function writes a block of DSP image to DPRAM
854 // Notes:
856 //---------------------------------------------------------------------------
857 static ULONG write_blk_fifo (struct ft1000_device *ft1000dev, USHORT **pUsFile, UCHAR **pUcFile, long word_length)
859 ULONG Status = STATUS_SUCCESS;
860 int byte_length;
861 long aligncnt;
863 byte_length = word_length * 4;
865 if (byte_length % 4)
866 aligncnt = 4 - (byte_length % 4);
867 else
868 aligncnt = 0;
869 byte_length += aligncnt;
871 if (byte_length && ((byte_length % 64) == 0)) {
872 byte_length += 4;
875 if (byte_length < 64)
876 byte_length = 68;
878 #if 0
879 pblk = kzalloc(byte_length, GFP_KERNEL);
880 memcpy (pblk, *pUcFile, byte_length);
882 pipe = usb_sndbulkpipe (ft1000dev->dev, ft1000dev->bulk_out_endpointAddr);
884 Status = usb_bulk_msg (ft1000dev->dev,
885 pipe,
886 pblk,
887 byte_length,
888 &cnt,
889 10);
890 DEBUG("write_blk_fifo Status = 0x%8x Bytes Transfer = %d Data = 0x%x\n", Status, cnt, *pblk);
892 kfree(pblk);
893 #else
894 usb_init_urb(ft1000dev->tx_urb);
895 memcpy (ft1000dev->tx_buf, *pUcFile, byte_length);
896 usb_fill_bulk_urb(ft1000dev->tx_urb,
897 ft1000dev->dev,
898 usb_sndbulkpipe(ft1000dev->dev, ft1000dev->bulk_out_endpointAddr),
899 ft1000dev->tx_buf,
900 byte_length,
901 usb_dnld_complete,
902 (void*)ft1000dev);
904 usb_submit_urb(ft1000dev->tx_urb, GFP_ATOMIC);
905 #endif
907 *pUsFile = *pUsFile + (word_length << 1);
908 *pUcFile = *pUcFile + (word_length << 2);
910 return Status;
913 //---------------------------------------------------------------------------
915 // Function: scram_dnldr
917 // Synopsis: Scramble downloader for Harley based ASIC via USB interface
919 // Arguments: pFileStart - pointer to start of file
920 // FileLength - file length
922 // Returns: status - return code
923 //---------------------------------------------------------------------------
925 u16 scram_dnldr(struct ft1000_device *ft1000dev, void *pFileStart, ULONG FileLength)
927 u16 Status = STATUS_SUCCESS;
928 UINT uiState;
929 USHORT handshake;
930 PPSEUDO_HDR pHdr;
931 USHORT usHdrLength;
932 //PPROV_RECORD pProvRecord;
933 PDSP_FILE_HDR pFileHdr;
934 long word_length;
935 USHORT request;
936 USHORT temp;
937 USHORT tempword;
939 PDSP_FILE_HDR_5 pFileHdr5;
940 PDSP_IMAGE_INFO_V6 pDspImageInfoV6 = NULL;
941 long requested_version;
942 BOOLEAN bGoodVersion;
943 PDRVMSG pMailBoxData;
944 USHORT *pUsData = NULL;
945 USHORT *pUsFile = NULL;
946 UCHAR *pUcFile = NULL;
947 UCHAR *pBootEnd = NULL, *pCodeEnd= NULL;
948 int imageN;
949 long loader_code_address, loader_code_size = 0;
950 long run_address = 0, run_size = 0;
952 ULONG templong;
953 ULONG image_chksum = 0;
955 USHORT dpram = 0;
956 PUCHAR pbuffer;
957 PPROV_RECORD pprov_record;
958 FT1000_INFO *pft1000info = netdev_priv(ft1000dev->net);
960 DEBUG("Entered scram_dnldr...\n");
962 pft1000info->fcodeldr = 0;
963 pft1000info->usbboot = 0;
964 pft1000info->dspalive = 0xffff;
968 // Get version id of file, at first 4 bytes of file, for newer files.
971 uiState = STATE_START_DWNLD;
973 pFileHdr = (PDSP_FILE_HDR)pFileStart;
974 pFileHdr5 = (PDSP_FILE_HDR_5)pFileStart;
976 ft1000_write_register (ft1000dev, 0x800, FT1000_REG_MAG_WATERMARK);
978 pUsFile = (USHORT *)(pFileStart + pFileHdr5->loader_offset);
979 pUcFile = (UCHAR *)(pFileStart + pFileHdr5->loader_offset);
981 pBootEnd = (UCHAR *)(pFileStart + pFileHdr5->loader_code_end);
983 loader_code_address = pFileHdr5->loader_code_address;
984 loader_code_size = pFileHdr5->loader_code_size;
985 bGoodVersion = FALSE;
987 while ((Status == STATUS_SUCCESS) && (uiState != STATE_DONE_FILE))
989 switch (uiState)
991 case STATE_START_DWNLD:
992 DEBUG("FT1000:STATE_START_DWNLD\n");
993 if (pft1000info->usbboot)
994 handshake = get_handshake_usb(ft1000dev, HANDSHAKE_DSP_BL_READY);
995 else
996 handshake = get_handshake(ft1000dev, HANDSHAKE_DSP_BL_READY);
998 if (handshake == HANDSHAKE_DSP_BL_READY)
1000 DEBUG("scram_dnldr: handshake is HANDSHAKE_DSP_BL_READY, call put_handshake(HANDSHAKE_DRIVER_READY)\n");
1001 put_handshake(ft1000dev, HANDSHAKE_DRIVER_READY);
1003 else
1005 DEBUG("FT1000:download:Download error: Handshake failed\n");
1006 Status = STATUS_FAILURE;
1009 uiState = STATE_BOOT_DWNLD;
1011 break;
1013 case STATE_BOOT_DWNLD:
1014 DEBUG("FT1000:STATE_BOOT_DWNLD\n");
1015 pft1000info->bootmode = 1;
1016 handshake = get_handshake(ft1000dev, HANDSHAKE_REQUEST);
1017 if (handshake == HANDSHAKE_REQUEST)
1020 * Get type associated with the request.
1022 request = get_request_type(ft1000dev);
1023 switch (request)
1025 case REQUEST_RUN_ADDRESS:
1026 DEBUG("FT1000:REQUEST_RUN_ADDRESS\n");
1027 put_request_value(ft1000dev, loader_code_address);
1028 break;
1029 case REQUEST_CODE_LENGTH:
1030 DEBUG("FT1000:REQUEST_CODE_LENGTH\n");
1031 put_request_value(ft1000dev, loader_code_size);
1032 break;
1033 case REQUEST_DONE_BL:
1034 DEBUG("FT1000:REQUEST_DONE_BL\n");
1035 /* Reposition ptrs to beginning of code section */
1036 pUsFile = (USHORT *)(pBootEnd);
1037 pUcFile = (UCHAR *)(pBootEnd);
1038 //DEBUG("FT1000:download:pUsFile = 0x%8x\n", (int)pUsFile);
1039 //DEBUG("FT1000:download:pUcFile = 0x%8x\n", (int)pUcFile);
1040 uiState = STATE_CODE_DWNLD;
1041 pft1000info->fcodeldr = 1;
1042 break;
1043 case REQUEST_CODE_SEGMENT:
1044 //DEBUG("FT1000:REQUEST_CODE_SEGMENT\n");
1045 word_length = get_request_value(ft1000dev);
1046 //DEBUG("FT1000:word_length = 0x%x\n", (int)word_length);
1047 //NdisMSleep (100);
1048 if (word_length > MAX_LENGTH)
1050 DEBUG("FT1000:download:Download error: Max length exceeded\n");
1051 Status = STATUS_FAILURE;
1052 break;
1054 if ( (word_length*2 + pUcFile) > pBootEnd)
1057 * Error, beyond boot code range.
1059 DEBUG("FT1000:download:Download error: Requested len=%d exceeds BOOT code boundry.\n",
1060 (int)word_length);
1061 Status = STATUS_FAILURE;
1062 break;
1065 * Position ASIC DPRAM auto-increment pointer.
1067 dpram = (USHORT)DWNLD_MAG1_PS_HDR_LOC;
1068 if (word_length & 0x1)
1069 word_length++;
1070 word_length = word_length / 2;
1072 Status = write_blk(ft1000dev, &pUsFile, &pUcFile, word_length);
1073 //DEBUG("write_blk returned %d\n", Status);
1074 break;
1075 default:
1076 DEBUG("FT1000:download:Download error: Bad request type=%d in BOOT download state.\n",request);
1077 Status = STATUS_FAILURE;
1078 break;
1080 if (pft1000info->usbboot)
1081 put_handshake_usb(ft1000dev, HANDSHAKE_RESPONSE);
1082 else
1083 put_handshake(ft1000dev, HANDSHAKE_RESPONSE);
1085 else
1087 DEBUG("FT1000:download:Download error: Handshake failed\n");
1088 Status = STATUS_FAILURE;
1091 break;
1093 case STATE_CODE_DWNLD:
1094 //DEBUG("FT1000:STATE_CODE_DWNLD\n");
1095 pft1000info->bootmode = 0;
1096 if (pft1000info->usbboot)
1097 handshake = get_handshake_usb(ft1000dev, HANDSHAKE_REQUEST);
1098 else
1099 handshake = get_handshake(ft1000dev, HANDSHAKE_REQUEST);
1100 if (handshake == HANDSHAKE_REQUEST)
1103 * Get type associated with the request.
1105 if (pft1000info->usbboot)
1106 request = get_request_type_usb(ft1000dev);
1107 else
1108 request = get_request_type(ft1000dev);
1109 switch (request)
1111 case REQUEST_FILE_CHECKSUM:
1112 DEBUG("FT1000:download:image_chksum = 0x%8x\n", image_chksum);
1113 put_request_value(ft1000dev, image_chksum);
1114 break;
1115 case REQUEST_RUN_ADDRESS:
1116 DEBUG("FT1000:download: REQUEST_RUN_ADDRESS\n");
1117 if (bGoodVersion)
1119 DEBUG("FT1000:download:run_address = 0x%8x\n", (int)run_address);
1120 put_request_value(ft1000dev, run_address);
1122 else
1124 DEBUG("FT1000:download:Download error: Got Run address request before image offset request.\n");
1125 Status = STATUS_FAILURE;
1126 break;
1128 break;
1129 case REQUEST_CODE_LENGTH:
1130 DEBUG("FT1000:download:REQUEST_CODE_LENGTH\n");
1131 if (bGoodVersion)
1133 DEBUG("FT1000:download:run_size = 0x%8x\n", (int)run_size);
1134 put_request_value(ft1000dev, run_size);
1136 else
1138 DEBUG("FT1000:download:Download error: Got Size request before image offset request.\n");
1139 Status = STATUS_FAILURE;
1140 break;
1142 break;
1143 case REQUEST_DONE_CL:
1144 #if FIFO_DNLD
1145 pft1000info->usbboot = 3;
1146 #endif
1147 /* Reposition ptrs to beginning of provisioning section */
1148 pUsFile = (USHORT *)(pFileStart + pFileHdr5->commands_offset);
1149 pUcFile = (UCHAR *)(pFileStart + pFileHdr5->commands_offset);
1150 uiState = STATE_DONE_DWNLD;
1151 break;
1152 case REQUEST_CODE_SEGMENT:
1153 //DEBUG("FT1000:download: REQUEST_CODE_SEGMENT - CODELOADER\n");
1154 if (!bGoodVersion)
1156 DEBUG("FT1000:download:Download error: Got Code Segment request before image offset request.\n");
1157 Status = STATUS_FAILURE;
1158 break;
1160 #if 0
1161 word_length = get_request_value_usb(ft1000dev);
1162 //DEBUG("FT1000:download:word_length = %d\n", (int)word_length);
1163 if (word_length > MAX_LENGTH/2)
1164 #else
1165 word_length = get_request_value(ft1000dev);
1166 //DEBUG("FT1000:download:word_length = %d\n", (int)word_length);
1167 if (word_length > MAX_LENGTH)
1168 #endif
1170 DEBUG("FT1000:download:Download error: Max length exceeded\n");
1171 Status = STATUS_FAILURE;
1172 break;
1174 if ( (word_length*2 + pUcFile) > pCodeEnd)
1177 * Error, beyond boot code range.
1179 DEBUG("FT1000:download:Download error: Requested len=%d exceeds DSP code boundry.\n",
1180 (int)word_length);
1181 Status = STATUS_FAILURE;
1182 break;
1185 * Position ASIC DPRAM auto-increment pointer.
1187 dpram = (USHORT)DWNLD_MAG1_PS_HDR_LOC;
1188 if (word_length & 0x1)
1189 word_length++;
1190 word_length = word_length / 2;
1192 #if FIFO_DNLD
1193 write_blk_fifo (ft1000dev, &pUsFile, &pUcFile, word_length);
1194 if (pft1000info->usbboot == 0)
1195 pft1000info->usbboot++;
1196 if (pft1000info->usbboot == 1) {
1197 tempword = 0;
1198 ft1000_write_dpram16 (ft1000dev, DWNLD_MAG1_PS_HDR_LOC, tempword, 0);
1200 #else
1201 write_blk (ft1000dev, &pUsFile, &pUcFile, word_length);
1202 //ft1000_write_dpram32 (ft1000dev, dpram, (PUCHAR)pUcFile, word_length);
1203 #endif
1204 break;
1206 case REQUEST_MAILBOX_DATA:
1207 DEBUG("FT1000:download: REQUEST_MAILBOX_DATA\n");
1208 // Convert length from byte count to word count. Make sure we round up.
1209 word_length = (long)(pft1000info->DSPInfoBlklen + 1)/2;
1210 put_request_value(ft1000dev, word_length);
1211 pMailBoxData = (PDRVMSG)&(pft1000info->DSPInfoBlk[0]);
1213 * Position ASIC DPRAM auto-increment pointer.
1217 pUsData = (USHORT *)&pMailBoxData->data[0];
1218 dpram = (USHORT)DWNLD_MAG1_PS_HDR_LOC;
1219 if (word_length & 0x1)
1220 word_length++;
1222 word_length = (word_length / 2);
1225 for (; word_length > 0; word_length--) /* In words */
1228 templong = *pUsData++;
1229 templong |= (*pUsData++ << 16);
1230 Status = fix_ft1000_write_dpram32 (ft1000dev, dpram++, (PUCHAR)&templong);
1233 break;
1235 case REQUEST_VERSION_INFO:
1236 DEBUG("FT1000:download:REQUEST_VERSION_INFO\n");
1237 word_length = pFileHdr5->version_data_size;
1238 put_request_value(ft1000dev, word_length);
1240 * Position ASIC DPRAM auto-increment pointer.
1243 pUsFile = (USHORT *)(pFileStart + pFileHdr5->version_data_offset);
1246 dpram = (USHORT)DWNLD_MAG1_PS_HDR_LOC;
1247 if (word_length & 0x1)
1248 word_length++;
1250 word_length = (word_length / 2);
1253 for (; word_length > 0; word_length--) /* In words */
1256 templong = ntohs(*pUsFile++);
1257 temp = ntohs(*pUsFile++);
1258 templong |= (temp << 16);
1259 Status = fix_ft1000_write_dpram32 (ft1000dev, dpram++, (PUCHAR)&templong);
1262 break;
1264 case REQUEST_CODE_BY_VERSION:
1265 DEBUG("FT1000:download:REQUEST_CODE_BY_VERSION\n");
1266 bGoodVersion = FALSE;
1267 requested_version = get_request_value(ft1000dev);
1269 pDspImageInfoV6 = (PDSP_IMAGE_INFO_V6)(pFileStart + sizeof(DSP_FILE_HDR_5));
1271 for (imageN = 0; imageN < pFileHdr5->nDspImages; imageN++)
1274 temp = (USHORT)(pDspImageInfoV6->version);
1275 templong = temp;
1276 temp = (USHORT)(pDspImageInfoV6->version >> 16);
1277 templong |= (temp << 16);
1278 if (templong == (ULONG)requested_version)
1280 bGoodVersion = TRUE;
1281 DEBUG("FT1000:download: bGoodVersion is TRUE\n");
1282 pUsFile = (USHORT *)(pFileStart + pDspImageInfoV6->begin_offset);
1283 pUcFile = (UCHAR *)(pFileStart + pDspImageInfoV6->begin_offset);
1284 pCodeEnd = (UCHAR *)(pFileStart + pDspImageInfoV6->end_offset);
1285 run_address = pDspImageInfoV6->run_address;
1286 run_size = pDspImageInfoV6->image_size;
1287 image_chksum = (ULONG)pDspImageInfoV6->checksum;
1288 break;
1290 pDspImageInfoV6++;
1293 } //end of for
1295 if (!bGoodVersion)
1298 * Error, beyond boot code range.
1300 DEBUG("FT1000:download:Download error: Bad Version Request = 0x%x.\n",(int)requested_version);
1301 Status = STATUS_FAILURE;
1302 break;
1304 break;
1306 default:
1307 DEBUG("FT1000:download:Download error: Bad request type=%d in CODE download state.\n",request);
1308 Status = STATUS_FAILURE;
1309 break;
1311 if (pft1000info->usbboot)
1312 put_handshake_usb(ft1000dev, HANDSHAKE_RESPONSE);
1313 else
1314 put_handshake(ft1000dev, HANDSHAKE_RESPONSE);
1316 else
1318 DEBUG("FT1000:download:Download error: Handshake failed\n");
1319 Status = STATUS_FAILURE;
1322 break;
1324 case STATE_DONE_DWNLD:
1325 DEBUG("FT1000:download:Code loader is done...\n");
1326 uiState = STATE_SECTION_PROV;
1327 break;
1329 case STATE_SECTION_PROV:
1330 DEBUG("FT1000:download:STATE_SECTION_PROV\n");
1331 pHdr = (PPSEUDO_HDR)pUcFile;
1333 if (pHdr->checksum == hdr_checksum(pHdr))
1335 if (pHdr->portdest != 0x80 /* Dsp OAM */)
1337 uiState = STATE_DONE_PROV;
1338 break;
1340 usHdrLength = ntohs(pHdr->length); /* Byte length for PROV records */
1342 // Get buffer for provisioning data
1343 pbuffer = kmalloc ( (usHdrLength + sizeof(PSEUDO_HDR) ), GFP_ATOMIC );
1344 if (pbuffer) {
1345 memcpy(pbuffer, (void *)pUcFile, (UINT)(usHdrLength + sizeof(PSEUDO_HDR)));
1346 // link provisioning data
1347 pprov_record = kmalloc( sizeof(PROV_RECORD), GFP_ATOMIC );
1348 if (pprov_record) {
1349 pprov_record->pprov_data = pbuffer;
1350 list_add_tail (&pprov_record->list, &pft1000info->prov_list);
1351 // Move to next entry if available
1352 pUcFile = (UCHAR *)((unsigned long)pUcFile + (UINT)((usHdrLength + 1) & 0xFFFFFFFE) + sizeof(PSEUDO_HDR));
1353 if ( (unsigned long)(pUcFile) - (unsigned long)(pFileStart) >= (unsigned long)FileLength) {
1354 uiState = STATE_DONE_FILE;
1357 else {
1358 kfree(pbuffer);
1359 Status = STATUS_FAILURE;
1362 else {
1363 Status = STATUS_FAILURE;
1366 else
1368 /* Checksum did not compute */
1369 Status = STATUS_FAILURE;
1371 DEBUG("ft1000:download: after STATE_SECTION_PROV, uiState = %d, Status= %d\n", uiState, Status);
1372 break;
1374 case STATE_DONE_PROV:
1375 DEBUG("FT1000:download:STATE_DONE_PROV\n");
1376 uiState = STATE_DONE_FILE;
1377 break;
1380 default:
1381 Status = STATUS_FAILURE;
1382 break;
1383 } /* End Switch */
1385 if (Status != STATUS_SUCCESS) {
1386 break;
1389 /****
1390 // Check if Card is present
1391 Status = Harley_Read_Register(&temp, FT1000_REG_SUP_IMASK);
1392 if ( (Status != NDIS_STATUS_SUCCESS) || (temp == 0x0000) ) {
1393 break;
1396 Status = Harley_Read_Register(&temp, FT1000_REG_ASIC_ID);
1397 if ( (Status != NDIS_STATUS_SUCCESS) || (temp == 0xffff) ) {
1398 break;
1400 ****/
1402 } /* End while */
1404 DEBUG("Download exiting with status = 0x%8x\n", Status);
1405 ft1000_write_register(ft1000dev, FT1000_DB_DNLD_TX, FT1000_REG_DOORBELL);
1407 return Status;