File:  [Apple Darwin 0.x] / driverkit / doc / OLD_NRW / IODiskTalk.rtf
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

{\rtf0\nextcset {\fonttbl{\f41487\fnil Ohlfs;}{\f21\fswiss 
Helvetica;}{\f3\fswiss Helvetica;}}
\paperw12240\paperh15840 \margl1800\margr1800\margt0\margb0 
\pgnstart1\ftnstart1 \deftab31680 \sectd\sbknone \linemod0\linex0 
\ftnbj \headery0\footery0 \cols1 {\header \pard \li0\ri0\fi0\qc\sl320 
\plain \f3 \par 
\par 
\par 
\par 
}{\footer \pard \li0\ri0\fi0\qc\sl320 \plain \f3 \par 
\par 
\par 
\par 
}\pard \li0\ri0\fi0\qc\sl280 \tx360 \tx6120 \plain \f21\fs36\b 
Driverkit Disk Classes\par 
16 April, 1993\par 
\par 
\pard \li0\ri0\fi0\sl280 \tx360 \tx1080 \tx1800 \tx2520 
\tx3240 \tx3960 \tx4680 \tx5400 \tx6120 \tx6840 \tx7560 
\tx8260 \par 
\par 
\par 
Outline:\par 
\par 
\'b7 Introduction\par 
\par 
\'b7 The volCheck module\par 
\par 
\'b7 IODiskReadingAndWriting protocol\par 
\par 
\'b7 IOPhysicalDiskMethods protocol\par 
\par 
\'b7 Interfacing to cdevsw and bdevsw\par 
\par 
\'b7 I/O thread architecture\par 
\par 
\'b7 Q & A\par 
\par 
\par 
\page \pard \li0\ri0\fi0\qc\sl280 \tx360 \tx1080 \tx1800 
\tx2520 \tx3240 \tx3960 \tx4680 \tx5400 \tx6120 \tx6840 
\tx7560 \tx8260 \par 
Class Hierarchy\par 
\pard \li0\ri0\fi0\sl280 \tx360 \tx1080 \tx1800 \tx2520 
\tx3240 \tx3960 \tx4680 \tx5400 \tx6120 \tx6840 \tx7560 
\tx8260 \par 
\par 
\par 
\par 
\par 
\pard \keep \li0\ri0\fi0\sl280 \tx360 \tx1080 \tx1800 \tx2520 
\tx3240 \tx3960 \tx4680 \tx5400 \tx6120 \tx6840 \tx7560 
\tx8260 \par 
\pard \keep \li0\ri0\fi0\qc\sl280 \tx360 \tx1080 \tx1800 
\tx2520 \tx3240 \tx3960 \tx4680 \tx5400 \tx6120 \tx6840 
\tx7560 \tx8260    \par 
\pard \keep \li0\ri0\fi0\sl280 \tx360 \tx1080 \tx1800 \tx2520 
\tx3240 \tx3960 \tx4680 \tx5400 \tx6120 \tx6840 \tx7560 
\tx8260 \par 
\par 
\page \pard \li0\ri0\fi0\qc\sl280 \tx360 \tx1080 \tx1800 
\tx2520 \tx3240 \tx3960 \tx4680 \tx5400 \tx6120 \tx6840 
\tx7560 \tx8260 \par 
\par 
The volCheck module\par 
\pard \li0\ri0\fi0\sl280 \tx360 \tx1080 \tx1800 \tx2520 
\tx3240 \tx3960 \tx4680 \tx5400 \tx6120 \tx6840 \tx7560 
\tx8260 \par 
\par 
\par 
\par 
\par 
\'b7 Disk Insertion detection\par 
\par 
\'b7 Automount\par 
\par 
\'b7 Alert panels\par 
\par 
\'b7 abort notification\par 
\par 
\par 
\page IODiskReadingAndWriting protocol\par 
\pard \li0\ri0\fi0\sl280 \tx360 \tx1080 \tx1800 \tx2520 
\tx3240 \tx3960 \tx4680 \tx5400 \tx6120 \tx6840 \tx7560 
\tx8260 \par 
\par 
\f-24049\fs24\b0 @protocol IODiskReadingAndWriting\par 
\par 
- (IOReturn) readAt\tab \tab : (unsigned)offset \par 
\tab \tab \tab \tab   length : (unsigned)length \par 
\tab \tab \tab \tab   buffer : (unsigned char *)buffer\par 
\tab \tab \tab \tab   actualLength : (unsigned *)actualLength 
\par 
\tab \tab \tab \tab   client : (vm_task_t)client;\par 
\par 
- (IOReturn) readAsyncAt\tab : (unsigned)offset \par 
\tab \tab \tab \tab   length : (unsigned)length \par 
\tab \tab \tab \tab   buffer : (unsigned char *)buffer\par 
\tab \tab \tab \tab   pending : (void *)pending\par 
\tab \tab \tab \tab   client : (vm_task_t)client;\par 
\tab \tab \par 
- (IOReturn) writeAt\tab \tab : (unsigned)offset \par 
\tab \tab \tab \tab   length : (unsigned)length \par 
\tab \tab \tab \tab   buffer : (unsigned char *)buffer\par 
\tab \tab \tab \tab   actualLength : (unsigned *)actualLength 
\par 
\tab \tab \tab \tab   client : (vm_task_t)client;\par 
\tab \tab   \par 
- (IOReturn) writeAsyncAt\tab : (unsigned)offset \par 
\tab \tab \tab \tab   length : (unsigned)length \par 
\tab \tab \tab \tab   buffer : (unsigned char *)buffer\par 
\tab \tab \tab \tab   pending : (void *)pending\par 
\tab \tab \tab \tab   client : (vm_task_t)client;\par 
\par 
@end\par 
\f21\fs36\b \par 
\par 
\page \pard \li0\ri0\fi0\qc\sl280 \tx360 \tx1080 \tx1800 
\tx2520 \tx3240 \tx3960 \tx4680 \tx5400 \tx6120 \tx6840 
\tx7560 \tx8260 IOPhysicalDiskMethods protocol\par 
\pard \li0\ri0\fi0\sl280 \tx360 \tx1080 \tx1800 \tx2520 
\tx3240 \tx3960 \tx4680 \tx5400 \tx6120 \tx6840 \tx7560 
\tx8260 \par 
\f-24049\fs24\b0 @protocol IOPhysicalDiskMethods\par 
\par 
/*\par 
 * Get physical parameters (dev_size, block_size, etc.) 
from\par 
 * new disk. Called upon disk insertion detection, or 
other\par 
 * transition to RS_READY, or other change of state 
of\par 
 * disk (like a transition to "formatted").\par 
 */\par 
- (IOReturn)updatePhysicalParameters;\par 
\par 
/*\par 
 * Called by volCheck thread when WS has told us that 
a\par 
 * requested disk is not present. Pending I/Os which 
require\par 
 * a disk to be present must be aborted.\par 
 */\par 
- (void)abortRequest;\par 
\par 
/*\par 
 * Called by the volCheck thread when a transition 
to\par 
 * "ready" is detected. Pending I/Os which require a 
disk\par 
 *  may proceed.\par 
 */\par 
- (void)diskBecameReady;\par 
\par 
/*\par 
 * Inquire if disk is present; if not, and 'prompt' 
is TRUE,\par 
 * ask for it. \par 
 * Returns IO_R_NODISK if:\par 
 *    prompt TRUE, disk not present, and user cancels\par 
 *        request for disk.\par 
 *    prompt FALSE, disk not present.\par 
 * Else returns IO_R_SUCCESS.\par 
 */\par 
- (IOReturn)isDiskReady\tab : (BOOL)prompt;\par 
\par 
\page \par 
/*\par 
 * Device-specific eject method, only called on physical\par 
 * device.\par 
 */\par 
- (IOReturn) ejectPhysical;\par 
\par 
/*\par 
 * Determine basic state of device. This method should 
NOT\par 
 * implement any retries. It also should not return\par 
 * RS_EJECTING (That's only used in the lastReadyState\par 
 * instance variable).\par 
 */\par 
- (IODiskReadyState)updateReadyState;\par 
\par 
@end\par 
\f21\fs36\b \par 
\par 
\f-24049\fs24\b0 /*\par 
 * Basic "usefulness" state of drive.\par 
 */\par 
typedef enum \{\par 
\tab IO_Ready, \tab \tab // Ready for r/w operations\par 
\tab IO_NotReady,\tab \tab // not ready (spinning up 
or busy)\par 
\tab IO_NoDisk, \tab \tab // no disk present\par 
\tab IO_Ejecting\tab \tab // eject in progress\par 
\} IODiskReadyState;\par 
\f21\fs36\b \par 
\page \pard \li0\ri0\fi0\qc\sl280 \tx360 \tx1080 \tx1800 
\tx2520 \tx3240 \tx3960 \tx4680 \tx5400 \tx6120 \tx6840 
\tx7560 \tx8260 Kernel "Glue" Layer\par 
\pard \li0\ri0\fi0\sl280 \tx360 \tx1080 \tx1800 \tx2520 
\tx3240 \tx3960 \tx4680 \tx5400 \tx6120 \tx6840 \tx7560 
\tx8260 \par 
\par 
This struct provides mapping between dev_t and id:\par 
\par 
\f-24049\fs24\b0 typedef struct \{\par 
\tab id liveId;\tab \tab \tab // instance for live partition\par 
\tab id partitionId[NPART-1];\tab // for block and raw 
devices\par 
\tab dev_t rawDev;\tab \tab \tab // used by volCheck 
logic\par 
\tab dev_t blockDev;\tab \tab // ditto\par 
\} IODevAndIdInfo;\par 
\f21\fs36\b \par 
\par 
\'b7 Allocated in glue layer module, one per physical\par 
  disk\par 
