#include <libkern/OSByteOrder.h>
#include <IOKit/IOLib.h>
#include <IOKit/IOMessage.h>
#include <IOKit/usb/IOUSBInterface.h>
#include "AnchorUSB.h"
#include "hex2c.h"
extern INTEL_HEX_RECORD demotonehex[];
OSDefineMetaClassAndStructors(com_apple_AnchorUSB, IOService)
#define super IOService
bool
com_apple_AnchorUSB::init(OSDictionary *propTable)
{
IOLog("com_apple_AnchorUSB: init\n");
return (super::init(propTable));
}
IOService*
com_apple_AnchorUSB::probe(IOService *provider, SInt32 *score)
{
IOLog("%s(%p)::probe\n", getName(), this);
return super::probe(provider, score); }
bool
com_apple_AnchorUSB::attach(IOService *provider)
{
IOLog("%s(%p)::attach\n", getName(), this);
return super::attach(provider);
}
void
com_apple_AnchorUSB::detach(IOService *provider)
{
IOLog("%s(%p)::detach\n", getName(), this);
return super::detach(provider);
}
bool
com_apple_AnchorUSB::start(IOService *provider)
{
IOReturn err;
UInt8 writeVal;
int i = 0;
const IOUSBConfigurationDescriptor *cd;
IOLog("%s(%p)::start!\n", getName(), this);
fDevice = OSDynamicCast(IOUSBDevice, provider);
if(!fDevice)
{
IOLog("%s(%p)::start - Provider isn't a USB device!!!\n", getName(), this);
return false;
}
if (fDevice->GetNumConfigurations() < 1)
{
IOLog("%s(%p)::start - no composite configurations\n", getName(), this);
return false;
}
cd = fDevice->GetFullConfigurationDescriptor(0);
if (!cd)
{
IOLog("%s(%p)::start - no config descriptor\n", getName(), this);
return false;
}
if (!fDevice->open(this))
{
IOLog("%s(%p)::start - unable to open device for configuration\n", getName(), this);
return false;
}
err = fDevice->SetConfiguration(this, cd->bConfigurationValue, true);
if (err)
{
IOLog("%s(%p)::start - unable to set the configuration\n", getName(), this);
fDevice->close(this);
return false;
}
writeVal = 1;
err = AnchorWrite(k8051_USBCS, 1, &writeVal);
if(kIOReturnSuccess != err)
{
IOLog("%s(%p)::start - AnchorWrite reset returned err 0x%x!\n", getName(), this, err);
fDevice->close(this);
return false;
}
while(demotonehex[i].Type == 0)
{
err = AnchorWrite(demotonehex[i].Address, demotonehex[i].Length, demotonehex[i].Data);
if(kIOReturnSuccess != err)
{
IOLog("%s(%p)::start - AnchorWrite download %i returned err 0x%x!\n", getName(), this, i, err);
fDevice->close(this);
return false;
}
i++;
}
writeVal = 0;
err = AnchorWrite(k8051_USBCS, 1, &writeVal);
if(kIOReturnSuccess != err)
{
IOLog("%s(%p)::start - AnchorWrite run returned err 0x%x!\n", getName(), this, err);
fDevice->close(this);
return false;
}
return true;
}
void
com_apple_AnchorUSB::stop(IOService *provider)
{
IOLog("%s(%p)::stop\n", getName(), this);
super::stop(provider);
}
bool
com_apple_AnchorUSB::handleOpen(IOService *forClient, IOOptionBits options, void *arg )
{
IOLog("%s(%p)::handleOpen\n", getName(), this);
return super::handleOpen(forClient, options, arg);
}
void
com_apple_AnchorUSB::handleClose(IOService *forClient, IOOptionBits options )
{
IOLog("%s(%p)::handleClose\n", getName(), this);
super::handleClose(forClient, options);
}
IOReturn
com_apple_AnchorUSB::message(UInt32 type, IOService *provider, void *argument)
{
IOLog("%s(%p)::message\n", getName(), this);
switch ( type )
{
case kIOMessageServiceIsTerminated:
if (fDevice->isOpen(this))
{
IOLog("%s(%p)::message - service is terminated - closing device\n", getName(), this);
fDevice->close(this);
}
break;
case kIOMessageServiceIsSuspended:
case kIOMessageServiceIsResumed:
case kIOMessageServiceIsRequestingClose:
case kIOMessageServiceWasClosed:
case kIOMessageServiceBusyStateChange:
default:
break;
}
return kIOReturnSuccess;
return super::message(type, provider, argument);
}
bool
com_apple_AnchorUSB::terminate(IOOptionBits options)
{
IOLog("%s(%p)::terminate\n", getName(), this);
return super::terminate(options);
}
bool
com_apple_AnchorUSB::finalize(IOOptionBits options)
{
IOLog("%s(%p)::finalize\n", getName(), this);
return super::finalize(options);
}
IOReturn
com_apple_AnchorUSB::AnchorWrite(UInt16 anchorAddress, UInt16 count, UInt8 writeBuffer[])
{
IOUSBDevRequest request;
request.bmRequestType = USBmakebmRequestType(kUSBOut, kUSBVendor, kUSBDevice);
request.bRequest = 0xa0;
request.wValue = anchorAddress;
request.wIndex = 0;
request.wLength = count;
request.pData = writeBuffer;
return fDevice->DeviceRequest(&request);
}