BETA ST-01 (p3 of 3)

Michael Grenier mike at cimcor.mn.org
Wed Jan 2 12:07:34 AEST 1991


#!/bin/sh
# this is st01.03 (part 3 of st01)
# do not concatenate these parts, unpack them in order with /bin/sh
# file scsi.c continued
#
if touch 2>&1 | fgrep 'amc' > /dev/null
 then TOUCH=touch
 else TOUCH=true
fi
if test ! -r shar3_seq_.tmp; then
	echo "Please unpack part 1 first!"
	exit 1
fi
(read Scheck
 if test "$Scheck" != 3; then
	echo "Please unpack part $Scheck next!"
	exit 1
 else
	exit 0
 fi
) < shar3_seq_.tmp || exit 1
echo "x - Continuing file scsi.c"
sed 's/^X//' << 'SHAR_EOF' >> scsi.c &&
X  buf[15] = 0xff; /* Threshold */
X  buf[16] = 0x34; /* Max Prefetch size */
X  buf[17] = 0; /* Fill out rest of structure */
X  buf[18] = 0; /* Fill out rest of structure */
X  buf[19] = 0; /* Fill out rest of structure */
X  buf[20] = 0; /* Fill out rest of structure */
X  buf[21] = 0; /* Fill out rest of structure */
X  buf[22] = 0; /* Fill out rest of structure */
X  buf[23] = 0; /* Fill out rest of structure */
X  buf[24] = 0; /* Fill out rest of structure */
X  buf[25] = 0; /* Fill out rest of structure */
X  buf[26] = 0; /* Fill out rest of structure */
X  buf[27] = 0; /* Fill out rest of structure */
X
X  if (doscsicmd(unit,cmd,buf,12 + 16,5,2,1,0,0,NULL) != COK)
X    printf("scsi: warning: mode select command returned error from drive %d\n",
X           unit);
X  cmd[0]=SCSIFORMATUNIT;
X  cmd[1]=0; /* primary and grown defect list only */
X  cmd[2]=0; /* data pattern */
X  cmd[3]=interleave>>8;
X  cmd[4]=interleave;
X  cmd[5]=0;
X
X  if (doscsicmd(unit,cmd,NULL,0,0,0,1,0,0,NULL) != COK)
X    {
X      printf("scsi: format failure.\n");
X      return 0;
X    }
X  printf("scsi: format complete.\n");
X  return 1;
X}
X
X/* This checks that the current user is the super-user.  Returns 0 if not. */
X
Xstatic int chksuper()
X{
X  if (u.u_uid != 0)
X    {
X      u.u_error=EPERM;
X      return 0;
X    }
X  return 1;
X}
X
X/* ioctl() for this device */
X
Xscsiioctl(dev,cmd,arg,mode)
Xint dev,cmd,mode;
Xchar *arg;
X{
X  int unit=UNITNO(minor(dev)),
X      part=PARTNO(minor(dev));
X  char *cp;
X  union io_arg hd_arg; /* hd(7) compatible arguments */
X
X  strlog(0, unit, 0, SL_ERROR, "scsiioctl called: unit=%d part=%d cmd=%d arg=%d mode=%d\n",
X         unit,part,cmd,arg,mode);
X
X  if (unit >= SCSIMAXPARTS ||
X      (part != SCSIMAXPARTS-1 && part >= d[unit].nparts))
X    {
X      u.u_error=EINVAL;
X      return;
X    }
X  switch (cmd)
X    {
X      case SCSIIOREADCAP:
X        if (part == 15)
X          suword((int *)arg,(int)d[unit].capacity);
X         else
X          suword((int *)arg,(int)d[unit].parts[part].len);
X        break;
X      case SCSIIOREADTYPE:
X        for (cp=d[unit].drivename;*cp;cp++,arg++)
X          subyte(arg,*cp);
X        subyte(arg,0);
X        break;
X      case SCSIIOSETBLK:
X        if (!chksuper()){
X          u.u_error=EPERM;
X          break;
X	}
X        d[unit].blocksize=fuword((int *)arg);
X        break;
X      case SCSIIOREASSIGN: {
X        int bad_block;
X        if (!chksuper()){
X          u.u_error=EPERM;
X          break;
X	}
X        if ((bad_block = (int) arg) < 0) {
X          strlog(0, unit, 0, SL_ERROR, "scsi: Reassign argument was less than zero!\n");
X	  u.u_error = EFAULT;
X          break;
X	}
X        if (bad_block >= d[unit].parts[part].len) {
X          strlog(0, unit, 0, SL_ERROR, "scsi: Reassign argument (%d) was greater than allowed for partition %d\n",
X            bad_block, part);
X	  u.u_error = EINVAL;
X	  break;
X	}
X        strlog(0, unit, 0, SL_ERROR, "scsi: Reassigning unit %d, partition %d, block %d = ",
X             unit, part, bad_block);
X        bad_block += d[unit].parts[part].start;
X        strlog(0, unit, 0, SL_ERROR, "raw block %d\n", bad_block);
X        if (reassign(unit, bad_block) != COK) {
X          strlog(0, unit, 0, SL_ERROR, "  -  Reassign of %d FAILED!\n", bad_block);
X	  u.u_error = EIO;
X	}
X       }
X       break;
X      case SCSIIORSENSE: {
X        char buf[50], i;
X        for (i = 0; i < sizeof(buf); i++)
X          buf[i] = 0;
X        if (requestsense(unit,buf,sizeof(buf),1) != COK) {
X	  u.u_error = EIO;
X          break;
X	}
X        /* Copy Extended Sense Information */
X        if (copyout(buf, (char *) arg, 6) == -1)
X             u.u_error = EFAULT;
X       }
X       break;
X
X      case SCSIIOFORMAT:
X        if (!chksuper()) {
X          u.u_error=EPERM;
X          break;
X        }
X        if (!formatscsidrive(unit,d[unit].blocksize,fuword((int *)arg)))
X          u.u_error=EIO;
X        /* fall to next case */
X      case SCSIIOINITUNIT:
X        initdrive(unit);
X        break;
X      case SCSIIOGETBLKSZ:
X        suword((int *)arg,d[unit].blocksize);
X        break;
X
X      /* UNIX V/386 hd(7) compatible ioctls */
X
X      case V_CONFIG : 
X	printf("scsi: Attempt to set drive confuration ignored!\n");
X        break;
X
X      case V_REMOUNT :  /* A do nothing command */
X        break;
X
X      case V_ADDBAD :  /* use a SCSI reassign command, eventually */
X        if (copyin(arg, &hd_arg, sizeof(hd_arg.ia_abs)) < 0) {
X	  u.u_error = EINVAL;
X          break;
X	}
X        printf("scsi : Ignoring attempt to remap block %d via V_ADDBAD\n", 
X             hd_arg.ia_abs.bad_sector);
X        strlog(0, unit, 0, SL_ERROR, "scsi : Ignoring attempt to remap block %d via V_ADDBAD\n", 
X             hd_arg.ia_abs.bad_sector);
X	break;
X
X      case V_GETPARMS : {/*This is not gaurenteed to work with any other than
X                        512 byte sectors!                                 */
X         struct disk_parms dp;
X         dp.dp_type = DPT_WINI;
X         dp.dp_heads = 10; /* Make up something reasonable */
X         dp.dp_cyls  = 100; 
X         dp.dp_sectors = 44; /* Wren IV */
X         dp.dp_secsiz  = d[unit].blocksize;
X         dp.dp_ptag    = (unit == 15) ? V_BACKUP : V_USR;
X         dp.dp_pflag   = V_VALID;
X         dp.dp_pstartsec = d[unit].parts[part].start;
X         dp.dp_pnumsec   = d[unit].parts[part].len;
X         if (copyout(&dp, arg, sizeof(dp)) < 0 )
X            u.u_error = EFAULT;
X         break;    
X       }
X      default:
X        u.u_error=EINVAL;
X        break;
X    }
X}
SHAR_EOF
echo "File scsi.c is complete" &&
$TOUCH -am 0101184991 scsi.c &&
chmod 0644 scsi.c ||
echo "restore of scsi.c failed"
set `wc -c scsi.c`;Wc_c=$1
if test "$Wc_c" != "50082"; then
	echo original size 50082, current size $Wc_c
