
// Original Author:	Jiro Nakamura 
// Created:		October 19, 1991
// Last Modified:	October 19, 1991
//
// RCS Information
// Revision Number->	$Revision: 1.5 $
// Last Revised->	$Date: 92/05/16 15:35:31 $
//

static char rcsid[]="$Id: DriveSCSI.m,v 1.5 92/05/16 15:35:31 jiro Exp Locker: jiro $";
static char copyrightid[]="Copyright (C) 1991, 1992 by Jiro Nakamura";

#import "DriveSCSI.h"
#import <stdio.h>
#import <libc.h>


@implementation DriveSCSI

- (int) seekExtendedTo: (u_int) logicalBlockAddress
{
	int tmp;
	
	if( scsiOpen)
		return [self seekExtendedSCSITo: logicalBlockAddress];
	else
		{
		if([self openSCSI] )
			{
			sprintf(errorString,"Can't open SCSI driver");
			return -1;
			}
		tmp = [self seekExtendedSCSITo: logicalBlockAddress];
		[self closeSCSI];
		return( tmp);
		}
}

- (int) seekExtendedSCSITo: (u_int) logicalBlockAddress
{	
	struct cdb_10 *cdbp = &sr.sr_cdb.cdb_c10;

	[SCSI clearCommandBlock: (union cdb *) cdbp];
	cdbp->c10_opcode = C10OP_SEEKEXTENDED;
	cdbp->c10_lun    = lun;
	cdbp->c10_lba	= logicalBlockAddress;
	sr.sr_dma_dir	= SR_DMA_RD;
	sr.sr_addr	= NULL;
	sr.sr_dma_max   = 0;
	sr.sr_ioto	= 10;

	return [self performSCSIRequest];
}

- (int) readExtended: (struct readWriteStruct *) s
{
	int tmp;
	
	if( scsiOpen)
		return  [self readExtendedSCSI: s];
	else
		{
		if([self openSCSI] )
			{
			sprintf(errorString,"Can't open SCSI driver");
			return -1;
			}
		tmp = [self readExtendedSCSI: s];
		[self closeSCSI];
		return( tmp);
		}
}

- (int) readExtendedSCSI: (struct readWriteStruct *) s
{	
	struct cdb_10 *cdbp = &sr.sr_cdb.cdb_c10;

	[SCSI clearCommandBlock: (union cdb *) cdbp];
	cdbp->c10_opcode = C10OP_READEXTENDED;
	cdbp->c10_lun    = lun;
	cdbp->c10_lba	= s->logicalBlockAddress;
	cdbp->c10_len 	= s->transferLength;
	sr.sr_dma_dir	= SR_DMA_RD;
	sr.sr_addr	= (char *) s->transferBuffer;
	sr.sr_dma_max   = s->byteTransferLength;
	sr.sr_ioto	= 60;

	return [self performSCSIRequest];
}


- (int) formatUnitSCSI
{
	struct cdb_6 *cdbp = &sr.sr_cdb.cdb_c6;
	
	[SCSI clearCommandBlock: (union cdb *) cdbp];
	cdbp->c6_opcode = C6OP_FORMAT;
	cdbp->c6_lun    = lun;
	cdbp->c6_len	= 0;
	sr.sr_dma_dir	= SR_DMA_WR;
	sr.sr_addr	= (char *) 0;
	sr.sr_dma_max   = 0;
	sr.sr_ioto	= 60*60*60;	/* 60 minutes to timeout is enough */

	return [self performSCSIRequest];
}

- (int)	canonWriteExtendedSCSI: (struct canonSectorTransfer *) sp  
		buffer: 	(char *) buffer 
		erase: 		(BOOL) erase
{	
	struct cdb_10 *cdbp = &sr.sr_cdb.cdb_c10;

	[SCSI clearCommandBlock: (union cdb *) cdbp];
	cdbp->c10_opcode = C10OP_WRITEEXTENDED;
	cdbp->c10_lun    = lun;
	cdbp->c10_lba	= sp->sectorAddress;
	cdbp->c10_len	= sp->transferLength;
	cdbp->c10_ctrl	= erase << 6;
	sr.sr_dma_dir	= SR_DMA_WR;
	sr.sr_addr	= (char *) buffer;
	sr.sr_dma_max   = erase? 0 : sp->transferLength;
	sr.sr_ioto	= 60*60*60;

	return ([self performSCSIRequest]);
}


@end
