Firmware can be reprogrammed on devices from Hitachi, HP, IBM, Plextor, Quantum, and Seagate. At least one device from each manufacturer has been tested with some version of this code, and it has been used to update thousands of drives so far. The man page suggests having a backup of the drive's data, and the operation must be confirmed, either interactively or on the command line. (This is the same as the confirmation on the format command.) This work is largely derived from fwprog.c by Andre Albsmeier. Submitted by: Nima Misaghian Sponsored by: Sandvine Incorporated MFC after: 3 months
185 lines
4.3 KiB
C
185 lines
4.3 KiB
C
/*
|
|
* Written By Julian ELischer
|
|
* Copyright julian Elischer 1993.
|
|
* Permission is granted to use or redistribute this file in any way as long
|
|
* as this notice remains. Julian Elischer does not guarantee that this file
|
|
* is totally correct for any given task and users of this file must
|
|
* accept responsibility for any damage that occurs from the application of this
|
|
* file.
|
|
*
|
|
* (julian@tfs.com julian@dialix.oz.au)
|
|
*
|
|
* User SCSI hooks added by Peter Dufault:
|
|
*
|
|
* Copyright (c) 1994 HD Associates
|
|
* (contact: dufault@hda.com)
|
|
* All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions
|
|
* are met:
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
* documentation and/or other materials provided with the distribution.
|
|
* 3. The name of HD Associates
|
|
* may not be used to endorse or promote products derived from this software
|
|
* without specific prior written permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY HD ASSOCIATES ``AS IS'' AND
|
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
* ARE DISCLAIMED. IN NO EVENT SHALL HD ASSOCIATES BE LIABLE
|
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
* SUCH DAMAGE.
|
|
*/
|
|
/*
|
|
* Taken from the original scsi(8) program.
|
|
* from: scsi.c,v 1.17 1998/01/12 07:57:57 charnier Exp $";
|
|
*/
|
|
#include <sys/cdefs.h>
|
|
__FBSDID("$FreeBSD$");
|
|
|
|
#include <sys/stdint.h>
|
|
#include <sys/types.h>
|
|
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
|
|
#include <camlib.h>
|
|
#include "camcontrol.h"
|
|
|
|
int verbose;
|
|
|
|
/* iget: Integer argument callback
|
|
*/
|
|
int
|
|
iget(void *hook, char *name)
|
|
{
|
|
struct get_hook *h = (struct get_hook *)hook;
|
|
int arg;
|
|
|
|
if (h->got >= h->argc)
|
|
{
|
|
fprintf(stderr, "Expecting an integer argument.\n");
|
|
usage(0);
|
|
exit(1);
|
|
}
|
|
arg = strtol(h->argv[h->got], 0, 0);
|
|
h->got++;
|
|
|
|
if (verbose && name && *name)
|
|
printf("%s: %d\n", name, arg);
|
|
|
|
return arg;
|
|
}
|
|
|
|
/* cget: char * argument callback
|
|
*/
|
|
char *
|
|
cget(void *hook, char *name)
|
|
{
|
|
struct get_hook *h = (struct get_hook *)hook;
|
|
char *arg;
|
|
|
|
if (h->got >= h->argc)
|
|
{
|
|
fprintf(stderr, "Expecting a character pointer argument.\n");
|
|
usage(0);
|
|
exit(1);
|
|
}
|
|
arg = h->argv[h->got];
|
|
h->got++;
|
|
|
|
if (verbose && name)
|
|
printf("cget: %s: %s", name, arg);
|
|
|
|
return arg;
|
|
}
|
|
|
|
/* arg_put: "put argument" callback
|
|
*/
|
|
void
|
|
arg_put(void *hook __unused, int letter, void *arg, int count, char *name)
|
|
{
|
|
if (verbose && name && *name)
|
|
printf("%s: ", name);
|
|
|
|
switch(letter)
|
|
{
|
|
case 'i':
|
|
case 'b':
|
|
printf("%jd ", (intmax_t)(intptr_t)arg);
|
|
break;
|
|
|
|
case 'c':
|
|
case 'z':
|
|
{
|
|
char *p;
|
|
|
|
p = malloc(count + 1);
|
|
if (p == NULL) {
|
|
fprintf(stderr, "can't malloc memory for p\n");
|
|
exit(1);
|
|
}
|
|
|
|
bzero(p, count +1);
|
|
strncpy(p, (char *)arg, count);
|
|
if (letter == 'z')
|
|
{
|
|
int i;
|
|
for (i = count - 1; i >= 0; i--)
|
|
if (p[i] == ' ')
|
|
p[i] = 0;
|
|
else
|
|
break;
|
|
}
|
|
printf("%s ", p);
|
|
|
|
free(p);
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
printf("Unknown format letter: '%c'\n", letter);
|
|
}
|
|
if (verbose)
|
|
putchar('\n');
|
|
}
|
|
|
|
/*
|
|
* Get confirmation from user
|
|
* Return values:
|
|
* 1: confirmed
|
|
* 0: unconfirmed
|
|
*/
|
|
int
|
|
get_confirmation()
|
|
{
|
|
char str[1024];
|
|
int response = -1;
|
|
|
|
do {
|
|
fprintf(stdout, "Are you SURE you want to do this? (yes/no) ");
|
|
if (fgets(str, sizeof(str), stdin) != NULL) {
|
|
if (strncasecmp(str, "yes", 3) == 0)
|
|
response = 1;
|
|
else if (strncasecmp(str, "no", 2) == 0)
|
|
response = 0;
|
|
else
|
|
fprintf(stdout,
|
|
"Please answer \"yes\" or \"no\"\n");
|
|
} else
|
|
response = 0;
|
|
} while (response == -1);
|
|
return (response);
|
|
}
|