Annotation of Gnu-Mach/linux/src/drivers/scsi/hosts.h, revision 1.1

1.1     ! root        1: /*
        !             2:  *  hosts.h Copyright (C) 1992 Drew Eckhardt 
        !             3:  *          Copyright (C) 1993, 1994, 1995 Eric Youngdale
        !             4:  *
        !             5:  *  mid to low-level SCSI driver interface header
        !             6:  *      Initial versions: Drew Eckhardt
        !             7:  *      Subsequent revisions: Eric Youngdale
        !             8:  *
        !             9:  *  <[email protected]>
        !            10:  *
        !            11:  *      Modified by Eric Youngdale [email protected] to
        !            12:  *      add scatter-gather, multiple outstanding request, and other
        !            13:  *      enhancements.
        !            14:  * 
        !            15:  *  Further modified by Eric Youngdale to support multiple host adapters
        !            16:  *  of the same type.
        !            17:  */
        !            18: 
        !            19: #ifndef _HOSTS_H
        !            20: #define _HOSTS_H
        !            21: 
        !            22: /*
        !            23:     $Header: /afs/sipb.mit.edu/project/hurddev/cvsroot/gnumach/linux/src/drivers/scsi/hosts.h,v 1.1 1999/04/26 05:54:41 tb Exp $
        !            24: */
        !            25: 
        !            26: #include <linux/proc_fs.h>
        !            27: 
        !            28: /* It is senseless to set SG_ALL any higher than this - the performance
        !            29:  *  does not get any better, and it wastes memory 
        !            30:  */
        !            31: #define SG_NONE 0
        !            32: #define SG_ALL 0xff
        !            33: 
        !            34: #define DISABLE_CLUSTERING 0
        !            35: #define ENABLE_CLUSTERING 1
        !            36: 
        !            37: /* The various choices mean:
        !            38:  * NONE: Self evident. Host adapter is not capable of scatter-gather.
        !            39:  * ALL:         Means that the host adapter module can do scatter-gather,
        !            40:  *      and that there is no limit to the size of the table to which
        !            41:  *      we scatter/gather data.
        !            42:  * Anything else:  Indicates the maximum number of chains that can be
        !            43:  *      used in one scatter-gather request.
        !            44:  */
        !            45: 
        !            46: /*
        !            47:  * The Scsi_Host_Template type has all that is needed to interface with a SCSI
        !            48:  * host in a device independent matter.         There is one entry for each different
        !            49:  * type of host adapter that is supported on the system.
        !            50:  */
        !            51: 
        !            52: typedef struct scsi_disk Disk;
        !            53: 
        !            54: typedef struct SHT
        !            55: {
        !            56:     
        !            57:     /* Used with loadable modules so we can construct a linked list. */
        !            58:     struct SHT * next;
        !            59:     
        !            60:     /* Used with loadable modules so that we know when it is safe to unload */
        !            61:     long * usage_count;
        !            62:     
        !            63:     /* The pointer to the /proc/scsi directory entry */
        !            64:     struct proc_dir_entry *proc_dir;
        !            65: 
        !            66:     /* proc-fs info function.
        !            67:      * Can be used to export driver statistics and other infos to the world 
        !            68:      * outside the kernel ie. userspace and it also provides an interface
        !            69:      * to feed the driver with information. Check eata_dma_proc.c for reference
        !            70:      */
        !            71:     int (*proc_info)(char *, char **, off_t, int, int, int);
        !            72: 
        !            73:     /*
        !            74:      * The name pointer is a pointer to the name of the SCSI
        !            75:      * device detected.
        !            76:      */
        !            77:     const char *name;
        !            78:     
        !            79:     /*
        !            80:      * The detect function shall return non zero on detection,
        !            81:      * indicating the number of host adapters of this particular
        !            82:      * type were found.         It should also
        !            83:      * initialize all data necessary for this particular
        !            84:      * SCSI driver.  It is passed the host number, so this host
        !            85:      * knows where the first entry is in the scsi_hosts[] array.
        !            86:      * 
        !            87:      * Note that the detect routine MUST not call any of the mid level
        !            88:      * functions to queue commands because things are not guaranteed
        !            89:      * to be set up yet.  The detect routine can send commands to
        !            90:      * the host adapter as long as the program control will not be
        !            91:      * passed to scsi.c in the processing of the command.  Note
        !            92:      * especially that scsi_malloc/scsi_free must not be called.
        !            93:      */
        !            94:     int (* detect)(struct SHT *); 
        !            95:     
        !            96:     /* Used with loadable modules to unload the host structures.  Note:
        !            97:      * there is a default action built into the modules code which may
        !            98:      * be sufficient for most host adapters.  Thus you may not have to supply
        !            99:      * this at all. 
        !           100:      */
        !           101:     int (*release)(struct Scsi_Host *);
        !           102: 
        !           103:     /*
        !           104:      * The info function will return whatever useful
        !           105:      * information the developer sees fit.  If not provided, then
        !           106:      * the name field will be used instead.
        !           107:      */
        !           108:     const char *(* info)(struct Scsi_Host *);
        !           109:     
        !           110:     /*
        !           111:      * The command function takes a target, a command (this is a SCSI 
        !           112:      * command formatted as per the SCSI spec, nothing strange), a 
        !           113:      * data buffer pointer, and data buffer length pointer.  The return
        !           114:      * is a status int, bit fielded as follows : 
        !           115:      * Byte What
        !           116:      * 0    SCSI status code
        !           117:      * 1    SCSI 1 byte message
        !           118:      * 2    host error return.
        !           119:      * 3    mid level error return
        !           120:      */
        !           121:     int (* command)(Scsi_Cmnd *);
        !           122: 
        !           123:     /*
        !           124:      * The QueueCommand function works in a similar manner
        !           125:      * to the command function.         It takes an additional parameter,
        !           126:      * void (* done)(int host, int code) which is passed the host 
        !           127:      * # and exit result when the command is complete. 
        !           128:      * Host number is the POSITION IN THE hosts array of THIS
        !           129:      * host adapter.
        !           130:      */
        !           131:     int (* queuecommand)(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
        !           132:     
        !           133:     /*
        !           134:      * Since the mid level driver handles time outs, etc, we want to 
        !           135:      * be able to abort the current command.  Abort returns 0 if the 
        !           136:      * abortion was successful.         The field SCpnt->abort reason
        !           137:      * can be filled in with the appropriate reason why we wanted
        !           138:      * the abort in the first place, and this will be used
        !           139:      * in the mid-level code instead of the host_byte().
        !           140:      * If non-zero, the code passed to it 
        !           141:      * will be used as the return code, otherwise 
        !           142:      * DID_ABORT  should be returned.
        !           143:      * 
        !           144:      * Note that the scsi driver should "clean up" after itself, 
        !           145:      * resetting the bus, etc. if necessary. 
        !           146:      */
        !           147:     int (* abort)(Scsi_Cmnd *);
        !           148: 
        !           149:     /*
        !           150:      * The reset function will reset the SCSI bus.  Any executing 
        !           151:      * commands should fail with a DID_RESET in the host byte.
        !           152:      * The Scsi_Cmnd  is passed so that the reset routine can figure
        !           153:      * out which host adapter should be reset, and also which command
        !           154:      * within the command block was responsible for the reset in
        !           155:      * the first place.         Some hosts do not implement a reset function,
        !           156:      * and these hosts must call scsi_request_sense(SCpnt) to keep
        !           157:      * the command alive.
        !           158:      */ 
        !           159:     int (* reset)(Scsi_Cmnd *, unsigned int);
        !           160: 
        !           161:     /*
        !           162:      * This function is used to select synchronous communications,
        !           163:      * which will result in a higher data throughput.  Not implemented
        !           164:      * yet.
        !           165:      */ 
        !           166:     int (* slave_attach)(int, int);
        !           167:     
        !           168:     /*
        !           169:      * This function determines the bios parameters for a given
        !           170:      * harddisk.  These tend to be numbers that are made up by
        !           171:      * the host adapter.  Parameters:
        !           172:      * size, device number, list (heads, sectors, cylinders)
        !           173:      */ 
        !           174:     int (* bios_param)(Disk *, kdev_t, int []);
        !           175:     
        !           176:     /*
        !           177:      * This determines if we will use a non-interrupt driven
        !           178:      * or an interrupt driven scheme,  It is set to the maximum number
        !           179:      * of simultaneous commands a given host adapter will accept.
        !           180:      */
        !           181:     int can_queue;
        !           182: 
        !           183:     /*
        !           184:      * In many instances, especially where disconnect / reconnect are 
        !           185:      * supported, our host also has an ID on the SCSI bus.  If this is 
        !           186:      * the case, then it must be reserved.  Please set this_id to -1 if
        !           187:      * your setup is in single initiator mode, and the host lacks an 
        !           188:      * ID.
        !           189:      */
        !           190:     int this_id;
        !           191: 
        !           192:     /*
        !           193:      * This determines the degree to which the host adapter is capable
        !           194:      * of scatter-gather.
        !           195:      */
        !           196:     short unsigned int sg_tablesize;
        !           197: 
        !           198:     /*
        !           199:      * True if this host adapter can make good use of linked commands.
        !           200:      * This will allow more than one command to be queued to a given
        !           201:      * unit on a given host.  Set this to the maximum number of command
        !           202:      * blocks to be provided for each device.  Set this to 1 for one
        !           203:      * command block per lun, 2 for two, etc.  Do not set this to 0.
        !           204:      * You should make sure that the host adapter will do the right thing
        !           205:      * before you try setting this above 1.
        !           206:      */
        !           207:     short cmd_per_lun;
        !           208: 
        !           209:     /*
        !           210:      * present contains counter indicating how many boards of this
        !           211:      * type were found when we did the scan.
        !           212:      */
        !           213:     unsigned char present;  
        !           214:     
        !           215:     /*
        !           216:      * true if this host adapter uses unchecked DMA onto an ISA bus.
        !           217:      */
        !           218:     unsigned unchecked_isa_dma:1;
        !           219:     
        !           220:     /*
        !           221:      * true if this host adapter can make good use of clustering.
        !           222:      * I originally thought that if the tablesize was large that it
        !           223:      * was a waste of CPU cycles to prepare a cluster list, but
        !           224:      * it works out that the Buslogic is faster if you use a smaller
        !           225:      * number of segments (i.e. use clustering).  I guess it is
        !           226:      * inefficient.
        !           227:      */
        !           228:     unsigned use_clustering:1;
        !           229: 
        !           230: } Scsi_Host_Template;
        !           231: 
        !           232: /*
        !           233:  * The scsi_hosts array is the array containing the data for all 
        !           234:  * possible <supported> scsi hosts.   This is similar to the
        !           235:  * Scsi_Host_Template, except that we have one entry for each
        !           236:  * actual physical host adapter on the system, stored as a linked
        !           237:  * list.  Note that if there are 2 aha1542 boards, then there will
        !           238:  * be two Scsi_Host entries, but only 1 Scsi_Host_Template entry.
        !           239:  */
        !           240: 
        !           241: struct Scsi_Host
        !           242: {
        !           243:     struct Scsi_Host * next;
        !           244:     unsigned short extra_bytes;
        !           245:     volatile unsigned char host_busy;
        !           246:     char host_no;  /* Used for IOCTL_GET_IDLUN, /proc/scsi et al. */
        !           247:     unsigned long last_reset;
        !           248:     struct wait_queue *host_wait;
        !           249:     Scsi_Cmnd *host_queue;
        !           250:     Scsi_Host_Template * hostt;
        !           251:     
        !           252:     /*
        !           253:      * These three parameters can be used to allow for wide scsi,
        !           254:      * and for host adapters that support multiple busses 
        !           255:      * The first two should be set to 1 more than the actual max id
        !           256:      * or lun (i.e. 8 for normal systems).
        !           257:      */
        !           258:     unsigned int max_id;
        !           259:     unsigned int max_lun;
        !           260:     unsigned int max_channel;
        !           261:    
        !           262:     /*
        !           263:      * Pointer to a circularly linked list - this indicates the hosts
        !           264:      * that should be locked out of performing I/O while we have an active
        !           265:      * command on this host. 
        !           266:      */
        !           267:     struct Scsi_Host * block;
        !           268:     unsigned wish_block:1;
        !           269:     
        !           270:     /* These parameters should be set by the detect routine */
        !           271:     unsigned char *base;
        !           272:     unsigned int  io_port;
        !           273:     unsigned char n_io_port;
        !           274:     unsigned char irq;
        !           275:     unsigned char dma_channel;
        !           276:     
        !           277:     /*
        !           278:      * This is a unique identifier that must be assigned so that we
        !           279:      * have some way of identifying each detected host adapter properly
        !           280:      * and uniquely.  For hosts that do not support more than one card
        !           281:      * in the system at one time, this does not need to be set.  It is
        !           282:      * initialized to 0 in scsi_register.
        !           283:      */
        !           284:     unsigned int unique_id;
        !           285:     
        !           286:     /*
        !           287:      * The rest can be copied from the template, or specifically
        !           288:      * initialized, as required.
        !           289:      */
        !           290:     
        !           291:     int this_id;
        !           292:     int can_queue;
        !           293:     short cmd_per_lun;
        !           294:     short unsigned int sg_tablesize;
        !           295:     unsigned unchecked_isa_dma:1;
        !           296:     unsigned use_clustering:1;
        !           297:     /*
        !           298:      * True if this host was loaded as a loadable module
        !           299:      */
        !           300:     unsigned loaded_as_module:1;
        !           301:  
        !           302:     void (*select_queue_depths)(struct Scsi_Host *, Scsi_Device *);
        !           303: 
        !           304:     unsigned long hostdata[0];  /* Used for storage of host specific stuff */
        !           305: };
        !           306: 
        !           307: extern struct Scsi_Host * scsi_hostlist;
        !           308: extern struct Scsi_Device_Template * scsi_devicelist;
        !           309: 
        !           310: extern Scsi_Host_Template * scsi_hosts;
        !           311: 
        !           312: extern void build_proc_dir_entries(Scsi_Host_Template  *);
        !           313: 
        !           314: 
        !           315: /*
        !           316:  *  scsi_init initializes the scsi hosts.
        !           317:  */
        !           318: 
        !           319: /* 
        !           320:  * We use these goofy things because the MM is not set up when we init
        !           321:  * the scsi subsystem. By using these functions we can write code that
        !           322:  * looks normal.  Also, it makes it possible to use the same code for a
        !           323:  * loadable module. 
        !           324:  */
        !           325: 
        !           326: extern void * scsi_init_malloc(unsigned int size, int priority);
        !           327: extern void scsi_init_free(char * ptr, unsigned int size);
        !           328: 
        !           329: extern int next_scsi_host;
        !           330: 
        !           331: extern int scsi_loadable_module_flag;
        !           332: unsigned int scsi_init(void);
        !           333: extern struct Scsi_Host * scsi_register(Scsi_Host_Template *, int j);
        !           334: extern void scsi_unregister(struct Scsi_Host * i);
        !           335: 
        !           336: #define BLANK_HOST {"", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
        !           337: 
        !           338: struct Scsi_Device_Template
        !           339: {
        !           340:     struct Scsi_Device_Template * next;
        !           341:     const char * name;
        !           342:     const char * tag;
        !           343:     long * usage_count;                  /* Used for loadable modules */
        !           344:     unsigned char scsi_type;
        !           345:     unsigned char major;
        !           346:     unsigned char nr_dev;        /* Number currently attached */
        !           347:     unsigned char dev_noticed;   /* Number of devices detected. */
        !           348:     unsigned char dev_max;       /* Current size of arrays */
        !           349:     unsigned blk:1;              /* 0 if character device */
        !           350:     int (*detect)(Scsi_Device *); /* Returns 1 if we can attach this device */
        !           351:     int (*init)(void);           /* Sizes arrays based upon number of devices
        !           352:                   *  detected */
        !           353:     void (*finish)(void);        /* Perform initialization after attachment */
        !           354:     int (*attach)(Scsi_Device *); /* Attach devices to arrays */
        !           355:     void (*detach)(Scsi_Device *);
        !           356: };
        !           357: 
        !           358: extern struct Scsi_Device_Template sd_template;
        !           359: extern struct Scsi_Device_Template st_template;
        !           360: extern struct Scsi_Device_Template sr_template;
        !           361: extern struct Scsi_Device_Template sg_template;
        !           362: 
        !           363: int scsi_register_device(struct Scsi_Device_Template * sdpnt);
        !           364: 
        !           365: /* These are used by loadable modules */
        !           366: extern int scsi_register_module(int, void *);
        !           367: extern void scsi_unregister_module(int, void *);
        !           368: 
        !           369: /* The different types of modules that we can load and unload */
        !           370: #define MODULE_SCSI_HA 1
        !           371: #define MODULE_SCSI_CONST 2
        !           372: #define MODULE_SCSI_IOCTL 3
        !           373: #define MODULE_SCSI_DEV 4
        !           374: 
        !           375: 
        !           376: /*
        !           377:  * This is an ugly hack.  If we expect to be able to load devices at run time,
        !           378:  * we need to leave extra room in some of the data structures. Doing a 
        !           379:  * realloc to enlarge the structures would be riddled with race conditions, 
        !           380:  * so until a better solution is discovered, we use this crude approach
        !           381:  */
        !           382: #define SD_EXTRA_DEVS 2
        !           383: #define ST_EXTRA_DEVS 2
        !           384: #define SR_EXTRA_DEVS 2
        !           385: #define SG_EXTRA_DEVS (SD_EXTRA_DEVS + SR_EXTRA_DEVS + ST_EXTRA_DEVS)
        !           386: 
        !           387: #endif
        !           388: /*
        !           389:  * Overrides for Emacs so that we follow Linus's tabbing style.
        !           390:  * Emacs will notice this stuff at the end of the file and automatically
        !           391:  * adjust the settings for this buffer only.  This must remain at the end
        !           392:  * of the file.
        !           393:  * ---------------------------------------------------------------------------
        !           394:  * Local variables:
        !           395:  * c-indent-level: 4
        !           396:  * c-brace-imaginary-offset: 0
        !           397:  * c-brace-offset: -4
        !           398:  * c-argdecl-indent: 4
        !           399:  * c-label-offset: -4
        !           400:  * c-continued-statement-offset: 4
        !           401:  * c-continued-brace-offset: 0
        !           402:  * indent-tabs-mode: nil
        !           403:  * tab-width: 8
        !           404:  * End:
        !           405:  */

unix.superglobalmegacorp.com

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