uint8_t ssc_write_attributes(struct scsi_cmd *cmd) { int sz; struct priv_lu_ssc *lu_priv; uint8_t *sam_stat; lu_priv = cmd->lu->lu_private; sam_stat = &cmd->dbuf_p->sam_stat; MHVTL_DBG(1, "Write Attributes (%ld) **", (long)cmd->dbuf_p->serialNo); switch (lu_priv->tapeLoaded) { case TAPE_UNLOADED: mkSenseBuf(NOT_READY, E_MEDIUM_NOT_PRESENT, sam_stat); return SAM_STAT_CHECK_CONDITION; break; case TAPE_LOADED: cmd->dbuf_p->sz = get_unaligned_be32(&cmd->scb[10]); sz = retrieve_CDB_data(cmd->cdev, cmd->dbuf_p); MHVTL_DBG(1, " --> Expected to read %d bytes" ", read %d", cmd->dbuf_p->sz, sz); if (resp_write_attribute(cmd) > 0) rewriteMAM(sam_stat); break; default: mkSenseBuf(NOT_READY, E_MEDIUM_FMT_CORRUPT, sam_stat); return SAM_STAT_CHECK_CONDITION; break; } return SAM_STAT_GOOD; }
uint8_t valid_encryption_media(struct scsi_cmd *cmd) { uint8_t *sam_stat = &cmd->dbuf_p->sam_stat; struct lu_phy_attr *lu; struct priv_lu_ssc *lu_priv; lu = cmd->lu; lu_priv = lu->lu_private; if (c_pos->blk_number == 0) { modeBlockDescriptor[0] = lu_priv->pm->native_drive_density->density; mam.MediumDensityCode = modeBlockDescriptor[0]; mam.FormattedDensityCode = modeBlockDescriptor[0]; rewriteMAM(sam_stat); } else { if (mam.MediumDensityCode != lu_priv->pm->native_drive_density->density) { mkSenseBuf(DATA_PROTECT, E_WRITE_PROTECT, sam_stat); return SAM_STAT_CHECK_CONDITION; } } return SAM_STAT_GOOD; }
static uint8_t valid_encryption_media_E06(struct scsi_cmd *cmd) { uint8_t *sam_stat = &cmd->dbuf_p->sam_stat; struct lu_phy_attr *lu; struct priv_lu_ssc *lu_priv; MHVTL_DBG(3, "+++ Trace +++"); lu = cmd->lu; lu_priv = lu->lu_private; if (c_pos->blk_number == 0) { /* 3590 media must be formatted to allow encryption. * This is done by writting an ANSI like label * (NBU label is close enough) to the tape while * an encryption key is in place. The drive doesn't * actually use the key, but sets the tape format */ if (lu_priv->pm->drive_type == drive_3592_E06) { if (lu_priv->ENCRYPT_MODE == 2) { lu_priv->cryptop = NULL; mam.Flags |= MAM_FLAGS_ENCRYPTION_FORMAT; } else mam.Flags &= ~MAM_FLAGS_ENCRYPTION_FORMAT; } modeBlockDescriptor[0] = lu_priv->pm->native_drive_density->density; mam.MediumDensityCode = modeBlockDescriptor[0]; mam.FormattedDensityCode = modeBlockDescriptor[0]; rewriteMAM(sam_stat); } else { /* Extra check for 3592 to be sure the cartridge is * formatted for encryption */ if ((lu_priv->pm->drive_type == drive_3592_E06) && lu_priv->ENCRYPT_MODE && !(mam.Flags & MAM_FLAGS_ENCRYPTION_FORMAT)) { sam_data_protect(E_WRITE_PROTECT, sam_stat); return 0; } if (mam.MediumDensityCode != lu_priv->pm->native_drive_density->density) { switch (lu_priv->pm->drive_type) { case drive_3592_E05: if (mam.MediumDensityCode == medium_density_code_j1a) break; sam_data_protect(E_WRITE_PROTECT, sam_stat); return SAM_STAT_CHECK_CONDITION; break; case drive_3592_E06: if (mam.MediumDensityCode == medium_density_code_e05) break; sam_data_protect(E_WRITE_PROTECT, sam_stat); return SAM_STAT_CHECK_CONDITION; break; case drive_3592_E07: if (mam.MediumDensityCode == medium_density_code_e06) break; sam_data_protect(E_WRITE_PROTECT, sam_stat); return SAM_STAT_CHECK_CONDITION; break; default: sam_data_protect(E_WRITE_PROTECT, sam_stat); return SAM_STAT_CHECK_CONDITION; break; } } } return SAM_STAT_GOOD; }
int main(int argc, char *argv[]) { unsigned char sam_stat; char *progname = argv[0]; char *pcl = NULL; char *mediaType = NULL; char *mediaCapacity = NULL; char *density = NULL; uint64_t size; struct MAM new_mam; char *lib = NULL; int libno = 0; int indx; int rc; char *config = MHVTL_CONFIG_PATH"/device.conf"; FILE *conf; char *b; /* Read from file into this buffer */ char *s; /* Somewhere for sscanf to store results */ if (sizeof(struct MAM) != 1024) { printf("Structure of MAM incorrect size: %d\n", (int)sizeof(struct MAM)); exit(2); } if (argc < 2) { usage(progname); exit(1); } debug = 0; my_id = 0; verbose = 0; wp = 0; while (argc > 0) { if (argv[0][0] == '-') { switch (argv[0][1]) { case 'd': if (argc > 1) density = argv[1]; break; case 'l': if (argc > 1) { lib = argv[1]; } else { puts(" More args needed for -l\n"); exit(1); } break; case 'm': if (argc > 1) { pcl = argv[1]; } else { puts(" More args needed for -m\n"); exit(1); } break; case 's': if (argc > 1) { mediaCapacity = argv[1]; } else { puts(" More args needed for -s\n"); exit(1); } break; case 't': if (argc > 1) { mediaType = argv[1]; } else { puts(" More args needed for -t\n"); exit(1); } break; case 'V': printf("%s: version %s\n%s\n\n", progname, MHVTL_VERSION, (char *)largefile_support); break; case 'v': verbose++; break; case 'w': if (argc > 1) { if (!strncasecmp("yes", argv[1], 3)) wp = WRITE_PROTECT_ON; else if (!strncasecmp("on", argv[1], 3)) wp = WRITE_PROTECT_ON; else wp = WRITE_PROTECT_OFF; } else { puts(" More args needed for -m\n"); exit(1); } break; } } argv++; argc--; } if (pcl == NULL) { printf("Please supply a barcode (-b barcode)\n\n"); usage(progname); exit(1); } conf = fopen(config , "r"); if (!conf) { printf("Can not open config file %s : %s", config, strerror(errno)); perror("Can not open config file"); exit(1); } s = zalloc(MALLOC_SZ); if (!s) { perror("Could not allocate memory"); exit(1); } b = zalloc(MALLOC_SZ); if (!b) { perror("Could not allocate memory"); exit(1); } rc = ENOENT; if (lib) { sscanf(lib, "%d", &libno); printf("Looking for PCL: %s in library %d\n", pcl, libno); find_media_home_directory(home_directory, libno); rc = load_tape(pcl, &sam_stat); } else { /* Walk thru all defined libraries looking for media */ while (readline(b, MALLOC_SZ, conf) != NULL) { if (b[0] == '#') /* Ignore comments */ continue; /* If found a library: Attempt to load media * Break out of loop if found. Otherwise try next lib. */ if (sscanf(b, "Library: %d CHANNEL:", &indx)) { find_media_home_directory(home_directory, indx); rc = load_tape(pcl, &sam_stat); if (!rc) break; } } } fclose(conf); free(s); free(b); if (rc) { fprintf(stderr, "PCL %s cannot be dumped, " "load_tape() returned %d\n", pcl, rc); exit(1); } /* Copy media MAM into temp location */ memcpy(&new_mam, &mam, sizeof(mam)); size = 0L; if (mediaCapacity) { sscanf(mediaCapacity, "%" PRId64, &size); printf("New capacity for %s: %ldMB\n", pcl, (unsigned long)size); } if (mediaType) { if (!strncasecmp("clean", mediaType, 5)) { MHVTL_DBG(1, "Setting media type to CLEAN"); new_mam.MediumType = MEDIA_TYPE_CLEAN; new_mam.MediumTypeInformation = 20; } else if (!strncasecmp("data", mediaType, 4)) { MHVTL_DBG(1, "Setting media type to DATA"); new_mam.MediumType = MEDIA_TYPE_DATA; } else if (!strncasecmp("null", mediaType, 4)) { MHVTL_DBG(1, "Setting media type to NULL"); new_mam.MediumType = MEDIA_TYPE_NULL; } else if (!strncasecmp("WORM", mediaType, 4)) { MHVTL_DBG(1, "Setting media type to NULL"); new_mam.MediumType = MEDIA_TYPE_WORM; } else { printf("Unknown media type: %s\n", mediaType); usage(progname); exit(1); } } if (density) { printf("Setting density to %s\n", density); if (set_media_params(&new_mam, density)) { printf("Could not determine media density: %s\n", density); unload_tape(&sam_stat); exit(1); } } if (size) { put_unaligned_be64(size * 1048576, &new_mam.max_capacity); /* This will set incorrect value to start with but next media * Usage, this will be recalculated correctly */ put_unaligned_be64(size * 1048576, &new_mam.remaining_capacity); } switch (wp) { case WRITE_PROTECT_ON: new_mam.Flags |= MAM_FLAGS_MEDIA_WRITE_PROTECT; printf("Setting write-protect for %s\n", pcl); break; case WRITE_PROTECT_OFF: new_mam.Flags &= ~MAM_FLAGS_MEDIA_WRITE_PROTECT; printf("Turning off write-protect for %s\n", pcl); break; } put_unaligned_be64(sizeof(mam.pad), &new_mam.MAMSpaceRemaining); memcpy(&mam, &new_mam, sizeof(mam)); rewriteMAM(&sam_stat); unload_tape(&sam_stat); exit(0); }