|
|
Darwin 0.2 Driver Kit
� " $ �` �l �h �X �\ � # &!�G 9 9 � d H H d �/ d �� � t �� � t w �� � � � = y " $ �` �l �h �X �\ � h &G 9 9 � d H H d �/ d ? �
9 ? �
9 w � � � =
8 8 x H H �/ d[(� H H d d ' � @ �� Z
Z�@�`� ��0�P��I/O Threads
� Z
Z �@�`� ��0�P��
Instance variables:
� m
m �@�`� ��0�P���� �queue_head_t ioQueueDisk; // for I/Os requiring disk
� �queue_head_t ioQueueNodisk; // for other I/O
id ioQLock; // NXConditionLock -
// protects the queues; I/O
// thread(s) sleeps on this
�� �
/*
* Values for ioQLock.condition.
*/
typedef enum { IOQueuesEmpty� �, WorkAvailable };
� Z
Z �@�`� ��0�P��
� �
Command Buffer:
`
/*
* Device-specific eject method, only called on physical
* device.
*/
- (IOReturn) ejectPhysical;
/*
* Determine basic state of device. This method should NOT
* implement any retries. It also should not return
* RS_EJECTING (That's only used in the lastReadyState
* instance variable).
*/
- (IODiskReadyState)updateReadyState;
@end
� �
�� �/*
* Basic "usefulness" state of drive.
*/
typedef enum {
IO_Ready, // Ready for r/w operations
IO_NotReady, // not ready (spinning up or busy)
IO_NoDisk, // no disk present
IO_Ejecting // eject in progress
} IODiskReadyState;
� �� �
��� �
� m
m �@�`� ��0�P��typedef struct {
/*
* device-specific stuff here which defines one I/O.
* For example, block number, transfer count,
* return status, etc.
*/
/*
* cmdLock is what an exported method blocks on
* when waiting for the I/O thread to process this
* command.
*/
NXConditionLock cmdLock;
/*
* This determines whether the operation is
* synchronous or async.
*/
void *pending;
} commandBuf;
�� Z
Z �@�`� ��0�P��
� �� �Exported method:
� m
m �@�`� ��0�P���� �{
Cons up a commandBuffer for this I/O;
/*
* Enqueue on appropriate I/O queue and wake up I/O
* thread.
*/
if this I/O requires disk {
enqueue on ioQueueDisk;
}
else {
enqueue on ioQueueNodisk;
}
[ioQLock lock];
[ioQLock unlockWith:WorkAvailable];
/*
* Wait for I/O complete.
*/
[commandBuffer.cmdLock lockWhen:YES];
� Z
Z �@�`� ��0�P��}
� �� �
�
I/O thread:
� m
m �@�`� ��0�P���� �{
initialize;
while(1) {
[ioQLock lockWhen: WorkAvailable];
[ioQLock unlock];
process everything on ioQueueNodisk;
if((lastReadyState != IO_RS_NODISK) &&
(lastReadyState != IO_RS_EJECTING)) {
process everything in ioQueueDisk;
else {
if ioQueueDisk non-empty {
[self requestInsertionPanelForDiskType];
}
}
[ioQLock unlockWith:<current queue state>];
}
}
�
� Z
Z �@�`� ��0�P��� �To process one commandBuf� �:
� m
m �@�`� ��0�P���� �{
perform device-specific I/O described in
commandBuf;
if(commandBuf.pending) {
/*
* Async operation.
*/
[self completeTransfer:commandBuf.pending
withStatus:...
actualLength:...];
}
else {
/*
* Wake up client.
*/
[commandBuf.cmdLock lock];
[commandBuf.cmdLock unlockWith:YES];
}
\� Z
Z�@�`� ��0�P��
Class Hierarchy
� Z
Z �@�`� ��0�P��
n
� Z
Z�@�`� ��0�P�� � �DiskHierarchy.590972.eps�
� Z
Z �@�`� ��0�P��
� */
- (void)abortRequest;
/*
* Called by the volCheck thread when a transition to
* "ready" is detected. Pending I/Os which require a disk
* may proceed.
*/
- (void)diskBecameReady;
/*
* Inquire if disk is present; if not, and 'prompt' is TRUE,
* ask for it.
* Returns IO_R_NODISK if:
* prompt TRUE, disk not present, and user cancels
* request for disk.
* prompt FALSE, disk not present.
* Else returns IO_R_SUCCESS.
*/
- (IOReturn)isDiskReady : (BOOL)prompt;
zIODiskReadingAndWriting protocol
� Z
Z �@�`� ��0�P��
�� �@protocol IODiskReadingAndWriting
- (IOReturn) readAt : (unsigned)offset
length : (unsigned)length
buffer : (unsigned char *)buffer
actualLength : (unsigned *)actualLength
client : (vm_task_t)client;
- (IOReturn) readAsyncAt : (unsigned)offset
length : (unsigned)length
buffer : (unsigned char *)buffer
pending : (void *)pending
client : (vm_task_t)client;
- (IOReturn) writeAt : (unsigned)offset
length : (unsigned)length
buffer : (unsigned char *)buffer
actualLength : (unsigned *)actualLength
client : (vm_task_t)client;
- (IOReturn) writeAsyncAt : (unsigned)offset
length : (unsigned)length
buffer : (unsigned char *)buffer
pending : (void *)pending
client : (vm_task_t)client;
@end
� �
�� Z
Z�@�`� ��0�P��
The volCheck module
� Z
Z �@�`� ��0�P��
� Disk Insertion detection
� Automount
� Alert panels
� abort notification
�� Z
Z�@�`� ��0�P��Kernel "Glue" Layer
� Z
Z �@�`� ��0�P��
This struct provides mapping between dev_t and id:
�� �typedef struct {
id liveId; // instance for live partition
id partitionId[NPART-1]; // for block and raw devices
dev_t rawDev; // used by volCheck logic
dev_t blockDev; // ditto
} IODevAndIdInfo;
� �� �
� Allocated in glue layer module, one per physical
disk
� Each instance of IODisk (or subclass) contains a
pointer to the associated IODevAndIdInfo.
� rawDev and blockDev initialized in device-
specific routine in kernel glue layer, typically
called from +probe or +initialize.
� Id fields initialized by IODiskPartition (drivers
don't need to worry about these).
!� Z
Z�0�� �Driverkit Disk Classes
16 April, 1993
� Z
Z �@�`� ��0�P��
Outline:
� Introduction
� The volCheck module
� IODiskReadingAndWriting protocol
� IOPhysicalDiskMethods protocol
� Interfacing to cdevsw and bdevsw
� I/O thread architecture
� Q & A
8� Z
Z�@�`� ��0�P��IOPhysicalDiskMethods protocol
� Z
Z �@�`� ��0�P��
�� �@protocol IOPhysicalDiskMethods
/*
* Get physical parameters (dev_size, block_size, etc.) from
* new disk. Called upon disk insertion detection, or other
* transition to RS_READY, or other change of state of
* disk (like a transition to "formatted").
*/
- (IOReturn)updatePhysicalParameters;
/*
* Called by volCheck thread when WS has told us that a
* requested disk is not present. Pending I/Os which require
* a disk to be present must be aborted.
Zd �T C �E � � � T }et t ?
P4 ��t 0.t �.d Pt ��t
�tt �Z�
� Z
Z �@�`� ��0�P��� �To process one commandBuf� �:
� m
m �@�`� ��0�P���� �{
perform device-specific I/O described in
commandBuf;
if(commandBuf.pending) {
/*
* Async operation.
*/
[self completeTransfer:commandBuf.pending
withStatus:...
actualLength:...];
}
else {
/*
* Wake up client.
*/
[commandBuf.cmdLock lock];
[commandBuf.cmdLock unlockWith:YES];
}
}
Zd �T C �E � � � T }et t ?
P4 ��t 0.t �.d Pt ��t
�tt �j
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.