fi
# ============= scsiasm.s ==============
echo "x - extracting scsiasm.s (Text)"
sed 's/^X//' << 'SHAR_EOF' > scsiasm.s &&
X	.file "scsiasm.s"
X/
X/ fast transfer to/from the scsi controller
X/
X/ Copyright (c) 1988 Tatu Yl|nen
X/               All rights reserved.
X/
X
X	.text
X	.align	4
X	.globl	getfromscsi
X
Xgetfromscsi:
X        pushl %ebp
X        movl %esp,%ebp
X        pushl %esi
X        pushl %edi
X	push %es
X	movw %ds,%ax
X	movw %ax,%es
X        movl 8(%ebp),%edi
X        movl 12(%ebp),%ecx
X        movl scsidataport,%esi
X	cld
X	rep
X	smovb
X	pop %es
X        popl %edi
X        popl %esi
X	popl %ebp
X        ret
X
X        .globl  sendtoscsi
Xsendtoscsi:
X        pushl %ebp
X        movl %esp,%ebp
X        pushl %esi
X        pushl %edi
X	push %es
X	movw %ds,%ax
X	movw %ax,%es
X        movl 8(%ebp),%esi
X        movl 12(%ebp),%ecx
X        movl scsidataport,%edi
X	cld
X	rep
X	smovb
X	pop %es
X        popl %edi
X        popl %esi
X	popl %ebp
X        ret
SHAR_EOF
$TOUCH -am 1027195290 scsiasm.s &&
chmod 0644 scsiasm.s ||
echo "restore of scsiasm.s failed"
set `wc -c scsiasm.s`;Wc_c=$1
if test "$Wc_c" != "805"; then
	echo original size 805, current size $Wc_c
