Annotation of linux/kernel/blk_drv/scsi/seagate.c, revision 1.1

1.1     ! root        1: /*
        !             2:  *     seagate.c Copyright (C) 1992 Drew Eckhardt 
        !             3:  *     low level scsi driver for ST01/ST02 by
        !             4:  *             Drew Eckhardt 
        !             5:  *
        !             6:  *     <[email protected]>
        !             7:  */
        !             8: 
        !             9: #include <linux/config.h>
        !            10: 
        !            11: #ifdef CONFIG_SCSI_SEAGATE
        !            12: #include <linux/sched.h>
        !            13: 
        !            14: #include "seagate.h"
        !            15: #include "scsi.h"
        !            16: #include "hosts.h"
        !            17: 
        !            18: static int incommand;                  /*
        !            19:                                                set if arbitration has finished and we are 
        !            20:                                                in some command phase.
        !            21:                                        */
        !            22: 
        !            23: static void *base_address = NULL;      /*
        !            24:                                                Where the card ROM starts,
        !            25:                                                used to calculate memory mapped
        !            26:                                                register location.
        !            27:                                        */
        !            28: static volatile int abort_confirm = 0;
        !            29: 
        !            30: volatile void *st0x_cr_sr;       /*
        !            31:                                                control register write,
        !            32:                                                status register read.
        !            33:                                                256 bytes in length.
        !            34: 
        !            35:                                                Read is status of SCSI BUS,
        !            36:                                                as per STAT masks.
        !            37: 
        !            38:                                        */
        !            39: 
        !            40: 
        !            41: static volatile void *st0x_dr;         /*
        !            42:                                                data register, read write
        !            43:                                                256 bytes in length.
        !            44:                                        */
        !            45: 
        !            46: 
        !            47: static volatile int st0x_aborted=0;    /* 
        !            48:                                                set when we are aborted, ie by a time out, etc.
        !            49:                                        */
        !            50: 
        !            51:                                        /*
        !            52:                                                In theory, we have a nice auto
        !            53:                                                detect routine - but this 
        !            54:                                                overides it. 
        !            55:                                        */
        !            56: 
        !            57:                        
        !            58: #define retcode(result) (((result) << 16) | (message << 8) | status)                   
        !            59: #define STATUS (*(unsigned char *) st0x_cr_sr)
        !            60: #define CONTROL STATUS 
        !            61: #define DATA (*(unsigned char *) st0x_dr)
        !            62: 
        !            63: #ifndef OVERRIDE               
        !            64: static const char *  seagate_bases[] = {(char *) 0xc8000, (char *) 0xca000, (char *) 0xcc000, (char *) 0xce000, (char *) 0xce000,
        !            65:                                        (char *) 0xdc000, (char *) 0xde000};
        !            66: typedef struct 
        !            67:        {
        !            68:        char *signature ;
        !            69:        unsigned offset;
        !            70:        unsigned length;
        !            71:        } Signature;
        !            72:        
        !            73: static const Signature signatures[] = {
        !            74: {"SCSI BIOS 2.00  (C) Copyright 1987 Seagate", 15, 40},
        !            75: {"SEAGATE SCSI BIOS ",16, 17},
        !            76: {"SEAGATE SCSI BIOS ",17, 17}};
        !            77: /*
        !            78:        Note that the last signature handles BIOS revisions 3.0.0 and 
        !            79:        3.2 - the real ID's are 
        !            80: 
        !            81: SEAGATE SCSI BIOS REVISION 3.0.0
        !            82: SEAGATE SCSI BIOS REVISION 3.2
        !            83: 
        !            84: */
        !            85: 
        !            86: #define NUM_SIGNATURES (sizeof(signatures) / sizeof(Signature))
        !            87: #endif
        !            88: 
        !            89: int seagate_st0x_detect (int hostnum)
        !            90:        {
        !            91:        #ifndef OVERRIDE
        !            92:                int i,j;
        !            93:        #endif
        !            94: 
        !            95:        /*
        !            96:                First, we try for the manual override.
        !            97:        */
        !            98:        #ifdef DEBUG 
        !            99:                printk("Autodetecting seagate ST0x\n");
        !           100:        #endif
        !           101:        
        !           102:        base_address = NULL;
        !           103:        #ifdef OVERRIDE
        !           104:                base_address = (void *) OVERRIDE;       
        !           105:                #ifdef DEBUG
        !           106:                        printk("Base address overridden to %x\n", base_address);
        !           107:                #endif
        !           108:        #else   
        !           109:        /*
        !           110:                To detect this card, we simply look for the SEAGATE SCSI
        !           111:                from the BIOS version notice in all the possible locations
        !           112:                of the ROM's.
        !           113:        */
        !           114: 
        !           115:        for (i = 0; i < (sizeof (seagate_bases) / sizeof (char  * )); ++i)
        !           116:                for (j = 0; !base_address && j < NUM_SIGNATURES; ++j)
        !           117:                if (!memcmp ((void *) (seagate_bases[i] +
        !           118:                    signatures[j].offset), (void *) signatures[j].signature,
        !           119:                    signatures[j].length))
        !           120:                        base_address = (void *) seagate_bases[i];
        !           121:                #endif
        !           122:  
        !           123:        if (base_address)
        !           124:                {
        !           125:                st0x_cr_sr =(void *) (((unsigned char *) base_address) + 0x1a00); 
        !           126:                st0x_dr = (void *) (((unsigned char *) base_address )+ 0x1c00);
        !           127:                #ifdef DEBUG
        !           128:                        printk("ST0x detected. Base address = %x, cr = %x, dr = %x\n", base_address, st0x_cr_sr, st0x_dr);
        !           129:                #endif
        !           130:                return -1;
        !           131:                }
        !           132:        else
        !           133:                {
        !           134:                #ifdef DEBUG
        !           135:                        printk("ST0x not detected.\n");
        !           136:                #endif
        !           137:                return 0;
        !           138:                }
        !           139:        }
        !           140:         
        !           141:        
        !           142: 
        !           143: char *seagate_st0x_info(void)
        !           144: {
        !           145:        static char buffer[] = "Seagate ST-0X SCSI driver by Drew Eckhardt \n"
        !           146: "$Header: /usr/src/linux/kernel/blk_drv/scsi/RCS/seagate.c,v 1.1 1992/04/24 18:01:50 root Exp root $\n";
        !           147:        return buffer;
        !           148: }
        !           149: 
        !           150: 
        !           151: 
        !           152: int seagate_st0x_command(unsigned char target, const void *cmnd,
        !           153:                         void *buff, int bufflen)
        !           154:        {
        !           155:        int len;                        
        !           156:        unsigned char *data;    
        !           157: 
        !           158:        int clock;                      /*
        !           159:                                                We use clock for timeouts, etc.   This replaces the 
        !           160:                                                seagate_st0x_timeout that we had been using.
        !           161:                                        */
        !           162:        #if (DEBUG & PHASE_SELECTION)
        !           163:                int temp;
        !           164:        #endif
        !           165: 
        !           166:        #if (DEBUG & PHASE_EXIT)
        !           167:                 void *retaddr, *realretaddr;
        !           168:        #endif
        !           169: 
        !           170:        #if ((DEBUG & PHASE_ETC) || (DEBUG & PRINT_COMMAND) || (DEBUG & PHASE_EXIT))    
        !           171:                int i;
        !           172:        #endif
        !           173: 
        !           174:        #if (DEBUG & PHASE_ETC)
        !           175:                int phase=0, newphase;
        !           176:        #endif
        !           177: 
        !           178:        int done = 0;
        !           179:        unsigned char status = 0;       
        !           180:        unsigned char message = 0;
        !           181:        register unsigned char status_read;
        !           182: 
        !           183:        #if (DEBUG & PHASE_EXIT)
        !           184:                 __asm__("
        !           185: movl 4(%%ebp), %%eax 
        !           186: ":"=a" (realretaddr):);
        !           187:                printk("return address = %08x\n", realretaddr);
        !           188:        #endif
        !           189: 
        !           190: 
        !           191:        len=bufflen;
        !           192:        data=(unsigned char *) buff;
        !           193: 
        !           194:        incommand = 0;
        !           195:        st0x_aborted = 0;
        !           196: 
        !           197:        #if (DEBUG & PRINT_COMMAND)
        !           198:                printk ("seagate_st0x_command, target = %d, command = ", target);
        !           199:                for (i = 0; i < COMMAND_SIZE(((unsigned char *)cmnd)[0]); ++i)
        !           200:                        printk("%02x ",  ((unsigned char *) cmnd)[i]);
        !           201:                printk("\n");
        !           202:        #endif
        !           203:        
        !           204:        if (target > 6)
        !           205:                return DID_BAD_TARGET;
        !           206: 
        !           207:        
        !           208:        #if (DEBUG & PHASE_BUS_FREE)
        !           209:                printk ("SCSI PHASE = BUS FREE \n");
        !           210:        #endif
        !           211: 
        !           212:        /*
        !           213: 
        !           214:                BUS FREE PHASE
        !           215: 
        !           216:                On entry, we make sure that the BUS is in a BUS FREE
        !           217:                phase, by insuring that both BSY and SEL are low for
        !           218:                at least one bus settle delay.  The standard requires a
        !           219:                minimum of 400 ns, which is 16 clock cycles on a
        !           220:                386-40  .
        !           221: 
        !           222:                This doesn't give us much time - so we'll do two several
        !           223:                reads to be sure be sure.
        !           224:        */
        !           225: 
        !           226:        clock = jiffies + ST0X_BUS_FREE_DELAY;  
        !           227: 
        !           228:        while (((STATUS |  STATUS | STATUS) & 
        !           229:                 (STAT_BSY | STAT_SEL)) && 
        !           230:                 (!st0x_aborted) && (jiffies < clock));
        !           231: 
        !           232:        if (jiffies > clock)
        !           233:                return retcode(DID_BUS_BUSY);
        !           234:        else if (st0x_aborted)
        !           235:                return retcode(st0x_aborted);
        !           236: 
        !           237:        /*
        !           238:                Bus free has been detected, within BUS settle.  I used to support an arbitration
        !           239:                phase - however, on the seagate, this degraded performance by a factor > 10 - so
        !           240:                it is no more.
        !           241:        */
        !           242: 
        !           243:        /*
        !           244:                SELECTION PHASE
        !           245: 
        !           246:                Now, we select the disk, giving it the SCSI ID at data
        !           247:                and a command of PARITY if necessary, plus driver enable,
        !           248:                plus raise select signal.
        !           249:        */
        !           250: 
        !           251:        #if (DEBUG & PHASE_SELECTION)
        !           252:                printk("SCSI PHASE = SELECTION\n");
        !           253:        #endif
        !           254: 
        !           255:        clock = jiffies + ST0X_SELECTION_DELAY;
        !           256:        DATA = (unsigned char) (1 << target);
        !           257: 
        !           258:        CONTROL =  BASE_CMD | CMD_DRVR_ENABLE | CMD_SEL;
        !           259: 
        !           260:        /*
        !           261:                When the SCSI device decides that we're gawking at it, it will respond by asserting BUSY on the bus.
        !           262:        */
        !           263:        while (!((status_read = STATUS) & STAT_BSY) && (jiffies < clock) && !st0x_aborted)
        !           264: 
        !           265: #if (DEBUG & PHASE_SELECTION)
        !           266:                {
        !           267:                temp = clock - jiffies;
        !           268: 
        !           269:                if (!(jiffies % 5))
        !           270:                        printk("seagate_st0x_timeout : %d            \r",temp);
        !           271:        
        !           272:                }
        !           273:                printk("Done.                                             \n\r");
        !           274:                printk("Status = %02x, seagate_st0x_timeout = %d, aborted = %02x \n", status_read, temp,
        !           275:                        st0x_aborted);
        !           276: #else
        !           277:                ;
        !           278: #endif
        !           279:        
        !           280: 
        !           281:        if ((jiffies > clock)  || (!st0x_aborted & !(status_read & STAT_BSY)))
        !           282:                {
        !           283:                #if (DEBUG & PHASE_SELECT)
        !           284:                        printk ("NO CONNECT with target %d, status = %x \n", target, STATUS);
        !           285:                #endif
        !           286:                return retcode(DID_NO_CONNECT);
        !           287:                }
        !           288: 
        !           289:        /*
        !           290:                If we have been aborted, and we have a command in progress, IE the target still has
        !           291:                BSY asserted, then we will reset the bus, and notify the midlevel driver to
        !           292:                expect sense.
        !           293:        */
        !           294: 
        !           295:        if (st0x_aborted)
        !           296:                {
        !           297:                CONTROL = BASE_CMD;
        !           298:                if (STATUS & STAT_BSY)
        !           299:                        {
        !           300:                        seagate_st0x_reset();
        !           301:                        return retcode(DID_RESET);
        !           302:                        }
        !           303:                
        !           304:                return retcode(st0x_aborted);
        !           305:                }       
        !           306:        
        !           307:        /*
        !           308:                COMMAND PHASE
        !           309:                The device has responded with a BSY, so we may now enter
        !           310:                the information transfer phase, where we will send / recieve
        !           311:                data and command as directed by the target.
        !           312: 
        !           313: 
        !           314:                The nasty looking read / write inline assembler loops we use for 
        !           315:                DATAIN and DATAOUT phases are approximately 4-5 times as fast as 
        !           316:                the 'C' versions - since we're moving 1024 bytes of data, this
        !           317:                really adds up.
        !           318:        */
        !           319: 
        !           320:        #if (DEBUG & PHASE_ETC)
        !           321:                printk("PHASE = information transfer\n");
        !           322:        #endif  
        !           323: 
        !           324:        incommand = 1;
        !           325: 
        !           326:        /*
        !           327:                Enable command
        !           328:        */
        !           329: 
        !           330:        CONTROL = BASE_CMD | CMD_DRVR_ENABLE;
        !           331: 
        !           332:        /*
        !           333:                Now, we poll the device for status information,
        !           334:                and handle any requests it makes.  Note that since we are unsure of 
        !           335:                how much data will be flowing across the system, etc and cannot 
        !           336:                make reasonable timeouts, that we will instead have the midlevel
        !           337:                driver handle any timeouts that occur in this phase.
        !           338:        */
        !           339: 
        !           340:        while (((status_read = STATUS) & STAT_BSY) && !st0x_aborted && !done) 
        !           341:                        {
        !           342:                        #ifdef PARITY
        !           343:                                if (status_read & STAT_PARITY)
        !           344:                                        {
        !           345:                                        done = 1;
        !           346:                                        st0x_aborted = DID_PARITY;
        !           347:                                        }       
        !           348:                        #endif
        !           349: 
        !           350:                        if (status_read & STAT_REQ)
        !           351:                                {
        !           352:                                #if (DEBUG & PHASE_ETC)
        !           353:                                        if ((newphase = (status_read & REQ_MASK)) != phase)
        !           354:                                                {
        !           355:                                                phase = newphase;
        !           356:                                                switch (phase)
        !           357:                                                        {
        !           358:                                                        case REQ_DATAOUT : printk("SCSI PHASE = DATA OUT\n"); break;
        !           359:                                                        case REQ_DATAIN : printk("SCSI PHASE = DATA IN\n"); break;
        !           360:                                                        case REQ_CMDOUT : printk("SCSI PHASE = COMMAND OUT\n"); break;
        !           361:                                                        case REQ_STATIN : printk("SCSI PHASE = STATUS IN\n"); break;
        !           362:                                                        case REQ_MSGOUT : printk("SCSI PHASE = MESSAGE OUT\n"); break;
        !           363:                                                        case REQ_MSGIN : printk("SCSI PHASE = MESSAGE IN\n"); break;
        !           364:                                                        default : printk("UNKNOWN PHASE"); st0x_aborted = 1; done = 1;
        !           365:                                                        }       
        !           366:                                                }
        !           367:                                #endif
        !           368: 
        !           369:                                switch (status_read & REQ_MASK)
        !           370:                                        {                       
        !           371:                                        case REQ_DATAOUT : 
        !           372: 
        !           373:        /*
        !           374:                We loop as long as we are in a data out phase, there is data to send, and BSY is still
        !           375:                active
        !           376:        */
        !           377:                                                        __asm__ ("
        !           378: 
        !           379: /*
        !           380:        Local variables : 
        !           381:        len = ecx
        !           382:        data = esi
        !           383:        st0x_cr_sr = ebx
        !           384:        st0x_dr =  edi
        !           385: 
        !           386:        Test for any data here at all.
        !           387: */
        !           388:        movl %0, %%esi          /* local value of data */
        !           389:        movl %1, %%ecx          /* local value of len */        
        !           390:        orl %%ecx, %%ecx
        !           391:        jz 2f
        !           392: 
        !           393:        cld
        !           394: 
        !           395:        movl _st0x_cr_sr, %%ebx
        !           396:        movl _st0x_dr, %%edi
        !           397:        
        !           398: 1:     movb (%%ebx), %%al
        !           399: /*
        !           400:        Test for BSY
        !           401: */
        !           402: 
        !           403:        test $1, %%al 
        !           404:        jz 2f
        !           405: 
        !           406: /*
        !           407:        Test for data out phase - STATUS & REQ_MASK should be REQ_DATAOUT, which is 0.
        !           408: */
        !           409:        test $0xe, %%al
        !           410:        jnz 2f  
        !           411: /*
        !           412:        Test for REQ
        !           413: */     
        !           414:        test $0x10, %%al
        !           415:        jz 1b
        !           416:        lodsb
        !           417:        movb %%al, (%%edi) 
        !           418:        loop 1b
        !           419: 
        !           420: 2: 
        !           421:        movl %%esi, %2
        !           422:        movl %%ecx, %3
        !           423:                                                                        ":
        !           424: /* output */
        !           425: "=r" (data), "=r" (len) :
        !           426: /* input */
        !           427: "0" (data), "1" (len) :
        !           428: /* clobbered */
        !           429: "ebx", "ecx", "edi", "esi"); 
        !           430: 
        !           431:                                                        break;
        !           432: 
        !           433:                                        case REQ_DATAIN : 
        !           434:        /*
        !           435:                We loop as long as we are in a data out phase, there is room to read, and BSY is still
        !           436:                active
        !           437:        */
        !           438:  
        !           439:                                                        __asm__ ("
        !           440: /*
        !           441:        Local variables : 
        !           442:        ecx = len
        !           443:        edi = data
        !           444:        esi = st0x_cr_sr
        !           445:        ebx = st0x_dr
        !           446: 
        !           447:        Test for room to read
        !           448: */
        !           449: 
        !           450:        movl %0, %%edi          /* data */
        !           451:        movl %1, %%ecx          /* len */
        !           452:        orl %%ecx, %%ecx
        !           453:        jz 2f
        !           454: 
        !           455:        cld
        !           456:        movl _st0x_cr_sr, %%esi
        !           457:        movl _st0x_dr, %%ebx
        !           458: 
        !           459: 1:     movb (%%esi), %%al
        !           460: /*
        !           461:        Test for BSY
        !           462: */
        !           463: 
        !           464:        test $1, %%al 
        !           465:        jz 2f
        !           466: 
        !           467: /*
        !           468:        Test for data in phase - STATUS & REQ_MASK should be REQ_DATAIN, = STAT_IO, which is 4.
        !           469: */
        !           470:        movb $0xe, %%ah 
        !           471:        andb %%al, %%ah
        !           472:        cmpb $0x04, %%ah
        !           473:        jne 2f
        !           474:                
        !           475: /*
        !           476:        Test for REQ
        !           477: */     
        !           478:        test $0x10, %%al
        !           479:        jz 1b
        !           480: 
        !           481:        movb (%%ebx), %%al      
        !           482:        stosb   
        !           483:        loop 1b
        !           484: 
        !           485: 2:     movl %%edi, %2          /* data */
        !           486:        movl %%ecx, %3          /* len */
        !           487:                                                                        ":
        !           488: /* output */
        !           489: "=r" (data), "=r" (len) :
        !           490: /* input */
        !           491: "0" (data), "1" (len) :
        !           492: /* clobbered */
        !           493: "ebx", "ecx", "edi", "esi"); 
        !           494:                                                        break;
        !           495: 
        !           496:                                        case REQ_CMDOUT : 
        !           497:                                                        while (((status_read = STATUS) & STAT_BSY) && ((status_read & REQ_MASK) ==
        !           498:                                                                REQ_CMDOUT))
        !           499:                                                                DATA = *(unsigned char *) cmnd ++;
        !           500:                                                break;
        !           501:        
        !           502:                                        case REQ_STATIN : 
        !           503:                                                status = DATA;
        !           504:                                                break;
        !           505:                                
        !           506:                                        case REQ_MSGOUT : 
        !           507:                                                DATA = MESSAGE_REJECT;
        !           508:                                                break;
        !           509:                                        
        !           510:                                        case REQ_MSGIN : 
        !           511:                                                if ((message = DATA) == COMMAND_COMPLETE)
        !           512:                                                        done=1;
        !           513:                                                
        !           514:                                                break;
        !           515: 
        !           516:                                        default : printk("UNKNOWN PHASE"); st0x_aborted = DID_ERROR; 
        !           517:                                        }       
        !           518:                                }
        !           519: 
        !           520:                }
        !           521: 
        !           522: #if (DEBUG & (PHASE_DATAIN | PHASE_DATAOUT | PHASE_EXIT))
        !           523:        printk("Transfered %d bytes, allowed %d additional bytes\n", (bufflen - len), len);
        !           524: #endif
        !           525: 
        !           526: #if (DEBUG & PHASE_EXIT)
        !           527:                printk("Buffer : \n");
        !           528:                for (i = 0; i < 20; ++i) 
        !           529:                        printk ("%02x  ", ((unsigned char *) buff)[i]);
        !           530:                printk("\n");
        !           531:                printk("Status = %02x, message = %02x\n", status, message);
        !           532: #endif
        !           533: 
        !           534:        
        !           535:                if (st0x_aborted)
        !           536:                        {
        !           537:                        if (STATUS & STAT_BSY)
        !           538:                                {
        !           539:                                seagate_st0x_reset();
        !           540:                                st0x_aborted = DID_RESET;
        !           541:                                }
        !           542:                        abort_confirm = 1;
        !           543:                        }       
        !           544:                        
        !           545:                CONTROL = BASE_CMD;
        !           546: 
        !           547: #if (DEBUG & PHASE_EXIT)
        !           548:        __asm__("
        !           549: mov 4(%%ebp), %%eax
        !           550: ":"=a" (retaddr):);
        !           551: 
        !           552:        printk("Exiting seagate_st0x_command() - return address is %08x \n", retaddr);
        !           553:        if (retaddr != realretaddr)
        !           554:                panic ("Corrupted stack : return address on entry != return address on exit.\n");
        !           555:        
        !           556: #endif
        !           557: 
        !           558:                return retcode (st0x_aborted);
        !           559:        }
        !           560: 
        !           561: int seagate_st0x_abort (int code)
        !           562:        {
        !           563:        if (code)
        !           564:                st0x_aborted = code;
        !           565:        else
        !           566:                st0x_aborted = DID_ABORT;
        !           567: 
        !           568:                return 0;
        !           569:        }
        !           570: 
        !           571: /*
        !           572:        the seagate_st0x_reset function resets the SCSI bus
        !           573: */
        !           574:        
        !           575: int seagate_st0x_reset (void)
        !           576:        {
        !           577:        unsigned clock;
        !           578:        /*
        !           579:                No timeouts - this command is going to fail because 
        !           580:                it was reset.
        !           581:        */
        !           582: 
        !           583: #ifdef DEBUG
        !           584:        printk("In seagate_st0x_reset()\n");
        !           585: #endif
        !           586: 
        !           587: 
        !           588:        /* assert  RESET signal on SCSI bus.  */
        !           589:                
        !           590:        CONTROL = BASE_CMD  | CMD_RST;
        !           591:        clock=jiffies+2;
        !           592: 
        !           593:        
        !           594:        /* Wait.  */
        !           595:        
        !           596:        while (jiffies < clock);
        !           597: 
        !           598:        CONTROL = BASE_CMD;
        !           599:        
        !           600:        st0x_aborted = DID_RESET;
        !           601: 
        !           602: #ifdef DEBUG
        !           603:        printk("SCSI bus reset.\n");
        !           604: #endif
        !           605:        return 0;
        !           606:        }
        !           607: #endif 

unix.superglobalmegacorp.com

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