|
|
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: */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.