This is DriveSCSI.m in view mode; [Download] [Up]
// // DriveSCSI_Class - subclass of SCSI2_Class for disk drive devices // // Copyright (C) 1994 by Christopher Wolf. // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Library General Public // License as published by the Free Software Foundation; either // version 2 of the License, or (at your option) any later version. // // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // Library General Public License for more details. // // You should have received a copy of the GNU Library General Public // License along with this library; if not, write to the Free // Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. // // Bug-reports, comments and questions should be directed to: // Christopher Wolf <chris@alchemy.geo.cornell.edu> // // Portions of this code and documentation are derived from an // earlier work (SCSI Inquirer) Copyright (C) 1990, 1991, 1992 by // Jiro Nakamura and used with permission. // // // For best results view this file with a tab size of 4 and // a display width of 132 columns or wider. // // file version information #define RCSDSM "$Id: DriveSCSI.m,v 0.30 94/09/18 03:07:41 chris Exp Locker: chris $" // generic Unix headers #import <stdio.h> #import <libc.h> // SCSI2 class specific headers #import "DriveSCSI.h" // string constants const char RCSdsm[] = RCSDSM; const char RCSdsh[] = RCSDSH; @implementation DriveSCSI // ---------------------------------------------------------------------- // // NAME // isDevice // // RETURNS // (BOOL) YES if sub-class can handle device, NO otherwise. // // EXPLANATION // It is the sub-classes responsibility to implement this method. // The method should return YES if the subclass of SCSI can handle // the device at the current target, NO otherwise. // // SEE ALSO // findDevice (SCSI), findDevice: (SCSI) // // ---------------------------------------------------------------------- - (BOOL) isDevice { struct inquiry2_reply ibuffer; BOOL result = NO; if ((![self inquiry: &ibuffer]) && (ibuffer.ir_devicetype == DEVTYPE_DISK)) { result = YES; } return result; } // ---------------------------------------------------------------------- // // NAME // seekExtendedTo: // // RETURNS // (int) 0 Seek succeeded // (int) -1 Seek failed // // PARAMETERS // (u_int) logicalBlockAddress logical block address to seek to // // EXPLANATION // This implements the SCSI command ªSeek Extendedº. It must be // passed a long integer logicalBlockAddress which to seek to. // This method returns when the device has finished seeking. // The method returns zero for success, non-zero otherwise. // // ---------------------------------------------------------------------- - (int) seekExtendedTo: (u_int) logicalBlockAddress { struct cdb2_10 *cdbp = (struct cdb2_10 *)&sr.sr_cdb.cdb_c10; BOOL wasOpen = isOpen; int result = -1; if (wasOpen || ![self open]) { [SCSI clearCommandBlock: (union cdb *) cdbp]; cdbp->c10_opcode = C10OP_SEEKEXTENDED; cdbp->c10_lun = lun; writeBigEndianLong(logicalBlockAddress, &cdbp->BE_c10_lba); sr.sr_dma_dir = SR_DMA_RD; sr.sr_addr = NULL; sr.sr_dma_max = 0; sr.sr_ioto = 10; result = [self performRequest]; } if (!wasOpen && [self close]) { result = -1; } return(result); } // ---------------------------------------------------------------------- // // NAME // readExtendedFrom: to: numBytes: numBlocks: // // RETURNS // (int) 0 read succeeded // (int) -1 read failed // // PARAMETERS // (u_int) lba logical block address to start read from // (char *) destBuffer pointer to buffer to place data in // (u_int) numBytes size of read in bytes // (u_int) numBlock size of read in blocks // // EXPLANATION // This implements the SCSI command ªRead Extendedº. It reads // data starting from the specified logical block address into the // specified buffer. The size of the read must be specified in // BOTH number of bytes and number of blocks to be read. The // method returns after the read has been completed. The method // returns zero on success, non-zero otherwise. // // ---------------------------------------------------------------------- - (int) readExtendedFrom: (u_int)lba to: (char *)destBuffer numBytes: (u_int)numBytes numBlocks: (u_int) numBlocks { struct cdb2_10 *cdbp = (struct cdb2_10 *)&sr.sr_cdb.cdb_c10; BOOL wasOpen = isOpen; int result = -1; if (wasOpen || ![self open]) { [SCSI clearCommandBlock: (union cdb *) cdbp]; cdbp->c10_opcode = C10OP_READEXTENDED; cdbp->c10_lun = lun; writeBigEndianLong(lba, &cdbp->BE_c10_lba); writeBigEndianShort(numBlocks, &cdbp->BE_c10_len); sr.sr_dma_dir = SR_DMA_RD; sr.sr_addr = destBuffer; sr.sr_dma_max = numBytes; sr.sr_ioto = 60*60; result = [self performRequest]; } if (!wasOpen && [self close]) { result = -1; } return(result); } // ---------------------------------------------------------------------- // // NAME // formatUnit // // RETURNS // (int) 0 format succeeded // (int) -1 format failed // // EXPLANATION // This implements the SCSI command ªFormat Unitº. It performs // a low level format of the device. ALL DATA WILL BE ERASED! // Use this command with caution. // // ---------------------------------------------------------------------- - (int) formatUnit { struct cdb_6 *cdbp = &sr.sr_cdb.cdb_c6; BOOL wasOpen = isOpen; int result = -1; if (wasOpen || ![self open]) { [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; result = [self performRequest]; } if (!wasOpen && [self close]) { result = -1; } return(result); } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.