Annotation of Gnu-Mach/linux/src/drivers/scsi/seagate.c, revision 1.1

1.1     ! root        1: /*
        !             2:  *     seagate.c Copyright (C) 1992, 1993 Drew Eckhardt 
        !             3:  *     low level scsi driver for ST01/ST02, Future Domain TMC-885, 
        !             4:  *     TMC-950  by
        !             5:  *
        !             6:  *             Drew Eckhardt 
        !             7:  *
        !             8:  *     <[email protected]>
        !             9:  *
        !            10:  *     Note : TMC-880 boards don't work because they have two bits in 
        !            11:  *             the status register flipped, I'll fix this "RSN"
        !            12:  *
        !            13:  *      This card does all the I/O via memory mapped I/O, so there is no need
        !            14:  *      to check or allocate a region of the I/O address space.
        !            15:  */
        !            16: 
        !            17: /*
        !            18:  * Configuration : 
        !            19:  * To use without BIOS -DOVERRIDE=base_address -DCONTROLLER=FD or SEAGATE
        !            20:  * -DIRQ will override the default of 5.
        !            21:  * Note: You can now set these options from the kernel's "command line".
        !            22:  * The syntax is:
        !            23:  *
        !            24:  *     st0x=ADDRESS,IRQ                (for a Seagate controller)
        !            25:  * or:
        !            26:  *     tmc8xx=ADDRESS,IRQ              (for a TMC-8xx or TMC-950 controller)
        !            27:  * eg:
        !            28:  *     tmc8xx=0xC8000,15
        !            29:  *
        !            30:  * will configure the driver for a TMC-8xx style controller using IRQ 15
        !            31:  * with a base address of 0xC8000.
        !            32:  * 
        !            33:  * -DFAST or -DFAST32 will use blind transfers where possible
        !            34:  *
        !            35:  * -DARBITRATE will cause the host adapter to arbitrate for the 
        !            36:  *     bus for better SCSI-II compatibility, rather than just 
        !            37:  *     waiting for BUS FREE and then doing its thing.  Should
        !            38:  *     let us do one command per Lun when I integrate my 
        !            39:  *     reorganization changes into the distribution sources.
        !            40:  *
        !            41:  * -DSLOW_HANDSHAKE will allow compatibility with broken devices that don't 
        !            42:  *     handshake fast enough (ie, some CD ROM's) for the Seagate
        !            43:  *     code.
        !            44:  *
        !            45:  * -DSLOW_RATE=x, x some number will let you specify a default 
        !            46:  *     transfer rate if handshaking isn't working correctly.
        !            47:  */
        !            48: 
        !            49: #include <linux/module.h>
        !            50: 
        !            51: #include <asm/io.h>
        !            52: #include <asm/system.h>
        !            53: #include <linux/signal.h>
        !            54: #include <linux/sched.h>
        !            55: #include <linux/string.h>
        !            56: #include <linux/config.h>
        !            57: #include <linux/proc_fs.h>
        !            58: 
        !            59: #include <linux/blk.h>
        !            60: #include "scsi.h"
        !            61: #include "hosts.h"
        !            62: #include "seagate.h"
        !            63: #include "constants.h"
        !            64: #include<linux/stat.h>
        !            65: 
        !            66: struct proc_dir_entry proc_scsi_seagate = {
        !            67:     PROC_SCSI_SEAGATE, 7, "seagate",
        !            68:     S_IFDIR | S_IRUGO | S_IXUGO, 2
        !            69: };
        !            70: 
        !            71: 
        !            72: #ifndef IRQ
        !            73: #define IRQ 5
        !            74: #endif
        !            75: 
        !            76: #if (defined(FAST32) && !defined(FAST))
        !            77: #define FAST
        !            78: #endif
        !            79: 
        !            80: #if defined(SLOW_RATE) && !defined(SLOW_HANDSHAKE)
        !            81: #define SLOW_HANDSHAKE
        !            82: #endif
        !            83: 
        !            84: #if defined(SLOW_HANDSHAKE) && !defined(SLOW_RATE)
        !            85: #define SLOW_RATE 50
        !            86: #endif
        !            87: 
        !            88: 
        !            89: #if defined(LINKED)
        !            90: #undef LINKED          /* Linked commands are currently broken ! */
        !            91: #endif
        !            92: 
        !            93: static int internal_command(unsigned char target, unsigned char lun,
        !            94:                            const void *cmnd,
        !            95:                         void *buff, int bufflen, int reselect);
        !            96: 
        !            97: static int incommand;                  /*
        !            98:                                                set if arbitration has finished and we are 
        !            99:                                                in some command phase.
        !           100:                                        */
        !           101: 
        !           102: static const void *base_address = NULL;        /*
        !           103:                                                Where the card ROM starts,
        !           104:                                                used to calculate memory mapped
        !           105:                                                register location.
        !           106:                                        */
        !           107: #ifdef notyet
        !           108: static volatile int abort_confirm = 0;
        !           109: #endif
        !           110: 
        !           111: static volatile void *st0x_cr_sr;       /*
        !           112:                                                control register write,
        !           113:                                                status register read.
        !           114:                                                256 bytes in length.
        !           115: 
        !           116:                                                Read is status of SCSI BUS,
        !           117:                                                as per STAT masks.
        !           118: 
        !           119:                                        */
        !           120: 
        !           121: 
        !           122: static volatile void *st0x_dr;         /*
        !           123:                                                data register, read write
        !           124:                                                256 bytes in length.
        !           125:                                        */
        !           126: 
        !           127: 
        !           128: static volatile int st0x_aborted=0;    /* 
        !           129:                                                set when we are aborted, ie by a time out, etc.
        !           130:                                        */
        !           131: 
        !           132: static unsigned char controller_type = 0; /* set to SEAGATE for ST0x boards or FD for TMC-8xx boards */
        !           133: static unsigned char irq = IRQ;
        !           134:                        
        !           135: #define retcode(result) (((result) << 16) | (message << 8) | status)                   
        !           136: #define STATUS (*(volatile unsigned char *) st0x_cr_sr)
        !           137: #define CONTROL STATUS 
        !           138: #define DATA (*(volatile unsigned char *) st0x_dr)
        !           139: 
        !           140: void st0x_setup (char *str, int *ints) {
        !           141:     controller_type = SEAGATE;
        !           142:     base_address = (void *) ints[1];
        !           143:     irq = ints[2];
        !           144: }
        !           145: 
        !           146: void tmc8xx_setup (char *str, int *ints) {
        !           147:     controller_type = FD;
        !           148:     base_address = (void *) ints[1];
        !           149:     irq = ints[2];
        !           150: }
        !           151:     
        !           152: 
        !           153: #ifndef OVERRIDE               
        !           154: static const char *  seagate_bases[] = {
        !           155:        (char *) 0xc8000, (char *) 0xca000, (char *) 0xcc000,
        !           156:        (char *) 0xce000, (char *) 0xdc000, (char *) 0xde000
        !           157: };
        !           158: 
        !           159: typedef struct {
        !           160:        const char *signature ;
        !           161:        unsigned offset;
        !           162:        unsigned length;
        !           163:        unsigned char type;
        !           164: } Signature;
        !           165:        
        !           166: static const Signature signatures[] = {
        !           167: #ifdef CONFIG_SCSI_SEAGATE
        !           168: {"ST01 v1.7  (C) Copyright 1987 Seagate", 15, 37, SEAGATE},
        !           169: {"SCSI BIOS 2.00  (C) Copyright 1987 Seagate", 15, 40, SEAGATE},
        !           170: 
        !           171: /*
        !           172:  * The following two lines are NOT mistakes.  One detects ROM revision 
        !           173:  * 3.0.0, the other 3.2.  Since seagate has only one type of SCSI adapter, 
        !           174:  * and this is not going to change, the "SEAGATE" and "SCSI" together
        !           175:  * are probably "good enough"
        !           176:  */
        !           177: 
        !           178: {"SEAGATE SCSI BIOS ",16, 17, SEAGATE},
        !           179: {"SEAGATE SCSI BIOS ",17, 17, SEAGATE},
        !           180: 
        !           181: /*
        !           182:  * However, future domain makes several incompatible SCSI boards, so specific
        !           183:  * signatures must be used.
        !           184:  */
        !           185: 
        !           186: {"FUTURE DOMAIN CORP. (C) 1986-1989 V5.0C2/14/89", 5, 46, FD},
        !           187: {"FUTURE DOMAIN CORP. (C) 1986-1989 V6.0A7/28/89", 5, 46, FD},
        !           188: {"FUTURE DOMAIN CORP. (C) 1986-1990 V6.0105/31/90",5, 47, FD},
        !           189: {"FUTURE DOMAIN CORP. (C) 1986-1990 V6.0209/18/90",5, 47, FD},
        !           190: {"FUTURE DOMAIN CORP. (C) 1986-1990 V7.009/18/90", 5, 46, FD},
        !           191: {"FUTURE DOMAIN CORP. (C) 1992 V8.00.004/02/92",   5, 44, FD},
        !           192: {"IBM F1 BIOS V1.1004/30/92",                     5, 25, FD},
        !           193: {"FUTURE DOMAIN TMC-950",                        5, 21, FD},
        !           194: #endif /* CONFIG_SCSI_SEAGATE */
        !           195: }
        !           196: ;
        !           197: 
        !           198: #define NUM_SIGNATURES (sizeof(signatures) / sizeof(Signature))
        !           199: #endif /* n OVERRIDE */
        !           200: 
        !           201: /*
        !           202:  * hostno stores the hostnumber, as told to us by the init routine.
        !           203:  */
        !           204: 
        !           205: static int hostno = -1;
        !           206: static void seagate_reconnect_intr(int, void *, struct pt_regs *);
        !           207: 
        !           208: #ifdef FAST
        !           209: static int fast = 1;
        !           210: #endif 
        !           211: 
        !           212: #ifdef SLOW_HANDSHAKE
        !           213: /* 
        !           214:  * Support for broken devices : 
        !           215:  * The Seagate board has a handshaking problem.  Namely, a lack 
        !           216:  * thereof for slow devices.  You can blast 600K/second through 
        !           217:  * it if you are polling for each byte, more if you do a blind 
        !           218:  * transfer.  In the first case, with a fast device, REQ will 
        !           219:  * transition high-low or high-low-high before your loop restarts 
        !           220:  * and you'll have no problems.  In the second case, the board 
        !           221:  * will insert wait states for up to 13.2 usecs for REQ to 
        !           222:  * transition low->high, and everything will work.
        !           223:  *
        !           224:  * However, there's nothing in the state machine that says 
        !           225:  * you *HAVE* to see a high-low-high set of transitions before
        !           226:  * sending the next byte, and slow things like the Trantor CD ROMS
        !           227:  * will break because of this.
        !           228:  * 
        !           229:  * So, we need to slow things down, which isn't as simple as it 
        !           230:  * seems.  We can't slow things down period, because then people
        !           231:  * who don't recompile their kernels will shoot me for ruining 
        !           232:  * their performance.  We need to do it on a case per case basis.
        !           233:  *
        !           234:  * The best for performance will be to, only for borken devices 
        !           235:  * (this is stored on a per-target basis in the scsi_devices array)
        !           236:  * 
        !           237:  * Wait for a low->high transition before continuing with that 
        !           238:  * transfer.  If we timeout, continue anyways.  We don't need 
        !           239:  * a long timeout, because REQ should only be asserted until the 
        !           240:  * corresponding ACK is received and processed.
        !           241:  *
        !           242:  * Note that we can't use the system timer for this, because of 
        !           243:  * resolution, and we *really* can't use the timer chip since 
        !           244:  * gettimeofday() and the beeper routines use that.  So,
        !           245:  * the best thing for us to do will be to calibrate a timing
        !           246:  * loop in the initialization code using the timer chip before
        !           247:  * gettimeofday() can screw with it.
        !           248:  */
        !           249: 
        !           250: static int borken_calibration = 0;
        !           251: static void borken_init (void) {
        !           252:   register int count = 0, start = jiffies + 1, stop = start + 25;
        !           253: 
        !           254:   while (jiffies < start);
        !           255:   for (;jiffies < stop; ++count);
        !           256: 
        !           257: /* 
        !           258:  * Ok, we now have a count for .25 seconds.  Convert to a 
        !           259:  * count per second and divide by transfer rate in K.
        !           260:  */
        !           261: 
        !           262:   borken_calibration =  (count * 4) / (SLOW_RATE*1024);
        !           263: 
        !           264:   if (borken_calibration < 1)
        !           265:        borken_calibration = 1;
        !           266: #if (DEBUG & DEBUG_BORKEN)
        !           267:   printk("scsi%d : borken calibrated to %dK/sec, %d cycles per transfer\n", 
        !           268:        hostno, BORKEN_RATE, borken_calibration);
        !           269: #endif
        !           270: }
        !           271: 
        !           272: static inline void borken_wait(void) {
        !           273:   register int count;
        !           274:   for (count = borken_calibration; count && (STATUS & STAT_REQ); 
        !           275:        --count);
        !           276: #if (DEBUG & DEBUG_BORKEN) 
        !           277:   if (count)
        !           278:        printk("scsi%d : borken timeout\n", hostno);
        !           279: #endif 
        !           280: }
        !           281: 
        !           282: #endif /* def SLOW_HANDSHAKE */
        !           283: 
        !           284: int seagate_st0x_detect (Scsi_Host_Template * tpnt)
        !           285:        {
        !           286:      struct Scsi_Host *instance;
        !           287: #ifndef OVERRIDE
        !           288:        int i,j;
        !           289: #endif 
        !           290: 
        !           291:      tpnt->proc_dir = &proc_scsi_seagate;
        !           292: /*
        !           293:  *     First, we try for the manual override.
        !           294:  */
        !           295: #ifdef DEBUG 
        !           296:        printk("Autodetecting ST0x / TMC-8xx\n");
        !           297: #endif
        !           298:        
        !           299:        if (hostno != -1)
        !           300:                {
        !           301:                printk ("ERROR : seagate_st0x_detect() called twice.\n");
        !           302:                return 0;
        !           303:                }
        !           304: 
        !           305:       /* If the user specified the controller type from the command line,
        !           306:         controller_type will be non-zero, so don't try to detect one */
        !           307: 
        !           308:        if (!controller_type) {
        !           309: #ifdef OVERRIDE
        !           310:        base_address = (void *) OVERRIDE;
        !           311: 
        !           312: /* CONTROLLER is used to override controller (SEAGATE or FD). PM: 07/01/93 */
        !           313: #ifdef CONTROLLER
        !           314:        controller_type = CONTROLLER;
        !           315: #else
        !           316: #error Please use -DCONTROLLER=SEAGATE or -DCONTROLLER=FD to override controller type
        !           317: #endif /* CONTROLLER */
        !           318: #ifdef DEBUG
        !           319:        printk("Base address overridden to %x, controller type is %s\n",
        !           320:                base_address,controller_type == SEAGATE ? "SEAGATE" : "FD");
        !           321: #endif 
        !           322: #else /* OVERRIDE */   
        !           323: /*
        !           324:  *     To detect this card, we simply look for the signature
        !           325:  *     from the BIOS version notice in all the possible locations
        !           326:  *     of the ROM's.  This has a nice side effect of not trashing
        !           327:  *     any register locations that might be used by something else.
        !           328:  *
        !           329:  * XXX - note that we probably should be probing the address
        !           330:  * space for the on-board RAM instead.
        !           331:  */
        !           332: 
        !           333:        for (i = 0; i < (sizeof (seagate_bases) / sizeof (char  * )); ++i)
        !           334:                for (j = 0; !base_address && j < NUM_SIGNATURES; ++j)
        !           335:                if (!memcmp ((const void *) (seagate_bases[i] +
        !           336:                    signatures[j].offset), (const void *) signatures[j].signature,
        !           337:                    signatures[j].length)) {
        !           338:                        base_address = (const void *) seagate_bases[i];
        !           339:                        controller_type = signatures[j].type;
        !           340:                }
        !           341: #endif /* OVERRIDE */
        !           342:        } /* (! controller_type) */
        !           343:  
        !           344:        tpnt->this_id = (controller_type == SEAGATE) ? 7 : 6;
        !           345:        tpnt->name = (controller_type == SEAGATE) ? ST0X_ID_STR : FD_ID_STR;
        !           346: 
        !           347:        if (base_address)
        !           348:                {
        !           349:                st0x_cr_sr =(void *) (((const unsigned char *) base_address) + (controller_type == SEAGATE ? 0x1a00 : 0x1c00)); 
        !           350:                st0x_dr = (void *) (((const unsigned char *) base_address ) + (controller_type == SEAGATE ? 0x1c00 : 0x1e00));
        !           351: #ifdef DEBUG
        !           352:                printk("%s detected. Base address = %x, cr = %x, dr = %x\n", tpnt->name, base_address, st0x_cr_sr, st0x_dr);
        !           353: #endif
        !           354: /*
        !           355:  *     At all times, we will use IRQ 5.  Should also check for IRQ3 if we 
        !           356:  *     loose our first interrupt.
        !           357:  */
        !           358:                instance = scsi_register(tpnt, 0);
        !           359:                hostno = instance->host_no;
        !           360:                if (request_irq((int) irq, seagate_reconnect_intr, SA_INTERRUPT,
        !           361:                   (controller_type == SEAGATE) ? "seagate" : "tmc-8xx", NULL)) {
        !           362:                        printk("scsi%d : unable to allocate IRQ%d\n",
        !           363:                                hostno, (int) irq);
        !           364:                        return 0;
        !           365:                }
        !           366:                instance->irq = irq;
        !           367:                instance->io_port = (unsigned int) base_address;
        !           368: #ifdef SLOW_HANDSHAKE
        !           369:                borken_init();
        !           370: #endif
        !           371:                
        !           372:                printk("%s options:"
        !           373: #ifdef ARBITRATE
        !           374:                " ARBITRATE"
        !           375: #endif
        !           376: #ifdef SLOW_HANDSHAKE
        !           377:                " SLOW_HANDSHAKE"
        !           378: #endif
        !           379: #ifdef FAST
        !           380: #ifdef FAST32
        !           381:                " FAST32"
        !           382: #else
        !           383:                " FAST"
        !           384: #endif
        !           385: #endif
        !           386: #ifdef LINKED
        !           387:                " LINKED"
        !           388: #endif
        !           389:              "\n", tpnt->name);
        !           390:                return 1;
        !           391:                }
        !           392:        else
        !           393:                {
        !           394: #ifdef DEBUG
        !           395:                printk("ST0x / TMC-8xx not detected.\n");
        !           396: #endif
        !           397:                return 0;
        !           398:                }
        !           399:        }
        !           400:         
        !           401: const char *seagate_st0x_info(struct Scsi_Host * shpnt) {
        !           402:       static char buffer[64];
        !           403:        sprintf(buffer, "%s at irq %d, address 0x%05X", 
        !           404:                (controller_type == SEAGATE) ? ST0X_ID_STR : FD_ID_STR,
        !           405:                irq, (unsigned int)base_address);
        !           406:        return buffer;
        !           407: }
        !           408: 
        !           409: int seagate_st0x_proc_info(char *buffer, char **start, off_t offset,
        !           410:                                int length, int hostno, int inout)
        !           411: {
        !           412:        const char *info = seagate_st0x_info(NULL);
        !           413:        int len;
        !           414:        int pos;
        !           415:        int begin;
        !           416: 
        !           417:        if (inout) return(-ENOSYS);
        !           418: 
        !           419:        begin = 0;
        !           420:        strcpy(buffer,info);
        !           421:        strcat(buffer,"\n");
        !           422: 
        !           423:        pos = len = strlen(buffer);
        !           424: 
        !           425:        if (pos<offset) {
        !           426:                len = 0;
        !           427:                begin = pos;
        !           428:                }
        !           429: 
        !           430:        *start = buffer + (offset - begin);
        !           431:        len -= (offset - begin);
        !           432:        if ( len > length ) len = length;
        !           433:        return(len);
        !           434: }
        !           435: 
        !           436: /*
        !           437:  * These are our saved pointers for the outstanding command that is 
        !           438:  * waiting for a reconnect
        !           439:  */
        !           440: 
        !           441: static unsigned char current_target, current_lun;
        !           442: static unsigned char *current_cmnd, *current_data;
        !           443: static int current_nobuffs;
        !           444: static struct scatterlist *current_buffer;
        !           445: static int current_bufflen;
        !           446: 
        !           447: #ifdef LINKED
        !           448: 
        !           449: /* 
        !           450:  * linked_connected indicates whether or not we are currently connected to 
        !           451:  * linked_target, linked_lun and in an INFORMATION TRANSFER phase,
        !           452:  * using linked commands.
        !           453:  */
        !           454: 
        !           455: static int linked_connected = 0;
        !           456: static unsigned char linked_target, linked_lun;
        !           457: #endif
        !           458: 
        !           459: 
        !           460: static void (*done_fn)(Scsi_Cmnd *) = NULL;
        !           461: static Scsi_Cmnd * SCint = NULL;
        !           462: 
        !           463: /*
        !           464:  * These control whether or not disconnect / reconnect will be attempted,
        !           465:  * or are being attempted.
        !           466:  */
        !           467: 
        !           468: #define NO_RECONNECT   0
        !           469: #define RECONNECT_NOW  1
        !           470: #define CAN_RECONNECT  2
        !           471: 
        !           472: #ifdef LINKED
        !           473: 
        !           474: /*
        !           475:  * LINKED_RIGHT indicates that we are currently connected to the correct target
        !           476:  * for this command, LINKED_WRONG indicates that we are connected to the wrong 
        !           477:  * target.  Note that these imply CAN_RECONNECT.
        !           478:  */
        !           479: 
        !           480: #define LINKED_RIGHT   3
        !           481: #define LINKED_WRONG   4
        !           482: #endif
        !           483: 
        !           484: /*
        !           485:  * This determines if we are expecting to reconnect or not.
        !           486:  */
        !           487: 
        !           488: static int should_reconnect = 0;
        !           489: 
        !           490: /*
        !           491:  * The seagate_reconnect_intr routine is called when a target reselects the 
        !           492:  * host adapter.  This occurs on the interrupt triggered by the target 
        !           493:  * asserting SEL.
        !           494:  */
        !           495: 
        !           496: static void seagate_reconnect_intr(int irq, void *dev_id, struct pt_regs *regs)
        !           497:        {
        !           498:        int temp;
        !           499:        Scsi_Cmnd * SCtmp;
        !           500: 
        !           501: /* enable all other interrupts. */     
        !           502:        sti();
        !           503: #if (DEBUG & PHASE_RESELECT)
        !           504:        printk("scsi%d : seagate_reconnect_intr() called\n", hostno);
        !           505: #endif
        !           506: 
        !           507:        if (!should_reconnect)
        !           508:            printk("scsi%d: unexpected interrupt.\n", hostno);
        !           509:        else {
        !           510:                 should_reconnect = 0;
        !           511: 
        !           512: #if (DEBUG & PHASE_RESELECT)
        !           513:                printk("scsi%d : internal_command("
        !           514:                       "%d, %08x, %08x, %d, RECONNECT_NOW\n", hostno, 
        !           515:                        current_target, current_data, current_bufflen);
        !           516: #endif
        !           517:        
        !           518:                temp =  internal_command (current_target, current_lun,
        !           519:                        current_cmnd, current_data, current_bufflen,
        !           520:                        RECONNECT_NOW);
        !           521: 
        !           522:                if (msg_byte(temp) != DISCONNECT) {
        !           523:                        if (done_fn) {
        !           524: #if (DEBUG & PHASE_RESELECT)
        !           525:                                printk("scsi%d : done_fn(%d,%08x)", hostno, 
        !           526:                                hostno, temp);
        !           527: #endif
        !           528:                                if(!SCint) panic("SCint == NULL in seagate");
        !           529:                                SCtmp = SCint;
        !           530:                                SCint = NULL;
        !           531:                                SCtmp->result = temp;
        !           532:                                done_fn (SCtmp);
        !           533:                        } else
        !           534:                                printk("done_fn() not defined.\n");
        !           535:                        }
        !           536:                }
        !           537:        } 
        !           538: 
        !           539: /* 
        !           540:  * The seagate_st0x_queue_command() function provides a queued interface
        !           541:  * to the seagate SCSI driver.  Basically, it just passes control onto the
        !           542:  * seagate_command() function, after fixing it so that the done_fn()
        !           543:  * is set to the one passed to the function.  We have to be very careful,
        !           544:  * because there are some commands on some devices that do not disconnect,
        !           545:  * and if we simply call the done_fn when the command is done then another
        !           546:  * command is started and queue_command is called again...  We end up
        !           547:  * overflowing the kernel stack, and this tends not to be such a good idea.
        !           548:  */
        !           549: 
        !           550: static int recursion_depth = 0;
        !           551: 
        !           552: int seagate_st0x_queue_command (Scsi_Cmnd * SCpnt,  void (*done)(Scsi_Cmnd *))
        !           553:        {
        !           554:        int result, reconnect;
        !           555:        Scsi_Cmnd * SCtmp;
        !           556: 
        !           557:        done_fn = done;
        !           558:        current_target = SCpnt->target;
        !           559:        current_lun = SCpnt->lun;
        !           560:        (const void *) current_cmnd = SCpnt->cmnd;
        !           561:        current_data = (unsigned char *) SCpnt->request_buffer;
        !           562:        current_bufflen = SCpnt->request_bufflen;
        !           563:        SCint = SCpnt;
        !           564:        if(recursion_depth) {
        !           565:          return 0;
        !           566:        };
        !           567:        recursion_depth++;
        !           568:        do{
        !           569: #ifdef LINKED
        !           570: /*
        !           571:  * Set linked command bit in control field of SCSI command.
        !           572:  */
        !           573: 
        !           574:          current_cmnd[SCpnt->cmd_len] |= 0x01;
        !           575:          if (linked_connected) {
        !           576: #if (DEBUG & DEBUG_LINKED) 
        !           577:            printk("scsi%d : using linked commands, current I_T_L nexus is ",
        !           578:              hostno);
        !           579: #endif
        !           580:            if ((linked_target == current_target) && 
        !           581:              (linked_lun == current_lun)) {
        !           582: #if (DEBUG & DEBUG_LINKED) 
        !           583:            printk("correct\n");
        !           584: #endif
        !           585:              reconnect = LINKED_RIGHT;
        !           586:            } else {
        !           587: #if (DEBUG & DEBUG_LINKED) 
        !           588:            printk("incorrect\n");
        !           589: #endif
        !           590:              reconnect = LINKED_WRONG;
        !           591:            }
        !           592:          } else 
        !           593: #endif /* LINKED */
        !           594:            reconnect = CAN_RECONNECT;
        !           595: 
        !           596: 
        !           597: 
        !           598: 
        !           599: 
        !           600:          result = internal_command (SCint->target, SCint->lun, SCint->cmnd, SCint->request_buffer,
        !           601:                                     SCint->request_bufflen, 
        !           602:                                     reconnect);
        !           603:          if (msg_byte(result) == DISCONNECT)  break;
        !           604:          SCtmp = SCint;
        !           605:          SCint = NULL;
        !           606:          SCtmp->result = result;
        !           607:          done_fn (SCtmp);
        !           608:        } while(SCint);
        !           609:        recursion_depth--;
        !           610:        return 0;
        !           611:       }
        !           612: 
        !           613: int seagate_st0x_command (Scsi_Cmnd * SCpnt) {
        !           614:        return internal_command (SCpnt->target, SCpnt->lun, SCpnt->cmnd, SCpnt->request_buffer,
        !           615:                                 SCpnt->request_bufflen, 
        !           616:                                 (int) NO_RECONNECT);
        !           617: }
        !           618:        
        !           619: static int internal_command(unsigned char target, unsigned char lun, const void *cmnd,
        !           620:                         void *buff, int bufflen, int reselect) {
        !           621:        int len = 0;
        !           622:        unsigned char *data = NULL;     
        !           623:        struct scatterlist *buffer = NULL;
        !           624:        int nobuffs = 0;
        !           625:        int clock;                      
        !           626:        int temp;
        !           627: #ifdef SLOW_HANDSHAKE
        !           628:        int borken;     /* Does the current target require Very Slow I/O ? */
        !           629: #endif
        !           630: 
        !           631: 
        !           632: #if (DEBUG & PHASE_DATAIN) || (DEBUG & PHASE_DATOUT) 
        !           633:        int transfered = 0;
        !           634: #endif
        !           635: 
        !           636: #if (((DEBUG & PHASE_ETC) == PHASE_ETC) || (DEBUG & PRINT_COMMAND) || \
        !           637:        (DEBUG & PHASE_EXIT))   
        !           638:        int i;
        !           639: #endif
        !           640: 
        !           641: #if ((DEBUG & PHASE_ETC) == PHASE_ETC)
        !           642:        int phase=0, newphase;
        !           643: #endif
        !           644: 
        !           645:        int done = 0;
        !           646:        unsigned char status = 0;       
        !           647:        unsigned char message = 0;
        !           648:        register unsigned char status_read;
        !           649: 
        !           650:        unsigned transfersize = 0, underflow = 0;
        !           651: 
        !           652:        incommand = 0;
        !           653:        st0x_aborted = 0;
        !           654: 
        !           655: #ifdef SLOW_HANDSHAKE
        !           656:        borken = (int) SCint->device->borken;
        !           657: #endif
        !           658: 
        !           659: #if (DEBUG & PRINT_COMMAND)
        !           660:        printk ("scsi%d : target = %d, command = ", hostno, target);
        !           661:        print_command((unsigned char *) cmnd);
        !           662:        printk("\n");
        !           663: #endif
        !           664: 
        !           665: #if (DEBUG & PHASE_RESELECT)
        !           666:        switch (reselect) {
        !           667:        case RECONNECT_NOW :
        !           668:                printk("scsi%d : reconnecting\n", hostno);
        !           669:                break;
        !           670: #ifdef LINKED
        !           671:        case LINKED_RIGHT : 
        !           672:                printk("scsi%d : connected, can reconnect\n", hostno);
        !           673:                break;
        !           674:        case LINKED_WRONG :
        !           675:                printk("scsi%d : connected to wrong target, can reconnect\n",
        !           676:                        hostno);
        !           677:                break;          
        !           678: #endif
        !           679:        case CAN_RECONNECT :
        !           680:                printk("scsi%d : allowed to reconnect\n", hostno);
        !           681:                break;
        !           682:        default :
        !           683:                printk("scsi%d : not allowed to reconnect\n", hostno);
        !           684:        }
        !           685: #endif
        !           686:        
        !           687: 
        !           688:        if (target == (controller_type == SEAGATE ? 7 : 6))
        !           689:                return DID_BAD_TARGET;
        !           690: 
        !           691: /*
        !           692:  *     We work it differently depending on if this is "the first time,"
        !           693:  *     or a reconnect.  If this is a reselect phase, then SEL will 
        !           694:  *     be asserted, and we must skip selection / arbitration phases.
        !           695:  */
        !           696: 
        !           697:        switch (reselect) {
        !           698:        case RECONNECT_NOW:
        !           699: #if (DEBUG & PHASE_RESELECT)
        !           700:                printk("scsi%d : phase RESELECT \n", hostno);
        !           701: #endif
        !           702: 
        !           703: /*
        !           704:  *     At this point, we should find the logical or of our ID and the original
        !           705:  *     target's ID on the BUS, with BSY, SEL, and I/O signals asserted.
        !           706:  *
        !           707:  *     After ARBITRATION phase is completed, only SEL, BSY, and the 
        !           708:  *     target ID are asserted.  A valid initiator ID is not on the bus
        !           709:  *     until IO is asserted, so we must wait for that.
        !           710:  */
        !           711:                clock = jiffies + 10;
        !           712:                for (;;) {
        !           713:                        temp = STATUS;
        !           714:                        if ((temp & STAT_IO) && !(temp & STAT_BSY))
        !           715:                                break;
        !           716: 
        !           717:                        if (jiffies > clock) {
        !           718: #if (DEBUG & PHASE_RESELECT)
        !           719:                                printk("scsi%d : RESELECT timed out while waiting for IO .\n",
        !           720:                                        hostno);
        !           721: #endif
        !           722:                                return (DID_BAD_INTR << 16);
        !           723:                        }
        !           724:                }
        !           725: 
        !           726: /* 
        !           727:  *     After I/O is asserted by the target, we can read our ID and its
        !           728:  *     ID off of the BUS.
        !           729:  */
        !           730:  
        !           731:                if (!((temp = DATA) & (controller_type == SEAGATE ? 0x80 : 0x40)))
        !           732:                        {
        !           733: #if (DEBUG & PHASE_RESELECT)
        !           734:                        printk("scsi%d : detected reconnect request to different target.\n" 
        !           735:                               "\tData bus = %d\n", hostno, temp);
        !           736: #endif
        !           737:                        return (DID_BAD_INTR << 16);
        !           738:                        }
        !           739: 
        !           740:                if (!(temp & (1 << current_target)))
        !           741:                        {
        !           742:                        printk("scsi%d : Unexpected reselect interrupt.  Data bus = %d\n",
        !           743:                                hostno, temp);
        !           744:                        return (DID_BAD_INTR << 16);
        !           745:                        }
        !           746: 
        !           747:                buffer=current_buffer;  
        !           748:                cmnd=current_cmnd;      /* WDE add */
        !           749:                data=current_data;      /* WDE add */
        !           750:                len=current_bufflen;    /* WDE add */
        !           751:                nobuffs=current_nobuffs;
        !           752: 
        !           753: /*
        !           754:  *     We have determined that we have been selected.  At this point, 
        !           755:  *     we must respond to the reselection by asserting BSY ourselves
        !           756:  */
        !           757: 
        !           758: #if 1
        !           759:                CONTROL = (BASE_CMD | CMD_DRVR_ENABLE | CMD_BSY);
        !           760: #else
        !           761:                CONTROL = (BASE_CMD | CMD_BSY);
        !           762: #endif
        !           763: 
        !           764: /*
        !           765:  *     The target will drop SEL, and raise BSY, at which time we must drop
        !           766:  *     BSY.
        !           767:  */
        !           768: 
        !           769:                for (clock = jiffies + 10; (jiffies < clock) &&  (STATUS & STAT_SEL););
        !           770: 
        !           771:                if (jiffies >= clock)
        !           772:                        { 
        !           773:                        CONTROL = (BASE_CMD | CMD_INTR);
        !           774: #if (DEBUG & PHASE_RESELECT)
        !           775:                        printk("scsi%d : RESELECT timed out while waiting for SEL.\n",
        !           776:                                hostno);
        !           777: #endif
        !           778:                        return (DID_BAD_INTR << 16);                             
        !           779:                        }
        !           780: 
        !           781:                CONTROL = BASE_CMD;
        !           782: 
        !           783: /*
        !           784:  *     At this point, we have connected with the target and can get 
        !           785:  *     on with our lives.
        !           786:  */     
        !           787:                break;
        !           788:        case CAN_RECONNECT:
        !           789: 
        !           790: #ifdef LINKED
        !           791: /*
        !           792:  * This is a bletcherous hack, just as bad as the Unix #! interpreter stuff.
        !           793:  * If it turns out we are using the wrong I_T_L nexus, the easiest way to deal
        !           794:  * with it is to go into our INFORMATION TRANSFER PHASE code, send a ABORT 
        !           795:  * message on MESSAGE OUT phase, and then loop back to here.
        !           796:  */
        !           797:   
        !           798: connect_loop :
        !           799: 
        !           800: #endif
        !           801: 
        !           802: #if (DEBUG & PHASE_BUS_FREE)
        !           803:                printk ("scsi%d : phase = BUS FREE \n", hostno);
        !           804: #endif
        !           805: 
        !           806: /*
        !           807:  *     BUS FREE PHASE
        !           808:  *
        !           809:  *     On entry, we make sure that the BUS is in a BUS FREE
        !           810:  *     phase, by insuring that both BSY and SEL are low for
        !           811:  *     at least one bus settle delay.  Several reads help
        !           812:  *     eliminate wire glitch.
        !           813:  */
        !           814: 
        !           815:                clock = jiffies + ST0X_BUS_FREE_DELAY;  
        !           816: 
        !           817: #if !defined (ARBITRATE) 
        !           818:                while (((STATUS |  STATUS | STATUS) & 
        !           819:                         (STAT_BSY | STAT_SEL)) && 
        !           820:                         (!st0x_aborted) && (jiffies < clock));
        !           821: 
        !           822:                if (jiffies > clock)
        !           823:                        return retcode(DID_BUS_BUSY);
        !           824:                else if (st0x_aborted)
        !           825:                        return retcode(st0x_aborted);
        !           826: #endif
        !           827: 
        !           828: #if (DEBUG & PHASE_SELECTION)
        !           829:                printk("scsi%d : phase = SELECTION\n", hostno);
        !           830: #endif
        !           831: 
        !           832:                clock = jiffies + ST0X_SELECTION_DELAY;
        !           833: 
        !           834: /*
        !           835:  * Arbitration/selection procedure : 
        !           836:  * 1.  Disable drivers
        !           837:  * 2.  Write HOST adapter address bit
        !           838:  * 3.  Set start arbitration.
        !           839:  * 4.  We get either ARBITRATION COMPLETE or SELECT at this
        !           840:  *     point.
        !           841:  * 5.  OR our ID and targets on bus.
        !           842:  * 6.  Enable SCSI drivers and asserted SEL and ATTN
        !           843:  */
        !           844:                
        !           845: #if defined(ARBITRATE) 
        !           846:        cli();
        !           847:        CONTROL = 0;
        !           848:        DATA = (controller_type == SEAGATE) ? 0x80 : 0x40;
        !           849:        CONTROL = CMD_START_ARB; 
        !           850:        sti();
        !           851:        while (!((status_read = STATUS) & (STAT_ARB_CMPL | STAT_SEL)) &&
        !           852:                (jiffies < clock) && !st0x_aborted);
        !           853: 
        !           854:        if (!(status_read & STAT_ARB_CMPL)) {
        !           855: #if (DEBUG & PHASE_SELECTION)
        !           856:                if (status_read & STAT_SEL) 
        !           857:                        printk("scsi%d : arbitration lost\n", hostno);
        !           858:                else
        !           859:                        printk("scsi%d : arbitration timeout.\n", hostno);
        !           860: #endif
        !           861:                CONTROL = BASE_CMD;
        !           862:                return retcode(DID_NO_CONNECT);
        !           863:        };
        !           864: 
        !           865: #if (DEBUG & PHASE_SELECTION)
        !           866:        printk("scsi%d : arbitration complete\n", hostno);
        !           867: #endif
        !           868: #endif
        !           869: 
        !           870: 
        !           871: /*
        !           872:  *     When the SCSI device decides that we're gawking at it, it will 
        !           873:  *     respond by asserting BUSY on the bus.
        !           874:  *
        !           875:  *     Note : the Seagate ST-01/02 product manual says that we should 
        !           876:  *     twiddle the DATA register before the control register.  However,
        !           877:  *     this does not work reliably so we do it the other way around.
        !           878:  *
        !           879:  *     Probably could be a problem with arbitration too, we really should
        !           880:  *     try this with a SCSI protocol or logic analyzer to see what is 
        !           881:  *     going on.
        !           882:  */
        !           883:        cli();
        !           884:        DATA = (unsigned char) ((1 << target) | (controller_type == SEAGATE ? 0x80 : 0x40));
        !           885:        CONTROL = BASE_CMD | CMD_DRVR_ENABLE | CMD_SEL | 
        !           886:                (reselect ? CMD_ATTN : 0);
        !           887:        sti();
        !           888:                while (!((status_read = STATUS) & STAT_BSY) && 
        !           889:                        (jiffies < clock) && !st0x_aborted)
        !           890: 
        !           891: #if 0 && (DEBUG & PHASE_SELECTION)
        !           892:                {
        !           893:                temp = clock - jiffies;
        !           894: 
        !           895:                if (!(jiffies % 5))
        !           896:                        printk("seagate_st0x_timeout : %d            \r",temp);
        !           897:        
        !           898:                }
        !           899:                printk("Done.                                             \n");
        !           900:                printk("scsi%d : status = %02x, seagate_st0x_timeout = %d, aborted = %02x \n", 
        !           901:                        hostno, status_read, temp, st0x_aborted);
        !           902: #else
        !           903:                ;
        !           904: #endif
        !           905:        
        !           906: 
        !           907:                if ((jiffies >= clock)  && !(status_read & STAT_BSY))
        !           908:                        {
        !           909: #if (DEBUG & PHASE_SELECTION)
        !           910:                        printk ("scsi%d : NO CONNECT with target %d, status = %x \n", 
        !           911:                                hostno, target, STATUS);
        !           912: #endif
        !           913:                        return retcode(DID_NO_CONNECT);
        !           914:                        }
        !           915: 
        !           916: /*
        !           917:  *     If we have been aborted, and we have a command in progress, IE the 
        !           918:  *     target still has BSY asserted, then we will reset the bus, and 
        !           919:  *     notify the midlevel driver to expect sense.
        !           920:  */
        !           921: 
        !           922:                if (st0x_aborted) {
        !           923:                        CONTROL = BASE_CMD;
        !           924:                        if (STATUS & STAT_BSY) {
        !           925:                                printk("scsi%d : BST asserted after we've been aborted.\n",
        !           926:                                        hostno);
        !           927:                                seagate_st0x_reset(NULL, 0);
        !           928:                                return retcode(DID_RESET);
        !           929:                        }
        !           930:                        return retcode(st0x_aborted);
        !           931:                }       
        !           932: 
        !           933: /* Establish current pointers.  Take into account scatter / gather */
        !           934: 
        !           935:        if ((nobuffs = SCint->use_sg)) {
        !           936: #if (DEBUG & DEBUG_SG)
        !           937:        {
        !           938:        int i;
        !           939:        printk("scsi%d : scatter gather requested, using %d buffers.\n",
        !           940:                hostno, nobuffs);
        !           941:        for (i = 0; i < nobuffs; ++i)
        !           942:                printk("scsi%d : buffer %d address = %08x length = %d\n",
        !           943:                        hostno, i, buffer[i].address, buffer[i].length);
        !           944:        }
        !           945: #endif
        !           946:                
        !           947:                buffer = (struct scatterlist *) SCint->buffer;
        !           948:                len = buffer->length;
        !           949:                data = (unsigned char *) buffer->address;
        !           950:        } else {
        !           951: #if (DEBUG & DEBUG_SG)
        !           952:        printk("scsi%d : scatter gather not requested.\n", hostno);
        !           953: #endif
        !           954:                buffer = NULL;
        !           955:                len = SCint->request_bufflen;
        !           956:                data = (unsigned char *) SCint->request_buffer;
        !           957:        }
        !           958: 
        !           959: #if (DEBUG & (PHASE_DATAIN | PHASE_DATAOUT))
        !           960:        printk("scsi%d : len = %d\n", hostno, len);
        !           961: #endif
        !           962: 
        !           963:                break;
        !           964: #ifdef LINKED
        !           965:        case LINKED_RIGHT:
        !           966:                break;
        !           967:        case LINKED_WRONG:
        !           968:                break;
        !           969: #endif
        !           970:        }
        !           971: 
        !           972: /*
        !           973:  *     There are several conditions under which we wish to send a message : 
        !           974:  *     1.  When we are allowing disconnect / reconnect, and need to establish
        !           975:  *         the I_T_L nexus via an IDENTIFY with the DiscPriv bit set.
        !           976:  *
        !           977:  *     2.  When we are doing linked commands, are have the wrong I_T_L nexus
        !           978:  *         established and want to send an ABORT message.
        !           979:  */
        !           980: 
        !           981:        
        !           982:        CONTROL = BASE_CMD | CMD_DRVR_ENABLE | 
        !           983:                (((reselect == CAN_RECONNECT)
        !           984: #ifdef LINKED 
        !           985:                || (reselect == LINKED_WRONG)
        !           986: #endif 
        !           987:                )  ? CMD_ATTN : 0) ;
        !           988:        
        !           989: /*
        !           990:  *     INFORMATION TRANSFER PHASE
        !           991:  *
        !           992:  *     The nasty looking read / write inline assembler loops we use for 
        !           993:  *     DATAIN and DATAOUT phases are approximately 4-5 times as fast as 
        !           994:  *     the 'C' versions - since we're moving 1024 bytes of data, this
        !           995:  *     really adds up.
        !           996:  */
        !           997: 
        !           998: #if ((DEBUG & PHASE_ETC) == PHASE_ETC)
        !           999:        printk("scsi%d : phase = INFORMATION TRANSFER\n", hostno);
        !          1000: #endif  
        !          1001: 
        !          1002:        incommand = 1;
        !          1003:        transfersize = SCint->transfersize;
        !          1004:        underflow = SCint->underflow;
        !          1005: 
        !          1006: 
        !          1007: /*
        !          1008:  *     Now, we poll the device for status information,
        !          1009:  *     and handle any requests it makes.  Note that since we are unsure of 
        !          1010:  *     how much data will be flowing across the system, etc and cannot 
        !          1011:  *     make reasonable timeouts, that we will instead have the midlevel
        !          1012:  *     driver handle any timeouts that occur in this phase.
        !          1013:  */
        !          1014: 
        !          1015:        while (((status_read = STATUS) & STAT_BSY) && !st0x_aborted && !done) 
        !          1016:                {
        !          1017: #ifdef PARITY
        !          1018:                if (status_read & STAT_PARITY)
        !          1019:                        {
        !          1020:                        printk("scsi%d : got parity error\n", hostno);
        !          1021:                        st0x_aborted = DID_PARITY;
        !          1022:                        }       
        !          1023: #endif
        !          1024: 
        !          1025:                if (status_read & STAT_REQ)
        !          1026:                        {
        !          1027: #if ((DEBUG & PHASE_ETC) == PHASE_ETC)
        !          1028:                        if ((newphase = (status_read & REQ_MASK)) != phase)
        !          1029:                                {
        !          1030:                                phase = newphase;
        !          1031:                                switch (phase)
        !          1032:                                {
        !          1033:                                case REQ_DATAOUT: 
        !          1034:                                        printk("scsi%d : phase = DATA OUT\n",
        !          1035:                                                hostno); 
        !          1036:                                        break;
        !          1037:                                case REQ_DATAIN : 
        !          1038:                                        printk("scsi%d : phase = DATA IN\n",
        !          1039:                                                hostno); 
        !          1040:                                        break;
        !          1041:                                case REQ_CMDOUT : 
        !          1042:                                        printk("scsi%d : phase = COMMAND OUT\n",
        !          1043:                                                hostno); 
        !          1044:                                        break;
        !          1045:                                case REQ_STATIN :
        !          1046:                                         printk("scsi%d : phase = STATUS IN\n",
        !          1047:                                                hostno); 
        !          1048:                                        break;
        !          1049:                                case REQ_MSGOUT :
        !          1050:                                        printk("scsi%d : phase = MESSAGE OUT\n",
        !          1051:                                                hostno); 
        !          1052:                                        break;
        !          1053:                                case REQ_MSGIN :
        !          1054:                                        printk("scsi%d : phase = MESSAGE IN\n",
        !          1055:                                                hostno);
        !          1056:                                        break;
        !          1057:                                default : 
        !          1058:                                        printk("scsi%d : phase = UNKNOWN\n",
        !          1059:                                                hostno); 
        !          1060:                                        st0x_aborted = DID_ERROR; 
        !          1061:                                }       
        !          1062:                                }
        !          1063: #endif
        !          1064:                switch (status_read & REQ_MASK)
        !          1065:                {                       
        !          1066:                case REQ_DATAOUT : 
        !          1067: /*
        !          1068:  * If we are in fast mode, then we simply splat the data out
        !          1069:  * in word-sized chunks as fast as we can.
        !          1070:  */
        !          1071: 
        !          1072: #ifdef FAST 
        !          1073: if (!len) {
        !          1074: #if 0 
        !          1075:        printk("scsi%d: underflow to target %d lun %d \n", 
        !          1076:                hostno, target, lun);
        !          1077:        st0x_aborted = DID_ERROR;
        !          1078:        fast = 0;
        !          1079: #endif
        !          1080:        break;
        !          1081: }
        !          1082: 
        !          1083: if (fast && transfersize && !(len % transfersize) && (len >= transfersize)
        !          1084: #ifdef FAST32
        !          1085:        && !(transfersize % 4)
        !          1086: #endif
        !          1087:        ) {
        !          1088: #if (DEBUG & DEBUG_FAST) 
        !          1089:        printk("scsi%d : FAST transfer, underflow = %d, transfersize = %d\n"
        !          1090:               "         len = %d, data = %08x\n", hostno, SCint->underflow, 
        !          1091:               SCint->transfersize, len, data);
        !          1092: #endif
        !          1093: 
        !          1094:        __asm__("
        !          1095:        cld;
        !          1096: "
        !          1097: #ifdef FAST32
        !          1098: "      shr $2, %%ecx;
        !          1099: 1:     lodsl;
        !          1100:        movl %%eax, (%%edi);
        !          1101: "
        !          1102: #else
        !          1103: "1:    lodsb;
        !          1104:        movb %%al, (%%edi);
        !          1105: "
        !          1106: #endif
        !          1107: "      loop 1b;" : :
        !          1108:        /* input */
        !          1109:        "D" (st0x_dr), "S" (data), "c" (SCint->transfersize) :
        !          1110:        /* clobbered */
        !          1111:        "eax", "ecx", "esi" );
        !          1112: 
        !          1113:        len -= transfersize;
        !          1114:        data += transfersize;
        !          1115: 
        !          1116: #if (DEBUG & DEBUG_FAST)
        !          1117:        printk("scsi%d : FAST transfer complete len = %d data = %08x\n", 
        !          1118:                hostno, len, data);
        !          1119: #endif
        !          1120: 
        !          1121: 
        !          1122: } else 
        !          1123: #endif
        !          1124: 
        !          1125: {
        !          1126: /*
        !          1127:  *     We loop as long as we are in a data out phase, there is data to send, 
        !          1128:  *     and BSY is still active.
        !          1129:  */
        !          1130:                __asm__ (
        !          1131: 
        !          1132: /*
        !          1133:        Local variables : 
        !          1134:        len = ecx
        !          1135:        data = esi
        !          1136:        st0x_cr_sr = ebx
        !          1137:        st0x_dr =  edi
        !          1138: 
        !          1139:        Test for any data here at all.
        !          1140: */
        !          1141:        "\torl %%ecx, %%ecx
        !          1142:        jz 2f
        !          1143: 
        !          1144:        cld
        !          1145: 
        !          1146:        movl " SYMBOL_NAME_STR(st0x_cr_sr) ", %%ebx
        !          1147:        movl " SYMBOL_NAME_STR(st0x_dr) ", %%edi
        !          1148:        
        !          1149: 1:     movb (%%ebx), %%al\n"
        !          1150: /*
        !          1151:        Test for BSY
        !          1152: */
        !          1153: 
        !          1154:        "\ttest $1, %%al
        !          1155:        jz 2f\n"
        !          1156: 
        !          1157: /*
        !          1158:        Test for data out phase - STATUS & REQ_MASK should be REQ_DATAOUT, which is 0.
        !          1159: */
        !          1160:        "\ttest $0xe, %%al
        !          1161:        jnz 2f  \n"
        !          1162: /*
        !          1163:        Test for REQ
        !          1164: */     
        !          1165:        "\ttest $0x10, %%al
        !          1166:        jz 1b
        !          1167:        lodsb
        !          1168:        movb %%al, (%%edi) 
        !          1169:        loop 1b
        !          1170: 
        !          1171: 2: 
        !          1172:                                                                        ":
        !          1173: /* output */
        !          1174: "=S" (data), "=c" (len) :
        !          1175: /* input */
        !          1176: "0" (data), "1" (len) :
        !          1177: /* clobbered */
        !          1178: "eax", "ebx", "edi"); 
        !          1179: }
        !          1180: 
        !          1181:                        if (!len && nobuffs) {
        !          1182:                                --nobuffs;
        !          1183:                                ++buffer;
        !          1184:                                len = buffer->length;
        !          1185:                                data = (unsigned char *) buffer->address;
        !          1186: #if (DEBUG & DEBUG_SG)
        !          1187:        printk("scsi%d : next scatter-gather buffer len = %d address = %08x\n",
        !          1188:                hostno, len, data);
        !          1189: #endif
        !          1190:                        }
        !          1191:                        break;
        !          1192: 
        !          1193:                case REQ_DATAIN : 
        !          1194: #ifdef SLOW_HANDSHAKE
        !          1195:        if (borken) {
        !          1196: #if (DEBUG & (PHASE_DATAIN))
        !          1197:                transfered += len;
        !          1198: #endif
        !          1199:                for (; len && (STATUS & (REQ_MASK | STAT_REQ)) == (REQ_DATAIN |
        !          1200:                        STAT_REQ); --len) {
        !          1201:                                *data++ = DATA;
        !          1202:                                borken_wait();
        !          1203: }
        !          1204: #if (DEBUG & (PHASE_DATAIN))
        !          1205:                transfered -= len;
        !          1206: #endif
        !          1207:        } else
        !          1208: #endif
        !          1209: #ifdef FAST
        !          1210: if (fast && transfersize && !(len % transfersize) && (len >= transfersize)
        !          1211: #ifdef FAST32
        !          1212:        && !(transfersize % 4)
        !          1213: #endif
        !          1214:        ) {
        !          1215: #if (DEBUG & DEBUG_FAST) 
        !          1216:        printk("scsi%d : FAST transfer, underflow = %d, transfersize = %d\n"
        !          1217:               "         len = %d, data = %08x\n", hostno, SCint->underflow, 
        !          1218:               SCint->transfersize, len, data);
        !          1219: #endif
        !          1220:        __asm__("
        !          1221:        cld;
        !          1222: "
        !          1223: #ifdef FAST32
        !          1224: "      shr $2, %%ecx;
        !          1225: 1:     movl (%%esi), %%eax;
        !          1226:        stosl;
        !          1227: "
        !          1228: #else
        !          1229: "1:    movb (%%esi), %%al;
        !          1230:        stosb;
        !          1231: "
        !          1232: #endif
        !          1233: 
        !          1234: "      loop 1b;" : :
        !          1235:        /* input */
        !          1236:        "S" (st0x_dr), "D" (data), "c" (SCint->transfersize) :
        !          1237:        /* clobbered */
        !          1238:        "eax", "ecx", "edi");
        !          1239: 
        !          1240:        len -= transfersize;
        !          1241:        data += transfersize;
        !          1242: 
        !          1243: #if (DEBUG & PHASE_DATAIN)
        !          1244:        printk("scsi%d: transfered += %d\n", hostno, transfersize);
        !          1245:        transfered += transfersize;
        !          1246: #endif
        !          1247: 
        !          1248: #if (DEBUG & DEBUG_FAST)
        !          1249:        printk("scsi%d : FAST transfer complete len = %d data = %08x\n", 
        !          1250:                hostno, len, data);
        !          1251: #endif
        !          1252: 
        !          1253: } else
        !          1254: #endif
        !          1255: {
        !          1256: 
        !          1257: #if (DEBUG & PHASE_DATAIN)
        !          1258:        printk("scsi%d: transfered += %d\n", hostno, len);
        !          1259:        transfered += len;      /* Assume we'll transfer it all, then
        !          1260:                                   subtract what we *didn't* transfer */
        !          1261: #endif
        !          1262:        
        !          1263: /*
        !          1264:  *     We loop as long as we are in a data in phase, there is room to read, 
        !          1265:  *     and BSY is still active
        !          1266:  */
        !          1267:  
        !          1268:                        __asm__ (
        !          1269: /*
        !          1270:        Local variables : 
        !          1271:        ecx = len
        !          1272:        edi = data
        !          1273:        esi = st0x_cr_sr
        !          1274:        ebx = st0x_dr
        !          1275: 
        !          1276:        Test for room to read
        !          1277: */
        !          1278:        "\torl %%ecx, %%ecx
        !          1279:        jz 2f
        !          1280: 
        !          1281:        cld
        !          1282:        movl " SYMBOL_NAME_STR(st0x_cr_sr) ", %%esi
        !          1283:        movl " SYMBOL_NAME_STR(st0x_dr) ", %%ebx
        !          1284: 
        !          1285: 1:     movb (%%esi), %%al\n"
        !          1286: /*
        !          1287:        Test for BSY
        !          1288: */
        !          1289: 
        !          1290:        "\ttest $1, %%al 
        !          1291:        jz 2f\n"
        !          1292: 
        !          1293: /*
        !          1294:        Test for data in phase - STATUS & REQ_MASK should be REQ_DATAIN, = STAT_IO, which is 4.
        !          1295: */
        !          1296:        "\tmovb $0xe, %%ah      
        !          1297:        andb %%al, %%ah
        !          1298:        cmpb $0x04, %%ah
        !          1299:        jne 2f\n"
        !          1300:                
        !          1301: /*
        !          1302:        Test for REQ
        !          1303: */     
        !          1304:        "\ttest $0x10, %%al
        !          1305:        jz 1b
        !          1306: 
        !          1307:        movb (%%ebx), %%al      
        !          1308:        stosb   
        !          1309:        loop 1b\n"
        !          1310: 
        !          1311: "2:\n"
        !          1312:                                                                        :
        !          1313: /* output */
        !          1314: "=D" (data), "=c" (len) :
        !          1315: /* input */
        !          1316: "0" (data), "1" (len) :
        !          1317: /* clobbered */
        !          1318: "eax","ebx", "esi"); 
        !          1319: 
        !          1320: #if (DEBUG & PHASE_DATAIN)
        !          1321:        printk("scsi%d: transfered -= %d\n", hostno, len);
        !          1322:        transfered -= len;              /* Since we assumed all of Len got 
        !          1323:                                         * transfered, correct our mistake */
        !          1324: #endif
        !          1325: }
        !          1326:        
        !          1327:                        if (!len && nobuffs) {
        !          1328:                                --nobuffs;
        !          1329:                                ++buffer;
        !          1330:                                len = buffer->length;
        !          1331:                                data = (unsigned char *) buffer->address;
        !          1332: #if (DEBUG & DEBUG_SG)
        !          1333:        printk("scsi%d : next scatter-gather buffer len = %d address = %08x\n",
        !          1334:                hostno, len, data);
        !          1335: #endif
        !          1336:                        }
        !          1337: 
        !          1338:                        break;
        !          1339: 
        !          1340:                case REQ_CMDOUT : 
        !          1341:                        while (((status_read = STATUS) & STAT_BSY) && 
        !          1342:                               ((status_read & REQ_MASK) == REQ_CMDOUT))
        !          1343:                                if (status_read & STAT_REQ) {
        !          1344:                                        DATA = *(const unsigned char *) cmnd;
        !          1345:                                        cmnd = 1+(const unsigned char *) cmnd;
        !          1346: #ifdef SLOW_HANDSHAKE
        !          1347:                                        if (borken) 
        !          1348:                                                borken_wait();
        !          1349: #endif
        !          1350:                                }
        !          1351:                        break;
        !          1352:        
        !          1353:                case REQ_STATIN : 
        !          1354:                        status = DATA;
        !          1355:                        break;
        !          1356:                                
        !          1357:                case REQ_MSGOUT : 
        !          1358: /*
        !          1359:  *     We can only have sent a MSG OUT if we requested to do this 
        !          1360:  *     by raising ATTN.  So, we must drop ATTN.
        !          1361:  */
        !          1362: 
        !          1363:                        CONTROL = BASE_CMD | CMD_DRVR_ENABLE;
        !          1364: /*
        !          1365:  *     If we are reconnecting, then we must send an IDENTIFY message in 
        !          1366:  *      response  to MSGOUT.
        !          1367:  */
        !          1368:                        switch (reselect) {
        !          1369:                        case CAN_RECONNECT:
        !          1370:                                DATA = IDENTIFY(1, lun);
        !          1371: 
        !          1372: #if (DEBUG & (PHASE_RESELECT | PHASE_MSGOUT)) 
        !          1373:                                printk("scsi%d : sent IDENTIFY message.\n", hostno);
        !          1374: #endif
        !          1375:                                break;
        !          1376: #ifdef LINKED
        !          1377:                        case LINKED_WRONG:
        !          1378:                                DATA = ABORT;
        !          1379:                                linked_connected = 0;
        !          1380:                                reselect = CAN_RECONNECT;
        !          1381:                                goto connect_loop;
        !          1382: #if (DEBUG & (PHASE_MSGOUT | DEBUG_LINKED))
        !          1383:                                printk("scsi%d : sent ABORT message to cancel incorrect I_T_L nexus.\n", hostno);
        !          1384: #endif
        !          1385: #endif /* LINKED */
        !          1386: #if (DEBUG & DEBUG_LINKED) 
        !          1387:            printk("correct\n");
        !          1388: #endif
        !          1389:                        default:
        !          1390:                                DATA = NOP;
        !          1391:                                printk("scsi%d : target %d requested MSGOUT, sent NOP message.\n", hostno, target);
        !          1392:                        }
        !          1393:                        break;
        !          1394:                                        
        !          1395:                case REQ_MSGIN : 
        !          1396:                        switch (message = DATA) {
        !          1397:                        case DISCONNECT :
        !          1398:                                should_reconnect = 1;
        !          1399:                                current_data = data;    /* WDE add */
        !          1400:                                current_buffer = buffer;
        !          1401:                                current_bufflen = len;  /* WDE add */
        !          1402:                                current_nobuffs = nobuffs;
        !          1403: #ifdef LINKED
        !          1404:                                linked_connected = 0;
        !          1405: #endif
        !          1406:                                done=1;
        !          1407: #if (DEBUG & (PHASE_RESELECT | PHASE_MSGIN))
        !          1408:                                printk("scsi%d : disconnected.\n", hostno);
        !          1409: #endif
        !          1410:                                break;
        !          1411: 
        !          1412: #ifdef LINKED
        !          1413:                        case LINKED_CMD_COMPLETE:
        !          1414:                        case LINKED_FLG_CMD_COMPLETE:
        !          1415: #endif
        !          1416:                        case COMMAND_COMPLETE :
        !          1417: /*
        !          1418:  * Note : we should check for underflow here.   
        !          1419:  */
        !          1420: #if (DEBUG & PHASE_MSGIN)      
        !          1421:                                printk("scsi%d : command complete.\n", hostno);
        !          1422: #endif
        !          1423:                                done = 1;
        !          1424:                                break;
        !          1425:                        case ABORT :
        !          1426: #if (DEBUG & PHASE_MSGIN)
        !          1427:                                printk("scsi%d : abort message.\n", hostno);
        !          1428: #endif
        !          1429:                                done=1;
        !          1430:                                break;
        !          1431:                        case SAVE_POINTERS :
        !          1432:                                current_buffer = buffer;
        !          1433:                                current_bufflen = len;  /* WDE add */
        !          1434:                                current_data = data;    /* WDE mod */
        !          1435:                                current_nobuffs = nobuffs;
        !          1436: #if (DEBUG & PHASE_MSGIN)
        !          1437:                                printk("scsi%d : pointers saved.\n", hostno);
        !          1438: #endif 
        !          1439:                                break;
        !          1440:                        case RESTORE_POINTERS:
        !          1441:                                buffer=current_buffer;
        !          1442:                                cmnd=current_cmnd;
        !          1443:                                data=current_data;      /* WDE mod */
        !          1444:                                len=current_bufflen;
        !          1445:                                nobuffs=current_nobuffs;
        !          1446: #if (DEBUG & PHASE_MSGIN)
        !          1447:                                printk("scsi%d : pointers restored.\n", hostno);
        !          1448: #endif
        !          1449:                                break;
        !          1450:                        default:
        !          1451: 
        !          1452: /*
        !          1453:  *     IDENTIFY distinguishes itself from the other messages by setting the
        !          1454:  *     high byte.
        !          1455:  *     
        !          1456:  *     Note : we need to handle at least one outstanding command per LUN,
        !          1457:  *     and need to hash the SCSI command for that I_T_L nexus based on the 
        !          1458:  *     known ID (at this point) and LUN.
        !          1459:  */
        !          1460: 
        !          1461:                                if (message & 0x80) {
        !          1462: #if (DEBUG & PHASE_MSGIN)
        !          1463:                                        printk("scsi%d : IDENTIFY message received from id %d, lun %d.\n",
        !          1464:                                                hostno, target, message & 7);
        !          1465: #endif
        !          1466:                                } else {
        !          1467: 
        !          1468: /*
        !          1469:  *      We should go into a MESSAGE OUT phase, and send  a MESSAGE_REJECT 
        !          1470:  *     if we run into a message that we don't like.  The seagate driver 
        !          1471:  *     needs some serious restructuring first though.
        !          1472:  */
        !          1473: 
        !          1474: #if (DEBUG & PHASE_MSGIN)
        !          1475:                                        printk("scsi%d : unknown message %d from target %d.\n",
        !          1476:                                                hostno,  message,   target);
        !          1477: #endif 
        !          1478:                                }
        !          1479:                        }
        !          1480:                        break;
        !          1481: 
        !          1482:                default : 
        !          1483:                        printk("scsi%d : unknown phase.\n", hostno); 
        !          1484:                        st0x_aborted = DID_ERROR; 
        !          1485:                }       
        !          1486: 
        !          1487: #ifdef SLOW_HANDSHAKE
        !          1488: /*
        !          1489:  * I really don't care to deal with borken devices in each single 
        !          1490:  * byte transfer case (ie, message in, message out, status), so
        !          1491:  * I'll do the wait here if necessary.
        !          1492:  */
        !          1493:                if (borken)
        !          1494:                        borken_wait();
        !          1495: #endif
        !          1496:  
        !          1497:                } /* if ends */
        !          1498:                } /* while ends */
        !          1499: 
        !          1500: #if (DEBUG & (PHASE_DATAIN | PHASE_DATAOUT | PHASE_EXIT))
        !          1501:        printk("scsi%d : Transfered %d bytes\n", hostno, transfered);
        !          1502: #endif
        !          1503: 
        !          1504: #if (DEBUG & PHASE_EXIT)
        !          1505: #if 0          /* Doesn't work for scatter / gather */
        !          1506:        printk("Buffer : \n");
        !          1507:        for (i = 0; i < 20; ++i) 
        !          1508:                printk ("%02x  ", ((unsigned char *) data)[i]); /* WDE mod */
        !          1509:        printk("\n");
        !          1510: #endif
        !          1511:        printk("scsi%d : status = ", hostno);
        !          1512:        print_status(status);
        !          1513:        printk("message = %02x\n", message);
        !          1514: #endif
        !          1515: 
        !          1516: 
        !          1517: /* We shouldn't reach this until *after* BSY has been deasserted */
        !          1518: #ifdef notyet
        !          1519:        if (st0x_aborted) {
        !          1520:                if (STATUS & STAT_BSY) {        
        !          1521:                        seagate_st0x_reset(NULL);
        !          1522:                        st0x_aborted = DID_RESET;
        !          1523:                } 
        !          1524:                abort_confirm = 1;
        !          1525:        } 
        !          1526: #endif
        !          1527: 
        !          1528: #ifdef LINKED
        !          1529: else {
        !          1530: /*
        !          1531:  * Fix the message byte so that unsuspecting high level drivers don't 
        !          1532:  * puke when they see a LINKED COMMAND message in place of the COMMAND 
        !          1533:  * COMPLETE they may be expecting.  Shouldn't be necessary, but it's 
        !          1534:  * better to be on the safe side. 
        !          1535:  *
        !          1536:  * A non LINKED* message byte will indicate that the command completed, 
        !          1537:  * and we are now disconnected.
        !          1538:  */
        !          1539: 
        !          1540:                switch (message) {
        !          1541:                case LINKED_CMD_COMPLETE :
        !          1542:                case LINKED_FLG_CMD_COMPLETE : 
        !          1543:                        message = COMMAND_COMPLETE;
        !          1544:                        linked_target = current_target;
        !          1545:                        linked_lun = current_lun;
        !          1546:                        linked_connected = 1;
        !          1547: #if (DEBUG & DEBUG_LINKED)
        !          1548:                        printk("scsi%d : keeping I_T_L nexus established for linked command.\n", 
        !          1549:                                hostno);
        !          1550: #endif
        !          1551: /*
        !          1552:  * We also will need to adjust status to accommodate intermediate conditions.
        !          1553:  */
        !          1554:                        if ((status == INTERMEDIATE_GOOD) ||
        !          1555:                                (status == INTERMEDIATE_C_GOOD))
        !          1556:                                status = GOOD;
        !          1557:                        
        !          1558:                        break;
        !          1559: /*
        !          1560:  * We should also handle what are "normal" termination messages 
        !          1561:  * here (ABORT, BUS_DEVICE_RESET?, and COMMAND_COMPLETE individually, 
        !          1562:  * and flake if things aren't right.
        !          1563:  */
        !          1564: 
        !          1565:                default :
        !          1566: #if (DEBUG & DEBUG_LINKED)
        !          1567:                        printk("scsi%d : closing I_T_L nexus.\n", hostno);
        !          1568: #endif
        !          1569:                        linked_connected = 0;
        !          1570:                }
        !          1571:        }
        !          1572: #endif /* LINKED */
        !          1573: 
        !          1574: 
        !          1575: 
        !          1576: 
        !          1577:        if (should_reconnect) {
        !          1578: #if (DEBUG & PHASE_RESELECT)
        !          1579:                printk("scsi%d : exiting seagate_st0x_queue_command() with reconnect enabled.\n",
        !          1580:                        hostno);
        !          1581: #endif
        !          1582:                CONTROL = BASE_CMD | CMD_INTR ;
        !          1583:        } else 
        !          1584:                CONTROL = BASE_CMD;
        !          1585: 
        !          1586:        return retcode (st0x_aborted);
        !          1587:        }
        !          1588: 
        !          1589: int seagate_st0x_abort (Scsi_Cmnd * SCpnt)
        !          1590:        {
        !          1591:          st0x_aborted = DID_ABORT;
        !          1592:          
        !          1593:          return SCSI_ABORT_PENDING;
        !          1594:        }
        !          1595: 
        !          1596: /*
        !          1597:        the seagate_st0x_reset function resets the SCSI bus
        !          1598: */
        !          1599:        
        !          1600: int seagate_st0x_reset (Scsi_Cmnd * SCpnt, unsigned int reset_flags)
        !          1601:        {
        !          1602:        unsigned clock;
        !          1603:        /*
        !          1604:                No timeouts - this command is going to fail because 
        !          1605:                it was reset.
        !          1606:        */
        !          1607: 
        !          1608: #ifdef DEBUG
        !          1609:        printk("In seagate_st0x_reset()\n");
        !          1610: #endif
        !          1611: 
        !          1612: 
        !          1613:        /* assert  RESET signal on SCSI bus.  */
        !          1614:                
        !          1615:        CONTROL = BASE_CMD  | CMD_RST;
        !          1616:        clock=jiffies+2;
        !          1617: 
        !          1618:        
        !          1619:        /* Wait.  */
        !          1620:        
        !          1621:        while (jiffies < clock);
        !          1622: 
        !          1623:        CONTROL = BASE_CMD;
        !          1624:        
        !          1625:        st0x_aborted = DID_RESET;
        !          1626: 
        !          1627: #ifdef DEBUG
        !          1628:        printk("SCSI bus reset.\n");
        !          1629: #endif
        !          1630:        return SCSI_RESET_WAKEUP;
        !          1631:        }
        !          1632: 
        !          1633: #include <asm/segment.h>
        !          1634: #include "sd.h"
        !          1635: #include <scsi/scsi_ioctl.h>
        !          1636: 
        !          1637: int seagate_st0x_biosparam(Disk * disk, kdev_t dev, int* ip) {
        !          1638:   unsigned char buf[256 + sizeof(int) * 2], cmd[6], *data, *page;
        !          1639:   int *sizes, result, formatted_sectors, total_sectors;
        !          1640:   int cylinders, heads, sectors;
        !          1641:   int capacity;
        !          1642: 
        !          1643: /*
        !          1644:  * Only SCSI-I CCS drives and later implement the necessary mode sense 
        !          1645:  * pages.  
        !          1646:  */
        !          1647: 
        !          1648:   if (disk->device->scsi_level < 2) 
        !          1649:        return -1;
        !          1650: 
        !          1651:   sizes = (int *) buf;
        !          1652:   data = (unsigned char *) (sizes + 2);
        !          1653: 
        !          1654:   cmd[0] = MODE_SENSE;
        !          1655:   cmd[1] = (disk->device->lun << 5) & 0xe5;
        !          1656:   cmd[2] = 0x04; /* Read page 4, rigid disk geometry page current values */
        !          1657:   cmd[3] = 0;
        !          1658:   cmd[4] = 255;
        !          1659:   cmd[5] = 0;
        !          1660: 
        !          1661: /*
        !          1662:  * We are transferring 0 bytes in the out direction, and expect to get back
        !          1663:  * 24 bytes for each mode page.
        !          1664:  */
        !          1665: 
        !          1666:   sizes[0] = 0;
        !          1667:   sizes[1] = 256;
        !          1668: 
        !          1669:   memcpy (data, cmd, 6);
        !          1670: 
        !          1671:   if (!(result = kernel_scsi_ioctl (disk->device, SCSI_IOCTL_SEND_COMMAND, (void *) buf))) {
        !          1672: /*
        !          1673:  * The mode page lies beyond the MODE SENSE header, with length 4, and 
        !          1674:  * the BLOCK DESCRIPTOR, with length header[3].
        !          1675:  */
        !          1676: 
        !          1677:     page = data + 4 + data[3];
        !          1678:     heads = (int) page[5];
        !          1679:     cylinders = (page[2] << 16) | (page[3] << 8) | page[4];
        !          1680: 
        !          1681:     cmd[2] = 0x03; /* Read page 3, format page current values */
        !          1682:     memcpy (data, cmd, 6);
        !          1683: 
        !          1684:     if (!(result = kernel_scsi_ioctl (disk->device, SCSI_IOCTL_SEND_COMMAND, (void *) buf))) {
        !          1685:       page = data + 4 + data[3];
        !          1686:       sectors = (page[10] << 8) | page[11];    
        !          1687: 
        !          1688:        
        !          1689: /*
        !          1690:  * Get the total number of formatted sectors from the block descriptor, 
        !          1691:  * so we can tell how many are being used for alternates.  
        !          1692:  */
        !          1693: 
        !          1694:       formatted_sectors = (data[4 + 1] << 16) | (data[4 + 2] << 8) |
        !          1695:        data[4 + 3] ;
        !          1696: 
        !          1697:       total_sectors = (heads * cylinders * sectors);
        !          1698: 
        !          1699: /*
        !          1700:  * Adjust the real geometry by subtracting 
        !          1701:  * (spare sectors / (heads * tracks)) cylinders from the number of cylinders.
        !          1702:  *
        !          1703:  * It appears that the CE cylinder CAN be a partial cylinder.
        !          1704:  */
        !          1705: 
        !          1706:      
        !          1707: printk("scsi%d : heads = %d cylinders = %d sectors = %d total = %d formatted = %d\n",
        !          1708:     hostno, heads, cylinders, sectors, total_sectors, formatted_sectors);
        !          1709: 
        !          1710:       if (!heads || !sectors || !cylinders)
        !          1711:        result = -1;
        !          1712:       else
        !          1713:        cylinders -= ((total_sectors - formatted_sectors) / (heads * sectors));
        !          1714: 
        !          1715: /*
        !          1716:  * Now, we need to do a sanity check on the geometry to see if it is 
        !          1717:  * BIOS compatible.  The maximum BIOS geometry is 1024 cylinders * 
        !          1718:  * 256 heads * 64 sectors. 
        !          1719:  */
        !          1720: 
        !          1721:       if ((cylinders > 1024) || (sectors > 64)) {
        !          1722:        /* The Seagate's seem to have some mapping
        !          1723:         * Multiple heads * sectors * cyl to get capacity
        !          1724:         * Then start rounding down. */
        !          1725:        capacity = heads * sectors * cylinders;
        !          1726:        sectors = 17;   /* Old MFM Drives use this, so does the Seagate */
        !          1727:        heads = 2;
        !          1728:        capacity = capacity / sectors;
        !          1729:        while (cylinders > 1024)
        !          1730:        {
        !          1731:                heads *= 2;     /* For some reason, they go in multiples */
        !          1732:                cylinders = capacity / heads;
        !          1733:        }
        !          1734:       }
        !          1735:       ip[0] = heads;
        !          1736:       ip[1] = sectors;
        !          1737:       ip[2] = cylinders;
        !          1738: 
        !          1739: /* 
        !          1740:  * There should be an alternate mapping for things the seagate doesn't
        !          1741:  * understand, but I couldn't say what it is with reasonable certainty.
        !          1742:  */
        !          1743: 
        !          1744:       }
        !          1745:     }
        !          1746:     
        !          1747:   return result;
        !          1748: }
        !          1749: 
        !          1750: #ifdef MODULE
        !          1751: /* Eventually this will go into an include file, but this will be later */
        !          1752: Scsi_Host_Template driver_template = SEAGATE_ST0X;
        !          1753: 
        !          1754: #include "scsi_module.c"
        !          1755: #endif

unix.superglobalmegacorp.com

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