|
|
Darwin 0.2 Driver Kit
/* Copyright (c) 1991 NeXT Computer, Inc. All rights reserved.
*
* IOLogicalDisk.m
*
* HISTORY
* 05-Mar-91 Doug Mitchell at NeXT
* Created.
*/
#import <driverkit/return.h>
#import <driverkit/IODisk.h>
#ifdef KERNEL
#import <kernserv/prototypes.h>
#import <mach/mach_interface.h>
#import <driverkit/kernelDiskMethods.h>
#else KERNEL
#import <mach/mach.h>
#import <bsd/libc.h>
#endif KERNEL
#import <driverkit/IOLogicalDisk.h>
#import <driverkit/Device_ddm.h>
#import <driverkit/generalFuncs.h>
@interface IOLogicalDisk(private)
- (IOReturn)_diskParamCommon :(u_int)logicalOffset
length : (u_int)bytesReq
deviceOffset : (u_int *)deviceOffset
bytesToMove : (u_int *)bytesToMove;
@end
@implementation IOLogicalDisk
/*
* Standard IODiskDeviceReadingAndWriting methods. We translate into raw device
* parameters and pass along to _physicalDisk.
*/
#ifdef KERNEL
- (IOReturn) readAt : (unsigned)offset
length : (unsigned)length
buffer : (unsigned char *)buffer
actualLength : (unsigned *)actualLength
client : (vm_task_t)client
{
unsigned deviceBlock;
IOReturn rtn;
unsigned bytesToMove;
if(rtn = [self _diskParamCommon:offset
length : length
deviceOffset : &deviceBlock
bytesToMove:&bytesToMove])
return(rtn);
return([_physicalDisk readAt:deviceBlock
length:bytesToMove
buffer:buffer
actualLength:actualLength
client:client]);
}
- (IOReturn) readAsyncAt : (unsigned)offset
length : (unsigned)length
buffer : (unsigned char *)buffer
pending : (void *)pending
client : (vm_task_t)client
{
unsigned deviceBlock;
IOReturn rtn;
unsigned bytesToMove;
if(rtn = [self _diskParamCommon:offset
length : length
deviceOffset : &deviceBlock
bytesToMove:&bytesToMove])
return(rtn);
return([_physicalDisk readAsyncAt:deviceBlock
length:bytesToMove
buffer:buffer
pending:pending
client:client]);
}
- (IOReturn) writeAt : (unsigned)offset
length : (unsigned)length
buffer : (unsigned char *)buffer
actualLength : (unsigned *)actualLength
client : (vm_task_t)client
{
unsigned deviceBlock;
IOReturn rtn;
unsigned bytesToMove;
if(rtn = [self _diskParamCommon:offset
length : length
deviceOffset : &deviceBlock
bytesToMove:&bytesToMove])
return(rtn);
return([_physicalDisk writeAt:deviceBlock
length:bytesToMove
buffer:buffer
actualLength:actualLength
client:client]);
}
- (IOReturn) writeAsyncAt : (unsigned)offset
length : (unsigned)length
buffer : (unsigned char *)buffer
pending : (void *)pending
client : (vm_task_t)client
{
unsigned deviceBlock;
IOReturn rtn;
unsigned bytesToMove;
if(rtn = [self _diskParamCommon:offset
length : length
deviceOffset : &deviceBlock
bytesToMove:&bytesToMove])
return(rtn);
return([_physicalDisk writeAsyncAt:deviceBlock
length:bytesToMove
buffer:buffer
pending:pending
client:client]);
}
#else KERNEL
- (IOReturn) readAt : (unsigned)offset
length : (unsigned)length
buffer : (unsigned char *)buffer
actualLength : (unsigned *)actualLength
{
unsigned deviceBlock;
IOReturn rtn;
unsigned bytesToMove;
if(rtn = [self _diskParamCommon:offset
length : length
deviceOffset : &deviceBlock
bytesToMove:&bytesToMove])
return(rtn);
return([_physicalDisk readAt:deviceBlock
length:bytesToMove
buffer:buffer
actualLength:actualLength]);
}
- (IOReturn) readAsyncAt : (unsigned)offset
length : (unsigned)length
buffer : (unsigned char *)buffer
pending : (void *)pending
{
unsigned deviceBlock;
IOReturn rtn;
unsigned bytesToMove;
if(rtn = [self _diskParamCommon:offset
length : length
deviceOffset : &deviceBlock
bytesToMove:&bytesToMove])
return(rtn);
return([_physicalDisk readAsyncAt:deviceBlock
length:bytesToMove
buffer:buffer
pending:pending]);
}
- (IOReturn) writeAt : (unsigned)offset
length : (unsigned)length
buffer : (unsigned char *)buffer
actualLength : (unsigned *)actualLength
{
unsigned deviceBlock;
IOReturn rtn;
unsigned bytesToMove;
if(rtn = [self _diskParamCommon:offset
length : length
deviceOffset : &deviceBlock
bytesToMove:&bytesToMove])
return(rtn);
return([_physicalDisk writeAt:deviceBlock
length:bytesToMove
buffer:buffer
actualLength:actualLength]);
}
- (IOReturn) writeAsyncAt : (unsigned)offset
length : (unsigned)length
buffer : (unsigned char *)buffer
pending : (void *)pending
{
unsigned deviceBlock;
IOReturn rtn;
unsigned bytesToMove;
if(rtn = [self _diskParamCommon:offset
length : length
deviceOffset : &deviceBlock
bytesToMove:&bytesToMove])
return(rtn);
return([_physicalDisk writeAsyncAt:deviceBlock
length:bytesToMove
buffer:buffer
pending:pending]);
}
#endif KERNEL
- (IODiskReadyState)updateReadyState
{
return [_physicalDisk updateReadyState];
}
/*
* Open a connection to physDevice. FIXME: when do we close??
*/
- (IOReturn)connectToPhysicalDisk : physicalDisk
{
IOReturn rtn = IO_R_SUCCESS;
unsigned removable_flag;
unsigned formatted_flag;
xpr_disk("connectToPhysicalDiskice\n", 1,2,3,4,5);
_physicalDisk = physicalDisk;
[self setIsPhysical:0];
/*
* Get some instance variables which must be the same as the
* physDevice's.
*/
_physicalBlockSize = [physicalDisk blockSize];
removable_flag = [physicalDisk isRemovable];
[self setRemovable:removable_flag];
formatted_flag = [physicalDisk isFormatted];
[self setFormattedInternal:formatted_flag];
[self setLogicalDisk:nil];
#ifdef KERNEL
[self setDevAndIdInfo:[physicalDisk devAndIdInfo]];
#endif KERNEL
return(rtn);
}
- (void)setPartitionBase : (unsigned)partBase
{
_partitionBase = partBase;
}
/*
* Determine if this LogicalDisk (or any other LogicalDisks in the
* logicalDisk list) are currently open. Returns NO if none open, else
* YES.
*/
- (BOOL)isOpen
{
if([self isInstanceOpen])
return(YES);
else if([self nextLogicalDisk])
return([[self nextLogicalDisk] isOpen]);
else
return(NO);
}
/*
* Free self and any objects in logicalDisk chain.
*/
- free
{
id nextLd;
nextLd = [self nextLogicalDisk];
if(nextLd) {
[nextLd free];
}
return([super free]);
}
- physicalDisk
{
return(_physicalDisk);
}
- (unsigned)physicalBlockSize
{
return(_physicalBlockSize);
}
- (void)setPhysicalBlockSize : (unsigned)size
{
_physicalBlockSize = size;
}
/*
* Pass this on to _physicalDisk.
*/
- (IOReturn)isDiskReady : (BOOL)prompt
{
return [_physicalDisk isDiskReady:prompt];
}
/*
* Determine if any logical disks in the _logicalDisk chain except
* for self are open.
*/
- (BOOL)isAnyOtherOpen
{
id logDisk = [_physicalDisk nextLogicalDisk];
while(logDisk) {
if((logDisk != self) && [logDisk isInstanceOpen]) {
return YES;
}
logDisk = [logDisk nextLogicalDisk];
}
return NO;
}
- (BOOL)isInstanceOpen
{
return _instanceOpen;
}
- (void)setInstanceOpen : (BOOL)isOpen
{
_instanceOpen = (isOpen ? YES : NO);
}
/*
* Generate device-specific parameters from logical parameters.
*/
@implementation IOLogicalDisk(private)
#define CRASHER_DEBUG 1
#if CRASHER_DEBUG
int crash_index = 33;
#endif CRASHER_DEBUG
- (IOReturn)_diskParamCommon :(unsigned)logicalOffset
length : (unsigned)length
deviceOffset : (unsigned *)deviceOffset
bytesToMove : (unsigned *)bytesToMove
{
unsigned ratio = 0; // bogus compiler warning
int deviceBlocks;
int logicalBlocks;
unsigned block_size;
unsigned dev_size;
IOReturn rtn;
const char *name = [self name];
#if CRASHER_DEBUG
if((unsigned)(self->isa->cache->buckets[crash_index]) > 0xf0000000) {
panic("Yeah!");
}
#endif CRASHER_DEBUG
/*
* Note we have to 'fault in' a possible non-present physical disk in
* order to get its physical parameters...
*/
rtn = [_physicalDisk isDiskReady:YES];
switch(rtn) {
case IO_R_SUCCESS:
break;
case IO_R_NO_DISK:
xpr_err("%s diskParamCommon: disk not present\n",
name, 2,3,4,5);
return(rtn);
default:
IOLog("%s deviceRwCommon: bogus return from isDiskReady "
"(%s)\n",
name, [self stringFromReturn:rtn]);
return(rtn);
}
block_size = [self blockSize];
dev_size = [self diskSize];
if(length % block_size) {
IOLog("%s: Bytes requested not multiple of block size\n",
name);
return(IO_R_INVALID_ARG);
}
logicalBlocks = length / block_size;
if((logicalOffset + logicalBlocks) > dev_size) {
if(logicalOffset >= dev_size)
return(IO_R_INVALID_ARG);
/*
* Truncate.
*/
logicalBlocks = dev_size - logicalOffset;
}
ratio = block_size / _physicalBlockSize;
deviceBlocks = logicalBlocks * ratio;
*deviceOffset = (logicalOffset * ratio) + _partitionBase;
*bytesToMove = deviceBlocks * _physicalBlockSize;
return(IO_R_SUCCESS);
}
@end
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.