lib/fw.c
/**
 * @brief Write a firmware file to the switchtec device
 * @param[in] dev		Switchtec device handle
 * @param[in] img_fd		File descriptor for the image file to write
 * @param[in] force		If 1, ignore if another download command is
 *			        already in progress.
 * @param[in] dont_activate	If 1, the new image will not be activated
 * @param[in] progress_callback If not NULL, this function will be called to
 * 	indicate the progress.
 * @return 0 on success, error code on failure
 */
@brief Write a firmware file to the switchtec device
@param[in] dev               Switchtec device handle
@param[in] img_fd            File descriptor for the image file to write
@param[in] force             If 1, ignore if another download command is
already in progress.
@param[in] dont_activate     If 1, the new image will not be activated
@param[in] progress_callback If not NULL, this function will be called to
indicate the progress.
@return 0 on success, error code on failure
@brief Write a firmware file to the switchtec device @param [ in ] dev Switchtec device handle @param [ in ] img_fd File descriptor for the image file to write @param [ in ] force If 1 ignore if another download command is already in progress . @param [ in ] dont_activate If 1 the new image will not be activated @param [ in ] progress_callback If not NULL this function will be called to indicate the progress . @return 0 on success error code on failure
int switchtec_fw_write_fd(struct switchtec_dev *dev, int img_fd,
			  int dont_activate, int force,
			  void (*progress_callback)(int cur, int tot))
{
	enum switchtec_fw_dlstatus status;
	enum mrpc_bg_status bgstatus;
	ssize_t image_size, offset = 0;
	int ret;
	struct cmd_fwdl cmd = {};
	image_size = lseek(img_fd, 0, SEEK_END);
	if (image_size < 0)
		return -errno;
	lseek(img_fd, 0, SEEK_SET);
	switchtec_fw_dlstatus(dev, &status, &bgstatus);
	if (!force && status == SWITCHTEC_DLSTAT_INPROGRESS) {
		errno = EBUSY;
		return -EBUSY;
	}
	if (bgstatus == MRPC_BG_STAT_INPROGRESS) {
		errno = EBUSY;
		return -EBUSY;
	}
	cmd.hdr.subcmd = MRPC_FWDNLD_DOWNLOAD;
	cmd.hdr.dont_activate = !!dont_activate;
	cmd.hdr.img_length = htole32(image_size);
	while (offset < image_size) {
		ssize_t blklen = read(img_fd, &cmd.data,
				      sizeof(cmd.data));
		if (blklen == -EAGAIN || blklen == -EWOULDBLOCK)
			continue;
		if (blklen < 0)
			return -errno;
		if (blklen == 0)
			break;
		cmd.hdr.offset = htole32(offset);
		cmd.hdr.blk_length = htole32(blklen);
		ret = switchtec_cmd(dev, MRPC_FWDNLD, &cmd, sizeof(cmd),
				    NULL, 0);
		if (ret < 0)
			return ret;
		ret = switchtec_fw_wait(dev, &status);
		if (ret != 0)
		    return ret;
		offset += cmd.hdr.blk_length;
		if (progress_callback)
			progress_callback(offset, image_size);
	}
	if (status == SWITCHTEC_DLSTAT_COMPLETES)
		return 0;
	if (status == SWITCHTEC_DLSTAT_SUCCESS_FIRM_ACT)
		return 0;
	if (status == SWITCHTEC_DLSTAT_SUCCESS_DATA_ACT)
		return 0;
	if (status == 0)
		return SWITCHTEC_DLSTAT_HARDWARE_ERR;
	return status;
}
int switchtec_fw_write_fd ( struct switchtec_dev * dev , int img_fd , int dont_activate , int force , void ( * progress_callback ) ( int cur , int tot ) ) { enum switchtec_fw_dlstatus status ; enum mrpc_bg_status bgstatus ; ssize_t image_size , offset = 0 ; int ret ; struct cmd_fwdl cmd = { } ; image_size = lseek ( img_fd , 0 , SEEK_END ) ; if ( image_size < 0 ) return - errno ; lseek ( img_fd , 0 , SEEK_SET ) ; switchtec_fw_dlstatus ( dev , & status , & bgstatus ) ; if ( ! force && status == SWITCHTEC_DLSTAT_INPROGRESS ) { errno = EBUSY ; return - EBUSY ; } if ( bgstatus == MRPC_BG_STAT_INPROGRESS ) { errno = EBUSY ; return - EBUSY ; } cmd . hdr . subcmd = MRPC_FWDNLD_DOWNLOAD ; cmd . hdr . dont_activate = ! ! dont_activate ; cmd . hdr . img_length = htole32 ( image_size ) ; while ( offset < image_size ) { ssize_t blklen = read ( img_fd , & cmd . data , sizeof ( cmd . data ) ) ; if ( blklen == - EAGAIN || blklen == - EWOULDBLOCK ) continue ; if ( blklen < 0 ) return - errno ; if ( blklen == 0 ) break ; cmd . hdr . offset = htole32 ( offset ) ; cmd . hdr . blk_length = htole32 ( blklen ) ; ret = switchtec_cmd ( dev , MRPC_FWDNLD , & cmd , sizeof ( cmd ) , NULL , 0 ) ; if ( ret < 0 ) return ret ; ret = switchtec_fw_wait ( dev , & status ) ; if ( ret != 0 ) return ret ; offset += cmd . hdr . blk_length ; if ( progress_callback ) progress_callback ( offset , image_size ) ; } if ( status == SWITCHTEC_DLSTAT_COMPLETES ) return 0 ; if ( status == SWITCHTEC_DLSTAT_SUCCESS_FIRM_ACT ) return 0 ; if ( status == SWITCHTEC_DLSTAT_SUCCESS_DATA_ACT ) return 0 ; if ( status == 0 ) return SWITCHTEC_DLSTAT_HARDWARE_ERR ; return status ; }
@brief Write a firmware file to the switchtec device
 @param[in] dev               Switchtec device handle
 @param[in] img_fd            File descriptor for the image file to write
 @param[in] force             If 1, ignore if another download command is
                              already in progress.
@brief Write a firmware file to the switchtec device @param [ in ] dev Switchtec device handle @param [ in ] img_fd File descriptor for the image file to write @param [ in ] force If 1 ignore if another download command is already in progress .