IOReturn net_habitue_device_SC101::reportMaxValidBlock(UInt64 *maxBlock) { OSNumber *size = OSDynamicCast(OSNumber, getProperty(gSC101DeviceSizeKey)); *maxBlock = (size ? size->unsigned64BitValue() / SECTOR_SIZE - 1 : 0); return kIOReturnSuccess; }
bool AppleLVMGroup::addMember(AppleRAIDMember * member) { if (super::addMember(member) == false) return false; OSNumber * number = OSDynamicCast(OSNumber, member->getHeaderProperty(kAppleRAIDChunkCountKey)); if (!number) return false; UInt64 memberBlockCount = number->unsigned64BitValue(); UInt32 memberIndex = member->getMemberIndex(); arMemberBlockCounts[memberIndex] = memberBlockCount; // total up the block count as we go arSetBlockCount += memberBlockCount; arSetMediaSize = arSetBlockCount * arSetBlockSize; // read the TOC on this member IOBufferMemoryDescriptor * newPrimaryBuffer = readPrimaryMetaData(member); if (newPrimaryBuffer && arPrimaryBuffer != newPrimaryBuffer) { if (arPrimaryBuffer) arPrimaryBuffer->release(); arPrimaryBuffer = newPrimaryBuffer; } // scan the logical volumes in start return true; }
bool IOFireWireNub::init( OSDictionary * propTable ) { bool success = true; OSNumber *offset; if( !IOService::init(propTable) ) { success = false; } if( success ) { fAuxiliary = createAuxiliary(); if( fAuxiliary == NULL ) success = false; } if( success ) { offset = OSDynamicCast(OSNumber, propTable->getObject("GUID")); if( offset ) fUniqueID = offset->unsigned64BitValue(); fConfigDirectorySet = OSSet::withCapacity(1); if( fConfigDirectorySet == NULL ) success = false; } return success; }
bool AppleLVMVolume::initWithHeader(OSDictionary * props) { IOLog1("AppleLVMVolume::initWithHeader() entered\n"); if (lvProps) lvProps->release(); lvProps = props; lvProps->retain(); if (!getVolumeUUID()) return false; if (!getGroupUUID()) return false; OSNumber * number; number = OSDynamicCast(OSNumber, lvProps->getObject(kAppleLVMVolumeSequenceKey)); if (!number) return false; lvSequenceNumber = number->unsigned32BitValue(); number = OSDynamicCast(OSNumber, lvProps->getObject(kAppleLVMVolumeExtentCountKey)); if (!number) return false; lvExtentCount = number->unsigned64BitValue(); number = OSDynamicCast(OSNumber, lvProps->getObject(kAppleLVMVolumeSizeKey)); if (!number) return false; lvClaimedSize = number->unsigned64BitValue(); OSString * type = OSDynamicCast(OSString, lvProps->getObject(kAppleLVMVolumeTypeKey)); if (!type) return false; if (type->isEqualTo(kAppleLVMVolumeTypeConcat)) lvTypeID = kLVMTypeConcat; if (type->isEqualTo(kAppleLVMVolumeTypeBitMap)) lvTypeID = kLVMTypeBitMap; if (type->isEqualTo(kAppleLVMVolumeTypeSnapRO)) lvTypeID = kLVMTypeSnapRO; if (type->isEqualTo(kAppleLVMVolumeTypeSnapRW)) lvTypeID = kLVMTypeSnapRW; if (type->isEqualTo(kAppleLVMVolumeTypeMaster)) lvTypeID = kLVMTypeMaster; if (!lvTypeID) return false; lvSnapShot = NULL; // just clear these, they might not exist yet. lvBitMap = NULL; lvParent = NULL; IOLog1("AppleLVMVolume::initWithHeader() successful for %s, size = %llu extent count = %llu\n", getVolumeUUIDString(), lvClaimedSize, lvExtentCount); return true; }
bool VNodeDiskDeviceClass::init(OSDictionary *dict) { m_filePath = NULL; m_vnode = NULL; OSNumber * blockSizeObject = NULL; OSNumber * blockNumObject = NULL; if (super::init(dict) && dict != NULL) { IOLog("Initializing device\n"); m_additionalInformation = (char *) ""; m_productString = (char *) (PROJECT "_" COMPONENT); m_revisionString = (char *) VERSION; m_vendorString = (char *) DEVELOPER; m_filePath = OSDynamicCast(OSString, dict->getObject("VNode File Path")); if (!m_filePath) { IOLog("Missing file path parameter in VNode Disk\n"); return false; } m_filePath->retain(); blockSizeObject = OSDynamicCast(OSNumber, dict->getObject("Block Size")); if (!blockSizeObject) { IOLog("Missing block size parameter\n"); return false; } m_blockSize = blockSizeObject->unsigned64BitValue(); blockNumObject = OSDynamicCast(OSNumber, dict->getObject("Block num")); if (!blockNumObject) { IOLog("Missing block num parameter\n"); return false; } m_blockNum = blockNumObject->unsigned64BitValue(); return true; } else { IOLog("Unsucessfuly initialised VNode Disk Device\n"); return false; } }
bool AppleRAIDMirrorSet::addMember(AppleRAIDMember * member) { if (arExpectingLiveAdd) { // for mirrors the set is not paused for adding while adding new // members, mark it as a spare here to avoid having it marked broken member->changeMemberState(kAppleRAIDMemberStateSpare, true); } if (super::addMember(member) == false) return false; // set block count = member block count OSNumber * number = OSDynamicCast(OSNumber, member->getHeaderProperty(kAppleRAIDChunkCountKey)); if (!number) return false; arSetBlockCount = number->unsigned64BitValue(); arSetMediaSize = arSetBlockCount * arSetBlockSize; if (arOpenLevel == kIOStorageAccessNone) startSetCompleteTimer(); return true; }
IOReturn IOATABlockStorageDriver::reportMaxWriteTransfer ( UInt64 blocksize, UInt64 * max ) { OSNumber * size; STATUS_LOG ( ( "IOATABlockStorageDriver::reportMaxWriteTransfer called.\n" ) ); *max = blocksize * kIOATAMaximumBlockCount8Bit; size = OSDynamicCast ( OSNumber, getProperty ( kIOMaximumBlockCountWriteKey ) ); if ( size != NULL ) { *max = size->unsigned64BitValue ( ) * blocksize; } return kIOReturnSuccess; }
void ApplePS2Mouse::setParamPropertiesGated(OSDictionary * config) { if (NULL == config) return; const struct {const char *name; int *var;} int32vars[]={ {"DefaultResolution", &defres}, {"ResolutionMode", &resmode}, {"ScrollResolution", &scrollres}, {"MouseYInverter", &mouseyinverter}, {"ScrollYInverter", &scrollyinverter}, {"WakeDelay", &wakedelay}, {"MouseCount", &mousecount}, {"ButtonCount", &_buttonCount}, }; const struct {const char *name; int *var;} boolvars[]={ {"ForceDefaultResolution", &forceres}, {"ForceSetResolution", &forcesetres}, {"ActLikeTrackpad", &actliketrackpad}, {"DisableLEDUpdating", &noled}, {"FakeMiddleButton", &_fakemiddlebutton}, }; const struct {const char* name; bool* var;} lowbitvars[]={ {"TrackpadScroll", &scroll}, {"OutsidezoneNoAction When Typing", &outzone_wt}, {"PalmNoAction Permanent", &palm}, {"PalmNoAction When Typing", &palm_wt}, {"USBMouseStopsTrackpad", &usb_mouse_stops_trackpad}, }; const struct {const char* name; uint64_t* var; } int64vars[]={ {"MiddleClickTime", &_maxmiddleclicktime}, }; OSNumber *num; OSBoolean *bl; int oldmousecount = mousecount; bool old_usb_mouse_stops_trackpad = usb_mouse_stops_trackpad; // 64-bit config items for (int i = 0; i < countof(int64vars); i++) if ((num=OSDynamicCast(OSNumber, config->getObject(int64vars[i].name)))) { *int64vars[i].var = num->unsigned64BitValue(); setProperty(int64vars[i].name, *int64vars[i].var, 64); } // boolean config items for (int i = 0; i < countof(boolvars); i++) if ((bl=OSDynamicCast (OSBoolean,config->getObject (boolvars[i].name)))) { *boolvars[i].var = bl->isTrue(); setProperty(boolvars[i].name, *boolvars[i].var ? kOSBooleanTrue : kOSBooleanFalse); } // lowbit config items for (int i = 0; i < countof(lowbitvars); i++) if ((num=OSDynamicCast (OSNumber,config->getObject(lowbitvars[i].name)))) { *lowbitvars[i].var = (num->unsigned32BitValue()&0x1)?true:false; setProperty(lowbitvars[i].name, *lowbitvars[i].var ? 1 : 0, 32); } // 32-bit config items for (int i = 0; i < countof(int32vars);i++) if ((num=OSDynamicCast (OSNumber,config->getObject (int32vars[i].name)))) { *int32vars[i].var = num->unsigned32BitValue(); setProperty(int32vars[i].name, *int32vars[i].var, 32); } // check for special terminating sequence from PS2Daemon if (-1 == mousecount) { // when system is shutting down/restarting we want to force LED off if (ledpresent && !noled) setTouchpadLED(0x10); mousecount = oldmousecount; } // disable trackpad when USB mouse is plugged in // check for mouse count changing... if ((oldmousecount != 0) != (mousecount != 0) || old_usb_mouse_stops_trackpad != usb_mouse_stops_trackpad) { // either last mouse removed or first mouse added ignoreall = (mousecount != 0) && usb_mouse_stops_trackpad; updateTouchpadLED(); } // convert to IOFixed format... defres <<= 16; }
bool ACPIProbe::start(IOService * provider) { ACPISensorsDebugLog("starting..."); if (!super::start(provider)) return false; if (!(acpiDevice = OSDynamicCast(IOACPIPlatformDevice, provider))) { ACPISensorsFatalLog("ACPI device not ready"); return false; } methods = OSArray::withCapacity(0); OSNumber *interval = NULL; OSNumber *timeout = NULL; OSBoolean *logging = NULL; OSArray *list = NULL; // Try to load configuration from info.plist first if (OSDictionary *configuration = getConfigurationNode()) { OSBoolean* disable = OSDynamicCast(OSBoolean, configuration->getObject("DisableDevice")); if (disable && disable->isTrue()) return false; interval = OSDynamicCast(OSNumber, configuration->getObject("PollingInterval")); timeout = OSDynamicCast(OSNumber, configuration->getObject("PollingTimeout")); logging = OSDynamicCast(OSBoolean, configuration->getObject("LoggingEnabled")); list = OSDynamicCast(OSArray, configuration->getObject("Methods")); } // Try to load configuration provided by ACPI device else { OSObject *object = NULL; if (kIOReturnSuccess == acpiDevice->evaluateObject("INVL", &object) && object) interval = OSDynamicCast(OSNumber, object); if (kIOReturnSuccess == acpiDevice->evaluateObject("TOUT", &object) && object) timeout = OSDynamicCast(OSNumber, object); if (kIOReturnSuccess == acpiDevice->evaluateObject("LOGG", &object) && object) { if (OSNumber *number = OSDynamicCast(OSNumber, object)) { logging = OSBoolean::withBoolean(number->unsigned8BitValue() == 1); } } if (kIOReturnSuccess == acpiDevice->evaluateObject("LIST", &object) && object) list = OSDynamicCast(OSArray, object); else ACPISensorsErrorLog("polling methods table (LIST) not found"); } if (interval) { pollingInterval = (double)interval->unsigned64BitValue() / (double)1000.0; ACPISensorsInfoLog("polling interval %lld ms", interval->unsigned64BitValue()); if (pollingInterval) { if (timeout) { pollingTimeout = (double)timeout->unsigned64BitValue() / 1000.0; ACPISensorsInfoLog("polling timeout %lld ms", timeout->unsigned64BitValue()); } if (logging) { loggingEnabled = logging->isTrue(); ACPISensorsInfoLog("logging %s", loggingEnabled ? "enabled" : "disabled"); } if (list) { for (unsigned int i = 0; i < list->getCount(); i++) { if (OSString *method = OSDynamicCast(OSString, list->getObject(i))) { if (method->getLength() && kIOReturnSuccess == acpiDevice->validateObject(method->getCStringNoCopy())) { methods->setObject(method); ACPISensorsInfoLog("method \"%s\" registered", method->getCStringNoCopy()); } else ACPISensorsErrorLog("unable to register method \"%s\"", method->getCStringNoCopy()); } } } } else ACPISensorsWarningLog("polling interval is set to zero, driver will be disabled"); } //REVIEW_REHABMAN: just bail if no methods to call... no need to stick around... if (!methods->getCount()) return false; if (methods->getCount()) { // woorkloop if (!(workloop = getWorkLoop())) { HWSensorsFatalLog("Failed to obtain workloop"); return false; } if (!(timerEventSource = IOTimerEventSource::timerEventSource( this, OSMemberFunctionCast(IOTimerEventSource::Action, this, &ACPIProbe::woorkloopTimerEvent)))) { ACPISensorsFatalLog("failed to initialize timer event source"); return false; } if (kIOReturnSuccess != workloop->addEventSource(timerEventSource)) { ACPISensorsFatalLog("failed to add timer event source into workloop"); return false; } timerEventSource->setTimeoutMS(100); //ACPISensorsInfoLog("%d method%s registered", methods->getCount(), methods->getCount() > 1 ? "s" : ""); } registerService(); ACPISensorsInfoLog("started"); return true; }
bool net_habitue_device_SC101::init(OSDictionary *properties) { KINFO("init"); gSC101DeviceIDKey = OSSymbol::withCString(kSC101DeviceIDKey); gSC101DeviceIOMaxReadSizeKey = OSSymbol::withCString(kSC101DeviceIOMaxReadSizeKey); gSC101DeviceIOMaxWriteSizeKey = OSSymbol::withCString(kSC101DeviceIOMaxWriteSizeKey); gSC101DevicePartitionAddressKey = OSSymbol::withCString(kSC101DevicePartitionAddressKey); gSC101DeviceRootAddressKey = OSSymbol::withCString(kSC101DeviceRootAddressKey); gSC101DevicePartNumberKey = OSSymbol::withCString(kSC101DevicePartNumberKey); gSC101DeviceVersionKey = OSSymbol::withCString(kSC101DeviceVersionKey); gSC101DeviceLabelKey = OSSymbol::withCString(kSC101DeviceLabelKey); gSC101DeviceSizeKey = OSSymbol::withCString(kSC101DeviceSizeKey); OSString *id = OSDynamicCast(OSString, properties->getObject(gSC101DeviceIDKey)); if (!id) return false; if (!super::init(properties)) return false; OSNumber *ioMaxReadSize = OSDynamicCast(OSNumber, properties->getObject(gSC101DeviceIOMaxReadSizeKey)); if (!ioMaxReadSize || ioMaxReadSize->unsigned64BitValue() < SECTOR_SIZE || ioMaxReadSize->unsigned64BitValue() > MAX_IO_READ_SIZE || ioMaxReadSize->unsigned64BitValue() & (ioMaxReadSize->unsigned64BitValue() - 1)) { ioMaxReadSize = OSNumber::withNumber(DEFAULT_IO_READ_SIZE, 64); if (ioMaxReadSize) { setProperty(gSC101DeviceIOMaxReadSizeKey, ioMaxReadSize); ioMaxReadSize->release(); } } OSNumber *ioMaxWriteSize = OSDynamicCast(OSNumber, properties->getObject(gSC101DeviceIOMaxWriteSizeKey)); if (!ioMaxWriteSize || ioMaxWriteSize->unsigned64BitValue() < SECTOR_SIZE || ioMaxWriteSize->unsigned64BitValue() > MAX_IO_WRITE_SIZE || ioMaxWriteSize->unsigned64BitValue() & (ioMaxWriteSize->unsigned64BitValue() - 1)) { ioMaxWriteSize = OSNumber::withNumber(DEFAULT_IO_WRITE_SIZE, 64); if (ioMaxWriteSize) { setProperty(gSC101DeviceIOMaxWriteSizeKey, ioMaxWriteSize); ioMaxWriteSize->release(); } } nanoseconds_to_absolutetime(1000000000ULL * 60, &_resolveInterval); _mediaStateAttached = false; _mediaStateChanged = true; STAILQ_INIT(&_pendingHead); _pendingCount = 0; STAILQ_INIT(&_outstandingHead); _outstandingCount = 0; return true; }
bool ZFSDatasetProxy::start(IOService *provider) { OSObject *property = NULL, *size = NULL; OSString *nameString = NULL; OSNumber *sizeNum = NULL; OSDictionary *deviceDict = NULL, *protocolDict = NULL; const OSSymbol *virtualSymbol = NULL, *internalSymbol = NULL; const char *cstr = NULL; char *pstring = NULL; int plen = 0; bool started = false; size = copyProperty(kZFSPoolSizeKey, gIOServicePlane, (kIORegistryIterateRecursively|kIORegistryIterateParents)); property = copyProperty(kZFSPoolNameKey, gIOServicePlane, (kIORegistryIterateRecursively|kIORegistryIterateParents)); if (!size || !property) { dprintf("couldn't get pool name or size"); goto error; } nameString = OSDynamicCast(OSString, property); if (!nameString) { dprintf("missing pool name"); goto error; } #if 0 /* Try hard to get the name string */ do { nameString = OSDynamicCast(OSString, property); if (nameString) nameString->retain(); if (!nameString) { OSSymbol *nameSymbol; nameSymbol = OSDynamicCast(OSSymbol, property); if (!nameSymbol) { dprintf("couldn't get name"); goto error; } nameString = OSString::withCString( nameSymbol->getCStringNoCopy()); } } while (0); #endif sizeNum = OSDynamicCast(OSNumber, size); if (!sizeNum) { dprintf("invalid size"); goto error; } _pool_bcount = sizeNum->unsigned64BitValue() / DEV_BSIZE; sizeNum = 0; size->release(); size = 0; cstr = nameString->getCStringNoCopy(); if (!cstr || (plen = strlen(cstr) + 1) == 1) { goto error; } pstring = (char *)IOMalloc(plen); if (!pstring) { goto error; } snprintf(pstring, plen, "%s", cstr); productString = pstring; pstring = 0; if (IOBlockStorageDevice::start(provider) == false) { dprintf("BlockStorageDevice start failed"); goto error; } started = true; deviceDict = OSDynamicCast(OSDictionary, getProperty(kIOPropertyDeviceCharacteristicsKey)); if (deviceDict) { /* Clone a new dictionary */ deviceDict = OSDictionary::withDictionary(deviceDict); if (!deviceDict) { dprintf("dict clone failed"); goto error; } } if (!deviceDict) { dprintf("creating new device dict"); deviceDict = OSDictionary::withCapacity(1); } if (!deviceDict) { dprintf("missing device dict"); goto error; } deviceDict->setObject(kIOPropertyProductNameKey, nameString); OSSafeReleaseNULL(nameString); if (setProperty(kIOPropertyDeviceCharacteristicsKey, deviceDict) == false) { dprintf("device dict setProperty failed"); goto error; } OSSafeReleaseNULL(deviceDict); protocolDict = OSDynamicCast(OSDictionary, getProperty(kIOPropertyProtocolCharacteristicsKey)); if (protocolDict) { /* Clone a new dictionary */ protocolDict = OSDictionary::withDictionary(protocolDict); if (!protocolDict) { dprintf("dict clone failed"); goto error; } } if (!protocolDict) { dprintf("creating new protocol dict"); protocolDict = OSDictionary::withCapacity(1); } if (!protocolDict) { dprintf("missing protocol dict"); goto error; } virtualSymbol = OSSymbol::withCString( kIOPropertyPhysicalInterconnectTypeVirtual); internalSymbol = OSSymbol::withCString( kIOPropertyInternalKey); if (!virtualSymbol || !internalSymbol) { dprintf("symbol alloc failed"); goto error; } protocolDict->setObject(kIOPropertyPhysicalInterconnectTypeKey, virtualSymbol); protocolDict->setObject(kIOPropertyPhysicalInterconnectLocationKey, internalSymbol); OSSafeReleaseNULL(virtualSymbol); OSSafeReleaseNULL(internalSymbol); if (setProperty(kIOPropertyProtocolCharacteristicsKey, protocolDict) == false) { dprintf("protocol dict setProperty failed"); goto error; } OSSafeReleaseNULL(protocolDict); registerService(kIOServiceAsynchronous); return (true); error: OSSafeReleaseNULL(size); OSSafeReleaseNULL(property); OSSafeReleaseNULL(deviceDict); OSSafeReleaseNULL(protocolDict); OSSafeReleaseNULL(nameString); OSSafeReleaseNULL(virtualSymbol); OSSafeReleaseNULL(internalSymbol); if (pstring) IOFree(pstring, plen); if (started) IOBlockStorageDevice::stop(provider); return (false); }
IOReturn IOHIKeyboard::setParamProperties( OSDictionary * dict ) { OSData * data = NULL; OSNumber * number = NULL; IOReturn err = kIOReturnSuccess; IOReturn err2 = kIOReturnSuccess; unsigned char * map = NULL; IOHIKeyboardMapper * oldMap = NULL; bool updated = false; UInt64 nano; if( dict->getObject(kIOHIDResetKeyboardKey)) resetKeyboard(); IOLockLock( _deviceLock); if ((number = OSDynamicCast(OSNumber, dict->getObject(kIOHIDKeyRepeatKey))) || (data = OSDynamicCast(OSData, dict->getObject(kIOHIDKeyRepeatKey)))) { nano = (number) ? number->unsigned64BitValue() : *((UInt64 *) (data->getBytesNoCopy())); if( nano < EV_MINKEYREPEAT) nano = EV_MINKEYREPEAT; nanoseconds_to_absolutetime(nano, &_keyRepeat); updated = true; } if ((number = OSDynamicCast(OSNumber, dict->getObject(kIOHIDInitialKeyRepeatKey))) || (data = OSDynamicCast(OSData, dict->getObject(kIOHIDInitialKeyRepeatKey)))) { nano = (number) ? number->unsigned64BitValue() : *((UInt64 *) (data->getBytesNoCopy())); if( nano < EV_MINKEYREPEAT) nano = EV_MINKEYREPEAT; nanoseconds_to_absolutetime(nano, &_initialKeyRepeat); updated = true; } if( (data = OSDynamicCast( OSData, dict->getObject(kIOHIDKeyMappingKey)))) { map = (unsigned char *)IOMalloc( data->getLength() ); bcopy( data->getBytesNoCopy(), map, data->getLength() ); oldMap = _keyMap; _keyMap = IOHIKeyboardMapper::keyboardMapper(this, map, data->getLength(), true); if (_keyMap) { // point the new keymap to the IOHIDSystem, so it can set properties in it _keyMap->setKeyboardTarget((IOService *) _keyboardEventTarget); if (oldMap) oldMap->release(); updated = true; } else { _keyMap = oldMap; err = kIOReturnBadArgument; } } if (NULL != (number = OSDynamicCast(OSNumber, dict->getObject(kIOHIDSubinterfaceIDKey)))) { _deviceType = number->unsigned32BitValue(); updated = true; } // give the keymap a chance to update to new properties if (_keyMap) err2 = _keyMap->setParamProperties(dict); IOLockUnlock( _deviceLock); if( updated ) updateProperties(); // we can only return one error if (err == kIOReturnSuccess) err = err2; return( err == kIOReturnSuccess ) ? super::setParamProperties(dict) : err; }
bool net_lundman_zfs_zvol_device::attach(IOService* provider) { OSDictionary *protocolCharacteristics = 0; OSDictionary *deviceCharacteristics = 0; OSDictionary *storageFeatures = 0; OSBoolean *unmapFeature = 0; OSString *dataString = 0; OSNumber *dataNumber = 0; if (super::attach(provider) == false) return (false); m_provider = OSDynamicCast(net_lundman_zfs_zvol, provider); if (m_provider == NULL) return (false); /* * We want to set some additional properties for ZVOLs, in * particular, "Virtual Device", and type "File" * (or is Internal better?) * * Finally "Generic" type. * * These properties are defined in *protocol* characteristics */ protocolCharacteristics = OSDictionary::withCapacity(3); if (!protocolCharacteristics) { IOLog("failed to create dict for protocolCharacteristics.\n"); return (true); } dataString = OSString::withCString( kIOPropertyPhysicalInterconnectTypeVirtual); if (!dataString) { IOLog("could not create interconnect type string\n"); return (true); } protocolCharacteristics->setObject( kIOPropertyPhysicalInterconnectTypeKey, dataString); dataString->release(); dataString = 0; dataString = OSString::withCString(kIOPropertyInterconnectFileKey); if (!dataString) { IOLog("could not create interconnect location string\n"); return (true); } protocolCharacteristics->setObject( kIOPropertyPhysicalInterconnectLocationKey, dataString); dataString->release(); dataString = 0; setProperty(kIOPropertyProtocolCharacteristicsKey, protocolCharacteristics); protocolCharacteristics->release(); protocolCharacteristics = 0; /* * We want to set some additional properties for ZVOLs, in * particular, physical block size (volblocksize) of the * underlying ZVOL, and 'logical' block size presented by * the virtual disk. Also set physical bytes per sector. * * These properties are defined in *device* characteristics */ deviceCharacteristics = OSDictionary::withCapacity(3); if (!deviceCharacteristics) { IOLog("failed to create dict for deviceCharacteristics.\n"); return (true); } /* Set logical block size to ZVOL_BSIZE (512b) */ dataNumber = OSNumber::withNumber(ZVOL_BSIZE, 8 * sizeof (ZVOL_BSIZE)); deviceCharacteristics->setObject(kIOPropertyLogicalBlockSizeKey, dataNumber); dprintf("logicalBlockSize %llu\n", dataNumber->unsigned64BitValue()); dataNumber->release(); dataNumber = 0; /* Set physical block size to match volblocksize property */ dataNumber = OSNumber::withNumber(zv->zv_volblocksize, 8 * sizeof (zv->zv_volblocksize)); deviceCharacteristics->setObject(kIOPropertyPhysicalBlockSizeKey, dataNumber); dprintf("physicalBlockSize %llu\n", dataNumber->unsigned64BitValue()); dataNumber->release(); dataNumber = 0; /* Set physical bytes per sector to match volblocksize property */ dataNumber = OSNumber::withNumber((uint64_t)(zv->zv_volblocksize), 8 * sizeof (uint64_t)); deviceCharacteristics->setObject(kIOPropertyBytesPerPhysicalSectorKey, dataNumber); dprintf("physicalBytesPerSector %llu\n", dataNumber->unsigned64BitValue()); dataNumber->release(); dataNumber = 0; /* Apply these characteristics */ setProperty(kIOPropertyDeviceCharacteristicsKey, deviceCharacteristics); deviceCharacteristics->release(); deviceCharacteristics = 0; /* * ZVOL unmap support * * These properties are defined in IOStorageFeatures */ storageFeatures = OSDictionary::withCapacity(1); if (!storageFeatures) { IOLog("failed to create dictionary for storageFeatures.\n"); return (true); } /* Set unmap feature */ unmapFeature = OSBoolean::withBoolean(true); storageFeatures->setObject(kIOStorageFeatureUnmap, unmapFeature); unmapFeature->release(); unmapFeature = 0; /* Apply these storage features */ setProperty(kIOStorageFeaturesKey, storageFeatures); storageFeatures->release(); storageFeatures = 0; /* * Set transfer limits: * * Maximum transfer size (bytes) * Maximum transfer block count * Maximum transfer block size (bytes) * Maximum transfer segment count * Maximum transfer segment size (bytes) * Minimum transfer segment size (bytes) * * We will need to establish safe defaults for all / per volblocksize * * Example: setProperty(kIOMinimumSegmentAlignmentByteCountKey, 1, 1); */ /* * Finally "Generic" type, set as a device property. Tried setting this * to the string "ZVOL" however the OS does not recognize it as a block * storage device. This would probably be possible by extending the * IOBlockStorage Device / Driver relationship. */ setProperty(kIOBlockStorageDeviceTypeKey, kIOBlockStorageDeviceTypeGeneric); return (true); }