@@ -425,6 +425,9 @@ qla2x00_set_nvram_protection(scsi_qla_host_t *ha, int stat)
425
425
/* Flash Manipulation Routines */
426
426
/*****************************************************************************/
427
427
428
+ #define OPTROM_BURST_SIZE 0x1000
429
+ #define OPTROM_BURST_DWORDS (OPTROM_BURST_SIZE / 4)
430
+
428
431
static inline uint32_t
429
432
flash_conf_to_access_addr (uint32_t faddr )
430
433
{
@@ -544,41 +547,59 @@ qla24xx_write_flash_data(scsi_qla_host_t *ha, uint32_t *dwptr, uint32_t faddr,
544
547
uint32_t dwords )
545
548
{
546
549
int ret ;
547
- uint32_t liter ;
548
- uint32_t sec_mask , rest_addr , conf_addr , sec_end_mask ;
550
+ uint32_t liter , miter ;
551
+ uint32_t sec_mask , rest_addr , conf_addr ;
549
552
uint32_t fdata , findex ;
550
553
uint8_t man_id , flash_id ;
551
554
struct device_reg_24xx __iomem * reg = & ha -> iobase -> isp24 ;
555
+ dma_addr_t optrom_dma ;
556
+ void * optrom = NULL ;
557
+ uint32_t * s , * d ;
552
558
553
559
ret = QLA_SUCCESS ;
554
560
561
+ /* Prepare burst-capable write on supported ISPs. */
562
+ if (IS_QLA25XX (ha ) && !(faddr & ~OPTROM_BURST_SIZE ) &&
563
+ dwords > OPTROM_BURST_DWORDS ) {
564
+ optrom = dma_alloc_coherent (& ha -> pdev -> dev , OPTROM_BURST_SIZE ,
565
+ & optrom_dma , GFP_KERNEL );
566
+ if (!optrom ) {
567
+ qla_printk (KERN_DEBUG , ha ,
568
+ "Unable to allocate memory for optrom burst write "
569
+ "(%x KB).\n" , OPTROM_BURST_SIZE / 1024 );
570
+ }
571
+ }
572
+
555
573
qla24xx_get_flash_manufacturer (ha , & man_id , & flash_id );
556
574
DEBUG9 (printk ("%s(%ld): Flash man_id=%d flash_id=%d\n" , __func__ ,
557
575
ha -> host_no , man_id , flash_id ));
558
576
559
- sec_end_mask = 0 ;
560
577
conf_addr = flash_conf_to_access_addr (0x03d8 );
561
578
switch (man_id ) {
562
579
case 0xbf : /* STT flash. */
563
- rest_addr = 0x1fff ;
564
- sec_mask = 0x3e000 ;
580
+ if (flash_id == 0x8e ) {
581
+ rest_addr = 0x3fff ;
582
+ sec_mask = 0x7c000 ;
583
+ } else {
584
+ rest_addr = 0x1fff ;
585
+ sec_mask = 0x7e000 ;
586
+ }
565
587
if (flash_id == 0x80 )
566
588
conf_addr = flash_conf_to_access_addr (0x0352 );
567
589
break ;
568
590
case 0x13 : /* ST M25P80. */
569
591
rest_addr = 0x3fff ;
570
- sec_mask = 0x3c000 ;
592
+ sec_mask = 0x7c000 ;
571
593
break ;
572
594
case 0x1f : // Atmel 26DF081A
573
- rest_addr = 0x0fff ;
574
- sec_mask = 0xff000 ;
575
- sec_end_mask = 0x003ff ;
595
+ rest_addr = 0x3fff ;
596
+ sec_mask = 0x7c000 ;
576
597
conf_addr = flash_conf_to_access_addr (0x0320 );
577
598
break ;
578
599
default :
579
600
/* Default to 64 kb sector size. */
580
601
rest_addr = 0x3fff ;
581
- sec_mask = 0x3c000 ;
602
+ sec_mask = 0x7c000 ;
582
603
break ;
583
604
}
584
605
@@ -592,56 +613,81 @@ qla24xx_write_flash_data(scsi_qla_host_t *ha, uint32_t *dwptr, uint32_t faddr,
592
613
/* Some flash parts need an additional zero-write to clear bits.*/
593
614
qla24xx_write_flash_dword (ha , flash_conf_to_access_addr (0x101 ), 0 );
594
615
595
- do { /* Loop once to provide quick error exit. */
596
- for (liter = 0 ; liter < dwords ; liter ++ , faddr ++ , dwptr ++ ) {
597
- if (man_id == 0x1f ) {
598
- findex = faddr << 2 ;
599
- fdata = findex & sec_mask ;
600
- } else {
601
- findex = faddr ;
602
- fdata = (findex & sec_mask ) << 2 ;
603
- }
616
+ for (liter = 0 ; liter < dwords ; liter ++ , faddr ++ , dwptr ++ ) {
617
+ if (man_id == 0x1f ) {
618
+ findex = faddr << 2 ;
619
+ fdata = findex & sec_mask ;
620
+ } else {
621
+ findex = faddr ;
622
+ fdata = (findex & sec_mask ) << 2 ;
623
+ }
604
624
605
- /* Are we at the beginning of a sector? */
606
- if ((findex & rest_addr ) == 0 ) {
607
- /*
608
- * Do sector unprotect at 4K boundry for Atmel
609
- * part.
610
- */
611
- if (man_id == 0x1f )
612
- qla24xx_write_flash_dword (ha ,
613
- flash_conf_to_access_addr (0x0339 ),
614
- (fdata & 0xff00 ) | ((fdata << 16 ) &
615
- 0xff0000 ) | ((fdata >> 16 ) & 0xff ));
616
- ret = qla24xx_write_flash_dword (ha , conf_addr ,
617
- (fdata & 0xff00 ) |((fdata << 16 ) &
625
+ /* Are we at the beginning of a sector? */
626
+ if ((findex & rest_addr ) == 0 ) {
627
+ /* Do sector unprotect at 4K boundry for Atmel part. */
628
+ if (man_id == 0x1f )
629
+ qla24xx_write_flash_dword (ha ,
630
+ flash_conf_to_access_addr (0x0339 ),
631
+ (fdata & 0xff00 ) | ((fdata << 16 ) &
618
632
0xff0000 ) | ((fdata >> 16 ) & 0xff ));
619
- if (ret != QLA_SUCCESS ) {
620
- DEBUG9 (printk ("%s(%ld) Unable to flash "
621
- "sector: address=%x.\n" , __func__ ,
622
- ha -> host_no , faddr ));
623
- break ;
624
- }
633
+ ret = qla24xx_write_flash_dword (ha , conf_addr ,
634
+ (fdata & 0xff00 ) |((fdata << 16 ) &
635
+ 0xff0000 ) | ((fdata >> 16 ) & 0xff ));
636
+ if (ret != QLA_SUCCESS ) {
637
+ DEBUG9 (printk ("%s(%ld) Unable to flash "
638
+ "sector: address=%x.\n" , __func__ ,
639
+ ha -> host_no , faddr ));
640
+ break ;
625
641
}
626
- ret = qla24xx_write_flash_dword (ha ,
642
+ }
643
+
644
+ /* Go with burst-write. */
645
+ if (optrom && (liter + OPTROM_BURST_DWORDS ) < dwords ) {
646
+ /* Copy data to DMA'ble buffer. */
647
+ for (miter = 0 , s = optrom , d = dwptr ;
648
+ miter < OPTROM_BURST_DWORDS ; miter ++ , s ++ , d ++ )
649
+ * s = cpu_to_le32 (* d );
650
+
651
+ ret = qla2x00_load_ram (ha , optrom_dma ,
627
652
flash_data_to_access_addr (faddr ),
628
- cpu_to_le32 ( * dwptr ) );
653
+ OPTROM_BURST_DWORDS );
629
654
if (ret != QLA_SUCCESS ) {
630
- DEBUG9 (printk ("%s(%ld) Unable to program flash "
631
- "address=%x data=%x.\n" , __func__ ,
632
- ha -> host_no , faddr , * dwptr ));
633
- break ;
655
+ qla_printk (KERN_WARNING , ha ,
656
+ "Unable to burst-write optrom segment "
657
+ "(%x/%x/%llx).\n" , ret ,
658
+ flash_data_to_access_addr (faddr ),
659
+ optrom_dma );
660
+ qla_printk (KERN_WARNING , ha ,
661
+ "Reverting to slow-write.\n" );
662
+
663
+ dma_free_coherent (& ha -> pdev -> dev ,
664
+ OPTROM_BURST_SIZE , optrom , optrom_dma );
665
+ optrom = NULL ;
666
+ } else {
667
+ liter += OPTROM_BURST_DWORDS - 1 ;
668
+ faddr += OPTROM_BURST_DWORDS - 1 ;
669
+ dwptr += OPTROM_BURST_DWORDS - 1 ;
670
+ continue ;
634
671
}
672
+ }
635
673
636
- /* Do sector protect at 4K boundry for Atmel part. */
637
- if ( man_id == 0x1f &&
638
- (( faddr & sec_end_mask ) == 0x3ff ))
639
- qla24xx_write_flash_dword ( ha ,
640
- flash_conf_to_access_addr ( 0x0336 ) ,
641
- ( fdata & 0xff00 ) | (( fdata << 16 ) &
642
- 0xff0000 ) | (( fdata >> 16 ) & 0xff )) ;
674
+ ret = qla24xx_write_flash_dword ( ha ,
675
+ flash_data_to_access_addr ( faddr ), cpu_to_le32 ( * dwptr ));
676
+ if ( ret != QLA_SUCCESS ) {
677
+ DEBUG9 ( printk ( "%s(%ld) Unable to program flash "
678
+ "address=%x data=%x.\n" , __func__ ,
679
+ ha -> host_no , faddr , * dwptr ));
680
+ break ;
643
681
}
644
- } while (0 );
682
+
683
+ /* Do sector protect at 4K boundry for Atmel part. */
684
+ if (man_id == 0x1f &&
685
+ ((faddr & rest_addr ) == rest_addr ))
686
+ qla24xx_write_flash_dword (ha ,
687
+ flash_conf_to_access_addr (0x0336 ),
688
+ (fdata & 0xff00 ) | ((fdata << 16 ) &
689
+ 0xff0000 ) | ((fdata >> 16 ) & 0xff ));
690
+ }
645
691
646
692
/* Enable flash write-protection. */
647
693
qla24xx_write_flash_dword (ha , flash_conf_to_access_addr (0x101 ), 0x9c );
@@ -651,6 +697,10 @@ qla24xx_write_flash_data(scsi_qla_host_t *ha, uint32_t *dwptr, uint32_t faddr,
651
697
RD_REG_DWORD (& reg -> ctrl_status ) & ~CSRX_FLASH_ENABLE );
652
698
RD_REG_DWORD (& reg -> ctrl_status ); /* PCI Posting. */
653
699
700
+ if (optrom )
701
+ dma_free_coherent (& ha -> pdev -> dev ,
702
+ OPTROM_BURST_SIZE , optrom , optrom_dma );
703
+
654
704
return ret ;
655
705
}
656
706
@@ -1728,15 +1778,13 @@ qla24xx_read_optrom_data(struct scsi_qla_host *ha, uint8_t *buf,
1728
1778
{
1729
1779
/* Suspend HBA. */
1730
1780
scsi_block_requests (ha -> host );
1731
- ha -> isp_ops -> disable_intrs (ha );
1732
1781
set_bit (MBX_UPDATE_FLASH_ACTIVE , & ha -> mbx_cmd_flags );
1733
1782
1734
1783
/* Go with read. */
1735
1784
qla24xx_read_flash_data (ha , (uint32_t * )buf , offset >> 2 , length >> 2 );
1736
1785
1737
1786
/* Resume HBA. */
1738
1787
clear_bit (MBX_UPDATE_FLASH_ACTIVE , & ha -> mbx_cmd_flags );
1739
- ha -> isp_ops -> enable_intrs (ha );
1740
1788
scsi_unblock_requests (ha -> host );
1741
1789
1742
1790
return buf ;
@@ -1750,7 +1798,6 @@ qla24xx_write_optrom_data(struct scsi_qla_host *ha, uint8_t *buf,
1750
1798
1751
1799
/* Suspend HBA. */
1752
1800
scsi_block_requests (ha -> host );
1753
- ha -> isp_ops -> disable_intrs (ha );
1754
1801
set_bit (MBX_UPDATE_FLASH_ACTIVE , & ha -> mbx_cmd_flags );
1755
1802
1756
1803
/* Go with write. */
@@ -1767,6 +1814,70 @@ qla24xx_write_optrom_data(struct scsi_qla_host *ha, uint8_t *buf,
1767
1814
return rval ;
1768
1815
}
1769
1816
1817
+ uint8_t *
1818
+ qla25xx_read_optrom_data (struct scsi_qla_host * ha , uint8_t * buf ,
1819
+ uint32_t offset , uint32_t length )
1820
+ {
1821
+ int rval ;
1822
+ dma_addr_t optrom_dma ;
1823
+ void * optrom ;
1824
+ uint8_t * pbuf ;
1825
+ uint32_t faddr , left , burst ;
1826
+
1827
+ if (offset & ~OPTROM_BURST_SIZE )
1828
+ goto slow_read ;
1829
+ if (length < OPTROM_BURST_SIZE )
1830
+ goto slow_read ;
1831
+
1832
+ optrom = dma_alloc_coherent (& ha -> pdev -> dev , OPTROM_BURST_SIZE ,
1833
+ & optrom_dma , GFP_KERNEL );
1834
+ if (!optrom ) {
1835
+ qla_printk (KERN_DEBUG , ha ,
1836
+ "Unable to allocate memory for optrom burst read "
1837
+ "(%x KB).\n" , OPTROM_BURST_SIZE / 1024 );
1838
+
1839
+ goto slow_read ;
1840
+ }
1841
+
1842
+ pbuf = buf ;
1843
+ faddr = offset >> 2 ;
1844
+ left = length >> 2 ;
1845
+ burst = OPTROM_BURST_DWORDS ;
1846
+ while (left != 0 ) {
1847
+ if (burst > left )
1848
+ burst = left ;
1849
+
1850
+ rval = qla2x00_dump_ram (ha , optrom_dma ,
1851
+ flash_data_to_access_addr (faddr ), burst );
1852
+ if (rval ) {
1853
+ qla_printk (KERN_WARNING , ha ,
1854
+ "Unable to burst-read optrom segment "
1855
+ "(%x/%x/%llx).\n" , rval ,
1856
+ flash_data_to_access_addr (faddr ), optrom_dma );
1857
+ qla_printk (KERN_WARNING , ha ,
1858
+ "Reverting to slow-read.\n" );
1859
+
1860
+ dma_free_coherent (& ha -> pdev -> dev , OPTROM_BURST_SIZE ,
1861
+ optrom , optrom_dma );
1862
+ goto slow_read ;
1863
+ }
1864
+
1865
+ memcpy (pbuf , optrom , burst * 4 );
1866
+
1867
+ left -= burst ;
1868
+ faddr += burst ;
1869
+ pbuf += burst * 4 ;
1870
+ }
1871
+
1872
+ dma_free_coherent (& ha -> pdev -> dev , OPTROM_BURST_SIZE , optrom ,
1873
+ optrom_dma );
1874
+
1875
+ return buf ;
1876
+
1877
+ slow_read :
1878
+ return qla24xx_read_optrom_data (ha , buf , offset , length );
1879
+ }
1880
+
1770
1881
/**
1771
1882
* qla2x00_get_fcode_version() - Determine an FCODE image's version.
1772
1883
* @ha: HA context
0 commit comments