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

unix.superglobalmegacorp.com

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