|
|
Darwin 0.3 EIDE device driver
/*
* Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
* "Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
* Reserved. This file contains Original Code and/or Modifications of
* Original Code as defined in and that are subject to the Apple Public
* Source License Version 1.0 (the 'License'). You may not use this file
* except in compliance with the License. Please obtain a copy of the
* License at http://www.apple.com/publicsource and read it before using
* this file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
* License for the specific language governing rights and limitations
* under the License."
*
* @APPLE_LICENSE_HEADER_END@
*/
/*
* Copyright 1997-1998 by Apple Computer, Inc., All rights reserved.
* Copyright 1994-1997 NeXT Software, Inc., All rights reserved.
*
* IdeDisk.m - Exported methods for IDE Disk device class.
*
* HISTORY
* 07-Jul-1994 Rakesh Dubey at NeXT
* Created from original driver written by David Somayajulu.
*/
#import <driverkit/return.h>
#import <driverkit/driverTypes.h>
#import <driverkit/devsw.h>
#import <driverkit/generalFuncs.h>
#import <driverkit/kernelDiskMethods.h>
#import <driverkit/IODevice.h>
#import <machkit/NXLock.h>
#import <sys/systm.h>
#import "IdeCnt.h"
#import "IdeDisk.h"
#import "IdeDiskInternal.h"
#import "IdeCntPublic.h"
#import "IdeKernel.h"
//#define DEBUG
static int diskUnit = 0;
static BOOL switchTableInited = NO;
/*
* List of controllers that have been already probed. We need this since each
* Instance table lists IdeDisk as well as IdeController classes. And we need
* to create instances of disks attached to each controller only once.
*/
static int probedControllerCount = 0;
static id probedControllers[MAX_IDE_CONTROLLERS];
@implementation IdeDisk
static Protocol *protocols[] = {
@protocol(IdeControllerPublic),
nil
};
+ (Protocol **)requiredProtocols
{
return protocols;
}
+ (IODeviceStyle)deviceStyle
{
return IO_IndirectDevice;
}
/*
* IDE drives come with a built in controller on each drive. Hence we can
* have just one object per controller-disk pair. Probe is invoked at load
* time. It determines what drives are on the bus and alloc's and init:'s an
* instance of this class for each one.
*
*/
+ (BOOL)probe : deviceDescription
{
id diskId;
IODevAndIdInfo *idMap = ide_idmap();
int unit, i;
id controllerId = [deviceDescription directDevice];
#ifdef DEBUG
IOLog("IdeDisk probed with controller id %x\n", controllerId);
#endif DEBUG
for (i = 0; i < probedControllerCount; i++) {
if (probedControllers[i] == controllerId) {
//IOLog("IdeDisk already probed for controller %x\n", controllerId);
return YES;
}
}
probedControllers[probedControllerCount++] = controllerId;
// IOLog("IdeDisk probing for controller %x\n", controllerId);
for (unit = 0; unit < MAX_IDE_DRIVES; unit++) {
diskId = [[IdeDisk alloc] initFromDeviceDescription:deviceDescription];
[diskId initResources:controllerId];
[diskId setDevAndIdInfo:&(idMap[diskUnit])];
if ([diskId ideDiskInit:diskUnit target:unit] == NO) {
[diskId free];
continue;
}
if (([self hd_devsw_init:deviceDescription]) == NO) {
[diskId free];
IOLog("IDEDisk: failed to add to devsw tables.\n");
return NO;
}
/*
* Success; we initialized a drive. Have DiskObject superclass take
* care of the rest.
*/
[diskId setDeviceKind:"IDEDisk"];
[diskId setIsPhysical:YES];
[diskId registerDevice];
diskUnit += 1;
}
return YES;
}
/*
* Add our entry to the device switch tables.
*/
+ (BOOL)hd_devsw_init:deviceDescription
{
extern int seltrue();
/*
* We get called once for each IDE controller in the system; we
* only have to call IOAddToCdevsw() once.
*/
if (switchTableInited == YES) {
return YES;
}
if ([self addToCdevswFromDescription: deviceDescription
open: (IOSwitchFunc) ideopen
close: (IOSwitchFunc) ideclose
read: (IOSwitchFunc) ideread
write: (IOSwitchFunc) idewrite
ioctl: (IOSwitchFunc) ideioctl
stop: (IOSwitchFunc) eno_stop
reset: (IOSwitchFunc) nulldev
select: (IOSwitchFunc) seltrue
mmap: (IOSwitchFunc) eno_mmap
getc: (IOSwitchFunc) eno_getc
putc: (IOSwitchFunc) eno_putc] != YES)
{
return NO;
}
if ([self addToBdevswFromDescription: deviceDescription
open: (IOSwitchFunc) ideopen
close: (IOSwitchFunc) ideclose
strategy: (IOSwitchFunc) idestrategy
ioctl: (IOSwitchFunc) ideioctl
dump: (IOSwitchFunc) eno_dump
psize: (IOSwitchFunc) idesize
isTape: FALSE] != YES)
{
return NO;
}
ide_init_idmap(self);
switchTableInited = YES;
#ifdef undef
IOLog("IDE: block major %d, character major %d\n",
[self blockMajor], [self characterMajor]);
#endif undef
return YES;
}
/*
* Common read/write methods. These are used directly in the kernel; user-level
* methods using remote objects as defined in IODevice.h in turn call these.
*/
- (IOReturn) readAt : (unsigned)offset
length : (unsigned)length
buffer : (unsigned char *)buffer
actualLength : (unsigned *)actualLength
client : (vm_task_t)client
{
IOReturn rtn;
rtn = [self deviceRwCommon : IDEC_READ
block : offset
length : length
buffer : buffer
client: client
pending : NULL
actualLength : actualLength];
return(rtn);
}
- (IOReturn) readAsyncAt : (unsigned)offset
length : (unsigned)length
buffer : (unsigned char *)buffer
pending : (void *)pending
client : (vm_task_t)client
{
IOReturn rtn;
rtn = [self deviceRwCommon : IDEC_READ
block : offset
length : length
buffer : buffer
client : client
pending : (void *)pending
actualLength : NULL];
return(rtn);
}
- (IOReturn) writeAt : (unsigned)offset
length : (unsigned)length
buffer : (unsigned char *)buffer
actualLength : (unsigned *)actualLength
client : (vm_task_t)client
{
IOReturn rtn;
rtn = [self deviceRwCommon : IDEC_WRITE
block : offset
length : length
buffer : buffer
client: client
pending : NULL
actualLength : actualLength];
return(rtn);
}
- (IOReturn) writeAsyncAt : (unsigned)offset
length : (unsigned)length
buffer : (unsigned char *)buffer
pending : (void *)pending
client : (vm_task_t)client
{
IOReturn rtn;
rtn = [self deviceRwCommon : IDEC_WRITE
block : offset
length : length
buffer : buffer
client : client
pending : (void *)pending
actualLength : NULL];
return(rtn);
}
- (IOReturn)updatePhysicalParameters
{
// we have got everything we need during initialization
return(IO_R_SUCCESS);
}
- (void)abortRequest
{
ideBuf_t *ideBuf;
IOReturn rtn;
ideBuf = [self allocIdeBuf:NULL];
ideBuf->command = IDEC_ABORT;
ideBuf->buf = NULL;
ideBuf->needsDisk = 0;
ideBuf->oneWay = 0;
rtn = [self enqueueIdeBuf:ideBuf];
[self freeIdeBuf:ideBuf];
}
- (void)diskBecameReady
{
[_ioQLock lock];
[_ioQLock unlockWith:WORK_AVAILABLE];
}
- (IOReturn)isDiskReady : (BOOL)prompt
{
return(IO_R_SUCCESS);
}
- (IODiskReadyState)updateReadyState
{
return([self lastReadyState]);
}
- (IOReturn) ejectPhysical
{
return(IO_R_UNSUPPORTED);
}
- (int)deviceOpen:(u_int)intentions
{
return(0);
}
- (void)deviceClose
{
return;
}
- (ideDriveInfo_t)ideGetDriveInfo
{
return(_ideInfo);
}
- (id)cntrlr
{
return _cntrlr;
}
- (unsigned)driveNum
{
return _driveNum;
}
- (IOReturn)getIntValues:(unsigned int *)values
forParameter:(IOParameterName)parameter
count:(unsigned int *)count
{
int maxCount = *count;
int blockMajor, characterMajor;
if (maxCount == 0) {
maxCount = IO_MAX_PARAMETER_ARRAY_LENGTH;
}
if (strcmp(parameter, "BlockMajor") == 0) {
ide_block_char_majors(&blockMajor, &characterMajor);
values[0] = blockMajor;
*count = 1;
return IO_R_SUCCESS;
}
if (strcmp(parameter, "CharacterMajor") == 0) {
ide_block_char_majors(&blockMajor, &characterMajor);
values[0] = characterMajor;
*count = 1;
return IO_R_SUCCESS;
}
/*
* Pass to superclass what we can't handle.
*/
return [super getIntValues:values forParameter:parameter
count:&maxCount];
}
- property_IOUnit:(char *)result length:(unsigned int *)maxLen
{
sprintf( result, "%d", [self driveNum]);
}
@end
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.