\par 
\'b7 Each instance of IODisk (or subclass) contains a 
\par 
  pointer to the associated IODevAndIdInfo.\par 
\par 
\'b7 rawDev and blockDev initialized in device-\par 
  specific routine in kernel glue layer, typically\par 
  called from +probe or +initialize.\par 
\par 
\'b7 Id fields initialized by IODiskPartition (drivers\par 
  don't need to worry about these).\par 
\par 
\par 
\page \pard \li0\ri0\fi0\qc\sl280 \tx360 \tx1080 \tx1800 
\tx2520 \tx3240 \tx3960 \tx4680 \tx5400 \tx6120 \tx6840 
\tx7560 \tx8260 I/O Threads\par 
\pard \li0\ri0\fi0\sl280 \tx360 \tx1080 \tx1800 \tx2520 
\tx3240 \tx3960 \tx4680 \tx5400 \tx6120 \tx6840 \tx7560 
\tx8260 \par 
Instance variables:\par 
\par 
\pard \li380\ri0\fi0\sl280 \tx360 \tx1080 \tx1800 \tx2520 
\tx3240 \tx3960 \tx4680 \tx5400 \tx6120 \tx6840 \tx7560 
\tx8260 \f-24049\fs24\b0 queue_head_t\tab ioQueueDisk;\tab 
// for I/Os requiring disk \par 
queue_head_t\tab ioQueueNodisk;\tab // for other I/O\par 
id \tab \tab \tab ioQLock;\tab \tab // NXConditionLock 
- \par 
\tab \tab \tab \tab \tab \tab // protects the queues; 
I/O\par 
\tab \tab \tab \tab \tab \tab // thread(s) sleeps on 
this\par 
\par 
/*\par 
 * Values for ioQLock.condition.\par 
 */\par 
 typedef enum \{ IOQueuesEmpty, WorkAvailable \}; \par 
