ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.6.tar.bz2
[linux-2.6.git] / drivers / scsi / qla2xxx / qla_sup.c
1 /******************************************************************************
2  *                  QLOGIC LINUX SOFTWARE
3  *
4  * QLogic ISP2x00 device driver for Linux 2.6.x
5  * Copyright (C) 2003-2004 QLogic Corporation
6  * (www.qlogic.com)
7  *
8  * This program is free software; you can redistribute it and/or modify it
9  * under the terms of the GNU General Public License as published by the
10  * Free Software Foundation; either version 2, or (at your option) any
11  * later version.
12  *
13  * This program is distributed in the hope that it will be useful, but
14  * WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * General Public License for more details.
17  *
18  ******************************************************************************/
19
20 #include "qla_os.h"
21 #include "qla_def.h"
22
23 static uint16_t qla2x00_nvram_request(scsi_qla_host_t *, uint32_t);
24 static void qla2x00_nv_deselect(scsi_qla_host_t *);
25 static void qla2x00_nv_write(scsi_qla_host_t *, uint16_t);
26
27 uint8_t qla2x00_read_flash_byte(scsi_qla_host_t *, uint32_t);
28 static void qla2x00_write_flash_byte(scsi_qla_host_t *, uint32_t, uint8_t);
29 static uint8_t qla2x00_poll_flash(scsi_qla_host_t *ha,
30                 uint32_t addr, uint8_t poll_data, uint8_t mid);
31 static uint8_t qla2x00_program_flash_address(scsi_qla_host_t *ha,
32                 uint32_t addr, uint8_t data, uint8_t mid);
33 static uint8_t qla2x00_erase_flash_sector(scsi_qla_host_t *ha,
34                 uint32_t addr, uint32_t sec_mask, uint8_t mid);
35
36 uint8_t qla2x00_get_flash_manufacturer(scsi_qla_host_t *ha);
37 uint16_t qla2x00_get_flash_version(scsi_qla_host_t *);
38 uint16_t qla2x00_get_flash_image(scsi_qla_host_t *ha, uint8_t *image);
39 uint16_t qla2x00_set_flash_image(scsi_qla_host_t *ha, uint8_t *image);
40
41
42 /*
43  * NVRAM support routines
44  */
45
46 /**
47  * qla2x00_lock_nvram_access() - 
48  * @ha: HA context
49  */
50 void
51 qla2x00_lock_nvram_access(scsi_qla_host_t *ha)
52 {
53         uint16_t data;
54         device_reg_t *reg;
55
56         reg = ha->iobase;
57
58         if (!IS_QLA2100(ha) && !IS_QLA2200(ha) && !IS_QLA2300(ha)) {
59                 data = RD_REG_WORD(&reg->nvram);
60                 while (data & NVR_BUSY) {
61                         udelay(100);
62                         data = RD_REG_WORD(&reg->nvram);
63                 }
64
65                 /* Lock resource */
66                 WRT_REG_WORD(&reg->u.isp2300.host_semaphore, 0x1);
67                 udelay(5);
68                 data = RD_REG_WORD(&reg->u.isp2300.host_semaphore);
69                 while ((data & BIT_0) == 0) {
70                         /* Lock failed */
71                         udelay(100);
72                         WRT_REG_WORD(&reg->u.isp2300.host_semaphore, 0x1);
73                         udelay(5);
74                         data = RD_REG_WORD(&reg->u.isp2300.host_semaphore);
75                 }
76         }
77 }
78
79 /**
80  * qla2x00_unlock_nvram_access() - 
81  * @ha: HA context
82  */
83 void
84 qla2x00_unlock_nvram_access(scsi_qla_host_t *ha)
85 {
86         device_reg_t *reg;
87
88         reg = ha->iobase;
89
90         if (!IS_QLA2100(ha) && !IS_QLA2200(ha) && !IS_QLA2300(ha))
91                 WRT_REG_WORD(&reg->u.isp2300.host_semaphore, 0);
92 }
93
94 /**
95  * qla2x00_get_nvram_word() - Calculates word position in NVRAM and calls the
96  *      request routine to get the word from NVRAM.
97  * @ha: HA context
98  * @addr: Address in NVRAM to read
99  *
100  * Returns the word read from nvram @addr.
101  */
102 uint16_t
103 qla2x00_get_nvram_word(scsi_qla_host_t *ha, uint32_t addr)
104 {
105         uint16_t        data;
106         uint32_t        nv_cmd;
107
108         nv_cmd = addr << 16;
109         nv_cmd |= NV_READ_OP;
110         data = qla2x00_nvram_request(ha, nv_cmd);
111
112         return (data);
113 }
114
115 /**
116  * qla2x00_write_nvram_word() - Write NVRAM data.
117  * @ha: HA context
118  * @addr: Address in NVRAM to write
119  * @data: word to program
120  */
121 void
122 qla2x00_write_nvram_word(scsi_qla_host_t *ha, uint32_t addr, uint16_t data)
123 {
124         int count;
125         uint16_t word;
126         uint32_t nv_cmd;
127         device_reg_t *reg = ha->iobase;
128
129         qla2x00_nv_write(ha, NVR_DATA_OUT);
130         qla2x00_nv_write(ha, 0);
131         qla2x00_nv_write(ha, 0);
132
133         for (word = 0; word < 8; word++)
134                 qla2x00_nv_write(ha, NVR_DATA_OUT);
135
136         qla2x00_nv_deselect(ha);
137
138         /* Erase Location */
139         nv_cmd = (addr << 16) | NV_ERASE_OP;
140         nv_cmd <<= 5;
141         for (count = 0; count < 11; count++) {
142                 if (nv_cmd & BIT_31)
143                         qla2x00_nv_write(ha, NVR_DATA_OUT);
144                 else
145                         qla2x00_nv_write(ha, 0);
146
147                 nv_cmd <<= 1;
148         }
149
150         qla2x00_nv_deselect(ha);
151
152         /* Wait for Erase to Finish */
153         WRT_REG_WORD(&reg->nvram, NVR_SELECT);
154         do {
155                 NVRAM_DELAY();
156                 word = RD_REG_WORD(&reg->nvram);
157         } while ((word & NVR_DATA_IN) == 0);
158
159         qla2x00_nv_deselect(ha);
160
161         /* Write data */
162         nv_cmd = (addr << 16) | NV_WRITE_OP;
163         nv_cmd |= data;
164         nv_cmd <<= 5;
165         for (count = 0; count < 27; count++) {
166                 if (nv_cmd & BIT_31)
167                         qla2x00_nv_write(ha, NVR_DATA_OUT);
168                 else
169                         qla2x00_nv_write(ha, 0);
170
171                 nv_cmd <<= 1;
172         }
173
174         qla2x00_nv_deselect(ha);
175
176         /* Wait for NVRAM to become ready */
177         WRT_REG_WORD(&reg->nvram, NVR_SELECT);
178         do {
179                 NVRAM_DELAY();
180                 word = RD_REG_WORD(&reg->nvram);
181         } while ((word & NVR_DATA_IN) == 0);
182
183         qla2x00_nv_deselect(ha);
184
185         /* Disable writes */
186         qla2x00_nv_write(ha, NVR_DATA_OUT);
187         for (count = 0; count < 10; count++)
188                 qla2x00_nv_write(ha, 0);
189
190         qla2x00_nv_deselect(ha);
191 }
192
193 /**
194  * qla2x00_nvram_request() - Sends read command to NVRAM and gets data from
195  *      NVRAM.
196  * @ha: HA context
197  * @nv_cmd: NVRAM command
198  *
199  * Bit definitions for NVRAM command:
200  *
201  *      Bit 26     = start bit
202  *      Bit 25, 24 = opcode
203  *      Bit 23-16  = address
204  *      Bit 15-0   = write data
205  *
206  * Returns the word read from nvram @addr.
207  */
208 static uint16_t
209 qla2x00_nvram_request(scsi_qla_host_t *ha, uint32_t nv_cmd)
210 {
211         uint8_t         cnt;
212         device_reg_t    *reg = ha->iobase;
213         uint16_t        data = 0;
214         uint16_t        reg_data;
215
216         /* Send command to NVRAM. */
217         nv_cmd <<= 5;
218         for (cnt = 0; cnt < 11; cnt++) {
219                 if (nv_cmd & BIT_31)
220                         qla2x00_nv_write(ha, NVR_DATA_OUT);
221                 else
222                         qla2x00_nv_write(ha, 0);
223                 nv_cmd <<= 1;
224         }
225
226         /* Read data from NVRAM. */
227         for (cnt = 0; cnt < 16; cnt++) {
228                 WRT_REG_WORD(&reg->nvram, NVR_SELECT | NVR_CLOCK);
229                 NVRAM_DELAY();
230                 data <<= 1;
231                 reg_data = RD_REG_WORD(&reg->nvram);
232                 if (reg_data & NVR_DATA_IN)
233                         data |= BIT_0;
234                 WRT_REG_WORD(&reg->nvram, NVR_SELECT);
235                 NVRAM_DELAY();
236                 RD_REG_WORD(&reg->nvram);       /* PCI Posting. */
237         }
238
239         /* Deselect chip. */
240         WRT_REG_WORD(&reg->nvram, NVR_DESELECT);
241         NVRAM_DELAY();
242         RD_REG_WORD(&reg->nvram);               /* PCI Posting. */
243
244         return (data);
245 }
246
247 /**
248  * qla2x00_nv_write() - Clean NVRAM operations.
249  * @ha: HA context
250  */
251 void
252 qla2x00_nv_deselect(scsi_qla_host_t *ha)
253 {
254         device_reg_t *reg = ha->iobase;
255
256         WRT_REG_WORD(&reg->nvram, NVR_DESELECT);
257         NVRAM_DELAY();
258         RD_REG_WORD(&reg->nvram);               /* PCI Posting. */
259 }
260
261 /**
262  * qla2x00_nv_write() - Prepare for NVRAM read/write operation.
263  * @ha: HA context
264  * @data: Serial interface selector
265  */
266 void
267 qla2x00_nv_write(scsi_qla_host_t *ha, uint16_t data)
268 {
269         device_reg_t *reg = ha->iobase;
270
271         WRT_REG_WORD(&reg->nvram, data | NVR_SELECT);
272         NVRAM_DELAY();
273         RD_REG_WORD(&reg->nvram);               /* PCI Posting. */
274         WRT_REG_WORD(&reg->nvram, data | NVR_SELECT | NVR_CLOCK);
275         NVRAM_DELAY();
276         RD_REG_WORD(&reg->nvram);               /* PCI Posting. */
277         WRT_REG_WORD(&reg->nvram, data | NVR_SELECT);
278         NVRAM_DELAY();
279         RD_REG_WORD(&reg->nvram);               /* PCI Posting. */
280 }
281
282 /*
283  * Flash support routines
284  */
285
286 /**
287  * qla2x00_flash_enable() - Setup flash for reading and writing.
288  * @ha: HA context
289  */
290 void
291 qla2x00_flash_enable(scsi_qla_host_t *ha)
292 {
293         uint16_t        data;
294         device_reg_t    *reg = ha->iobase;
295
296         data = RD_REG_WORD(&reg->ctrl_status);
297         data |= CSR_FLASH_ENABLE;
298         WRT_REG_WORD(&reg->ctrl_status, data);
299         RD_REG_WORD(&reg->ctrl_status);         /* PCI Posting. */
300 }
301
302 /**
303  * qla2x00_flash_disable() - Disable flash and allow RISC to run.
304  * @ha: HA context
305  */
306 void
307 qla2x00_flash_disable(scsi_qla_host_t *ha)
308 {
309         uint16_t        data;
310         device_reg_t    *reg = ha->iobase;
311
312         data = RD_REG_WORD(&reg->ctrl_status);
313         data &= ~(CSR_FLASH_ENABLE);
314         WRT_REG_WORD(&reg->ctrl_status, data);
315         RD_REG_WORD(&reg->ctrl_status);         /* PCI Posting. */
316 }
317
318 /**
319  * qla2x00_read_flash_byte() - Reads a byte from flash
320  * @ha: HA context
321  * @addr: Address in flash to read
322  *
323  * A word is read from the chip, but, only the lower byte is valid.
324  *
325  * Returns the byte read from flash @addr.
326  */
327 uint8_t
328 qla2x00_read_flash_byte(scsi_qla_host_t *ha, uint32_t addr)
329 {
330         uint16_t        data;
331         uint16_t        bank_select;
332         device_reg_t    *reg = ha->iobase;
333
334         /* Setup bit 16 of flash address. */
335         bank_select = RD_REG_WORD(&reg->ctrl_status);
336         if ((addr & BIT_16) && ((bank_select & CSR_FLASH_64K_BANK) == 0)) {
337                 bank_select |= CSR_FLASH_64K_BANK;
338                 WRT_REG_WORD(&reg->ctrl_status, bank_select);
339                 RD_REG_WORD(&reg->ctrl_status); /* PCI Posting. */
340         } else if (((addr & BIT_16) == 0) &&
341             (bank_select & CSR_FLASH_64K_BANK)) {
342                 bank_select &= ~(CSR_FLASH_64K_BANK);
343                 WRT_REG_WORD(&reg->ctrl_status, bank_select);
344                 RD_REG_WORD(&reg->ctrl_status); /* PCI Posting. */
345         }
346
347         /* The ISP2312 v2 chip cannot access the FLASH registers via MMIO. */
348         if (IS_QLA2312(ha) && ha->product_id[3] == 0x2 && ha->pio_address) {
349                 uint16_t data2;
350
351                 reg = (device_reg_t *)ha->pio_address;
352                 outw((uint16_t)addr, (unsigned long)(&reg->flash_address));
353                 do {
354                         data = inw((unsigned long)(&reg->flash_data));
355                         barrier();
356                         cpu_relax();
357                         data2 = inw((unsigned long)(&reg->flash_data));
358                 } while (data != data2);
359         } else {
360                 WRT_REG_WORD(&reg->flash_address, (uint16_t)addr);
361                 data = qla2x00_debounce_register(&reg->flash_data);
362         }
363
364         return ((uint8_t)data);
365 }
366
367 /**
368  * qla2x00_write_flash_byte() - Write a byte to flash
369  * @ha: HA context
370  * @addr: Address in flash to write
371  * @data: Data to write
372  */
373 static void
374 qla2x00_write_flash_byte(scsi_qla_host_t *ha, uint32_t addr, uint8_t data)
375 {
376         uint16_t        bank_select;
377         device_reg_t    *reg = ha->iobase;
378
379         /* Setup bit 16 of flash address. */
380         bank_select = RD_REG_WORD(&reg->ctrl_status);
381         if ((addr & BIT_16) && ((bank_select & CSR_FLASH_64K_BANK) == 0)) {
382                 bank_select |= CSR_FLASH_64K_BANK;
383                 WRT_REG_WORD(&reg->ctrl_status, bank_select);
384                 RD_REG_WORD(&reg->ctrl_status); /* PCI Posting. */
385         } else if (((addr & BIT_16) == 0) &&
386             (bank_select & CSR_FLASH_64K_BANK)) {
387                 bank_select &= ~(CSR_FLASH_64K_BANK);
388                 WRT_REG_WORD(&reg->ctrl_status, bank_select);
389                 RD_REG_WORD(&reg->ctrl_status); /* PCI Posting. */
390         }
391
392         /* The ISP2312 v2 chip cannot access the FLASH registers via MMIO. */
393         if (IS_QLA2312(ha) && ha->product_id[3] == 0x2 && ha->pio_address) {
394                 reg = (device_reg_t *)ha->pio_address;
395                 outw((uint16_t)addr, (unsigned long)(&reg->flash_address));
396                 outw((uint16_t)data, (unsigned long)(&reg->flash_data));
397         } else {
398                 WRT_REG_WORD(&reg->flash_address, (uint16_t)addr);
399                 RD_REG_WORD(&reg->ctrl_status);         /* PCI Posting. */
400                 WRT_REG_WORD(&reg->flash_data, (uint16_t)data);
401                 RD_REG_WORD(&reg->ctrl_status);         /* PCI Posting. */
402         }
403 }
404
405 /**
406  * qla2x00_poll_flash() - Polls flash for completion.
407  * @ha: HA context
408  * @addr: Address in flash to poll
409  * @poll_data: Data to be polled
410  * @mid: Flash manufacturer ID
411  *
412  * This function polls the device until bit 7 of what is read matches data
413  * bit 7 or until data bit 5 becomes a 1.  If that hapens, the flash ROM timed
414  * out (a fatal error).  The flash book recommeds reading bit 7 again after
415  * reading bit 5 as a 1.
416  *
417  * Returns 0 on success, else non-zero.
418  */
419 static uint8_t
420 qla2x00_poll_flash(scsi_qla_host_t *ha,
421     uint32_t addr, uint8_t poll_data, uint8_t mid)
422 {
423         uint8_t         status;
424         uint8_t         flash_data;
425         uint32_t        cnt;
426         int             failed_pass;
427
428         status = 1;
429         failed_pass = 1;
430
431         /* Wait for 30 seconds for command to finish. */
432         poll_data &= BIT_7;
433         for (cnt = 3000000; cnt; cnt--) {
434                 flash_data = qla2x00_read_flash_byte(ha, addr);
435                 if ((flash_data & BIT_7) == poll_data) {
436                         status = 0;
437                         break;
438                 }
439
440                 if (mid != 0x40 && mid != 0xda) {
441                         if (flash_data & BIT_5)
442                                 failed_pass--;
443                         if (failed_pass < 0)
444                                 break;
445                 }
446                 udelay(10);
447                 barrier();
448         }
449         return (status);
450 }
451
452 /**
453  * qla2x00_program_flash_address() - Programs a flash address
454  * @ha: HA context
455  * @addr: Address in flash to program
456  * @data: Data to be written in flash
457  * @mid: Flash manufacturer ID
458  *
459  * Returns 0 on success, else non-zero.
460  */
461 static uint8_t
462 qla2x00_program_flash_address(scsi_qla_host_t *ha,
463     uint32_t addr, uint8_t data, uint8_t mid)
464 {
465         /* Write Program Command Sequence */
466         qla2x00_write_flash_byte(ha, 0x5555, 0xaa);
467         qla2x00_write_flash_byte(ha, 0x2aaa, 0x55);
468         qla2x00_write_flash_byte(ha, 0x5555, 0xa0);
469         qla2x00_write_flash_byte(ha, addr, data);
470
471         /* Wait for write to complete. */
472         return (qla2x00_poll_flash(ha, addr, data, mid));
473 }
474
475 /**
476  * qla2x00_erase_flash_sector() - Erase a flash sector.
477  * @ha: HA context
478  * @addr: Flash sector to erase
479  * @sec_mask: Sector address mask
480  * @mid: Flash manufacturer ID
481  *
482  * Returns 0 on success, else non-zero.
483  */
484 static uint8_t
485 qla2x00_erase_flash_sector(scsi_qla_host_t *ha,
486     uint32_t addr, uint32_t sec_mask, uint8_t mid)
487 {
488         /* Individual Sector Erase Command Sequence */
489         qla2x00_write_flash_byte(ha, 0x5555, 0xaa);
490         qla2x00_write_flash_byte(ha, 0x2aaa, 0x55);
491         qla2x00_write_flash_byte(ha, 0x5555, 0x80);
492         qla2x00_write_flash_byte(ha, 0x5555, 0xaa);
493         qla2x00_write_flash_byte(ha, 0x2aaa, 0x55);
494
495         if (mid == 0xda)
496                 qla2x00_write_flash_byte(ha, addr & sec_mask, 0x10);
497         else
498                 qla2x00_write_flash_byte(ha, addr & sec_mask, 0x30);
499
500         udelay(150);
501
502         /* Wait for erase to complete. */
503         return (qla2x00_poll_flash(ha, addr, 0x80, mid));
504 }
505
506 /**
507  * qla2x00_get_flash_manufacturer() - Read manufacturer ID from flash chip.
508  * @ha: HA context
509  *
510  * Returns the manufacturer's ID read from the flash chip.
511  */
512 uint8_t
513 qla2x00_get_flash_manufacturer(scsi_qla_host_t *ha)
514 {
515         uint8_t manuf_id;
516
517         qla2x00_write_flash_byte(ha, 0x5555, 0xaa);
518         qla2x00_write_flash_byte(ha, 0x2aaa, 0x55);
519         qla2x00_write_flash_byte(ha, 0x5555, 0x90);
520         manuf_id = qla2x00_read_flash_byte(ha, 0x0001);
521
522         return (manuf_id);
523 }
524
525 /**
526  * qla2x00_get_flash_version() - Read version information from flash.
527  * @ha: HA context
528  *
529  * Returns QLA_SUCCESS on successful retrieval of flash version.
530  */
531 uint16_t
532 qla2x00_get_flash_version(scsi_qla_host_t *ha)
533 {
534         uint16_t        ret = QLA_SUCCESS;
535         uint32_t        loop_cnt = 1;  /* this is for error exit only */
536         uint32_t        pcir_adr;
537
538         /* The ISP2312 v2 chip cannot access the FLASH registers via MMIO. */
539         if (IS_QLA2312(ha) && ha->product_id[3] == 0x2 && !ha->pio_address)
540                 ret = QLA_FUNCTION_FAILED;
541
542         qla2x00_flash_enable(ha);
543         do {    /* Loop once to provide quick error exit */
544                 /* Match signature */
545                 if (!(qla2x00_read_flash_byte(ha, 0) == 0x55 &&
546                     qla2x00_read_flash_byte(ha, 1) == 0xaa)) {
547                         /* No signature */
548                         DEBUG2(printk("scsi(%ld): No matching FLASH "
549                             "signature.\n", ha->host_no));
550                         ret = QLA_FUNCTION_FAILED;
551                         break;
552                 }
553
554                 pcir_adr = qla2x00_read_flash_byte(ha, 0x18) & 0xff;
555
556                 /* validate signature of PCI data structure */
557                 if ((qla2x00_read_flash_byte(ha, pcir_adr)) == 'P' &&
558                     (qla2x00_read_flash_byte(ha, pcir_adr + 1)) == 'C' &&
559                     (qla2x00_read_flash_byte(ha, pcir_adr + 2)) == 'I' &&
560                     (qla2x00_read_flash_byte(ha, pcir_adr + 3)) == 'R') {
561
562                         /* Read version */
563                         ha->optrom_minor =
564                             qla2x00_read_flash_byte(ha, pcir_adr + 0x12);
565                         ha->optrom_major =
566                             qla2x00_read_flash_byte(ha, pcir_adr + 0x13);
567                         DEBUG3(printk("%s(): got %d.%d.\n",
568                             __func__, ha->optrom_major, ha->optrom_minor));
569                 } else {
570                         /* error */
571                         DEBUG2(printk("%s(): PCI data struct not found. "
572                             "pcir_adr=%x.\n",
573                             __func__, pcir_adr));
574                         ret = QLA_FUNCTION_FAILED;
575                         break;
576                 }
577
578         } while (--loop_cnt);
579         qla2x00_flash_disable(ha);
580
581         return (ret);
582 }
583
584 /**
585  * qla2x00_get_flash_image() - Read image from flash chip.
586  * @ha: HA context
587  * @image: Buffer to receive flash image
588  *
589  * Returns 0 on success, else non-zero.
590  */
591 uint16_t
592 qla2x00_get_flash_image(scsi_qla_host_t *ha, uint8_t *image)
593 {
594         uint32_t        addr;
595         uint32_t        midpoint;
596         uint8_t         *data;
597         device_reg_t    *reg = ha->iobase;
598
599         midpoint = FLASH_IMAGE_SIZE / 2;
600
601         qla2x00_flash_enable(ha);
602         WRT_REG_WORD(&reg->nvram, 0);
603         RD_REG_WORD(&reg->nvram);               /* PCI Posting. */
604         for (addr = 0, data = image; addr < FLASH_IMAGE_SIZE; addr++, data++) {
605                 if (addr == midpoint)
606                         WRT_REG_WORD(&reg->nvram, NVR_SELECT);
607
608                 *data = qla2x00_read_flash_byte(ha, addr);
609         }
610         qla2x00_flash_disable(ha);
611
612         return (0);
613 }
614
615 /**
616  * qla2x00_set_flash_image() - Write image to flash chip.
617  * @ha: HA context
618  * @image: Source image to write to flash
619  *
620  * Returns 0 on success, else non-zero.
621  */
622 uint16_t
623 qla2x00_set_flash_image(scsi_qla_host_t *ha, uint8_t *image)
624 {
625         uint16_t        status;
626         uint32_t        addr;
627         uint32_t        midpoint;
628         uint32_t        sec_mask;
629         uint32_t        rest_addr;
630         uint8_t         mid;
631         uint8_t         sec_number;
632         uint8_t         data;
633         device_reg_t    *reg = ha->iobase;
634
635         status = 0;
636         sec_number = 0;
637
638         /* Reset ISP chip. */
639         WRT_REG_WORD(&reg->ctrl_status, CSR_ISP_SOFT_RESET);
640         RD_REG_WORD(&reg->ctrl_status);         /* PCI Posting. */
641
642         qla2x00_flash_enable(ha);
643         do {    /* Loop once to provide quick error exit */
644                 /* Structure of flash memory based on manufacturer */
645                 mid = qla2x00_get_flash_manufacturer(ha);
646                 if (mid == 0x6d) {
647                         // Am29LV001 part
648                         rest_addr = 0x1fff;
649                         sec_mask = 0x1e000;
650                 } else if (mid == 0x40) {
651                         // Mostel v29c51001 part
652                         rest_addr = 0x1ff;
653                         sec_mask = 0x1fe00;
654                 } else if (mid == 0xbf) {
655                         // SST39sf10 part
656                         rest_addr = 0xfff;
657                         sec_mask = 0x1f000;
658                 } else if (mid == 0xda) {
659                         // Winbond W29EE011 part
660                         rest_addr = 0x7f;
661                         sec_mask = 0x1ff80;
662                         addr = 0;
663                         if (qla2x00_erase_flash_sector(ha, addr, sec_mask,
664                             mid)) {
665                                 status = 1;
666                                 break;
667                         }
668                 } else {
669                         // Am29F010 part
670                         rest_addr = 0x3fff;
671                         sec_mask = 0x1c000;
672                 }
673
674                 midpoint = FLASH_IMAGE_SIZE / 2;
675                 for (addr = 0; addr < FLASH_IMAGE_SIZE; addr++) {
676                         data = *image++;
677                         /* Are we at the beginning of a sector? */
678                         if (!(addr & rest_addr)) {
679                                 if (addr == midpoint)
680                                         WRT_REG_WORD(&reg->nvram, NVR_SELECT);
681
682                                 /* Then erase it */
683                                 if (qla2x00_erase_flash_sector(ha, addr,
684                                     sec_mask, mid)) {
685                                         status = 1;
686                                         break;
687                                 }
688
689                                 sec_number++;
690                         }
691                         if (mid == 0x6d) {
692                                 if (sec_number == 1 &&
693                                     (addr == (rest_addr - 1))) {
694                                         rest_addr = 0x0fff;
695                                         sec_mask   = 0x1f000;
696                                 } else if (sec_number == 3 && (addr & 0x7ffe)) {
697                                         rest_addr = 0x3fff;
698                                         sec_mask   = 0x1c000;
699                                 }
700                         }
701
702                         if (qla2x00_program_flash_address(ha, addr, data,
703                             mid)) {
704                                 status = 1;
705                                 break;
706                         }
707                 }
708         } while (0);
709
710         qla2x00_flash_disable(ha);
711
712         return (status);
713 }