@@ -97,7 +97,7 @@ qla2x00_write_nvram_word(scsi_qla_host_t *ha, uint32_t addr, uint16_t data)
97
97
{
98
98
int count ;
99
99
uint16_t word ;
100
- uint32_t nv_cmd ;
100
+ uint32_t nv_cmd , wait_cnt ;
101
101
struct device_reg_2xxx __iomem * reg = & ha -> iobase -> isp ;
102
102
103
103
qla2x00_nv_write (ha , NVR_DATA_OUT );
@@ -127,7 +127,13 @@ qla2x00_write_nvram_word(scsi_qla_host_t *ha, uint32_t addr, uint16_t data)
127
127
/* Wait for NVRAM to become ready */
128
128
WRT_REG_WORD (& reg -> nvram , NVR_SELECT );
129
129
RD_REG_WORD (& reg -> nvram ); /* PCI Posting. */
130
+ wait_cnt = NVR_WAIT_CNT ;
130
131
do {
132
+ if (!-- wait_cnt ) {
133
+ DEBUG9_10 (printk ("%s(%ld): NVRAM didn't go ready...\n" ,
134
+ __func__ , ha -> host_no ));
135
+ break ;
136
+ }
131
137
NVRAM_DELAY ();
132
138
word = RD_REG_WORD (& reg -> nvram );
133
139
} while ((word & NVR_DATA_IN ) == 0 );
@@ -301,16 +307,17 @@ qla2x00_clear_nvram_protection(scsi_qla_host_t *ha)
301
307
{
302
308
int ret , stat ;
303
309
struct device_reg_2xxx __iomem * reg = & ha -> iobase -> isp ;
304
- uint32_t word ;
310
+ uint32_t word , wait_cnt ;
305
311
uint16_t wprot , wprot_old ;
306
312
307
313
/* Clear NVRAM write protection. */
308
314
ret = QLA_FUNCTION_FAILED ;
309
- wprot_old = cpu_to_le16 (qla2x00_get_nvram_word (ha , 0 ));
310
- stat = qla2x00_write_nvram_word_tmo (ha , 0 ,
315
+
316
+ wprot_old = cpu_to_le16 (qla2x00_get_nvram_word (ha , ha -> nvram_base ));
317
+ stat = qla2x00_write_nvram_word_tmo (ha , ha -> nvram_base ,
311
318
__constant_cpu_to_le16 (0x1234 ), 100000 );
312
- wprot = cpu_to_le16 (qla2x00_get_nvram_word (ha , 0 ));
313
- if (stat != QLA_SUCCESS || wprot != __constant_cpu_to_le16 ( 0x1234 ) ) {
319
+ wprot = cpu_to_le16 (qla2x00_get_nvram_word (ha , ha -> nvram_base ));
320
+ if (stat != QLA_SUCCESS || wprot != 0x1234 ) {
314
321
/* Write enable. */
315
322
qla2x00_nv_write (ha , NVR_DATA_OUT );
316
323
qla2x00_nv_write (ha , 0 );
@@ -341,14 +348,22 @@ qla2x00_clear_nvram_protection(scsi_qla_host_t *ha)
341
348
/* Wait for NVRAM to become ready. */
342
349
WRT_REG_WORD (& reg -> nvram , NVR_SELECT );
343
350
RD_REG_WORD (& reg -> nvram ); /* PCI Posting. */
351
+ wait_cnt = NVR_WAIT_CNT ;
344
352
do {
353
+ if (!-- wait_cnt ) {
354
+ DEBUG9_10 (printk ("%s(%ld): NVRAM didn't go "
355
+ "ready...\n" , __func__ ,
356
+ ha -> host_no ));
357
+ break ;
358
+ }
345
359
NVRAM_DELAY ();
346
360
word = RD_REG_WORD (& reg -> nvram );
347
361
} while ((word & NVR_DATA_IN ) == 0 );
348
362
349
- ret = QLA_SUCCESS ;
363
+ if (wait_cnt )
364
+ ret = QLA_SUCCESS ;
350
365
} else
351
- qla2x00_write_nvram_word (ha , 0 , wprot_old );
366
+ qla2x00_write_nvram_word (ha , ha -> nvram_base , wprot_old );
352
367
353
368
return ret ;
354
369
}
@@ -357,7 +372,7 @@ static void
357
372
qla2x00_set_nvram_protection (scsi_qla_host_t * ha , int stat )
358
373
{
359
374
struct device_reg_2xxx __iomem * reg = & ha -> iobase -> isp ;
360
- uint32_t word ;
375
+ uint32_t word , wait_cnt ;
361
376
362
377
if (stat != QLA_SUCCESS )
363
378
return ;
@@ -393,7 +408,13 @@ qla2x00_set_nvram_protection(scsi_qla_host_t *ha, int stat)
393
408
/* Wait for NVRAM to become ready. */
394
409
WRT_REG_WORD (& reg -> nvram , NVR_SELECT );
395
410
RD_REG_WORD (& reg -> nvram ); /* PCI Posting. */
411
+ wait_cnt = NVR_WAIT_CNT ;
396
412
do {
413
+ if (!-- wait_cnt ) {
414
+ DEBUG9_10 (printk ("%s(%ld): NVRAM didn't go ready...\n" ,
415
+ __func__ , ha -> host_no ));
416
+ break ;
417
+ }
397
418
NVRAM_DELAY ();
398
419
word = RD_REG_WORD (& reg -> nvram );
399
420
} while ((word & NVR_DATA_IN ) == 0 );
@@ -500,6 +521,20 @@ qla24xx_get_flash_manufacturer(scsi_qla_host_t *ha, uint8_t *man_id,
500
521
ids = qla24xx_read_flash_dword (ha , flash_data_to_access_addr (0xd03ab ));
501
522
* man_id = LSB (ids );
502
523
* flash_id = MSB (ids );
524
+
525
+ /* Check if man_id and flash_id are valid. */
526
+ if (ids != 0xDEADDEAD && (* man_id == 0 || * flash_id == 0 )) {
527
+ /* Read information using 0x9f opcode
528
+ * Device ID, Mfg ID would be read in the format:
529
+ * <Ext Dev Info><Device ID Part2><Device ID Part 1><Mfg ID>
530
+ * Example: ATMEL 0x00 01 45 1F
531
+ * Extract MFG and Dev ID from last two bytes.
532
+ */
533
+ ids = qla24xx_read_flash_dword (ha ,
534
+ flash_data_to_access_addr (0xd009f ));
535
+ * man_id = LSB (ids );
536
+ * flash_id = MSB (ids );
537
+ }
503
538
}
504
539
505
540
int
@@ -508,8 +543,8 @@ qla24xx_write_flash_data(scsi_qla_host_t *ha, uint32_t *dwptr, uint32_t faddr,
508
543
{
509
544
int ret ;
510
545
uint32_t liter ;
511
- uint32_t sec_mask , rest_addr , conf_addr ;
512
- uint32_t fdata ;
546
+ uint32_t sec_mask , rest_addr , conf_addr , sec_end_mask ;
547
+ uint32_t fdata , findex ;
513
548
uint8_t man_id , flash_id ;
514
549
struct device_reg_24xx __iomem * reg = & ha -> iobase -> isp24 ;
515
550
@@ -519,6 +554,7 @@ qla24xx_write_flash_data(scsi_qla_host_t *ha, uint32_t *dwptr, uint32_t faddr,
519
554
DEBUG9 (printk ("%s(%ld): Flash man_id=%d flash_id=%d\n" , __func__ ,
520
555
ha -> host_no , man_id , flash_id ));
521
556
557
+ sec_end_mask = 0 ;
522
558
conf_addr = flash_conf_to_access_addr (0x03d8 );
523
559
switch (man_id ) {
524
560
case 0xbf : /* STT flash. */
@@ -531,6 +567,12 @@ qla24xx_write_flash_data(scsi_qla_host_t *ha, uint32_t *dwptr, uint32_t faddr,
531
567
rest_addr = 0x3fff ;
532
568
sec_mask = 0x3c000 ;
533
569
break ;
570
+ case 0x1f : // Atmel 26DF081A
571
+ rest_addr = 0x0fff ;
572
+ sec_mask = 0xff000 ;
573
+ sec_end_mask = 0x003ff ;
574
+ conf_addr = flash_conf_to_access_addr (0x0320 );
575
+ break ;
534
576
default :
535
577
/* Default to 64 kb sector size. */
536
578
rest_addr = 0x3fff ;
@@ -545,11 +587,30 @@ qla24xx_write_flash_data(scsi_qla_host_t *ha, uint32_t *dwptr, uint32_t faddr,
545
587
546
588
/* Disable flash write-protection. */
547
589
qla24xx_write_flash_dword (ha , flash_conf_to_access_addr (0x101 ), 0 );
590
+ /* Some flash parts need an additional zero-write to clear bits.*/
591
+ qla24xx_write_flash_dword (ha , flash_conf_to_access_addr (0x101 ), 0 );
548
592
549
593
do { /* Loop once to provide quick error exit. */
550
594
for (liter = 0 ; liter < dwords ; liter ++ , faddr ++ , dwptr ++ ) {
595
+ if (man_id == 0x1f ) {
596
+ findex = faddr << 2 ;
597
+ fdata = findex & sec_mask ;
598
+ } else {
599
+ findex = faddr ;
600
+ fdata = (findex & sec_mask ) << 2 ;
601
+ }
602
+
551
603
/* Are we at the beginning of a sector? */
552
- if ((faddr & rest_addr ) == 0 ) {
604
+ if ((findex & rest_addr ) == 0 ) {
605
+ /*
606
+ * Do sector unprotect at 4K boundry for Atmel
607
+ * part.
608
+ */
609
+ if (man_id == 0x1f )
610
+ qla24xx_write_flash_dword (ha ,
611
+ flash_conf_to_access_addr (0x0339 ),
612
+ (fdata & 0xff00 ) | ((fdata << 16 ) &
613
+ 0xff0000 ) | ((fdata >> 16 ) & 0xff ));
553
614
fdata = (faddr & sec_mask ) << 2 ;
554
615
ret = qla24xx_write_flash_dword (ha , conf_addr ,
555
616
(fdata & 0xff00 ) |((fdata << 16 ) &
@@ -570,6 +631,14 @@ qla24xx_write_flash_data(scsi_qla_host_t *ha, uint32_t *dwptr, uint32_t faddr,
570
631
ha -> host_no , faddr , * dwptr ));
571
632
break ;
572
633
}
634
+
635
+ /* Do sector protect at 4K boundry for Atmel part. */
636
+ if (man_id == 0x1f &&
637
+ ((faddr & sec_end_mask ) == 0x3ff ))
638
+ qla24xx_write_flash_dword (ha ,
639
+ flash_conf_to_access_addr (0x0336 ),
640
+ (fdata & 0xff00 ) | ((fdata << 16 ) &
641
+ 0xff0000 ) | ((fdata >> 16 ) & 0xff ));
573
642
}
574
643
} while (0 );
575
644
0 commit comments