\pard \li0\ri0\fi0\sl280 \tx360 \tx1080 \tx1800 \tx2520 
\tx3240 \tx3960 \tx4680 \tx5400 \tx6120 \tx6840 \tx7560 
\tx8260 \par 
\f21\fs36\b \par 
Command Buffer:\par 
\f-24049\fs24\b0 \par 
\pard \li380\ri0\fi0\sl280 \tx360 \tx1080 \tx1800 \tx2520 
\tx3240 \tx3960 \tx4680 \tx5400 \tx6120 \tx6840 \tx7560 
\tx8260 typedef struct \{\par 
\tab /* \par 
 \tab  * device-specific stuff here which defines one 
I/O.\par 
\tab  * For example, block number, transfer count,\par 
\tab  * return status, etc.\par 
\tab  */\par 
\par 
\tab /* \par 
\tab  * cmdLock is what an exported method blocks on\par 
 \tab  * when waiting for the I/O thread to process 
this\par 
\tab  * command.\par 
\tab  */\par 
\tab NXConditionLock\tab cmdLock;\par 
\par 
\tab /*\par 
\tab  * This determines whether the operation is \par 
   \tab  * synchronous or async.\par 
\tab  */\par 
\tab void \tab \tab \tab *pending;\par 
\} commandBuf;\par 
\page \pard \li0\ri0\fi0\sl280 \tx360 \tx1080 \tx1800 \tx2520 
\tx3240 \tx3960 \tx4680 \tx5400 \tx6120 \tx6840 \tx7560 
\tx8260 \par 
\f21\fs36\b Exported method:\par 
\par 
\pard \li380\ri0\fi0\sl280 \tx360 \tx1080 \tx1800 \tx2520 
\tx3240 \tx3960 \tx4680 \tx5400 \tx6120 \tx6840 \tx7560 
\tx8260 \f-24049\fs24\b0 \{\par 
\tab Cons up a commandBuffer for this I/O;\par 
\par 
\tab /*\par 
\tab  * Enqueue on appropriate I/O queue and wake up 
I/O\par 
\tab  * thread.\par 
\tab  */\par 
\tab if this I/O requires disk \{\par 
\tab \tab enqueue on ioQueueDisk;\par 
\tab \}\par 
\tab else \{\par 
\tab \tab enqueue on ioQueueNodisk;\par 
\tab \}\par 
\tab [ioQLock lock];\par 
\tab [ioQLock unlockWith:WorkAvailable];\par 
\par 
\tab /*\par 
\tab  * Wait for I/O complete.\par 
\tab  */\par 
\tab [commandBuffer.cmdLock lockWhen:YES];\par 
\pard \li0\ri0\fi0\sl280 \tx360 \tx1080 \tx1800 \tx2520 
\tx3240 \tx3960 \tx4680 \tx5400 \tx6120 \tx6840 \tx7560 
\tx8260 \}\par 
\par 
\f21\fs36\b \par 
\page \par 
I/O thread:\par 
\par 
\par 
\pard \li380\ri0\fi0\sl280 \tx360 \tx1080 \tx1800 \tx2520 
\tx3240 \tx3960 \tx4680 \tx5400 \tx6120 \tx6840 \tx7560 
\tx8260 \f-24049\fs24\b0 \{\par 
\tab initialize;\par 
\tab while(1) \{\par 
\tab \tab [ioQLock lockWhen: WorkAvailable];\par 
\tab \tab [ioQLock unlock];\par 
\tab \tab process everything on ioQueueNodisk;\par 
\tab \tab if((lastReadyState != IO_RS_NODISK) &&\par 
      \tab   (lastReadyState != IO_RS_EJECTING)) 
\{\par 
\tab \tab \tab process everything in ioQueueDisk;\par 
\tab \tab else \{\par 
\tab \tab \tab if ioQueueDisk non-empty \{\par 
\tab \tab \tab   [self requestInsertionPanelForDiskType];\par 
\tab \tab \tab \}\par 
\tab \tab \}\par 
\tab \tab [ioQLock unlockWith:<current queue state>];\par 
\tab \}\par 
 \}\par 
\par 
\page \par 
\pard \li0\ri0\fi0\sl280 \tx360 \tx1080 \tx1800 \tx2520 
\tx3240 \tx3960 \tx4680 \tx5400 \tx6120 \tx6840 \tx7560 
\tx8260 \f21\fs36\b To process one commandBuf:\par 
\par 
\pard \li380\ri0\fi0\sl280 \tx360 \tx1080 \tx1800 \tx2520 
\tx3240 \tx3960 \tx4680 \tx5400 \tx6120 \tx6840 \tx7560 
\tx8260 \f-24049\fs24\b0 \{\par 
\tab perform device-specific I/O described in\par 
\tab \tab commandBuf;\par 
\tab if(commandBuf.pending) \{\par 
\tab \tab /*\par 
\tab \tab  * Async operation. \par 
\tab \tab  */\par 
\tab \tab [self completeTransfer:commandBuf.pending\par 
\tab \tab \tab \tab \tab withStatus:...\par 
\tab \tab \tab \tab \tab actualLength:...];\par 
\tab \}\par 
\tab else \{\par 
\tab \tab /*\par 
\tab \tab  * Wake up client.\par 
\tab \tab  */\par 
\tab \tab [commandBuf.cmdLock lock];\par 
\tab \tab [commandBuf.cmdLock unlockWith:YES];\par 
\tab \} \par 
\}\par 
}

unix.superglobalmegacorp.com

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