fi
# ============= scsipart.c ==============
echo "x - extracting scsipart.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > scsipart.c &&
X/*
X
XSCSI disk partitioning program
X
XCopyright (c) 9.6.1988 Tatu Yl|nen
X              All rights reserved.
X
X*/
X
X/* Modification history.
X *
X * M000		det at hawkmoon.MN.ORG -- Sat Dec 30 23:09:48 CST 1989
X * 		Moved raw scsi device name to user specified name.  Ostensibly
X *		it should be "/dev/rdsk/?sf" for consistency with the rest of
X *		disk drive devices.
X *		Added -h for a usage line.
X *		Added -uunit# for command line specification of the scsi unit#.
X *		Print out number of minutes format took at completion of format.
X */
X
X#include <stdio.h>
X#include <fcntl.h>
X/* beg M000 */
X#include <time.h>
X#include <string.h>
X#include <sys/types.h>
X#include <sys/stat.h>
X/* end M000 */
X#include "st01.h"
X
X/* beg M000 */
X#define DEV	"/dev/rdsk/%dsf"	/* must be raw device to use ioctls */
X#define	HELP	"man scsipart"
X#define	I_USAGE	"Usage: %s [-hH] [-uunit#] special\n"
X#define	then
X/* end M000 */
X
Xchar drivename[80];
Xchar buf[4096];
Xint capacity;
Xint interleave,blocksize;
X
Xint nparts;
Xlong partstart[SCSIMAXPARTS];
Xlong partlen[SCSIMAXPARTS];
X/* beg M000 */
Xlong t;
Xint drivenumber;
X
Xint scsiunit = -1;
X/* end M000 */
Xint scsihandle;
X
Xint asknumber(s,low,high)
Xchar *s;
Xint low,high;
X{
X  int a;
X
X  while (1)
X    {
X      /* beg M000 */
X      printf("%s ",s);
X      /* end M000 */
X      if (scanf("%d",&a) == 1 && a >= low && a <= high)
X        return a;
X      printf("invalid input, try again.\n");
X      fflush(stdin);
X    }
X}
X
Xreadparts()
X{
X  unsigned char *cp;
X
X  lseek(scsihandle,0l,0);
X  if (read(scsihandle,buf,1024) != 1024)
X    {
X      perror("Could not read partition table");
X      exit(1);
X    }
X  for (nparts=0,cp=(unsigned char *)buf;
X       cp[0] || cp[1] || cp[2] || cp[3] || cp[4] || cp[5];
X       nparts++,cp+=6)
X     {
X       if (nparts >= SCSIMAXPARTS-1)
X         {
X           printf("Invalid partition table - assuming no partitions\n");
X           nparts=0;
X           return;
X         }
X       partstart[nparts]=(cp[0] << 16) + (cp[1] << 8) + cp[2];
X       partlen[nparts]=(cp[3] << 16) + (cp[4] << 8) + cp[5];
X     }
X}
X
Xsaveparts()
X{
X  int a;
X  char *cp;
X
X  for (a=0,cp=buf;a<nparts;a++,cp+=6)
X    {
X      cp[0]=partstart[a]>>16;
X      cp[1]=partstart[a]>>8;
X      cp[2]=partstart[a];
X      cp[3]=partlen[a]>>16;
X      cp[4]=partlen[a]>>8;
X      cp[5]=partlen[a];
X    }
X  memset(cp,0,6);
X  lseek(scsihandle,0l,0);
X  if (write(scsihandle,buf,1024) != 1024)
X    {
X      printf("error saving partition table\n");
X      exit(1);
X    }
X}
X
Xint addpart(s,l)
Xlong s,l;
X{
X  if (nparts >= SCSIMAXPARTS-1)
X    {
X      printf("too many partitions\n");
X      return 0;
X    }
X  partstart[nparts]=s;
X  partlen[nparts]=l;
X  nparts++;
X  return 1;
X}
X
Xint delpart(n)
Xint n;
X{
X  int a;
X
X  if (n < 0 || n >= nparts)
X    {
X      printf("invalid partition number\n");
X      return 0;
X    }
X  for (a=n;a<nparts-1;a++)
X    {
X      partstart[a]=partstart[a+1];
X      partlen[a]=partlen[a+1];
X    }
X  nparts--;
X  return 1;
X}
X
Xprintparts()
X{
X  int a;
X
X  printf("capacity=%ld.  Defined partitions:\n",capacity);
X  for (a=0;a<nparts;a++)
X    {
X      printf("  %d: start=%ld len=%ld blocks\n",a,partstart[a],partlen[a]);
X    }
X  if (nparts == 0)
X    printf("  no partitions defined.\n");
X}
X
X/* beg M000 */
Xmain(argc,argv)
X  int argc;
X  char *argv[];
X/* end M000 */
X{
X  int a;
X  long s,l;
X  /* beg M000 */
X  char *pid;
X  char *usage;
X  extern char *optarg;
X  extern int optind;
X  struct stat stbuf;
X
X pid=strrchr(argv[0],'/');
X if (!pid) pid=argv[0]; else ++pid;
X usage=(char *)malloc(sizeof(I_USAGE)+strlen(pid)+1);
X sprintf(usage,I_USAGE,pid);
X while ((a=getopt(argc,argv,"hHu:"))!=EOF)
X  {switch (a)
X    {default:
X       fprintf(stderr,usage);
X       return(0);
X     case 'H':
X       return(system(HELP));
X     case 'u':
X       scsiunit=atoi(optarg);
X       break;
X    }
X  }
X
X  if (optind>=argc)	/* there is NO default drive; for safety */
X    then
X     {fprintf(stderr,usage);
X      return(1);
X     }
X
X printf("\nscsi disk drive formatting and partitioning utility  V1.0\n");
X printf("Copyright (c) 9.6.1988 Tatu Yl|nen\n\n");
X printf("Warning: It is easy to destroy data with this program.  Abort now\n");
X printf("if you are not sure what you are doing.\n");
X
X  /* make some simple consistency checks for the user...
X   */
X  if (stat(argv[optind],&stbuf))
X    then
X     {fprintf(stderr,"%s: no such file `%s'\n",pid,argv[optind]);
X      return(2);
X     }
X  /* Why do i check the mode vs 30000 instead of doing "stbuf.st_mode&S_IFCHR" ?
X   * Good question.  the result was always TRUE for both raw and block devices.
X   * I don't know why.
X   */
X  if (stbuf.st_mode>030000)
X    then
X     {fprintf(stderr,"%s: must be a raw device\n",pid);
X      return(3);
X     }
X
X  if (scsiunit<0)
X    then
X     {sprintf(buf,"Enter scsi unit id for %s? ",argv[1]);
X      scsiunit=asknumber(buf,0,7);
X     }
X  /* end M000 */
X  scsihandle=open(argv[optind],O_RDWR);
X  if (scsihandle == -1)
X    {
X      perror(argv[optind]);
X      exit(1);
X    }
X  if (ioctl(scsihandle,SCSIIOREADTYPE,drivename) == -1)
X    perror("SCSIIOREADTYPE ioctl");
X  if (ioctl(scsihandle,SCSIIOREADCAP,&capacity) == -1)
X    perror("SCSIIOREADCAP ioctl");
X  if (ioctl(scsihandle,SCSIIOGETBLKSZ,&blocksize) == -1)
X    perror("SCSIIOGETBLKSZ ioctl");
X  printf("Drive %d: %d blocks, blocksize=%d\n",scsiunit,capacity,blocksize);
X  printf("%s\n",drivename);
X  printf("Do you wish to format the unit (y/n)?\n");
X  fflush(stdin);
X  gets(buf);
X  if (buf[0] == 'y' || buf[0] == 'Y')
X    {
X      printf("FORMATTING WILL DESTROY ALL AND ANY DATA ON THE DRIVE.\n");
X      printf("ARE YOU SURE YOU WANT TO DO THIS (Y/N)?\n");
X      gets(buf);
X      if (buf[0] != 'y' && buf[0] != 'Y')
X        exit(1);
X      blocksize=asknumber("Enter block size for the drive (usually 512)?",
X                          0,4096);
X      interleave=asknumber("Enter interleave factor for the drive (usually between 1 and 10)?",
X                           0,34);
X      /* beg M000 */
X      time(&t);
X      /* end M000 */
X      if (ioctl(scsihandle,SCSIIOSETBLK,&blocksize) == -1 ||
X          ioctl(scsihandle,SCSIIOFORMAT,&interleave) == -1)
X        {
X          perror("Format failure");
X          exit(1);
X        }
X      /* beg M000 */
X      printf("\007Format complete in %.1f minutes.\n",(time(0L)-t)/60.0);
X      /* end M000 */
X      if (ioctl(scsihandle,SCSIIOREADCAP,&capacity) == -1)
X        perror("SCSIIOREADCAP ioctl");
X      nparts=0;
X      saveparts();
X      /* beg M000 */
X      printf("Drive capacity is %d blocks.\n",capacity);
X      /* end M000 */
X    }
X  if (ioctl(scsihandle,SCSIIOINITUNIT,NULL) == -1)
X    perror("SCSIIOINITUNIT ioctl");
X  if (ioctl(scsihandle,SCSIIOREADTYPE,drivename) == -1)
X    perror("SCSIIOREADTYPE ioctl");
X  if (ioctl(scsihandle,SCSIIOREADCAP,&capacity) == -1)
X    perror("SCSIIOREADCAP ioctl");
X  if (ioctl(scsihandle,SCSIIOGETBLKSZ,&blocksize) == -1)
X    perror("SCSIIOGETBLKSZ ioctl");
X  if (!readparts())
X    nparts=0;
X  while (1)
X    {
X      printparts();
X      a=asknumber("1 add partition 2 delete partition 8 quit (no save) 9 save",
X                  1,9);
X      switch (a)
X        {
X          case 1: /* add partition */
X            s=asknumber("enter partition start in blocks?",0,capacity);
X            l=asknumber("enter partition length in blocks?",0,capacity-s);
X            addpart(s,l);
X            break;
X          case 2: /* delete partition */
X            a=asknumber("enter partition number to delete?",0,nparts-1);
X            delpart(a);
X            break;
X          case 8: /* quit no save */
X            printf("partition table not modified\n");
X            exit(1);
X          case 9: /* quit, save modifications */
X            printf("saving partition table\n");
X            saveparts();
X            if (ioctl(scsihandle,SCSIIOINITUNIT,NULL) == -1)
X              perror("SCSIIOINITUNIT ioctl");
X            exit(0);
X          default:
X            printf("invalid command\n");
X            break;
X        }
X    }
X}
SHAR_EOF
$TOUCH -am 1226195090 scsipart.c &&
chmod 0644 scsipart.c ||
echo "restore of scsipart.c failed"
set `wc -c scsipart.c`;Wc_c=$1
if test "$Wc_c" != "7896"; then
	echo original size 7896, current size $Wc_c
