FreeBSD/sbin/camcontrol/fwdownload.c
/* 
 * Download firmware stored in buf to cam_dev. If simulation mode
 * is enabled, only show what packet sizes would be sent to the 
 * device but do not sent any actual packets
 */
Download firmware stored in buf to cam_dev. If simulation mode
is enabled, only show what packet sizes would be sent to the
device but do not sent any actual packets
Download firmware stored in buf to cam_dev . If simulation mode is enabled only show what packet sizes would be sent to the device but do not sent any actual packets
static int
fw_download_img(struct cam_device *cam_dev, struct fw_vendor *vp,
    char *buf, int img_size, int sim_mode, int printerrors, int quiet, 
    int retry_count, int timeout, const char *imgname,
    camcontrol_devtype devtype)
{
	struct scsi_write_buffer cdb;
	progress_t progress;
	int size = 0;
	union ccb *ccb = NULL;
	int pkt_count = 0;
	int max_pkt_size;
	u_int32_t pkt_size = 0;
	char *pkt_ptr = buf;
	u_int32_t offset;
	int last_pkt = 0;
	int retval = 0;
	retval = fw_check_device_ready(cam_dev, devtype, vp, printerrors,
				       timeout);
	if (retval != 0)
		goto bailout;
	if ((ccb = cam_getccb(cam_dev)) == NULL) {
		warnx("Could not allocate CCB");
		retval = 1;
		goto bailout;
	}
	CCB_CLEAR_ALL_EXCEPT_HDR(ccb);
	max_pkt_size = vp->max_pkt_size;
	if (max_pkt_size == 0)
		max_pkt_size = UNKNOWN_MAX_PKT_SIZE;
	pkt_size = max_pkt_size;
	progress_init(&progress, imgname, size = img_size);
	do {
		if (img_size <= max_pkt_size) {
			last_pkt = 1;
			pkt_size = img_size;
		}
		progress_update(&progress, size - img_size);
		if (((sim_mode == 0) && (quiet == 0))
		 || ((sim_mode != 0) && (printerrors == 0)))
			progress_draw(&progress);
		bzero(&cdb, sizeof(cdb));
		switch (devtype) {
		case CC_DT_SCSI:
			cdb.opcode  = WRITE_BUFFER;
			cdb.control = 0;
			scsi_ulto3b(pkt_size, &cdb.length[0]);
			offset = vp->inc_cdb_offset ? (pkt_ptr - buf) : 0;
			scsi_ulto3b(offset, &cdb.offset[0]);
			cdb.byte2 = last_pkt ? vp->cdb_byte2_last :
					       vp->cdb_byte2;
			cdb.buffer_id = vp->inc_cdb_buffer_id ? pkt_count : 0;
			CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
			bcopy(&cdb, &ccb->csio.cdb_io.cdb_bytes[0],
			    sizeof(struct scsi_write_buffer));
			cam_fill_csio(&ccb->csio,		
			    retry_count,			
			    NULL,				
			    CAM_DIR_OUT | CAM_DEV_QFRZDIS,	
			    CAM_TAG_ACTION_NONE,		
			    (u_char *)pkt_ptr,			
			    pkt_size,				
			    SSD_FULL_SIZE,			
			    sizeof(struct scsi_write_buffer),	
			    timeout ? timeout : WB_TIMEOUT);	
			break;
		case CC_DT_ATA:
		case CC_DT_ATA_BEHIND_SCSI: {
			uint32_t	off;
			off = (uint32_t)(pkt_ptr - buf);
			retval = build_ata_cmd(ccb,
			     retry_count,
			     CAM_DIR_OUT | CAM_DEV_QFRZDIS,
			     CAM_TAG_ACTION_NONE,
			     AP_PROTO_PIO_OUT,
			     AP_FLAG_BYT_BLOK_BYTES |
					  AP_FLAG_TLEN_SECT_CNT |
					  AP_FLAG_TDIR_TO_DEV,
			     USE_OFFSETS_FEATURE,
			     ATA_MAKE_SECTORS(pkt_size),
			     ATA_MAKE_LBA(off, pkt_size),
			     ATA_DOWNLOAD_MICROCODE,
			     0,
			     (uint8_t *)pkt_ptr,
			     pkt_size,
			     NULL,
			     0,
			     SSD_FULL_SIZE,
			     timeout ? timeout : WB_TIMEOUT,
			     0,
			     devtype);
			if (retval != 0) {
				warnx("%s: build_ata_cmd() failed, likely "
				    "programmer error", __func__);
				goto bailout;
			}
			break;
		}
		default:
			warnx("Unknown device type %d", devtype);
			retval = 1;
			goto bailout;
			break; 
		}
		if (!sim_mode) {
			if (cam_send_ccb(cam_dev, ccb) < 0 ||
			    (ccb->ccb_h.status & CAM_STATUS_MASK) !=
			    CAM_REQ_CMP) {
				warnx("Error writing image to device");
				if (printerrors)
					cam_error_print(cam_dev, ccb,
					    CAM_ESF_ALL, CAM_EPF_ALL, stderr);
				retval = 1;
				goto bailout;
			}
		} else if (printerrors) {
			cam_error_print(cam_dev, ccb, CAM_ESF_COMMAND, 0,
			    stdout);
		}
		pkt_count++;
		pkt_ptr += pkt_size;
		img_size -= pkt_size;
	} while(!last_pkt);
bailout:
	if (quiet == 0)
		progress_complete(&progress, size - img_size);
	if (ccb != NULL)
		cam_freeccb(ccb);
	return (retval);
}
static int fw_download_img ( struct cam_device * cam_dev , struct fw_vendor * vp , char * buf , int img_size , int sim_mode , int printerrors , int quiet , int retry_count , int timeout , const char * imgname , camcontrol_devtype devtype ) { struct scsi_write_buffer cdb ; progress_t progress ; int size = 0 ; union ccb * ccb = NULL ; int pkt_count = 0 ; int max_pkt_size ; u_int32_t pkt_size = 0 ; char * pkt_ptr = buf ; u_int32_t offset ; int last_pkt = 0 ; int retval = 0 ; retval = fw_check_device_ready ( cam_dev , devtype , vp , printerrors , timeout ) ; if ( retval != 0 ) goto bailout ; if ( ( ccb = cam_getccb ( cam_dev ) ) == NULL ) { warnx ( " " ) ; retval = 1 ; goto bailout ; } CCB_CLEAR_ALL_EXCEPT_HDR ( ccb ) ; max_pkt_size = vp -> max_pkt_size ; if ( max_pkt_size == 0 ) max_pkt_size = UNKNOWN_MAX_PKT_SIZE ; pkt_size = max_pkt_size ; progress_init ( & progress , imgname , size = img_size ) ; do { if ( img_size <= max_pkt_size ) { last_pkt = 1 ; pkt_size = img_size ; } progress_update ( & progress , size - img_size ) ; if ( ( ( sim_mode == 0 ) && ( quiet == 0 ) ) || ( ( sim_mode != 0 ) && ( printerrors == 0 ) ) ) progress_draw ( & progress ) ; bzero ( & cdb , sizeof ( cdb ) ) ; switch ( devtype ) { case CC_DT_SCSI : cdb . opcode = WRITE_BUFFER ; cdb . control = 0 ; scsi_ulto3b ( pkt_size , & cdb . length [ 0 ] ) ; offset = vp -> inc_cdb_offset ? ( pkt_ptr - buf ) : 0 ; scsi_ulto3b ( offset , & cdb . offset [ 0 ] ) ; cdb . byte2 = last_pkt ? vp -> cdb_byte2_last : vp -> cdb_byte2 ; cdb . buffer_id = vp -> inc_cdb_buffer_id ? pkt_count : 0 ; CCB_CLEAR_ALL_EXCEPT_HDR ( & ccb -> csio ) ; bcopy ( & cdb , & ccb -> csio . cdb_io . cdb_bytes [ 0 ] , sizeof ( struct scsi_write_buffer ) ) ; cam_fill_csio ( & ccb -> csio , retry_count , NULL , CAM_DIR_OUT | CAM_DEV_QFRZDIS , CAM_TAG_ACTION_NONE , ( u_char * ) pkt_ptr , pkt_size , SSD_FULL_SIZE , sizeof ( struct scsi_write_buffer ) , timeout ? timeout : WB_TIMEOUT ) ; break ; case CC_DT_ATA : case CC_DT_ATA_BEHIND_SCSI : { uint32_t off ; off = ( uint32_t ) ( pkt_ptr - buf ) ; retval = build_ata_cmd ( ccb , retry_count , CAM_DIR_OUT | CAM_DEV_QFRZDIS , CAM_TAG_ACTION_NONE , AP_PROTO_PIO_OUT , AP_FLAG_BYT_BLOK_BYTES | AP_FLAG_TLEN_SECT_CNT | AP_FLAG_TDIR_TO_DEV , USE_OFFSETS_FEATURE , ATA_MAKE_SECTORS ( pkt_size ) , ATA_MAKE_LBA ( off , pkt_size ) , ATA_DOWNLOAD_MICROCODE , 0 , ( uint8_t * ) pkt_ptr , pkt_size , NULL , 0 , SSD_FULL_SIZE , timeout ? timeout : WB_TIMEOUT , 0 , devtype ) ; if ( retval != 0 ) { warnx ( " " " " , __func__ ) ; goto bailout ; } break ; } default : warnx ( " " , devtype ) ; retval = 1 ; goto bailout ; break ; } if ( ! sim_mode ) { if ( cam_send_ccb ( cam_dev , ccb ) < 0 || ( ccb -> ccb_h . status & CAM_STATUS_MASK ) != CAM_REQ_CMP ) { warnx ( " " ) ; if ( printerrors ) cam_error_print ( cam_dev , ccb , CAM_ESF_ALL , CAM_EPF_ALL , stderr ) ; retval = 1 ; goto bailout ; } } else if ( printerrors ) { cam_error_print ( cam_dev , ccb , CAM_ESF_COMMAND , 0 , stdout ) ; } pkt_count ++ ; pkt_ptr += pkt_size ; img_size -= pkt_size ; } while ( ! last_pkt ) ; bailout : if ( quiet == 0 ) progress_complete ( & progress , size - img_size ) ; if ( ccb != NULL ) cam_freeccb ( ccb ) ; return ( retval ) ; }
Download firmware stored in buf to cam_dev.
Download firmware stored in buf to cam_dev .
/*
	 * Check to see whether the device is ready to accept a firmware
	 * download.
	 */ /* Download single fw packets. */ /* Parameter list length. */ /* Zero out payload of ccb union after ccb header. */ /*
			 * Copy previously constructed cdb into ccb_scsiio
			 * struct.
			 */ /* Fill rest of ccb_scsiio struct. */ /* ccb_scsiio*/ /* retries*/ /* cbfcnp*/ /* flags*/ /* tag_action*/ /* data_ptr*/ /* dxfer_len*/ /* sense_len*/ /* cdb_len*/ /* timeout*/ /*retry_count*/ /*flags*/ /*tag_action*/ /*protocol*/ /*ata_flags*/ /*features*/ /*sector_count*/ /*lba*/ /*command*/ /*auxiliary*/ /*data_ptr*/ /*dxfer_len*/ /*cdb_storage*/ /*cdb_storage_len*/ /*sense_len*/ /*timeout*/ /*is48bit*/ /*devtype*/ /*NOTREACHED*/ /* Execute the command. */ /* Prepare next round. */