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

1.1     ! root        1: /*
        !             2:  *     scsi.c Copyright (C) 1992 Drew Eckhardt 
        !             3:  *     generic mid-level SCSI driver by
        !             4:  *             Drew Eckhardt 
        !             5:  *
        !             6:  *     <[email protected]>
        !             7:  */
        !             8: #include <linux/config.h>
        !             9: 
        !            10: #ifdef CONFIG_SCSI
        !            11: #include <asm/system.h>
        !            12: #include <linux/sched.h>
        !            13: #include <linux/timer.h>
        !            14: #include <linux/string.h>
        !            15: 
        !            16: #include "scsi.h"
        !            17: #include "hosts.h"
        !            18: 
        !            19: #ifdef CONFIG_BLK_DEV_SD
        !            20: #include "sd.h"
        !            21: #endif
        !            22: 
        !            23: #ifdef CONFIG_BLK_DEV_ST
        !            24: #include "st.h"
        !            25: #endif
        !            26: 
        !            27: /*
        !            28: static const char RCSid[] = "$Header: /usr/src/linux/kernel/blk_drv/scsi/RCS/scsi.c,v 1.1 1992/04/24 18:01:50 root Exp root $";
        !            29: */
        !            30: 
        !            31: #define INTERNAL_ERROR (printk ("Internal error in file %s, line %s.\n", __FILE__, __LINE__), panic(""))
        !            32: 
        !            33: static void scsi_done (int host, int result);
        !            34: static void update_timeout (void);
        !            35: 
        !            36: static int time_start;
        !            37: static int time_elapsed;
        !            38: 
        !            39: /*
        !            40:        global variables : 
        !            41:        NR_SCSI_DEVICES is the number of SCSI devices we have detected, 
        !            42:        scsi_devices an array of these specifing the address for each 
        !            43:        (host, id, LUN)
        !            44: */
        !            45:        
        !            46: int NR_SCSI_DEVICES=0;
        !            47: Scsi_Device scsi_devices[MAX_SCSI_DEVICE];
        !            48: 
        !            49: #define SENSE_LENGTH 255
        !            50: /*
        !            51:        As the scsi do command functions are inteligent, and may need to 
        !            52:        redo a command, we need to keep track of the last command 
        !            53:        executed on each one.
        !            54: */
        !            55: 
        !            56: #define WAS_RESET      0x01
        !            57: #define WAS_TIMEDOUT   0x02
        !            58: #define WAS_SENSE      0x04
        !            59: #define IS_RESETTING   0x08
        !            60: 
        !            61: static Scsi_Cmnd last_cmnd[MAX_SCSI_HOSTS];
        !            62: static int last_reset[MAX_SCSI_HOSTS];
        !            63: 
        !            64: /*
        !            65:        This is the number  of clock ticks we should wait before we time out 
        !            66:        and abort the command.  This is for  where the scsi.c module generates 
        !            67:        the command, not where it originates from a higher level, in which
        !            68:        case the timeout is specified there.
        !            69:        
        !            70: 
        !            71:        ABORT_TIMEOUT and RESET_TIMEOUT are the timeouts for RESET and ABORT
        !            72:        respectively.
        !            73: */
        !            74: #ifdef DEBUG
        !            75:        #define SCSI_TIMEOUT 500
        !            76: #else
        !            77:        #define SCSI_TIMEOUT 100
        !            78: #endif
        !            79: #ifdef DEBUG
        !            80:        #define SENSE_TIMEOUT SCSI_TIMEOUT
        !            81:        #define ABORT_TIMEOUT SCSI_TIMEOUT
        !            82:        #define RESET_TIMEOUT SCSI_TIMEOUT
        !            83: #else
        !            84: 
        !            85:        #define SENSE_TIMEOUT 50
        !            86:        #define RESET_TIMEOUT 50
        !            87:        #define ABORT_TIMEOUT 50
        !            88:        #define MIN_RESET_DELAY 25
        !            89: 
        !            90: #endif
        !            91: /*
        !            92:        As the actual SCSI command runs in the background, we must set up a 
        !            93:        flag that tells scan_scsis() when the result it has is valid.  
        !            94:        scan_scsis can set the_result to -1, and watch for it to become the 
        !            95:        actual return code for that call.  the scan_scsis_done function() is 
        !            96:        our user specified completion function that is passed on to the  
        !            97:        scsi_do_cmd() function.
        !            98: */
        !            99: 
        !           100: static int the_result;
        !           101: static unsigned char sense_buffer[SENSE_LENGTH];
        !           102: static void scan_scsis_done (int host, int result)
        !           103:        {
        !           104:        
        !           105: #ifdef DEBUG
        !           106:        printk ("scan_scsis_done(%d, %06x\n\r", host, result);
        !           107: #endif 
        !           108:        the_result = result;
        !           109:        }
        !           110: /*
        !           111:        Detecting SCSI devices :        
        !           112:        We scan all present host adapter's busses,  from ID 0 to ID 6.  
        !           113:        We use the INQUIRY command, determine device type, and pass the ID / 
        !           114:        lun address of all sequential devices to the tape driver, all random 
        !           115:        devices to the disk driver.
        !           116: */
        !           117: 
        !           118: static void scan_scsis (void)
        !           119:        {
        !           120:         int host_nr , dev, lun, type, maxed;
        !           121:        static unsigned char scsi_cmd [12];
        !           122:        static unsigned char scsi_result [256];
        !           123: 
        !           124:         for (host_nr = 0; host_nr < MAX_SCSI_HOSTS; ++host_nr)
        !           125:                 if (scsi_hosts[host_nr].present)
        !           126:                        {
        !           127:                        for (dev = 0; dev < 7; ++dev)
        !           128:                                if (scsi_hosts[host_nr].this_id != dev)
        !           129:                                 #ifdef MULTI_LUN
        !           130:                                for (lun = 0; lun < 8; ++lun)
        !           131:                                        {
        !           132:                                #else
        !           133:                                        {
        !           134:                                        lun = 0;
        !           135:                                #endif
        !           136:                                        /* Build an INQUIRY command block.  */
        !           137: 
        !           138:                                        scsi_cmd[0] = INQUIRY;
        !           139:                                        scsi_cmd[1] = (lun << 5) & 0xe0;
        !           140:                                        scsi_cmd[2] = 0;
        !           141:                                        scsi_cmd[3] = 0;
        !           142:                                        scsi_cmd[4] = 255;
        !           143:                                        scsi_cmd[5] = 0;
        !           144:                                        the_result = -1;        
        !           145: #ifdef DEBUG
        !           146:        memset ((void *) scsi_result , 0, 255);
        !           147: #endif 
        !           148:                                        scsi_do_cmd (host_nr, dev, (void *)  scsi_cmd, (void *)                                                             
        !           149:                                                 scsi_result, 256,  scan_scsis_done, 
        !           150:                                                 SCSI_TIMEOUT, sense_buffer, 3);
        !           151:                                        
        !           152:                                        /* Wait for valid result */
        !           153: 
        !           154:                                        while (the_result < 0);
        !           155:        
        !           156: 
        !           157:                                         if (!the_result)
        !           158:                                                {
        !           159:                                                 scsi_devices[NR_SCSI_DEVICES].
        !           160:                                                        host_no = host_nr;
        !           161:                                                 scsi_devices[NR_SCSI_DEVICES].
        !           162:                                                        id = dev;
        !           163:                                                 scsi_devices[NR_SCSI_DEVICES].
        !           164:                                                        lun = lun;
        !           165:                                                 scsi_devices[NR_SCSI_DEVICES].
        !           166:                                                        removable = (0x80 & 
        !           167:                                                        scsi_result[1]) >> 7;
        !           168: 
        !           169: 
        !           170: 
        !           171: /* 
        !           172:        Currently, all sequential devices are assumed to be tapes,
        !           173:        all random devices disk, with the appropriate read only 
        !           174:        flags set for ROM / WORM treated as RO.
        !           175: */ 
        !           176: 
        !           177:                                                 switch (type = scsi_result[0])
        !           178:                                                        {
        !           179:                                                         case TYPE_TAPE:
        !           180:                                                         case TYPE_DISK:
        !           181:                                                                scsi_devices[NR_SCSI_DEVICES].writeable = 1;
        !           182:                                                                 break;
        !           183:                                                         case TYPE_WORM:
        !           184:                                                         case TYPE_ROM:
        !           185:                                                                scsi_devices[NR_SCSI_DEVICES].writeable = 0;
        !           186:                                                                 break;
        !           187:                                                         default:
        !           188:                                                                 type = -1;
        !           189:                                                         }
        !           190: 
        !           191:                                                 scsi_devices[NR_SCSI_DEVICES].random = (type == TYPE_TAPE) ? 0 : 1;
        !           192: 
        !           193:                                                 maxed = 0;
        !           194:                                                 switch (type)
        !           195:                                                        {
        !           196:                                                         case -1:
        !           197:                                                                break;
        !           198:                                                         case TYPE_TAPE:
        !           199:                                                                printk("Detected scsi tape at host %d, ID  %d, lun %d \n", host_nr, dev, lun);
        !           200: #ifdef CONFIG_BLK_DEV_ST
        !           201:                                                                 if (!(maxed = (NR_ST == MAX_ST)))
        !           202:                                                                                 scsi_tapes[NR_ST].device = &scsi_devices[NR_SCSI_DEVICES];
        !           203: #endif
        !           204:                                                         default:
        !           205:                                                                printk("Detected scsi disk at host %d, ID  %d, lun %d \n", host_nr, dev, lun);
        !           206: #ifdef CONFIG_BLK_DEV_SD
        !           207:                                                                        if (!(maxed = (NR_SD >= MAX_SD)))
        !           208:                                                                                rscsi_disks[NR_SD].device = &scsi_devices[NR_SCSI_DEVICES];
        !           209: #endif
        !           210:                                                                 }
        !           211: 
        !           212:                                                         if (maxed)
        !           213:                                                                 {
        !           214:                                                                 printk ("Already have detected maximum number of SCSI %ss Unable to \n"
        !           215:                                                                         "add drive at SCSI host %s, ID %d, LUN %d\n\r", (type == TYPE_TAPE) ?
        !           216:                                                                         "tape" : "disk", scsi_hosts[host_nr].name,
        !           217:                                                                         dev, lun);
        !           218:                                                                 type = -1;
        !           219:                                                                 break;
        !           220:                                                                 }
        !           221: 
        !           222:                                                         else if (type != -1)
        !           223:                                                                 {
        !           224:                                                                 if (type == TYPE_TAPE)
        !           225: #ifdef CONFIG_BLK_DEV_ST
        !           226:                                                                        ++NR_ST;
        !           227: #else
        !           228: ;
        !           229: #endif
        !           230: 
        !           231:                                                                 else
        !           232: #ifdef CONFIG_BLK_DEV_SD
        !           233:                                                                         ++NR_SD;
        !           234: #else
        !           235: ;
        !           236: #endif
        !           237:                                                                 }
        !           238:                                                        ++NR_SCSI_DEVICES;
        !           239:                                                         }       /* if result == DID_OK ends */
        !           240:                                         }       /* for lun ends */
        !           241:                         }              /* if present */  
        !           242: 
        !           243:        printk("Detected "
        !           244: #ifdef CONFIG_BLK_DEV_SD
        !           245: "%d disk%s "
        !           246: #endif
        !           247: 
        !           248: #ifdef CONFIG_BLK_DEV_ST
        !           249: "%d tape%s "
        !           250: #endif
        !           251: 
        !           252: "total.\n",  
        !           253: 
        !           254: #ifdef CONFIG_BLK_DEV_SD
        !           255: NR_SD, (NR_SD != 1) ? "s" : ""
        !           256: #ifdef CONFIG_BLK_DEV_ST 
        !           257: ,
        !           258: #endif
        !           259: #endif
        !           260: 
        !           261: #ifdef CONFIG_BLK_DEV_ST
        !           262: NR_ST, (NR_ST != 1) ? "s" : ""
        !           263: #endif
        !           264: );
        !           265:         }       /* scan_scsis  ends */
        !           266: 
        !           267: /*
        !           268:        We handle the timeout differently if it happens when a reset, 
        !           269:        abort, etc are in process. 
        !           270: */
        !           271: 
        !           272: static unsigned char internal_timeout[MAX_SCSI_HOSTS];
        !           273: 
        !           274: /* Flag bits for the internal_timeout array */
        !           275: 
        !           276: #define NORMAL_TIMEOUT 0
        !           277: #define IN_ABORT 1
        !           278: #define IN_RESET 2
        !           279: /*
        !           280:        This is our time out function, called when the timer expires for a 
        !           281:        given host adapter.  It will attempt to abort the currently executing 
        !           282:        command, that failing perform a kernel panic.
        !           283: */ 
        !           284: 
        !           285: static void scsi_times_out (int host)
        !           286:        {
        !           287:        
        !           288:        switch (internal_timeout[host] & (IN_ABORT | IN_RESET))
        !           289:                {
        !           290:                case NORMAL_TIMEOUT:
        !           291:                        printk("SCSI host %d timed out - aborting command \r\n",
        !           292:                                host);
        !           293:                        
        !           294:                        if (!scsi_abort (host, DID_TIME_OUT))
        !           295:                                return;                         
        !           296:                case IN_ABORT:
        !           297:                        printk("SCSI host %d abort() timed out - reseting \r\n",
        !           298:                                host);
        !           299:                        if (!scsi_reset (host)) 
        !           300:                                return;
        !           301:                case IN_RESET:
        !           302:                case (IN_ABORT | IN_RESET):
        !           303:                        printk("Unable to reset scsi host %d\r\n",host);
        !           304:                        panic("");
        !           305:                default:
        !           306:                        INTERNAL_ERROR;
        !           307:                }
        !           308:                                        
        !           309:        }
        !           310: 
        !           311: /*
        !           312:        This is inline because we have stack problemes if we recurse to deeply.
        !           313: */
        !           314:                         
        !           315: static void internal_cmnd (int host,  unsigned char target, const void *cmnd , 
        !           316:                  void *buffer, unsigned bufflen, void (*done)(int,int))
        !           317:        {
        !           318:        int temp;
        !           319: 
        !           320: #ifdef DEBUG_DELAY     
        !           321:        int clock;
        !           322: #endif
        !           323: 
        !           324:        if ((host < 0) ||  (host > MAX_SCSI_HOSTS))
        !           325:                panic ("Host number in internal_cmnd() is out of range.\n");
        !           326: 
        !           327: 
        !           328: /*
        !           329:        We will wait MIN_RESET_DELAY clock ticks after the last reset so 
        !           330:        we can avoid the drive not being ready.
        !           331: */ 
        !           332: temp = last_reset[host];
        !           333: while (jiffies < temp);
        !           334: 
        !           335: host_timeout[host] = last_cmnd[host].timeout_per_command;
        !           336: update_timeout();
        !           337: 
        !           338: /*
        !           339:        We will use a queued command if possible, otherwise we will emulate the
        !           340:        queing and calling of completion function ourselves. 
        !           341: */
        !           342: #ifdef DEBUG
        !           343:        printk("internal_cmnd (host = %d, target = %d, command = %08x, buffer =  %08x, \n"
        !           344:                "bufflen = %d, done = %08x)\n", host, target, cmnd, buffer, bufflen, done);
        !           345: #endif
        !           346: 
        !           347:        
        !           348:         if (scsi_hosts[host].can_queue)
        !           349:                {
        !           350: #ifdef DEBUG
        !           351:        printk("queuecommand : routine at %08x\n", 
        !           352:                scsi_hosts[host].queuecommand);
        !           353: #endif
        !           354:                 scsi_hosts[host].queuecommand (target, cmnd, buffer, bufflen, 
        !           355:                                               done);
        !           356:                }
        !           357:        else
        !           358:                {
        !           359: 
        !           360: #ifdef DEBUG
        !           361:        printk("command() :  routine at %08x\n", scsi_hosts[host].command);
        !           362: #endif
        !           363:                temp=scsi_hosts[host].command (target, cmnd, buffer, bufflen);
        !           364: 
        !           365: #ifdef DEBUG_DELAY
        !           366:        clock = jiffies + 400;
        !           367:        while (jiffies < clock);
        !           368:        printk("done(host = %d, result = %04x) : routine at %08x\n", host, temp, done);
        !           369: #endif
        !           370:                done(host, temp);
        !           371:                }       
        !           372: #ifdef DEBUG
        !           373:        printk("leaving internal_cmnd()\n");
        !           374: #endif
        !           375:        }       
        !           376: 
        !           377: static void scsi_request_sense (int host, unsigned char target, 
        !           378:                                        unsigned char lun)
        !           379:        {
        !           380:        cli();
        !           381:        host_timeout[host] = SENSE_TIMEOUT;
        !           382:        update_timeout();
        !           383:        last_cmnd[host].flags |= WAS_SENSE;
        !           384:        sti();
        !           385:        
        !           386:        last_cmnd[host].sense_cmnd[1] = lun << 5;       
        !           387: 
        !           388:        internal_cmnd (host, target, (void *) last_cmnd[host].sense_cmnd, 
        !           389:                       (void *) last_cmnd[host].sense_buffer, SENSE_LENGTH,
        !           390:                       scsi_done);
        !           391:        }
        !           392: 
        !           393: 
        !           394: 
        !           395: 
        !           396: 
        !           397: /*
        !           398:        scsi_do_cmd sends all the commands out to the low-level driver.  It 
        !           399:        handles the specifics required for each low level driver - ie queued 
        !           400:        or non queud.  It also prevents conflicts when different high level 
        !           401:        drivers go for the same host at the same time.
        !           402: */
        !           403: 
        !           404: void scsi_do_cmd (int host,  unsigned char target, const void *cmnd , 
        !           405:                  void *buffer, unsigned bufflen, void (*done)(int,int),
        !           406:                  int timeout, unsigned  char *sense_buffer, int retries 
        !           407:                   )
        !           408:         {
        !           409:        int ok = 0;
        !           410: 
        !           411: #ifdef DEBUG
        !           412:        int i;  
        !           413:        printk ("scsi_do_cmd (host = %d, target = %d, buffer =%08x, "
        !           414:                "bufflen = %d, done = %08x, timeout = %d, retries = %d)\n"
        !           415:                "command : " , host, target, buffer, bufflen, done, timeout, retries);
        !           416:        for (i = 0; i < 10; ++i)
        !           417:                printk ("%02x  ", ((unsigned char *) cmnd)[i]); 
        !           418:        printk("\n");
        !           419: #endif
        !           420:        
        !           421:        if ((host  >= MAX_SCSI_HOSTS) || !scsi_hosts[host].present)
        !           422:                {
        !           423:                printk ("Invalid or not present host number. %d\n", host);
        !           424:                panic("");
        !           425:                }
        !           426: 
        !           427:        
        !           428: /*
        !           429:        We must prevent reentrancy to the lowlevel host driver.  This prevents 
        !           430:        it - we enter a loop until the host we want to talk to is not busy.   
        !           431:        Race conditions are prevented, as interrupts are disabled inbetween the
        !           432:        time we check for the host being not busy, and the time we mark it busy
        !           433:        ourselves.
        !           434: */
        !           435: 
        !           436:        do      {
        !           437:                cli();
        !           438:                if (host_busy[host])
        !           439:                        {
        !           440:                        sti();
        !           441: #ifdef DEBUG
        !           442:                        printk("Host %d is busy.\n"     );
        !           443: #endif
        !           444:                        while (host_busy[host]);
        !           445: #ifdef DEBUG
        !           446:                        printk("Host %d is no longer busy.");
        !           447: #endif
        !           448:                        }
        !           449:                else
        !           450:                        {
        !           451:                        host_busy[host] = 1;
        !           452:                        ok = 1;
        !           453:                        sti();
        !           454:                        }
        !           455:                } while (!ok);
        !           456:                
        !           457: 
        !           458: /*
        !           459:        Our own function scsi_done (which marks the host as not busy, disables 
        !           460:        the timeout counter, etc) will be called by us or by the 
        !           461:        scsi_hosts[host].queuecommand() function needs to also call
        !           462:        the completion function for the high level driver.
        !           463: 
        !           464: */
        !           465: 
        !           466:        memcpy ((void *) last_cmnd[host].cmnd , (void *) cmnd, 10);
        !           467:        last_cmnd[host].host = host;
        !           468:        last_cmnd[host].target = target;
        !           469:        last_cmnd[host].lun = (last_cmnd[host].cmnd[1] >> 5);
        !           470:        last_cmnd[host].bufflen = bufflen;
        !           471:        last_cmnd[host].buffer = buffer;
        !           472:        last_cmnd[host].sense_buffer = sense_buffer;
        !           473:        last_cmnd[host].flags=0;
        !           474:        last_cmnd[host].retries=0;
        !           475:        last_cmnd[host].allowed=retries;
        !           476:        last_cmnd[host].done = done;
        !           477:        last_cmnd[host].timeout_per_command = timeout;
        !           478:                                
        !           479:        /* Start the timer ticking.  */
        !           480: 
        !           481:        internal_timeout[host] = 0;
        !           482:        internal_cmnd (host,  target, cmnd , buffer, bufflen, scsi_done);
        !           483: 
        !           484: #ifdef DEBUG
        !           485:        printk ("Leaving scsi_do_cmd()\n");
        !           486: #endif
        !           487:         }
        !           488: 
        !           489: 
        !           490: /*
        !           491:        The scsi_done() function disables the timeout timer for the scsi host, 
        !           492:        marks the host as not busy, and calls the user specified completion 
        !           493:        function for that host's current command.
        !           494: */
        !           495: 
        !           496: static void reset (int host)
        !           497:        {
        !           498:        #ifdef DEBUG
        !           499:                printk("reset(%d)\n", host);
        !           500:        #endif
        !           501: 
        !           502:        last_cmnd[host].flags |= (WAS_RESET | IS_RESETTING);
        !           503:        scsi_reset(host);
        !           504: 
        !           505:        #ifdef DEBUG
        !           506:                printk("performing request sense\n");
        !           507:        #endif
        !           508: 
        !           509:        scsi_request_sense (host, last_cmnd[host].target, last_cmnd[host].lun);
        !           510:        }
        !           511:        
        !           512:        
        !           513: 
        !           514: static int check_sense (int host)
        !           515:        {
        !           516:        if (((sense_buffer[0] & 0x70) >> 4) == 7)
        !           517:                switch (sense_buffer[2] & 0xf)
        !           518:                {
        !           519:                case NO_SENSE:
        !           520:                case RECOVERED_ERROR:
        !           521:                        return 0;
        !           522: 
        !           523:                case ABORTED_COMMAND:
        !           524:                case NOT_READY:
        !           525:                case UNIT_ATTENTION:    
        !           526:                        return SUGGEST_RETRY;   
        !           527:        
        !           528:                /* these three are not supported */     
        !           529:                case COPY_ABORTED:
        !           530:                case VOLUME_OVERFLOW:
        !           531:                case MISCOMPARE:
        !           532:        
        !           533:                case MEDIUM_ERROR:
        !           534:                        return SUGGEST_REMAP;
        !           535:                case BLANK_CHECK:
        !           536:                case DATA_PROTECT:
        !           537:                case HARDWARE_ERROR:
        !           538:                case ILLEGAL_REQUEST:
        !           539:                default:
        !           540:                        return SUGGEST_ABORT;
        !           541:                }
        !           542:        else
        !           543:                return SUGGEST_RETRY;   
        !           544:        }       
        !           545: 
        !           546: static void scsi_done (int host, int result)
        !           547:        {
        !           548:        int status=0;
        !           549:        int exit=0;
        !           550:        int checked;
        !           551:        int oldto;
        !           552:        oldto = host_timeout[host];
        !           553:        host_timeout[host] = 0;
        !           554:        update_timeout();
        !           555: 
        !           556: #define FINISHED 0
        !           557: #define MAYREDO  1
        !           558: #define REDO    3
        !           559: 
        !           560: #ifdef DEBUG
        !           561:        printk("In scsi_done(host = %d, result = %06x)\n", host, result);
        !           562: #endif
        !           563:        if (host > MAX_SCSI_HOSTS || host  < 0) 
        !           564:                {
        !           565:                host_timeout[host] = 0;
        !           566:                update_timeout();
        !           567:                panic("scsi_done() called with invalid host number.\n");
        !           568:                }
        !           569: 
        !           570:        switch (host_byte(result))      
        !           571:        {
        !           572:        case DID_OK:
        !           573:                if (last_cmnd[host].flags & IS_RESETTING)
        !           574:                        {
        !           575:                        last_cmnd[host].flags &= ~IS_RESETTING;
        !           576:                        status = REDO;
        !           577:                        break;
        !           578:                        }
        !           579: 
        !           580:                if (status_byte(result) && (last_cmnd[host].flags & 
        !           581:                    WAS_SENSE)) 
        !           582:                        {
        !           583:                        last_cmnd[host].flags &= ~WAS_SENSE;
        !           584:                        cli();
        !           585:                        internal_timeout[host] &= ~SENSE_TIMEOUT;
        !           586:                        sti();
        !           587: 
        !           588:                        if (!(last_cmnd[host].flags & WAS_RESET)) 
        !           589:                                reset(host);
        !           590:                        else
        !           591:                                {
        !           592:                                exit = (DRIVER_HARD | SUGGEST_ABORT);
        !           593:                                status = FINISHED;
        !           594:                                }
        !           595:                        }
        !           596:                else switch(msg_byte(result))
        !           597:                        {
        !           598:                        case COMMAND_COMPLETE:
        !           599:                        switch (status_byte(result))
        !           600:                        {
        !           601:                        case GOOD:
        !           602:                                if (last_cmnd[host].flags & WAS_SENSE)
        !           603:                                        {
        !           604: #ifdef DEBUG
        !           605:        printk ("In scsi_done, GOOD status, COMMAND COMPLETE, parsing sense information.\n");
        !           606: #endif
        !           607: 
        !           608:                                        last_cmnd[host].flags &= ~WAS_SENSE;
        !           609:                                        cli();
        !           610:                                        internal_timeout[host] &= ~SENSE_TIMEOUT;
        !           611:                                        sti();
        !           612:        
        !           613:                                        switch (checked = check_sense(host))
        !           614:                                        {
        !           615:                                        case 0: 
        !           616: #ifdef DEBUG
        !           617:        printk("NO SENSE.  status = REDO\n");
        !           618: #endif
        !           619: 
        !           620:                                                host_timeout[host] = oldto;
        !           621:                                                update_timeout();
        !           622:                                                status = REDO;
        !           623:                                                break;
        !           624:                                        case SUGGEST_REMAP:                     
        !           625:                                        case SUGGEST_RETRY: 
        !           626: #ifdef DEBUG
        !           627:        printk("SENSE SUGGEST REMAP or SUGGEST RETRY - status = MAYREDO\n");
        !           628: #endif
        !           629: 
        !           630:                                                status = MAYREDO;
        !           631:                                                exit = SUGGEST_RETRY;
        !           632:                                                break;
        !           633:                                        case SUGGEST_ABORT:
        !           634: #ifdef DEBUG
        !           635:        printk("SENSE SUGGEST ABORT - status = FINISHED");
        !           636: #endif
        !           637: 
        !           638:                                                status = FINISHED;
        !           639:                                                exit =  DRIVER_SENSE;
        !           640:                                                break;
        !           641:                                        default:
        !           642:                                                printk ("Internal error %s %s \n", __FILE__, 
        !           643:                                                        __LINE__);
        !           644:                                        }                          
        !           645:                                        }       
        !           646:                                else
        !           647:                                        {
        !           648: #ifdef DEBUG
        !           649:        printk("COMMAND COMPLETE message returned, status = FINISHED. \n");
        !           650: #endif
        !           651: 
        !           652:                                        exit =  DRIVER_OK;
        !           653:                                        status = FINISHED;
        !           654:                                        }
        !           655:                                break;  
        !           656: 
        !           657:                        case CHECK_CONDITION:
        !           658: 
        !           659: #ifdef DEBUG
        !           660:        printk("CHECK CONDITION message returned, performing request sense.\n");
        !           661: #endif
        !           662: 
        !           663:                                scsi_request_sense (host, last_cmnd[host].target, last_cmnd[host].lun);
        !           664:                                break;          
        !           665:                        
        !           666:                        case CONDITION_GOOD:
        !           667:                        case INTERMEDIATE_GOOD:
        !           668:                        case INTERMEDIATE_C_GOOD:
        !           669: #ifdef DEBUG
        !           670:        printk("CONDITION GOOD, INTERMEDIATE GOOD, or INTERMEDIATE CONDITION GOOD recieved and ignored. \n");
        !           671: #endif
        !           672:                                break;
        !           673:                                
        !           674:                        case BUSY:
        !           675: #ifdef DEBUG
        !           676:        printk("BUSY message returned, performing REDO");
        !           677: #endif
        !           678:                                host_timeout[host] = oldto;
        !           679:                                update_timeout();
        !           680:                                status = REDO;
        !           681:                                break;
        !           682: 
        !           683:                        case RESERVATION_CONFLICT:
        !           684:                                reset(host);
        !           685:                                exit = DRIVER_SOFT | SUGGEST_ABORT;
        !           686:                                status = MAYREDO;
        !           687:                                break;
        !           688:                        default:
        !           689:                                printk ("Internal error %s %s \n"
        !           690:                                        "status byte = %d \n", __FILE__, 
        !           691:                                        __LINE__, status_byte(result));
        !           692:                                
        !           693:                        }
        !           694:                        break;
        !           695:                        default:
        !           696:                                panic ("unsupported message byte recieved.");
        !           697:                        }
        !           698:                        break;
        !           699:        case DID_TIME_OUT:      
        !           700: #ifdef DEBUG
        !           701:        printk("Host returned DID_TIME_OUT - ");
        !           702: #endif
        !           703: 
        !           704:                if (last_cmnd[host].flags & WAS_TIMEDOUT)       
        !           705:                        {
        !           706: #ifdef DEBUG
        !           707:        printk("Aborting\n");
        !           708: #endif 
        !           709:                        exit = (DRIVER_TIMEOUT | SUGGEST_ABORT);
        !           710:                        }               
        !           711:                else 
        !           712:                        {
        !           713: #ifdef DEBUG
        !           714:                        printk ("Retrying.\n");
        !           715: #endif
        !           716:                        last_cmnd[host].flags  |= WAS_TIMEDOUT;
        !           717:                        status = REDO;
        !           718:                        }
        !           719:                break;
        !           720:        case DID_BUS_BUSY:
        !           721:        case DID_PARITY:
        !           722:                status = REDO;
        !           723:                break;
        !           724:        case DID_NO_CONNECT:
        !           725: #ifdef DEBUG
        !           726:                printk("Couldn't connect.\n");
        !           727: #endif
        !           728:                exit  = (DRIVER_HARD | SUGGEST_ABORT);
        !           729:                break;
        !           730:        case DID_ERROR: 
        !           731:                status = MAYREDO;
        !           732:                exit = (DRIVER_HARD | SUGGEST_ABORT);
        !           733:                break;
        !           734:        case DID_BAD_TARGET:
        !           735:        case DID_ABORT:
        !           736:                exit = (DRIVER_INVALID | SUGGEST_ABORT);
        !           737:                break;  
        !           738:        default :               
        !           739:                exit = (DRIVER_ERROR | SUGGEST_DIE);
        !           740:        }
        !           741: 
        !           742:        switch (status) 
        !           743:                {
        !           744:                case FINISHED:
        !           745:                        break;
        !           746:                case MAYREDO:
        !           747: 
        !           748: #ifdef DEBUG
        !           749:        printk("In MAYREDO, allowing %d retries, have %d\n\r",
        !           750:               last_cmnd[host].allowed, last_cmnd[host].retries);
        !           751: #endif
        !           752: 
        !           753:                        if ((++last_cmnd[host].retries) < last_cmnd[host].allowed)
        !           754:                        {
        !           755:                        if ((last_cmnd[host].retries >= (last_cmnd[host].allowed >> 1)) 
        !           756:                            && !(last_cmnd[host].flags & WAS_RESET))
        !           757:                                reset(host);
        !           758:                                break;
        !           759:                        
        !           760:                        }
        !           761:                        else
        !           762:                                {
        !           763:                                status = FINISHED;
        !           764:                                break;
        !           765:                                }
        !           766:                        /* fall through to REDO */
        !           767: 
        !           768:                case REDO:
        !           769:                        if (last_cmnd[host].flags & WAS_SENSE)                  
        !           770:                                scsi_request_sense (host, last_cmnd[host].target,       
        !           771:                               last_cmnd[host].lun);    
        !           772:                        else    
        !           773:                                internal_cmnd (host, last_cmnd[host].target,    
        !           774:                                last_cmnd[host].cmnd,  
        !           775:                                last_cmnd[host].buffer,   
        !           776:                                last_cmnd[host].bufflen, scsi_done);                    
        !           777:                        break;  
        !           778:                default: 
        !           779:                        INTERNAL_ERROR;
        !           780:                }
        !           781: 
        !           782:        if (status == FINISHED) 
        !           783:                {
        !           784:                #ifdef DEBUG
        !           785:                        printk("Calling done function - at address %08x\n", last_cmnd[host].done);
        !           786:                #endif
        !           787:                last_cmnd[host].done (host, (result | ((exit & 0xff) << 24)));
        !           788:                host_busy[host] = 0;
        !           789:                }
        !           790: 
        !           791: 
        !           792: #undef FINISHED
        !           793: #undef REDO
        !           794: #undef MAYREDO
        !           795:                
        !           796:        }
        !           797: 
        !           798: /*
        !           799:        The scsi_abort function interfaces with the abort() function of the host
        !           800:        we are aborting, and causes the current command to not complete.  The 
        !           801:        caller should deal with any error messages or status returned on the 
        !           802:        next call.
        !           803:        
        !           804:        This will not be called rentrantly for a given host.
        !           805: */
        !           806:        
        !           807: /*
        !           808:        Since we're nice guys and specified that abort() and reset()
        !           809:        can be non-reentrant.  The internal_timeout flags are used for
        !           810:        this.
        !           811: */
        !           812: 
        !           813: 
        !           814: int scsi_abort (int host, int why)
        !           815:        {
        !           816:        int temp, oldto;
        !           817:        
        !           818:        while(1)        
        !           819:                {
        !           820:                cli();
        !           821:                if (internal_timeout[host] & IN_ABORT) 
        !           822:                        {
        !           823:                        sti();
        !           824:                        while (internal_timeout[host] & IN_ABORT);
        !           825:                        }
        !           826:                else
        !           827:                        {       
        !           828:                        internal_timeout[host] |= IN_ABORT;
        !           829:                        host_timeout[host] = ABORT_TIMEOUT;     
        !           830:                        update_timeout();
        !           831: 
        !           832:                        oldto = host_timeout[host];
        !           833:                        
        !           834:                        sti();
        !           835:                        if (!host_busy[host] || !scsi_hosts[host].abort(why))
        !           836:                                temp =  0;
        !           837:                        else
        !           838:                                temp = 1;
        !           839:                        
        !           840:                        cli();
        !           841:                        internal_timeout[host] &= ~IN_ABORT;
        !           842:                        host_timeout[host]=oldto;
        !           843:                        update_timeout();
        !           844:                        sti();
        !           845:                        return temp;
        !           846:                        }
        !           847:                }       
        !           848:        }
        !           849: 
        !           850: int scsi_reset (int host)
        !           851:        {
        !           852:        int temp, oldto;
        !           853:        
        !           854:        while (1) {
        !           855:                cli();  
        !           856:                if (internal_timeout[host] & IN_RESET)
        !           857:                        {
        !           858:                        sti();
        !           859:                        while (internal_timeout[host] & IN_RESET);
        !           860:                        }
        !           861:                else
        !           862:                        {
        !           863:                        oldto = host_timeout[host];     
        !           864:                        host_timeout[host] = RESET_TIMEOUT;     
        !           865:                        update_timeout();       
        !           866:                        internal_timeout[host] |= IN_RESET;
        !           867:                                        
        !           868:                        if (host_busy[host])
        !           869:                                {       
        !           870:                                sti();
        !           871:                                if (!(last_cmnd[host].flags & IS_RESETTING) && !(internal_timeout[host] & IN_ABORT))
        !           872:                                        scsi_abort(host, DID_RESET);
        !           873: 
        !           874:                                temp = scsi_hosts[host].reset();                        
        !           875:                                }                               
        !           876:                        else
        !           877:                                {
        !           878:                                host_busy[host]=1;
        !           879:        
        !           880:                                sti();
        !           881:                                temp = scsi_hosts[host].reset();
        !           882:                                last_reset[host] = jiffies;
        !           883:                                host_busy[host]=0;
        !           884:                                }
        !           885:        
        !           886:                        cli();
        !           887:                        host_timeout[host] = oldto;             
        !           888:                        update_timeout();
        !           889:                        internal_timeout[host] &= ~IN_RESET;
        !           890:                        sti();
        !           891:                        return temp;    
        !           892:                        }
        !           893:                }
        !           894:        }
        !           895:                         
        !           896: 
        !           897: static void scsi_main_timeout(void)
        !           898:        {
        !           899:        /*
        !           900:                We must not enter update_timeout with a timeout condition still pending.
        !           901:        */
        !           902: 
        !           903:        int i, timed_out;
        !           904: 
        !           905:        do      {       
        !           906:                cli();
        !           907: 
        !           908:        /*
        !           909:                Find all timers such that they have 0 or negative (shouldn't happen)
        !           910:                time remaining on them.
        !           911:        */
        !           912:                        
        !           913:                for (i = timed_out = 0; i < MAX_SCSI_HOSTS; ++i)
        !           914:                        if (host_timeout[i] != 0 && host_timeout[i] <= time_elapsed)
        !           915:                                {
        !           916:                                sti();
        !           917:                                host_timeout[i] = 0;
        !           918:                                scsi_times_out(i);
        !           919:                                ++timed_out; 
        !           920:                                }
        !           921: 
        !           922:                update_timeout();                               
        !           923:                } while (timed_out);    
        !           924:        sti();
        !           925:        }
        !           926: 
        !           927: /*
        !           928:        These are used to keep track of things. 
        !           929: */
        !           930: 
        !           931: static int time_start, time_elapsed;
        !           932: 
        !           933: /*
        !           934:        The strategy is to cause the timer code to call scsi_times_out()
        !           935:        when the soonest timeout is pending.  
        !           936: */
        !           937:        
        !           938: static void update_timeout(void)
        !           939:        {
        !           940:        int i, least, used;
        !           941: 
        !           942:        cli();
        !           943: 
        !           944: /* 
        !           945:        Figure out how much time has passed since the last time the timeouts 
        !           946:        were updated 
        !           947: */
        !           948:        used = (time_start) ? (jiffies - time_start) : 0;
        !           949: 
        !           950: /*
        !           951:        Find out what is due to timeout soonest, and adjust all timeouts for
        !           952:        the amount of time that has passed since the last time we called 
        !           953:        update_timeout. 
        !           954: */
        !           955:        
        !           956:        for (i = 0, least = 0xffffffff; i < MAX_SCSI_HOSTS; ++i)        
        !           957:                if (host_timeout[i] > 0 && (host_timeout[i] -= used) < least)
        !           958:                        least = host_timeout[i]; 
        !           959: 
        !           960: /*
        !           961:        If something is due to timeout again, then we will set the next timeout 
        !           962:        interrupt to occur.  Otherwise, timeouts are disabled.
        !           963: */
        !           964:        
        !           965:        if (least != 0xffffffff)
        !           966:                {
        !           967:                time_start = jiffies;   
        !           968:                timer_table[SCSI_TIMER].expires = (time_elapsed = least) + jiffies;     
        !           969:                timer_active |= 1 << SCSI_TIMER;
        !           970:                }
        !           971:        else
        !           972:                {
        !           973:                timer_table[SCSI_TIMER].expires = time_start = time_elapsed = 0;
        !           974:                timer_active &= ~(1 << SCSI_TIMER);
        !           975:                }       
        !           976:        sti();
        !           977:        }               
        !           978: /*
        !           979:        scsi_dev_init() is our initialization routine, which inturn calls host 
        !           980:        initialization, bus scanning, and sd/st initialization routines.  It 
        !           981:        should be called from main().
        !           982: */
        !           983: 
        !           984: static unsigned char generic_sense[6] = {REQUEST_SENSE, 0,0,0, 255, 0};                
        !           985: void scsi_dev_init (void)
        !           986:        {
        !           987:        int i;
        !           988: #ifdef FOO_ON_YOU
        !           989:        return;
        !           990: #endif 
        !           991:        timer_table[SCSI_TIMER].fn = scsi_main_timeout;
        !           992:        timer_table[SCSI_TIMER].expires = 0;
        !           993: 
        !           994:        scsi_init();            /* initialize all hosts */
        !           995:        /*
        !           996:                Set up sense command in each host structure.
        !           997:        */
        !           998: 
        !           999:        for (i = 0; i < MAX_SCSI_HOSTS; ++i)
        !          1000:                {
        !          1001:                memcpy ((void *) last_cmnd[i].sense_cmnd, (void *) generic_sense,
        !          1002:                        6);
        !          1003:                last_reset[i] = 0;
        !          1004:                }
        !          1005:                                
        !          1006:         scan_scsis();           /* scan for scsi devices */
        !          1007: 
        !          1008: #ifdef CONFIG_BLK_DEV_SD
        !          1009:        sd_init();              /* init scsi disks */
        !          1010: #endif
        !          1011: 
        !          1012: #ifdef CONFIG_BLK_DEV_ST
        !          1013:         st_init();              /* init scsi tapes */
        !          1014: #endif
        !          1015:        }
        !          1016: #endif

unix.superglobalmegacorp.com

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