Subject: Re: low-level formatting a SCSI drive?
To: Sean Doran <smd@ebone.net>
From: Matthew Jacob <mjacob@feral.com>
List: port-alpha
Date: 10/28/1998 12:48:57
On Wed, 28 Oct 1998, Sean Doran wrote:

> 
> Is there some magic incantation to SRM or some means within -current
> to tell a SCSI drive to go format itself?
> 
> The controller is the builtin NCR in an AlphaStation 200, if that helps.
> 
> Pointers appreciated.
> 
> 

Why do you need to format it?

And anyway, w/o BIOS support you don't get formatting/verify
functions on Alpha.

Otherwise, below is a tool that'll work under NetBSD. Use at your
own risk!!


> 	Sean. (starting to really like this architecture, though...)

What NetBSD's SCSI architecture? It loses...NetBSD? Well, that's
okay. Alpha? Yes- quite nice in many ways.

-matt
/*
 * Copyright (c) 1997 by Feral Software
 */
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <memory.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/scsiio.h>

static void make_uscsi(scsireq_t *, int, int, int);
static void free_uscsi(scsireq_t *);
static void run_uscsi(scsireq_t *, int, const char *);
static void getprint_rqsdata(scsireq_t *, int, const char *);


int
main(int a, char **v)
{
	static const char *usage = "usage: %s device\n";
	scsireq_t working;
	int rval;
	int fd;

	if (a != 2) {
		fprintf(stderr, usage, v[0]);
		return (1);
	}
	fd = open(*++v, O_RDWR|O_NDELAY);
	if (fd < 0) {
		perror(*v);
		return (1);
	}
	make_uscsi(&working, 6, 4+4, SCCMD_WRITE);
working.cmd[0] = 4;
working.cmd[1] = 0x10;
working.cmd[4] = 1;
working.databuf[1] = 0x88;
	run_uscsi(&working, fd, "FMT");
	free_uscsi(&working);
	return (0);
}

static void
make_uscsi(scsireq_t *wp, int cdbsize, int bufsize, int flags)
{
	memset((char *) wp, 0, sizeof (*wp));
	wp->cmdlen = cdbsize;
	if (bufsize) {
		wp->databuf = malloc(bufsize);
		memset(wp->databuf, 0, bufsize);
		wp->datalen = bufsize;
	} else {
		wp->databuf = NULL;
		wp->datalen = 0;
	}
	wp->timeout = 60 * 60 * 4;
	wp->flags = (u_long) flags;
}

static void
free_uscsi(scsireq_t *wp)
{
	if (wp->databuf)
		free(wp->databuf);
}

static void
run_uscsi(scsireq_t *wp, int fd, const char *cmd)
{
	int r;

	wp->status = 0;
	r = ioctl(fd, SCIOCCOMMAND, (caddr_t) wp);
	if (wp->status == 2) {
		getprint_rqsdata(wp, fd, cmd);
	} else if (r < 0) {
		fprintf(stderr, "SCIOCCOMMAND ioctl fails for command %s: %s\n",
		    cmd, strerror(errno));
		exit (1);
	} else if (wp->status != 0) {
		fprintf(stderr, "Non-zero status (%x) on command %s\n",
		    wp->status, cmd);
		exit (1);
	}
}

static void
getprint_rqsdata(scsireq_t *wp, int fd, const char *cmd)
{
	fprintf(stderr, "%s AUTOSENSE: Key=0x%x ASC/ASCQ=0x%02x/0x%02x\n",
	       cmd, wp->sense[2] & 0xf, wp->sense[12] & 0xff,
	       wp->sense[13] & 0xff);
}