|
|
1.1 ! root 1: /* ! 2: * hosts.c Copyright (C) 1992 Drew Eckhardt ! 3: * Copyright (C) 1993, 1994, 1995 Eric Youngdale ! 4: * ! 5: * mid to lowlevel SCSI driver interface ! 6: * Initial versions: Drew Eckhardt ! 7: * Subsequent revisions: Eric Youngdale ! 8: * ! 9: * <[email protected]> ! 10: */ ! 11: ! 12: ! 13: /* ! 14: * This file contains the medium level SCSI ! 15: * host interface initialization, as well as the scsi_hosts array of SCSI ! 16: * hosts currently present in the system. ! 17: */ ! 18: ! 19: /* ! 20: * Don't import our own symbols, as this would severely mess up our ! 21: * symbol tables. ! 22: */ ! 23: #define _SCSI_SYMS_VER_ ! 24: #define __NO_VERSION__ ! 25: #include <linux/module.h> ! 26: ! 27: #include <linux/config.h> ! 28: #include <linux/blk.h> ! 29: #include <linux/kernel.h> ! 30: #include <linux/string.h> ! 31: #include <linux/mm.h> ! 32: #include <linux/proc_fs.h> ! 33: ! 34: #include "scsi.h" ! 35: ! 36: #ifndef NULL ! 37: #define NULL 0L ! 38: #endif ! 39: ! 40: #define HOSTS_C ! 41: ! 42: #include "hosts.h" ! 43: ! 44: #ifdef CONFIG_SCSI_ADVANSYS ! 45: #include "advansys.h" ! 46: #endif ! 47: ! 48: #ifdef CONFIG_SCSI_AHA152X ! 49: #include "aha152x.h" ! 50: #endif ! 51: ! 52: #ifdef CONFIG_SCSI_AHA1542 ! 53: #include "aha1542.h" ! 54: #endif ! 55: ! 56: #ifdef CONFIG_SCSI_AHA1740 ! 57: #include "aha1740.h" ! 58: #endif ! 59: ! 60: #ifdef CONFIG_SCSI_AIC7XXX ! 61: #include "aic7xxx.h" ! 62: #endif ! 63: ! 64: #ifdef CONFIG_SCSI_BUSLOGIC ! 65: #include "BusLogic.h" ! 66: #endif ! 67: ! 68: #ifdef CONFIG_SCSI_EATA_DMA ! 69: #include "eata_dma.h" ! 70: #endif ! 71: ! 72: #ifdef CONFIG_SCSI_EATA_PIO ! 73: #include "eata_pio.h" ! 74: #endif ! 75: ! 76: #ifdef CONFIG_SCSI_U14_34F ! 77: #include "u14-34f.h" ! 78: #endif ! 79: ! 80: #ifdef CONFIG_SCSI_FUTURE_DOMAIN ! 81: #include "fdomain.h" ! 82: #endif ! 83: ! 84: #ifdef CONFIG_SCSI_GENERIC_NCR5380 ! 85: #include "g_NCR5380.h" ! 86: #endif ! 87: ! 88: #ifdef CONFIG_SCSI_IN2000 ! 89: #include "in2000.h" ! 90: #endif ! 91: ! 92: #ifdef CONFIG_SCSI_PAS16 ! 93: #include "pas16.h" ! 94: #endif ! 95: ! 96: #ifdef CONFIG_SCSI_QLOGIC ! 97: #include "qlogic.h" ! 98: #endif ! 99: ! 100: #ifdef CONFIG_SCSI_SEAGATE ! 101: #include "seagate.h" ! 102: #endif ! 103: ! 104: #ifdef CONFIG_SCSI_T128 ! 105: #include "t128.h" ! 106: #endif ! 107: ! 108: #ifdef CONFIG_SCSI_NCR53C7xx ! 109: #include "53c7,8xx.h" ! 110: #endif ! 111: ! 112: #ifdef CONFIG_SCSI_ULTRASTOR ! 113: #include "ultrastor.h" ! 114: #endif ! 115: ! 116: #ifdef CONFIG_SCSI_7000FASST ! 117: #include "wd7000.h" ! 118: #endif ! 119: ! 120: #ifdef CONFIG_SCSI_EATA ! 121: #include "eata.h" ! 122: #endif ! 123: ! 124: #ifdef CONFIG_SCSI_NCR53C406A ! 125: #include "NCR53c406a.h" ! 126: #endif ! 127: ! 128: #ifdef CONFIG_SCSI_AM53C974 ! 129: #include "AM53C974.h" ! 130: #endif ! 131: ! 132: #ifdef CONFIG_SCSI_DEBUG ! 133: #include "scsi_debug.h" ! 134: #endif ! 135: ! 136: /* ! 137: static const char RCSid[] = "$Header: /gd4/gnu/cvsroot/gnumach/i386/i386at/gpl/linux/scsi/hosts.c,v 1.2 1997/03/24 21:51:24 thomas Exp $"; ! 138: */ ! 139: ! 140: /* ! 141: * The scsi host entries should be in the order you wish the ! 142: * cards to be detected. A driver may appear more than once IFF ! 143: * it can deal with being detected (and therefore initialized) ! 144: * with more than one simultaneous host number, can handle being ! 145: * reentrant, etc. ! 146: * ! 147: * They may appear in any order, as each SCSI host is told which host ! 148: * number it is during detection. ! 149: */ ! 150: ! 151: /* This is a placeholder for controllers that are not configured into ! 152: * the system - we do this to ensure that the controller numbering is ! 153: * always consistent, no matter how the kernel is configured. */ ! 154: ! 155: #define NO_CONTROLLER {NULL, NULL, NULL, NULL, NULL, NULL, NULL, \ ! 156: NULL, NULL, 0, 0, 0, 0, 0, 0} ! 157: ! 158: /* ! 159: * When figure is run, we don't want to link to any object code. Since ! 160: * the macro for each host will contain function pointers, we cannot ! 161: * use it and instead must use a "blank" that does no such ! 162: * idiocy. ! 163: */ ! 164: ! 165: Scsi_Host_Template * scsi_hosts = NULL; ! 166: ! 167: static Scsi_Host_Template builtin_scsi_hosts[] = ! 168: { ! 169: #ifdef CONFIG_SCSI_ADVANSYS ! 170: ADVANSYS, ! 171: #endif ! 172: /* BusLogic must come before aha1542.c */ ! 173: #ifdef CONFIG_SCSI_BUSLOGIC ! 174: BUSLOGIC, ! 175: #endif ! 176: #ifdef CONFIG_SCSI_U14_34F ! 177: ULTRASTOR_14_34F, ! 178: #endif ! 179: #ifdef CONFIG_SCSI_ULTRASTOR ! 180: ULTRASTOR_14F, ! 181: #endif ! 182: #ifdef CONFIG_SCSI_AHA152X ! 183: AHA152X, ! 184: #endif ! 185: #ifdef CONFIG_SCSI_AHA1542 ! 186: AHA1542, ! 187: #endif ! 188: #ifdef CONFIG_SCSI_AHA1740 ! 189: AHA1740, ! 190: #endif ! 191: #ifdef CONFIG_SCSI_AIC7XXX ! 192: AIC7XXX, ! 193: #endif ! 194: #ifdef CONFIG_SCSI_FUTURE_DOMAIN ! 195: FDOMAIN_16X0, ! 196: #endif ! 197: #ifdef CONFIG_SCSI_IN2000 ! 198: IN2000, ! 199: #endif ! 200: #ifdef CONFIG_SCSI_GENERIC_NCR5380 ! 201: GENERIC_NCR5380, ! 202: #endif ! 203: #ifdef CONFIG_SCSI_NCR53C406A /* 53C406A should come before QLOGIC */ ! 204: NCR53c406a, ! 205: #endif ! 206: #ifdef CONFIG_SCSI_QLOGIC ! 207: QLOGIC, ! 208: #endif ! 209: #ifdef CONFIG_SCSI_PAS16 ! 210: MV_PAS16, ! 211: #endif ! 212: #ifdef CONFIG_SCSI_SEAGATE ! 213: SEAGATE_ST0X, ! 214: #endif ! 215: #ifdef CONFIG_SCSI_T128 ! 216: TRANTOR_T128, ! 217: #endif ! 218: #ifdef CONFIG_SCSI_NCR53C7xx ! 219: NCR53c7xx, ! 220: #endif ! 221: #ifdef CONFIG_SCSI_EATA_DMA ! 222: EATA_DMA, ! 223: #endif ! 224: #ifdef CONFIG_SCSI_EATA_PIO ! 225: EATA_PIO, ! 226: #endif ! 227: #ifdef CONFIG_SCSI_7000FASST ! 228: WD7000, ! 229: #endif ! 230: #ifdef CONFIG_SCSI_EATA ! 231: EATA, ! 232: #endif ! 233: #ifdef CONFIG_SCSI_AM53C974 ! 234: AM53C974, ! 235: #endif ! 236: #ifdef CONFIG_SCSI_DEBUG ! 237: SCSI_DEBUG, ! 238: #endif ! 239: }; ! 240: ! 241: #define MAX_SCSI_HOSTS (sizeof(builtin_scsi_hosts) / sizeof(Scsi_Host_Template)) ! 242: ! 243: ! 244: /* ! 245: * Our semaphores and timeout counters, where size depends on ! 246: * MAX_SCSI_HOSTS here. ! 247: */ ! 248: ! 249: struct Scsi_Host * scsi_hostlist = NULL; ! 250: struct Scsi_Device_Template * scsi_devicelist = NULL; ! 251: ! 252: int max_scsi_hosts = 0; ! 253: int next_scsi_host = 0; ! 254: ! 255: void ! 256: scsi_unregister(struct Scsi_Host * sh){ ! 257: struct Scsi_Host * shpnt; ! 258: ! 259: if(scsi_hostlist == sh) ! 260: scsi_hostlist = sh->next; ! 261: else { ! 262: shpnt = scsi_hostlist; ! 263: while(shpnt->next != sh) shpnt = shpnt->next; ! 264: shpnt->next = shpnt->next->next; ! 265: } ! 266: ! 267: /* If we are removing the last host registered, it is safe to reuse ! 268: * its host number (this avoids "holes" at boot time) (DB) ! 269: */ ! 270: if (max_scsi_hosts == next_scsi_host && !scsi_loadable_module_flag) ! 271: max_scsi_hosts--; ! 272: ! 273: next_scsi_host--; ! 274: scsi_init_free((char *) sh, sizeof(struct Scsi_Host) + sh->extra_bytes); ! 275: } ! 276: ! 277: /* We call this when we come across a new host adapter. We only do this ! 278: * once we are 100% sure that we want to use this host adapter - it is a ! 279: * pain to reverse this, so we try and avoid it ! 280: */ ! 281: ! 282: struct Scsi_Host * scsi_register(Scsi_Host_Template * tpnt, int j){ ! 283: struct Scsi_Host * retval, *shpnt; ! 284: retval = (struct Scsi_Host *)scsi_init_malloc(sizeof(struct Scsi_Host) + j, ! 285: (tpnt->unchecked_isa_dma && j ? GFP_DMA : 0) | GFP_ATOMIC); ! 286: retval->host_busy = 0; ! 287: retval->block = NULL; ! 288: retval->wish_block = 0; ! 289: if(j > 0xffff) panic("Too many extra bytes requested\n"); ! 290: retval->extra_bytes = j; ! 291: retval->loaded_as_module = scsi_loadable_module_flag; ! 292: retval->host_no = max_scsi_hosts++; /* never reuse host_no (DB) */ ! 293: next_scsi_host++; ! 294: retval->host_queue = NULL; ! 295: retval->host_wait = NULL; ! 296: retval->last_reset = 0; ! 297: retval->irq = 0; ! 298: retval->dma_channel = 0xff; ! 299: ! 300: /* These three are default values which can be overridden */ ! 301: retval->max_channel = 0; ! 302: retval->max_id = 8; ! 303: retval->max_lun = 8; ! 304: ! 305: retval->unique_id = 0; ! 306: retval->io_port = 0; ! 307: retval->hostt = tpnt; ! 308: retval->next = NULL; ! 309: #ifdef DEBUG ! 310: printk("Register %x %x: %d\n", (int)retval, (int)retval->hostt, j); ! 311: #endif ! 312: ! 313: /* The next six are the default values which can be overridden ! 314: * if need be */ ! 315: retval->this_id = tpnt->this_id; ! 316: retval->can_queue = tpnt->can_queue; ! 317: retval->sg_tablesize = tpnt->sg_tablesize; ! 318: retval->cmd_per_lun = tpnt->cmd_per_lun; ! 319: retval->unchecked_isa_dma = tpnt->unchecked_isa_dma; ! 320: retval->use_clustering = tpnt->use_clustering; ! 321: if(!scsi_hostlist) ! 322: scsi_hostlist = retval; ! 323: else ! 324: { ! 325: shpnt = scsi_hostlist; ! 326: while(shpnt->next) shpnt = shpnt->next; ! 327: shpnt->next = retval; ! 328: } ! 329: ! 330: return retval; ! 331: } ! 332: ! 333: int ! 334: scsi_register_device(struct Scsi_Device_Template * sdpnt) ! 335: { ! 336: if(sdpnt->next) panic("Device already registered"); ! 337: sdpnt->next = scsi_devicelist; ! 338: scsi_devicelist = sdpnt; ! 339: return 0; ! 340: } ! 341: ! 342: unsigned int scsi_init() ! 343: { ! 344: static int called = 0; ! 345: int i, pcount; ! 346: Scsi_Host_Template * tpnt; ! 347: struct Scsi_Host * shpnt; ! 348: const char * name; ! 349: ! 350: if(called) return 0; ! 351: ! 352: called = 1; ! 353: for (tpnt = &builtin_scsi_hosts[0], i = 0; i < MAX_SCSI_HOSTS; ++i, tpnt++) ! 354: { ! 355: /* ! 356: * Initialize our semaphores. -1 is interpreted to mean ! 357: * "inactive" - where as 0 will indicate a time out condition. ! 358: */ ! 359: ! 360: pcount = next_scsi_host; ! 361: if ((tpnt->detect) && ! 362: (tpnt->present = ! 363: tpnt->detect(tpnt))) ! 364: { ! 365: /* The only time this should come up is when people use ! 366: * some kind of patched driver of some kind or another. */ ! 367: if(pcount == next_scsi_host) { ! 368: if(tpnt->present > 1) ! 369: panic("Failure to register low-level scsi driver"); ! 370: /* The low-level driver failed to register a driver. We ! 371: * can do this now. */ ! 372: scsi_register(tpnt,0); ! 373: } ! 374: tpnt->next = scsi_hosts; ! 375: scsi_hosts = tpnt; ! 376: ! 377: /* Add the driver to /proc/scsi */ ! 378: #if CONFIG_PROC_FS ! 379: build_proc_dir_entries(tpnt); ! 380: #endif ! 381: } ! 382: } ! 383: ! 384: for(shpnt=scsi_hostlist; shpnt; shpnt = shpnt->next) ! 385: { ! 386: if(shpnt->hostt->info) ! 387: name = shpnt->hostt->info(shpnt); ! 388: else ! 389: name = shpnt->hostt->name; ! 390: #if 0 ! 391: printk ("scsi%d : %s\n", /* And print a little message */ ! 392: shpnt->host_no, name); ! 393: #endif ! 394: } ! 395: ! 396: #if 0 ! 397: printk ("scsi : %d host%s.\n", next_scsi_host, ! 398: (next_scsi_host == 1) ? "" : "s"); ! 399: #endif ! 400: ! 401: scsi_make_blocked_list(); ! 402: ! 403: /* Now attach the high level drivers */ ! 404: #ifdef CONFIG_BLK_DEV_SD ! 405: scsi_register_device(&sd_template); ! 406: #endif ! 407: #ifdef CONFIG_BLK_DEV_SR ! 408: scsi_register_device(&sr_template); ! 409: #endif ! 410: #ifdef CONFIG_CHR_DEV_ST ! 411: scsi_register_device(&st_template); ! 412: #endif ! 413: #ifdef CONFIG_CHR_DEV_SG ! 414: scsi_register_device(&sg_template); ! 415: #endif ! 416: ! 417: #if 0 ! 418: max_scsi_hosts = next_scsi_host; ! 419: #endif ! 420: return 0; ! 421: } ! 422: ! 423: /* ! 424: * Overrides for Emacs so that we follow Linus's tabbing style. ! 425: * Emacs will notice this stuff at the end of the file and automatically ! 426: * adjust the settings for this buffer only. This must remain at the end ! 427: * of the file. ! 428: * --------------------------------------------------------------------------- ! 429: * Local variables: ! 430: * c-indent-level: 4 ! 431: * c-brace-imaginary-offset: 0 ! 432: * c-brace-offset: -4 ! 433: * c-argdecl-indent: 4 ! 434: * c-label-offset: -4 ! 435: * c-continued-statement-offset: 4 ! 436: * c-continued-brace-offset: 0 ! 437: * indent-tabs-mode: nil ! 438: * tab-width: 8 ! 439: * End: ! 440: */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.