#include <libintl.h>
#include <fwflash/fwflash.h>
#include <scsi/libscsi.h>
extern struct vrfyplugin *verifier;
char vendor[] = "GENERIC";
int
vendorvrfy(struct devicelist *dvp)
{
libscsi_hdl_t *hdl = NULL;
libscsi_target_t *targ = NULL;
libscsi_action_t *act = NULL;
libscsi_errno_t serr;
spc3_read_buffer_cdb_t *rb_cdb;
uint8_t descbuf[4];
uint32_t size;
int ret = FWFLASH_FAILURE;
if ((hdl = libscsi_init(LIBSCSI_VERSION, &serr)) == NULL) {
logmsg(MSG_ERROR, gettext("%s: failed to initialize "
"libscsi: %s\n"),
verifier->vendor, libscsi_strerror(serr));
return (FWFLASH_FAILURE);
}
if ((targ = libscsi_open(hdl, NULL, dvp->access_devname)) ==
NULL) {
logmsg(MSG_ERROR,
gettext("%s: unable to open device %s\n"),
verifier->vendor, dvp->access_devname);
goto cleanup;
}
if ((act = libscsi_action_alloc(hdl, SPC3_CMD_READ_BUFFER,
LIBSCSI_AF_READ, descbuf, sizeof (descbuf))) == NULL) {
logmsg(MSG_ERROR, "%s: failed to alloc scsi action: %s\n",
verifier->vendor, libscsi_errmsg(hdl));
goto cleanup;
}
rb_cdb = (spc3_read_buffer_cdb_t *)libscsi_action_get_cdb(act);
rb_cdb->rbc_mode = SPC3_RB_MODE_DESCRIPTOR;
rb_cdb->rbc_bufferid = 0;
rb_cdb->rbc_allocation_len[0] = 0;
rb_cdb->rbc_allocation_len[1] = 0;
rb_cdb->rbc_allocation_len[2] = sizeof (descbuf);
if (libscsi_exec(act, targ) != 0) {
logmsg(MSG_ERROR, gettext("%s: failed to execute SCSI buffer "
"descriptor read: %s\n"), verifier->vendor,
libscsi_errmsg(hdl));
goto cleanup;
}
if (libscsi_action_get_status(act) != SAM4_STATUS_GOOD) {
logmsg(MSG_ERROR, gettext("%s: SCSI READ BUFFER command to "
"determine maximum image size failed\n"), verifier->vendor);
goto cleanup;
}
if (descbuf[0] == 0 && descbuf[1] == 0 && descbuf[2] == 0 &&
descbuf[3] == 0) {
logmsg(MSG_ERROR, gettext("%s: devices %s does not support "
"firmware upgrade\n"), verifier->vendor,
dvp->access_devname);
goto cleanup;
}
size = (descbuf[1] << 16) | (descbuf[2] << 8) | descbuf[3];
logmsg(MSG_INFO, gettext("%s: checking maximum image size %u against "
"actual image size: %u\n"), verifier->vendor, size,
verifier->imgsize);
if (size < verifier->imgsize) {
logmsg(MSG_ERROR, gettext("%s: supplied firmware image %s "
"exceeds maximum image size of %u\n"),
verifier->vendor, verifier->imgfile, size);
goto cleanup;
}
logmsg(MSG_INFO, gettext("%s: successfully validated images %s\n"),
verifier->vendor, verifier->imgfile);
verifier->flashbuf = 0;
ret = FWFLASH_SUCCESS;
cleanup:
if (act != NULL)
libscsi_action_free(act);
if (targ != NULL)
libscsi_close(hdl, targ);
if (hdl != NULL)
libscsi_fini(hdl);
return (ret);
}