fi
# ============= sdevice ==============
echo "x - extracting sdevice (Text)"
sed 's/^X//' << 'SHAR_EOF' > sdevice &&
X* SCSI Host Device Driver
Xaha	Y	1	5	1	11	330	332	0	0
Xaha	N	1	5	1	0	0	0	0	0
Xasy	Y	1	7	1	4	3f8	3ff	0	0
Xasy	N	2	7	1	3	2f8	2ff	0	0
Xclone	Y	1	0	0	0	0	0	0	0
Xcmos	Y	1	5	1	8	0	0	0	0
Xcpyrt	Y	1	0	0	0	0	0	0	0
Xdu	N	1	0	0	0	0	0	0	0
X* SCSI ESIX Common Host Adapter Driver (SCSI)
Xecha	Y	1	0	0	0	0	0	0	0
X*
X* ESIX Common Hard Disk Driver
X*
Xechd	Y	1	0	0	0	0	0	0	0
Xfd	Y	1	4	2	6	3f0	3f7	0	0
Xffs	Y	1	0	0	0	0	0	0	0
Xfha	N	1	5	1	12	0	0	ce000	cffff
Xfp	Y	1	1	1	13	0	0	0	0
Xgentty	Y	1	0	0	0	0	0	0	0
X* 
X* ST506/ESDI Hard Disk Driver
X*
Xhd	Y	1	5	1	14	320	32f	0	0
Xip	Y	1	0	0	0	0	0	0	0
Xipc	Y	1	0	0	0	0	0	0	0
Xiplan	Y	1	0	0	0	0	0	0	0
Xippln	Y	1	0	0	0	0	0	0	0
Xkd	Y	1	6	3	1	60	62	0	0
Xldterm	Y	16	0	0	0	0	0	0	0
Xlog	Y	1	0	0	0	0	0	0	0
X*****************************************************************
X*								*
X* WARNING : if the second field of any entry is changed, make   *
X*           sure that the corresponding parallel port entry in  *
X*	    /etc/conf/pack.d/lp/space.c file is also updated    *
X*	    before rebuilding the kernel.		        *
X*								*
X*****************************************************************
Xlp	N	1	3	2	7	3bc	3be	0	0
Xlp	Y	2	3	2	7	378	37a	0	0
Xlp	N	3	3	2	7	278	27a	0	0
Xmem	Y	1	0	0	0	0	0	0	0
Xmsg	Y	1	0	0	0	0	0	0	0
Xmux	Y	1	0	0	0	0	0	0	0
Xnmi	Y	1	0	0	0	0	0	0	0
Xosm	Y	1	0	0	0	0	0	0	0
Xpln	Y	1	0	0	0	0	0	0	0
Xprf	Y	1	0	0	0	0	0	0	0
X* Pseudo Terminal Master side
Xptcp	Y	1	0	0	0	0	0	0	0
Xptem	Y	16	0	0	0	0	0	0	0
Xptm	Y	16	0	0	0	0	0	0	0
Xpts	Y	1	0	0	0	0	0	0	0
X* Pseudo Terminal Slave side
Xptyp	Y	1	0	0	0	0	0	0	0
Xramd	N	2	0	0	0	0	0	0	0
Xs52k	N	1	0	0	0	0	0	0	0
X*
X* SCSI Hard Disk Driver
X*
Xschd	Y	1	0	0	0	0	0	0	0
X* SCSI Magtape Device
Xscmt	Y	1	0	0	0	0	0	0	0
Xscsi	Y	1	5	1	5	0	0	df000	e0000
Xsem	Y	1	0	0	0	0	0	0	0
Xshm	Y	1	0	0	0	0	0	0	0
Xsl	N	1	7	1	4	3f8	3ff	0	0
Xsl	N	2	7	1	3	2f8	2ff	0	0
Xslip	Y	1	0	0	0	0	0	0	0
Xsxt	Y	1	0	0	0	0	0	0	0
Xtcp	Y	1	0	0	0	0	0	0	0
Xtimod	Y	1	0	0	0	0	0	0	0
Xtirdwr	Y	1	0	0	0	0	0	0	0
Xudp	Y	1	0	0	0	0	0	0	0
Xudpm	Y	1	0	0	0	0	0	0	0
Xvx	Y	1	0	0	0	0	0	0	0
Xweitek	Y	1	0	0	0	0	0	0	0
Xxkb	Y	1	0	0	0	0	0	0	0
Xxms	Y	1	6	1	3	0	0	0	0
Xxsd	Y	1	0	0	0	0	0	0	0
Xxsem	Y	1	0	0	0	0	0	0	0
Xxt	Y	1	0	0	0	0	0	0	0
SHAR_EOF
$TOUCH -am 1027195590 sdevice &&
chmod 0644 sdevice ||
echo "restore of sdevice failed"
set `wc -c sdevice`;Wc_c=$1
if test "$Wc_c" != "2074"; then
	echo original size 2074, current size $Wc_c
