Annotation of drvEIDE/EIDE.drvproj/EIDE.lksproj/AtapiCntInternal.m, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
        !             3:  *
        !             4:  * @APPLE_LICENSE_HEADER_START@
        !             5:  * 
        !             6:  * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
        !             7:  * Reserved.  This file contains Original Code and/or Modifications of
        !             8:  * Original Code as defined in and that are subject to the Apple Public
        !             9:  * Source License Version 1.0 (the 'License').  You may not use this file
        !            10:  * except in compliance with the License.  Please obtain a copy of the
        !            11:  * License at http://www.apple.com/publicsource and read it before using
        !            12:  * this file.
        !            13:  * 
        !            14:  * The Original Code and all software distributed under the License are
        !            15:  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
        !            16:  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
        !            17:  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
        !            18:  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
        !            19:  * License for the specific language governing rights and limitations
        !            20:  * under the License."
        !            21:  * 
        !            22:  * @APPLE_LICENSE_HEADER_END@
        !            23:  */
        !            24: /*
        !            25:  * Copyright 1997-1998 by Apple Computer, Inc., All rights reserved.
        !            26:  * Copyright 1994-1997 NeXT Software, Inc., All rights reserved.
        !            27:  *
        !            28:  * AtapiCntInternal.m - Implementation of ATAPI controller class.
        !            29:  *
        !            30:  *
        !            31:  * HISTORY
        !            32:  *
        !            33:  * 05-Mar-1996  Rakesh Dubey at NeXT
        !            34:  *     Modified so that no memory is allocated at run-time.
        !            35:  *
        !            36:  * 21-Mar-1995         Rakesh Dubey at NeXT 
        !            37:  *     Created. 
        !            38:  */
        !            39: 
        !            40: #import "IdeCnt.h"
        !            41: #import "AtapiCntInternal.h"
        !            42: #import <kern/assert.h>
        !            43: #import <driverkit/kernelDriver.h>
        !            44: #import <driverkit/interruptMsg.h>
        !            45: #import <mach/mach_interface.h>
        !            46: #import <driverkit/IODevice.h>
        !            47: #import <machkit/NXLock.h>
        !            48: #import <kernserv/prototypes.h>
        !            49: 
        !            50: /*
        !            51:  * Top-level I/O thread.
        !            52:  */
        !            53: static volatile void atapiThread(AtapiController *atapiCnt);
        !            54: 
        !            55: @implementation AtapiController(Internal)
        !            56: 
        !            57: - initResources:direct
        !            58: {
        !            59: #ifdef NO_ATAPI_RUNTIME_MEMORY_ALLOCATION
        !            60:     int i;
        !            61:     atapiBuf_t *atapiBuf;
        !            62: #endif NO_ATAPI_RUNTIME_MEMORY_ALLOCATION
        !            63:        
        !            64:     _ataController = direct;
        !            65:     
        !            66:     queue_init(&_ioQueueNodisk);
        !            67:     
        !            68: #ifdef NO_ATAPI_RUNTIME_MEMORY_ALLOCATION
        !            69: 
        !            70:     /* Set up a queue of ideBufs */
        !            71:     queue_init(&_atapiBufQueue);
        !            72:     _atapiBufLock = [NXLock new];
        !            73:     [_atapiBufLock lock];
        !            74:     
        !            75:     for (i = 0; i < MAX_NUM_ATAPIBUF; i++)     {
        !            76:        atapiBuf = &_atapiBufPool[i];
        !            77:        atapiBuf->waitLock = [NXConditionLock alloc];
        !            78:        [atapiBuf->waitLock initWith:NO];
        !            79:        queue_enter(&_atapiBufQueue, atapiBuf, atapiBuf_t *, bufLink);
        !            80:     }
        !            81:     [_atapiBufLock unlock];
        !            82:     
        !            83:     if (_ide_debug)    {
        !            84:        IOLog("NO_ATAPI_RUNTIME_MEMORY_ALLOCATION\n");
        !            85:     }
        !            86: 
        !            87: #endif NO_ATAPI_RUNTIME_MEMORY_ALLOCATION
        !            88: 
        !            89:     _ioQLock = [NXConditionLock alloc];
        !            90:     [_ioQLock initWith:NO_WORK_AVAILABLE];
        !            91:     
        !            92:     IOForkThread((IOThreadFunc)atapiThread, self);
        !            93:     
        !            94:     return self;
        !            95: }
        !            96: 
        !            97: /*
        !            98:  * Free up local resources. 
        !            99:  */
        !           100: - free
        !           101: {
        !           102:     /*
        !           103:      * First kill the I/O thread, then free alloc'd instance variables. 
        !           104:      */
        !           105:     atapiBuf_t *atapiBuf;
        !           106:     int i;
        !           107: 
        !           108:     atapiBuf = [self allocAtapiBuf];
        !           109:     [self enqueueAtapiBuf:atapiBuf];
        !           110:     
        !           111:     [self freeAtapiBuf:atapiBuf];
        !           112:     [_ioQLock free];
        !           113: 
        !           114: #ifdef NO_ATAPI_RUNTIME_MEMORY_ALLOCATION
        !           115:     if (_atapiBufLock)
        !           116:        [_atapiBufLock free];
        !           117:     
        !           118:     for (i = 0; i < MAX_NUM_ATAPIBUF; i++) {
        !           119:        if (_atapiBufPool[i].waitLock)
        !           120:            [_atapiBufPool[i].waitLock free];
        !           121:     }
        !           122: #endif NO_ATAPI_RUNTIME_MEMORY_ALLOCATION
        !           123: 
        !           124:     return ([super free]);
        !           125: }
        !           126: 
        !           127: /*
        !           128:  * Allocate and free AtapiBuf_t's.
        !           129:  */
        !           130: 
        !           131: #ifdef NO_ATAPI_RUNTIME_MEMORY_ALLOCATION
        !           132: - (atapiBuf_t *) allocAtapiBuf
        !           133: {
        !           134:     atapiBuf_t *atapiBuf;
        !           135:     id waitLock;
        !           136: 
        !           137:     while (1)  {
        !           138:        [_atapiBufLock lock];
        !           139:        if (!queue_empty(&_atapiBufQueue))
        !           140:            break;
        !           141:        [_atapiBufLock unlock];
        !           142:        IOSleep(20);            // the system is overloaded
        !           143:     }
        !           144:     
        !           145:     ASSERT(queue_empty(&_atapiBufQueue) != 0);
        !           146:     atapiBuf = (atapiBuf_t *) queue_first(&_atapiBufQueue);
        !           147:     ASSERT(atapiBuf != 0);
        !           148:     queue_remove(&_atapiBufQueue, atapiBuf, atapiBuf_t *, bufLink);
        !           149: 
        !           150:     waitLock = atapiBuf->waitLock;
        !           151:     bzero(atapiBuf, sizeof(atapiBuf_t));
        !           152:     atapiBuf->waitLock = waitLock;
        !           153:     [atapiBuf->waitLock initWith:NO];
        !           154:     
        !           155:     [_atapiBufLock unlock];
        !           156:     return (atapiBuf);
        !           157: }
        !           158: 
        !           159: - (void)freeAtapiBuf:(atapiBuf_t *) atapiBuf
        !           160: {
        !           161:     [_atapiBufLock lock];
        !           162:     queue_enter(&_atapiBufQueue, atapiBuf, atapiBuf_t *, bufLink);
        !           163:     ASSERT(queue_empty(&_atapiBufQueue) != 0);
        !           164:     [_atapiBufLock unlock];
        !           165: }
        !           166: 
        !           167: #else NO_ATAPI_RUNTIME_MEMORY_ALLOCATION
        !           168: 
        !           169: - (atapiBuf_t *) allocAtapiBuf
        !           170: {
        !           171:     atapiBuf_t *atapiBuf = IOMalloc(sizeof(atapiBuf_t));
        !           172: 
        !           173:     bzero(atapiBuf, sizeof(atapiBuf_t));
        !           174:     atapiBuf->waitLock = [NXConditionLock alloc];
        !           175:     [atapiBuf->waitLock initWith:NO];
        !           176:     
        !           177:     return (atapiBuf);
        !           178: }
        !           179: 
        !           180: - (void)freeAtapiBuf:(atapiBuf_t *) atapiBuf
        !           181: {
        !           182:     if (atapiBuf->waitLock) {
        !           183:        [atapiBuf->waitLock free];
        !           184:     }
        !           185:     IOFree(atapiBuf, sizeof(atapiBuf_t));
        !           186: }
        !           187: #endif NO_ATAPI_RUNTIME_MEMORY_ALLOCATION
        !           188: 
        !           189: /*
        !           190:  * -- Enqueue an AtapiBuf_t on ioQueue<Disk,Nodisk>
        !           191:  * -- wake up the I/O thread
        !           192:  * -- wait for I/O complete (if atapiBuf->pending == NULL)
        !           193:  *
        !           194:  * All I/O goes thru here; this is the last method called by exported methods
        !           195:  * before the I/O thread takes over. 
        !           196:  */
        !           197: - (IOReturn) enqueueAtapiBuf:(atapiBuf_t *) atapiBuf
        !           198: {
        !           199:     queue_head_t *q;
        !           200: 
        !           201:     [_ioQLock lock];
        !           202:     q = &_ioQueueNodisk;
        !           203:     queue_enter(q, atapiBuf, atapiBuf_t *, link);
        !           204:     [_ioQLock unlockWith:WORK_AVAILABLE];
        !           205: 
        !           206:     /*
        !           207:      * Wait for I/O complete. 
        !           208:      */
        !           209:     [atapiBuf->waitLock lockWhen:YES];
        !           210:     [atapiBuf->waitLock unlock];
        !           211: 
        !           212:     /* FIXME: What should this value be?? */
        !           213:     return (atapiBuf->status);
        !           214: }
        !           215: 
        !           216: 
        !           217: /*
        !           218:  * Either wake up the thread which is waiting on the ideCmdBuf, or send an 
        !           219:  * ioComplete back to client. ideCmdBuf->status must be valid.
        !           220:  */
        !           221: - (void)atapiIoComplete:(atapiBuf_t *) atapiBuf
        !           222: {
        !           223:     /*
        !           224:      * Sync I/O. Just wake up the waiting thread. 
        !           225:      */
        !           226:     [atapiBuf->waitLock lock];
        !           227:     [atapiBuf->waitLock unlockWith:YES];
        !           228: }
        !           229: 
        !           230: /*
        !           231:  * Main command dispatch method. 
        !           232:  */
        !           233: - (void)atapiCmdDispatch:(atapiBuf_t *)atapiBuf
        !           234: {
        !           235:     switch (atapiBuf->command) {
        !           236:     
        !           237:                case ATAPI_CNT_IOREQ:
        !           238:                        atapiBuf->status = [_ataController
        !           239:                                atapiExecuteCmd:atapiBuf->atapiIoReq 
        !           240:                                buffer:atapiBuf->buffer client:atapiBuf->client];
        !           241:                        break;
        !           242: 
        !           243:                case ATAPI_CNT_THREAD_ABORT:
        !           244: 
        !           245:                        /*
        !           246:                         * First give I/O complete before we die. 
        !           247:                         */
        !           248:                        atapiBuf->status = STAT_GOOD;
        !           249:                        [self atapiIoComplete:atapiBuf];
        !           250:                        IOExitThread();
        !           251: 
        !           252:                default:
        !           253:                        IOLog("%s: Bogus atapiBuf->command 0x%0x in atapiCmdDispatch\n", 
        !           254:                                [self name], atapiBuf->command);
        !           255:                        IOPanic("atapiThread");
        !           256:        }
        !           257: 
        !           258:     [self atapiIoComplete:atapiBuf];
        !           259:     return;
        !           260: }
        !           261: 
        !           262: /*
        !           263:  * Unlock ioQLock, updating condition variable as appropriate.
        !           264:  */
        !           265: - (void)unlockIoQLock
        !           266: {
        !           267:     int     queue_state;
        !           268: 
        !           269:     if (!queue_empty(&_ioQueueNodisk))
        !           270:        queue_state = WORK_AVAILABLE;
        !           271:     else
        !           272:        queue_state = NO_WORK_AVAILABLE;
        !           273:     [_ioQLock unlockWith:queue_state];
        !           274: }
        !           275: 
        !           276: 
        !           277: @end
        !           278: 
        !           279: /*
        !           280:  * I/O thread. Each one of these sits around waiting for work to do on 
        !           281:  * ioQueue; when something appears, the thread grabs it and disptahes it.
        !           282:  */
        !           283: 
        !           284: static volatile void
        !           285: atapiThread(AtapiController *atapiCnt)
        !           286: {
        !           287:     atapiBuf_t *atapiBuf;
        !           288:     queue_head_t *q;
        !           289: 
        !           290:     while (1) {
        !           291: 
        !           292:        /*
        !           293:         * Wait for some work to do. 
        !           294:         */
        !           295:        [atapiCnt->_ioQLock lockWhen:WORK_AVAILABLE];
        !           296: 
        !           297:        /*
        !           298:         * Service all requests which do not require a disk. 
        !           299:         */
        !           300:        q = &atapiCnt->_ioQueueNodisk;
        !           301:        while (!queue_empty(q)) {
        !           302:            atapiBuf = (atapiBuf_t *) queue_first(q);
        !           303:            queue_remove(q, atapiBuf, atapiBuf_t *, link);
        !           304:            [atapiCnt->_ioQLock unlock];
        !           305:            [atapiCnt atapiCmdDispatch:atapiBuf];
        !           306:            [atapiCnt->_ioQLock lock];
        !           307:        }
        !           308: 
        !           309:        [atapiCnt unlockIoQLock];
        !           310:     }
        !           311: 
        !           312:     /* NOT REACHED */
        !           313: }

unix.superglobalmegacorp.com

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