/* Copyright (c) 1993 NeXT Computer, Inc. All rights reserved.
*
* Example of a loadable i386 driver. This driver doesn't do anything
* other than show that it has been loaded, probed, and has a valid
* IOEISADeviceDescription.
*
* HISTORY
* 04-Feb-93 Doug Mitchell at NeXT
* Created.
* 29-Mar-93 Kathy Walrath at NeXT
* Modified for use as an example of building, loading, & debugging.
*/
#import <driverkit/i386/directDevice.h>
#import <driverkit/i386/IOEISADeviceDescription.h>
#import <driverkit/generalFuncs.h>
#import <kernserv/kern_server_types.h>
#import <kernserv/prototypes.h>
#import "myTestDriver.h"
#import "myTestDriverUser.h"

#define my_PARAMETER_STRING "ack"

static int _myTestDriverUnit = 0;

@implementation myTestDriver

/*
* Probe, configure board and init new instance. This method is
* documented in the IODevice spec sheet.
*/
+ (BOOL)probe:deviceDescription
{
id driver;

driver = [[self alloc] initFromDeviceDescription:deviceDescription];
if (driver == nil)
return NO;
else return YES;
}

/*
* Init the new instance. This method is documented in the i386-specific
* part of the IODirectDevice spec sheet.
*/
- initFromDeviceDescription:deviceDescription
{
char name[80];

#ifdef USE_HW
/*
* A real driver would call [super initFromDeviceDescription:], which
* reserves hardware resources (DMA channels, I/O ports, etc.).
* Since this driver doesn't really do anything, it isn't necessary
* to reserve resources. However, it shouldn't hurt anything to
* reserve them. If the resources specified in this driver's bundle
* (in /usr/Devices/myTestDriver.config/*.table) are already reserved,
* [super initFromDeviceDescription:] will return nil.
*/
if ([super initFromDeviceDescription:deviceDescription] == nil)
return nil;
#endif USE_HW

IOLog("myTestDriver: interrupt %d channel %d\n",
[deviceDescription interrupt],
[deviceDescription channel]);
sprintf(name, "%s%d", my_DEVICE_NAME, _myTestDriverUnit);
[self setName:name];
[self setUnit:_myTestDriverUnit++];
[self setLocation:NULL];
[self registerDevice];
_myParameter = my_PARAMETER_STRING;

return self;
}

/*
* This method is documented in the IODevice spec sheet.
*/
- (IOReturn)getCharValues : (unsigned char *)parameterArray
forParameter : (IOParameterName)parameterName
count : (unsigned int *)count
{
const char *param;
unsigned int length;
unsigned int maxCount = *count;

if(strcmp(parameterName, my_PARAMETER_NAME) == 0){
param = _myParameter;
length = strlen(param);
if(length >= maxCount) {
length = maxCount - 1;
}
*count = length + 1;
strncpy(parameterArray, param, length);
parameterArray[length] = '\0';
return IO_R_SUCCESS;
}
else {
/* Pass parameters we don't recognize to our superclass. */
return [super getCharValues:parameterArray
forParameter:parameterName count:count];
}
}