fi
# ============= st01.h ==============
echo "x - extracting st01.h (Text)"
sed 's/^X//' << 'SHAR_EOF' > st01.h &&
X/*
X
XSCSI disk driver for unix system V (Microport system V/386)
XThis driver uses the ST-01 controller.  This supports multiple initiators
Xand multiple targets.
X
XCopyright (c) 9.6.1988 Tatu Yl|nen
X              All rights reserved.
X
X*/
X
X#define SCSIMAXDRIVES  4   /* max # disk drives supported */
X#define SCSIMAXPARTS   16  /* max partitions/drive */
X
Xtypedef struct scsidrivest
X{
X  char drivename[64]; /* drive type identification string */
X  int blocksize;  /* logical block size; if 0, not present */
X  long capacity;  /* total disk capacity in blocks */
X  char nomsgs;    /* set if drive does not support messages */
X  int nparts;     /* # partitions */
X  struct partst
X    {
X      long start; /* starting sector number */
X      long len;   /* partition length */
X    } parts[SCSIMAXPARTS];
X
X  char *xferbuf;  /* transfer buffer address */
X  int xferlen;    /* data len to transfer */
X  char *xfercmd;  /* command to transfer */
X  char xferslow;  /* true if watch out for slow transfers */
X  char xferstatus; /* status byte received from target */
X  int xfertimeout; /* if nonzero, timeout in 1/10 sec */
X  int xfertime;    /* if nonzero, elapsed time waiting (1/10 sec) */
X  int xferretries; /* if nonzero, retry the current request and decrement*/
X  char xferphys;   /* if true, transferring data with raw io */
X  char xferpolled; /* if true, transfer must be polled */
X
X  /* Info on current command */
X
X  int num_blocks, logical_block, scsicmd;
X
X  char *savedbuf;  /* saved buffer */
X  int savedlen;    /* saved lenght */
X  char *savedcmd;  /* saved command */
X
X  char *origbuf;   /* original buffer */
X  int origlen;     /* original length */
X  char *origcmd;   /* original command */
X
X  struct buf *reqlist; /* queued requests */
X  struct buf *currentbuf; /* buffer being executed */
X
X  char connected; /* true if connection to drive established */
X  char busy;      /* true if currently executing a command */
X} SCSIDRIVE;
X
X#define SCSIIOREADCAP  1 /* read capacity of partition or drive
X                            (if part == 15); arg=&capacity */
X#define SCSIIOREADTYPE 2 /* read drive type name (as a string); arg=buf */
X#define SCSIIOFORMAT   3 /* reformat the drive; arg=&interleave */
X#define SCSIIOSETBLK   4 /* set drive block size for format; arg=&size */
X#define SCSIIOINITUNIT 5 /* re-initializes the unit, reading partition table */
X#define SCSIIOGETBLKSZ 6 /* read sector size */
X#define SCSIIORSENSE   7 /* Return 4 byte request sense data */
X#define SCSIIOREASSIGN 8 /* reassign given block */
X
X/* Partitioning is done by writing on the first block of partition 15
X   (the entire drive).  Note that drive block size may not be the same as
X   system block size.  Partition table format: each entry 3 bytes start,
X   3 bytes length (in blocks, msb first), terminated by 6 zeroes.  If first
X   partition starts at 0, it will be moved to 1 automatically; this appears
X   to be the convention under dos. */
X
SHAR_EOF
$TOUCH -am 1226163690 st01.h &&
chmod 0644 st01.h ||
echo "restore of st01.h failed"
set `wc -c st01.h`;Wc_c=$1
if test "$Wc_c" != "2929"; then
	echo original size 2929, current size $Wc_c
