FreeBSD/sys/dev/cxgbe/common/t4_hw.c
/**
 *	t4_write_flash - write up to a page of data to the serial flash
 *	@adapter: the adapter
 *	@addr: the start address to write
 *	@n: length of data to write in bytes
 *	@data: the data to write
 *	@byte_oriented: whether to store data as bytes or as words
 *
 *	Writes up to a page of data (256 bytes) to the serial flash starting
 *	at the given address.  All the data must be written to the same page.
 *	If @byte_oriented is set the write data is stored as byte stream
 *	(i.e. matches what on disk), otherwise in big-endian.
 */


Writes up to a page of data (256 bytes) to the serial flash starting
at the given address.  All the data must be written to the same page.
If @byte_oriented is set the write data is stored as byte stream
, otherwise in big-endian.
Writes up to a page of data ( 256 bytes ) to the serial flash starting at the given address . All the data must be written to the same page . If @byte_oriented is set the write data is stored as byte stream otherwise in big - endian .
int t4_write_flash(struct adapter *adapter, unsigned int addr,
			  unsigned int n, const u8 *data, int byte_oriented)
{
	int ret;
	u32 buf[SF_PAGE_SIZE / 4];
	unsigned int i, c, left, val, offset = addr & 0xff;
	if (addr >= adapter->params.sf_size || offset + n > SF_PAGE_SIZE)
		return -EINVAL;
	val = swab32(addr) | SF_PROG_PAGE;
	if ((ret = sf1_write(adapter, 1, 0, 1, SF_WR_ENABLE)) != 0 ||
	    (ret = sf1_write(adapter, 4, 1, 1, val)) != 0)
		goto unlock;
	for (left = n; left; left -= c) {
		c = min(left, 4U);
		for (val = 0, i = 0; i < c; ++i)
			val = (val << 8) + *data++;
		if (!byte_oriented)
			val = cpu_to_be32(val);
		ret = sf1_write(adapter, c, c != left, 1, val);
		if (ret)
			goto unlock;
	}
	ret = flash_wait_op(adapter, 8, 1);
	if (ret)
		goto unlock;
	t4_write_reg(adapter, A_SF_OP, 0);    
	ret = t4_read_flash(adapter, addr & ~0xff, ARRAY_SIZE(buf), buf,
			    byte_oriented);
	if (ret)
		return ret;
	if (memcmp(data - n, (u8 *)buf + offset, n)) {
		CH_ERR(adapter,
			"failed to correctly write the flash page at %#x\n",
			addr);
		return -EIO;
	}
	return 0;
unlock:
	t4_write_reg(adapter, A_SF_OP, 0);    
	return ret;
}
int t4_write_flash ( struct adapter * adapter , unsigned int addr , unsigned int n , const u8 * data , int byte_oriented ) { int ret ; u32 buf [ SF_PAGE_SIZE / 4 ] ; unsigned int i , c , left , val , offset = addr & 0xff ; if ( addr >= adapter -> params . sf_size || offset + n > SF_PAGE_SIZE ) return - EINVAL ; val = swab32 ( addr ) | SF_PROG_PAGE ; if ( ( ret = sf1_write ( adapter , 1 , 0 , 1 , SF_WR_ENABLE ) ) != 0 || ( ret = sf1_write ( adapter , 4 , 1 , 1 , val ) ) != 0 ) goto unlock ; for ( left = n ; left ; left -= c ) { c = min ( left , 4U ) ; for ( val = 0 , i = 0 ; i < c ; ++ i ) val = ( val << 8 ) + * data ++ ; if ( ! byte_oriented ) val = cpu_to_be32 ( val ) ; ret = sf1_write ( adapter , c , c != left , 1 , val ) ; if ( ret ) goto unlock ; } ret = flash_wait_op ( adapter , 8 , 1 ) ; if ( ret ) goto unlock ; t4_write_reg ( adapter , A_SF_OP , 0 ) ; ret = t4_read_flash ( adapter , addr & ~ 0xff , ARRAY_SIZE ( buf ) , buf , byte_oriented ) ; if ( ret ) return ret ; if ( memcmp ( data - n , ( u8 * ) buf + offset , n ) ) { CH_ERR ( adapter , " \n " , addr ) ; return - EIO ; } return 0 ; unlock : t4_write_reg ( adapter , A_SF_OP , 0 ) ; return ret ; }
t4_write_flash - write up to a page of data to the serial flash
      @adapter: the adapter
      @addr: the start address to write
      @n: length of data to write in bytes
      @data: the data to write
      @byte_oriented: whether to store data as bytes or as words
t4_write_flash - write up to a page of data to the serial flash @adapter : the adapter @addr : the start address to write @n : length of data to write in bytes @data : the data to write @byte_oriented : whether to store data as bytes or as words
/* unlock SF */ /* Read the page to verify the write succeeded */ /* unlock SF */