File:  [Apple Darwin 0.x] / driverkit / doc / OLD_NRW / IODiskTalk.wn / WNDocument.wn
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs
Tue Apr 24 17:37:51 2018 UTC (8 years, 3 months ago) by root
Branches: MAIN, Apple
CVS tags: HEAD, Darwin03, Darwin02
Darwin 0.2 Driver Kit

�"$�`�l�h�X�\	�#&!�G99�dHHd�/d�� �t�� �tw�����=y"$�`�l�h�X�\	�h&G99�dHHd�/d?�
9?�
9w���=







88xHH�/d[(�HHdd'�@��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�TC�E���T}ett?
P4��t0.t�.dPt��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�TC�E���T}ett?
P4��t0.t�.dPt��t
�tt�j

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.