static bool _io_init(spi_device_t *dev, struct gpio_pin *cs) { do { if (!gpio_configure(cs)) break; gpio_set(cs); if (!device_open(dev)) break; device_setup(dev, SPI_DEVICE_PARAMETER_CLOCK, 1000000UL); device_setup(dev, SPI_DEVICE_PARAMETER_BITS, SPI_8_BIT); device_setup(dev, SPI_DEVICE_PARAMETER_PHASE, SPI_PHASE_0); device_setup(dev, SPI_DEVICE_PARAMETER_POLARITY, SPI_POLARITY_0); device_setup(dev, SPI_DEVICE_PARAMETER_MODE, SPI_MODE_MASTER); device_setup(dev, SPI_DEVICE_PARAMETER_DIRECTION, SPI_DIRECTION_1LINE); if (!device_configure(dev)) break; return true; } while (0); return false; }
/* This function checks the label of a single tape, which may or may not * have been loaded by the changer. With the addition of char *dev, and *slot, * it has the same interface as taper_scan. slot should be the slot where * this tape is found, or NULL if no changer is in use. * Return value is the same as taper_scan. */ int scan_read_label( char *dev, char *slot, char *desired_label, char** label, char** timestamp, char** error_message) { Device * device; char *labelstr; DeviceStatusFlags device_status; char *new_label_errmsg; g_return_val_if_fail(dev != NULL, -1); if (*error_message == NULL) *error_message = stralloc(""); *label = *timestamp = NULL; device = device_open(dev); g_assert(device != NULL); if (device->status != DEVICE_STATUS_SUCCESS ) { *error_message = newvstrallocf(*error_message, _("%sError opening device %s: %s.\n"), *error_message, dev, device_error_or_status(device)); g_object_unref(device); amfree(*timestamp); amfree(*label); return -1; } if (!device_configure(device, TRUE)) { *error_message = newvstrallocf(*error_message, _("%sError configuring device %s: %s.\n"), *error_message, dev, device_error_or_status(device)); g_object_unref(device); amfree(*timestamp); amfree(*label); return -1; } device_status = device_read_label(device); if (device_status == DEVICE_STATUS_SUCCESS && device->volume_label != NULL) { *label = g_strdup(device->volume_label); *timestamp = strdup(device->volume_time); } else if (device_status & DEVICE_STATUS_VOLUME_UNLABELED) { if (!getconf_seen(CNF_LABEL_NEW_TAPES)) { *error_message = newvstrallocf(*error_message, _("%sFound an empty or non-amanda tape.\n"), *error_message); g_object_unref(device); return -1; } /* If we got a header, but the Device doesn't think it's labeled, then this * tape probably has some data on it, so refuse to automatically label it */ if (device->volume_header && device->volume_header->type != F_EMPTY) { *error_message = newvstrallocf(*error_message, _("%sFound a non-amanda tape; check and relabel it with 'amlabel -f'\n"), *error_message); g_object_unref(device); return -1; } g_object_unref(device); *label = find_brand_new_tape_label(&new_label_errmsg); if (*label != NULL) { *timestamp = stralloc("X"); *error_message = newvstrallocf(*error_message, _("%sFound an empty tape, will label it `%s'.\n"), *error_message, *label); return 3; } *error_message = newvstrallocf(*error_message, _("%s%s.\n"), *error_message, new_label_errmsg); return -1; } else { char * label_errstr; label_errstr = g_strdup_printf(_("Error reading label: %s.\n"), device_error_or_status(device)); *error_message = newvstralloc(*error_message, *error_message, label_errstr, NULL); g_free(label_errstr); return -1; } g_assert(*label != NULL && *timestamp != NULL); g_object_unref(device); *error_message = newvstrallocf(*error_message, _("%sread label `%s', date `%s'.\n"), *error_message, *label, *timestamp); /* Register this with the barcode database, even if its not ours. */ if (slot != NULL) { changer_label(slot, *label); } if (desired_label != NULL && strcmp(*label, desired_label) == 0) { /* Got desired label. */ return 1; } /* Is this actually an acceptable tape? */ labelstr = getconf_str(CNF_LABELSTR); if(!match(labelstr, *label)) { *error_message = newvstrallocf(*error_message, _("%slabel \"%s\" doesn't match \"%s\".\n"), *error_message, *label, labelstr); return -1; } else { tape_t *tp; if (strcmp(*timestamp, "X") == 0) { /* new, labeled tape. */ return 1; } tp = lookup_tapelabel(*label); if(tp == NULL) { *error_message = newvstrallocf(*error_message, _("%slabel \"%s\" matches labelstr but it is" " not listed in the tapelist file.\n"), *error_message, *label); return -1; } else if(tp != NULL && !reusable_tape(tp)) { *error_message = newvstrallocf(*error_message, _("%sTape with label %s is still active" " and cannot be overwritten.\n"), *error_message, *label); return -1; } } /* Yay! We got a good tape! */ return 2; }
static gboolean label_new_tape(taper_state_t * state, dump_info_t * dump_info) { char *old_volume_name = NULL; char *old_volume_time = NULL; tape_search_request_t request; gboolean search_result; DeviceStatusFlags status; /* If we got here, it means that we have found a tape to label and * have gotten permission from the driver to write it. But we * still can say NO-NEW-TAPE if a problem shows up, and must still * say NEW-TAPE if one doesn't. */ amfree(state->last_errmsg); state->device = device_open(state->next_tape_device); g_assert(state->device != NULL); amfree(state->next_tape_device); if (state->device->status != DEVICE_STATUS_SUCCESS) goto skip_volume; if (!device_configure(state->device, TRUE)) goto skip_volume; /* if we have an error, and are sure it isn't just an unlabeled volume, * then skip this volume */ status = device_read_label(state->device); if ((status & ~DEVICE_STATUS_VOLUME_UNLABELED) && !(status & DEVICE_STATUS_VOLUME_UNLABELED)) goto skip_volume; old_volume_name = g_strdup(state->device->volume_label); old_volume_time = g_strdup(state->device->volume_time); if (!device_start(state->device, ACCESS_WRITE, state->next_tape_label, state->driver_start_time)) { gboolean tape_used; /* Something broke, see if we can tell if the volume was erased or * not. */ g_fprintf(stderr, "taper: Error writing label %s to device %s: %s.\n", state->next_tape_label, state->device->device_name, device_error_or_status(state->device)); if (!device_finish(state->device)) goto request_new_volume; /* This time, if we can't read the label, assume we've overwritten * the volume or otherwise corrupted it */ status = device_read_label(state->device); if ((status & ~DEVICE_STATUS_VOLUME_UNLABELED) && !(status & DEVICE_STATUS_VOLUME_UNLABELED)) goto request_new_volume; tape_used = check_volume_changed(state->device, old_volume_name, old_volume_time); if (tape_used) goto request_new_volume; else goto skip_volume; } amfree(old_volume_name); amfree(old_volume_time); amfree(state->next_tape_label); update_tapelist(state); state->cur_tape++; if (state->have_changer && changer_label("UNKNOWN", state->device->volume_label) != 0) { error(_("couldn't update barcode database")); /*NOTREACHED*/ } log_add(L_START, "datestamp %s label %s tape %d", state->driver_start_time, state->device->volume_label, state->cur_tape); putresult(NEW_TAPE, "%s %s\n", dump_info->handle, state->device->volume_label); return TRUE; request_new_volume: /* Tell the driver we overwrote this volume, even if it was empty, and request * a new volume. */ if (state->device) state->last_errmsg = newstralloc(state->last_errmsg, device_error_or_status(state->device)); else state->last_errmsg = newstralloc(state->last_errmsg, "(unknown)"); putresult(NEW_TAPE, "%s %s\n", dump_info->handle, state->next_tape_label); if (old_volume_name) { log_add(L_WARNING, "Problem writing label '%s' to volume %s " "(volume may be erased): %s\n", state->next_tape_label, old_volume_name, state->last_errmsg); } else { log_add(L_WARNING, "Problem writing label '%s' to new volume " "(volume may be erased): %s\n", state->next_tape_label, state->last_errmsg); } if (state->device) { g_object_unref(state->device); state->device = NULL; } amfree(state->next_tape_label); amfree(old_volume_name); amfree(old_volume_time); return find_and_label_new_tape(state, dump_info); skip_volume: /* grab a new volume without talking to the driver again -- we do this if we're * confident we didn't overwrite the last tape we got. */ if (state->device) state->last_errmsg = newstralloc(state->last_errmsg, device_error_or_status(state->device)); else state->last_errmsg = newstralloc(state->last_errmsg, "(unknown)"); if (old_volume_name) { log_add(L_WARNING, "Problem writing label '%s' to volume '%s' " "(old volume data intact): %s\n", state->next_tape_label, old_volume_name, state->last_errmsg); } else { log_add(L_WARNING, "Problem writing label '%s' to new volume " "(old volume data intact): %s\n", state->next_tape_label, state->last_errmsg); } if (state->device) { g_object_unref(state->device); state->device = NULL; } amfree(state->next_tape_label); amfree(old_volume_name); amfree(old_volume_time); request.state = state; request.prolong = TRUE; request.errmsg = NULL; search_result = GPOINTER_TO_INT(tape_search_thread(&request)); if (search_result) { amfree(request.errmsg); return label_new_tape(state, dump_info); } else { /* Problem finding a new tape! */ log_taper_scan_errmsg(request.errmsg); putresult(NO_NEW_TAPE, "%s\n", dump_info->handle); return FALSE; } }