fi
# ============= verify.c ==============
echo "x - extracting verify.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > verify.c &&
X
X#include <stdio.h>
X#include <fcntl.h>
X#include "st01.h"
X
X#define NBLOCKS 200              /* Number of blocks to read at a time */
X#define BLOCK_LEN (512*NBLOCKS)  /* Number of bytes to read at a time */
X
Xint d_size, cur_block, rfd;
Xchar buf[BLOCK_LEN]; 
Xchar ans[10];
X
Xint check_sense(rfd)
Xint rfd;
X{
X    unsigned char buf[10], address_valid, err_class, err_code, sense;
X    unsigned long addr;
X    static char *smsg[] = 
X        { "No Error", "CRC or other error that was recovered",
X          "Not Ready", "Medium Error (Bad Block)", "Hardware Failure",
X          "Illegal Request or parameter", "Unit Attention - removeable media",
X          "Data is protected and not available or changeable",
X          "Blank Check", "** Vendor Unique **", "Copy aborted", 
X          "Target Aborted Command for some reason",
X          "Search Data command has found successful comparison",
X          "Volume Overflow - unable to write full buffer",
X          "Miscompare on a verify command",
X          "**Reserved**"};
X
X    if (ioctl(rfd, SCSIIORSENSE, buf) < 0) {
X      fprintf(stderr,"Unable to get more detail on error..sorry\n");
X      perror("Request Sense");
X      return 0;
X    }
X
X    address_valid = buf[0] >> 7;
X    err_class = (buf[0] >> 4) & 0x7;
X    err_code = buf[0] & 0xf;
X    sense = buf[2] & 0xf;
X
X    addr = (buf[3] << 24l) +
X           (buf[4] << 16l) +
X           (buf[5] << 8l ) +
X           buf[6];
X    fprintf(stderr," Request Sense : Error Class 0x%x, Error Code 0x%x\n", 
X       err_class, err_code);
X    fprintf(stderr," Sense key 0x%x = %s\n", sense, smsg[sense]);
X    if (address_valid)
X      fprintf(stderr,"  on logical block %u\n", addr);
X    else
X      fprintf(stderr,"Unable to determine logical block where failure occured\n");
X    return 1;
X}
X
Xlocalize( cur_block )
Xint cur_block;
X{
X   int final_block = cur_block + NBLOCKS - 1;
X   fprintf(stderr,"Attempting to localize exact blocks\n");
X   for (; cur_block <= final_block; cur_block ++){
X      fprintf(stderr,"\r %07d  ", cur_block);
X
X      if (lseek(rfd, cur_block * 512, 0) < 0) {
X         fprintf(stderr,"Unable to seek to block %d\n", cur_block);
X         perror("lseek");
X         exit(2);
X       }
X
X      if (read(rfd, buf, 512) < 0) {
X	fprintf(stderr,"\n Block %07d failed - ", 
X           cur_block);
X        perror("");
X        check_sense(rfd);
X        fprintf(stderr,"Do you wish to reassign this block? ");
X        gets(ans);
X        if ((ans[0]== 'Y') || (ans[0] == 'y')) 
X          if (ioctl(rfd, SCSIIOREASSIGN, cur_block) < 0)
X             perror("Unable to reassign block ");
X          else
X             fprintf(stderr,"Reassign of %d complete\n", cur_block);
X      }
X   }
X}
X
X
Xint main(argc, argv)
Xint argc;
Xchar **argv;
X{
X  int amount_to_read, amount_read;
X
X  if (argc != 2) {
X     fprintf(stderr,"Usage : verify raw_scsi_device \n");
X     exit(1);
X   }
X
X   if ((rfd = open(argv[1], O_RDONLY)) < 0) {
X     fputs("Unable to open character device!\n");
X     perror(argv[1]);
X     exit(2);
X   }
X
X   if (ioctl(rfd, SCSIIOREADCAP, &d_size) < 0) {
X     fprintf(stderr,"Unable to get size of this partition\n");
X     perror(argv[1]);
X     exit(5);
X   }
X
X   fprintf(stderr,"Partition %s has %d blocks\n", argv[1], d_size);
X
X   for (cur_block = 0; cur_block < d_size; cur_block += NBLOCKS){
X      if (cur_block >= d_size - NBLOCKS) 
X         amount_to_read = (d_size - cur_block) * 512;
X      else
X         amount_to_read = NBLOCKS * 512;
X      
X      fprintf(stderr,"\r %07d  ", cur_block);
X      if (lseek(rfd, cur_block * 512, 0) < 0) {
X         fprintf(stderr,"Unable to seek to block %d\n", cur_block);
X         perror("lseek");
X         exit(2);
X      }
X      if (read(rfd, buf, amount_to_read) != amount_to_read) {
X	fprintf(stderr,"\n Blocks %07d - %07d failed : amount read = %d - ", 
X           cur_block, cur_block + amount_to_read / 512, amount_read);
X        perror("");
X        check_sense(rfd);
X        localize(cur_block);
X      }
X   }
X}
X     
X  
SHAR_EOF
$TOUCH -am 0101184691 verify.c &&
chmod 0644 verify.c ||
echo "restore of verify.c failed"
set `wc -c verify.c`;Wc_c=$1
if test "$Wc_c" != "3950"; then
	echo original size 3950, current size $Wc_c
fi
rm -f shar3_seq_.tmp
echo "You have unpacked the last part"
exit 0



More information about the Comp.unix.sysv386 mailing list