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

unix.superglobalmegacorp.com

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