|
|
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_A3000_SCSI ! 45: #include "a3000.h" ! 46: #endif ! 47: ! 48: #ifdef CONFIG_A2091_SCSI ! 49: #include "a2091.h" ! 50: #endif ! 51: ! 52: #ifdef CONFIG_GVP11_SCSI ! 53: #include "gvp11.h" ! 54: #endif ! 55: ! 56: #ifdef CONFIG_ATARI_SCSI ! 57: #include "atari_scsi.h" ! 58: #endif ! 59: ! 60: #ifdef CONFIG_SCSI_ADVANSYS ! 61: #include "advansys.h" ! 62: #endif ! 63: ! 64: #ifdef CONFIG_SCSI_AHA152X ! 65: #include "aha152x.h" ! 66: #endif ! 67: ! 68: #ifdef CONFIG_SCSI_AHA1542 ! 69: #include "aha1542.h" ! 70: #endif ! 71: ! 72: #ifdef CONFIG_SCSI_AHA1740 ! 73: #include "aha1740.h" ! 74: #endif ! 75: ! 76: #ifdef CONFIG_SCSI_AIC7XXX ! 77: #include "aic7xxx.h" ! 78: #endif ! 79: ! 80: #ifdef CONFIG_SCSI_BUSLOGIC ! 81: #include "BusLogic.h" ! 82: #endif ! 83: ! 84: #ifdef CONFIG_SCSI_EATA_DMA ! 85: #include "eata_dma.h" ! 86: #endif ! 87: ! 88: #ifdef CONFIG_SCSI_EATA_PIO ! 89: #include "eata_pio.h" ! 90: #endif ! 91: ! 92: #ifdef CONFIG_SCSI_U14_34F ! 93: #include "u14-34f.h" ! 94: #endif ! 95: ! 96: #ifdef CONFIG_SCSI_FUTURE_DOMAIN ! 97: #include "fdomain.h" ! 98: #endif ! 99: ! 100: #ifdef CONFIG_SCSI_GENERIC_NCR5380 ! 101: #include "g_NCR5380.h" ! 102: #endif ! 103: ! 104: #ifdef CONFIG_SCSI_IN2000 ! 105: #include "in2000.h" ! 106: #endif ! 107: ! 108: #ifdef CONFIG_SCSI_PAS16 ! 109: #include "pas16.h" ! 110: #endif ! 111: ! 112: #ifdef CONFIG_SCSI_QLOGIC_FAS ! 113: #include "qlogicfas.h" ! 114: #endif ! 115: ! 116: #ifdef CONFIG_SCSI_QLOGIC_ISP ! 117: #include "qlogicisp.h" ! 118: #endif ! 119: ! 120: #ifdef CONFIG_SCSI_SEAGATE ! 121: #include "seagate.h" ! 122: #endif ! 123: ! 124: #ifdef CONFIG_SCSI_T128 ! 125: #include "t128.h" ! 126: #endif ! 127: ! 128: #ifdef CONFIG_SCSI_DTC3280 ! 129: #include "dtc.h" ! 130: #endif ! 131: ! 132: #ifdef CONFIG_SCSI_NCR53C7xx ! 133: #include "53c7,8xx.h" ! 134: #endif ! 135: ! 136: #ifdef CONFIG_SCSI_NCR53C8XX ! 137: #include "ncr53c8xx.h" ! 138: #endif ! 139: ! 140: #ifdef CONFIG_SCSI_ULTRASTOR ! 141: #include "ultrastor.h" ! 142: #endif ! 143: ! 144: #ifdef CONFIG_SCSI_7000FASST ! 145: #include "wd7000.h" ! 146: #endif ! 147: ! 148: #ifdef CONFIG_SCSI_EATA ! 149: #include "eata.h" ! 150: #endif ! 151: ! 152: #ifdef CONFIG_SCSI_NCR53C406A ! 153: #include "NCR53c406a.h" ! 154: #endif ! 155: ! 156: #ifdef CONFIG_SCSI_DC390T ! 157: #include "dc390.h" ! 158: #endif ! 159: ! 160: #ifdef CONFIG_SCSI_AM53C974 ! 161: #include "AM53C974.h" ! 162: #endif ! 163: ! 164: #ifdef CONFIG_SCSI_MEGARAID ! 165: #include "megaraid.h" ! 166: #endif ! 167: ! 168: #ifdef CONFIG_SCSI_PPA ! 169: #include "ppa.h" ! 170: #endif ! 171: ! 172: #ifdef CONFIG_SCSI_SUNESP ! 173: #include "esp.h" ! 174: #endif ! 175: ! 176: #ifdef CONFIG_BLK_DEV_IDESCSI ! 177: #include "ide-scsi.h" ! 178: #endif ! 179: ! 180: #ifdef CONFIG_SCSI_GDTH ! 181: #include "gdth.h" ! 182: #endif ! 183: ! 184: #ifdef CONFIG_SCSI_DEBUG ! 185: #include "scsi_debug.h" ! 186: #endif ! 187: ! 188: ! 189: /* ! 190: static const char RCSid[] = "$Header: /afs/sipb.mit.edu/project/hurddev/cvsroot/gnumach/linux/src/drivers/scsi/hosts.c,v 1.1 1999/04/26 05:54:40 tb Exp $"; ! 191: */ ! 192: ! 193: /* ! 194: * The scsi host entries should be in the order you wish the ! 195: * cards to be detected. A driver may appear more than once IFF ! 196: * it can deal with being detected (and therefore initialized) ! 197: * with more than one simultaneous host number, can handle being ! 198: * reentrant, etc. ! 199: * ! 200: * They may appear in any order, as each SCSI host is told which host ! 201: * number it is during detection. ! 202: */ ! 203: ! 204: /* This is a placeholder for controllers that are not configured into ! 205: * the system - we do this to ensure that the controller numbering is ! 206: * always consistent, no matter how the kernel is configured. */ ! 207: ! 208: #define NO_CONTROLLER {NULL, NULL, NULL, NULL, NULL, NULL, NULL, \ ! 209: NULL, NULL, 0, 0, 0, 0, 0, 0} ! 210: ! 211: /* ! 212: * When figure is run, we don't want to link to any object code. Since ! 213: * the macro for each host will contain function pointers, we cannot ! 214: * use it and instead must use a "blank" that does no such ! 215: * idiocy. ! 216: */ ! 217: ! 218: Scsi_Host_Template * scsi_hosts = NULL; ! 219: ! 220: static Scsi_Host_Template builtin_scsi_hosts[] = ! 221: { ! 222: #ifdef CONFIG_AMIGA ! 223: #ifdef CONFIG_A3000_SCSI ! 224: A3000_SCSI, ! 225: #endif ! 226: #ifdef CONFIG_A2091_SCSI ! 227: A2091_SCSI, ! 228: #endif ! 229: #ifdef CONFIG_GVP11_SCSI ! 230: GVP11_SCSI, ! 231: #endif ! 232: #endif ! 233: ! 234: #ifdef CONFIG_ATARI ! 235: #ifdef CONFIG_ATARI_SCSI ! 236: ATARI_SCSI, ! 237: #endif ! 238: #endif ! 239: ! 240: #ifdef CONFIG_SCSI_ADVANSYS ! 241: ADVANSYS, ! 242: #endif ! 243: /* BusLogic must come before aha1542.c */ ! 244: #ifdef CONFIG_SCSI_BUSLOGIC ! 245: BUSLOGIC, ! 246: #endif ! 247: #ifdef CONFIG_SCSI_U14_34F ! 248: ULTRASTOR_14_34F, ! 249: #endif ! 250: #ifdef CONFIG_SCSI_ULTRASTOR ! 251: ULTRASTOR_14F, ! 252: #endif ! 253: #ifdef CONFIG_SCSI_AHA152X ! 254: AHA152X, ! 255: #endif ! 256: #ifdef CONFIG_SCSI_AHA1542 ! 257: AHA1542, ! 258: #endif ! 259: #ifdef CONFIG_SCSI_AHA1740 ! 260: AHA1740, ! 261: #endif ! 262: #ifdef CONFIG_SCSI_AIC7XXX ! 263: AIC7XXX, ! 264: #endif ! 265: #ifdef CONFIG_SCSI_FUTURE_DOMAIN ! 266: FDOMAIN_16X0, ! 267: #endif ! 268: #ifdef CONFIG_SCSI_IN2000 ! 269: IN2000, ! 270: #endif ! 271: #ifdef CONFIG_SCSI_GENERIC_NCR5380 ! 272: GENERIC_NCR5380, ! 273: #endif ! 274: #ifdef CONFIG_SCSI_NCR53C406A /* 53C406A should come before QLOGIC */ ! 275: NCR53c406a, ! 276: #endif ! 277: #ifdef CONFIG_SCSI_QLOGIC_FAS ! 278: QLOGICFAS, ! 279: #endif ! 280: #ifdef CONFIG_SCSI_QLOGIC_ISP ! 281: QLOGICISP, ! 282: #endif ! 283: #ifdef CONFIG_SCSI_PAS16 ! 284: MV_PAS16, ! 285: #endif ! 286: #ifdef CONFIG_SCSI_SEAGATE ! 287: SEAGATE_ST0X, ! 288: #endif ! 289: #ifdef CONFIG_SCSI_T128 ! 290: TRANTOR_T128, ! 291: #endif ! 292: #ifdef CONFIG_SCSI_DTC3280 ! 293: DTC3x80, ! 294: #endif ! 295: #ifdef CONFIG_SCSI_DC390T ! 296: DC390_T, ! 297: #endif ! 298: #ifdef CONFIG_SCSI_NCR53C7xx ! 299: NCR53c7xx, ! 300: #endif ! 301: #ifdef CONFIG_SCSI_NCR53C8XX ! 302: NCR53C8XX, ! 303: #endif ! 304: #ifdef CONFIG_SCSI_EATA_DMA ! 305: EATA_DMA, ! 306: #endif ! 307: #ifdef CONFIG_SCSI_EATA_PIO ! 308: EATA_PIO, ! 309: #endif ! 310: #ifdef CONFIG_SCSI_7000FASST ! 311: WD7000, ! 312: #endif ! 313: #ifdef CONFIG_SCSI_EATA ! 314: EATA, ! 315: #endif ! 316: #ifdef CONFIG_SCSI_AM53C974 ! 317: AM53C974, ! 318: #endif ! 319: #ifdef CONFIG_SCSI_MEGARAID ! 320: MEGARAID, ! 321: #endif ! 322: #ifdef CONFIG_SCSI_PPA ! 323: PPA, ! 324: #endif ! 325: #ifdef CONFIG_SCSI_SUNESP ! 326: SCSI_SPARC_ESP, ! 327: #endif ! 328: #ifdef CONFIG_SCSI_GDTH ! 329: GDTH, ! 330: #endif ! 331: #ifdef CONFIG_BLK_DEV_IDESCSI ! 332: IDESCSI, ! 333: #endif ! 334: #ifdef CONFIG_SCSI_DEBUG ! 335: SCSI_DEBUG, ! 336: #endif ! 337: }; ! 338: ! 339: #define MAX_SCSI_HOSTS (sizeof(builtin_scsi_hosts) / sizeof(Scsi_Host_Template)) ! 340: ! 341: ! 342: /* ! 343: * Our semaphores and timeout counters, where size depends on ! 344: * MAX_SCSI_HOSTS here. ! 345: */ ! 346: ! 347: struct Scsi_Host * scsi_hostlist = NULL; ! 348: struct Scsi_Device_Template * scsi_devicelist = NULL; ! 349: ! 350: int max_scsi_hosts = 0; ! 351: int next_scsi_host = 0; ! 352: ! 353: void ! 354: scsi_unregister(struct Scsi_Host * sh){ ! 355: struct Scsi_Host * shpnt; ! 356: ! 357: if(scsi_hostlist == sh) ! 358: scsi_hostlist = sh->next; ! 359: else { ! 360: shpnt = scsi_hostlist; ! 361: while(shpnt->next != sh) shpnt = shpnt->next; ! 362: shpnt->next = shpnt->next->next; ! 363: } ! 364: ! 365: /* If we are removing the last host registered, it is safe to reuse ! 366: * its host number (this avoids "holes" at boot time) (DB) ! 367: * It is also safe to reuse those of numbers directly below which have ! 368: * been released earlier (to avoid some holes in numbering). ! 369: */ ! 370: if(sh->host_no == max_scsi_hosts - 1) { ! 371: while(--max_scsi_hosts >= next_scsi_host) { ! 372: shpnt = scsi_hostlist; ! 373: while(shpnt && shpnt->host_no != max_scsi_hosts - 1) ! 374: shpnt = shpnt->next; ! 375: if(shpnt) ! 376: break; ! 377: } ! 378: } ! 379: next_scsi_host--; ! 380: scsi_init_free((char *) sh, sizeof(struct Scsi_Host) + sh->extra_bytes); ! 381: } ! 382: ! 383: /* We call this when we come across a new host adapter. We only do this ! 384: * once we are 100% sure that we want to use this host adapter - it is a ! 385: * pain to reverse this, so we try to avoid it ! 386: */ ! 387: ! 388: struct Scsi_Host * scsi_register(Scsi_Host_Template * tpnt, int j){ ! 389: struct Scsi_Host * retval, *shpnt; ! 390: retval = (struct Scsi_Host *)scsi_init_malloc(sizeof(struct Scsi_Host) + j, ! 391: (tpnt->unchecked_isa_dma && j ? GFP_DMA : 0) | GFP_ATOMIC); ! 392: retval->host_busy = 0; ! 393: retval->block = NULL; ! 394: retval->wish_block = 0; ! 395: if(j > 0xffff) panic("Too many extra bytes requested\n"); ! 396: retval->extra_bytes = j; ! 397: retval->loaded_as_module = scsi_loadable_module_flag; ! 398: retval->host_no = max_scsi_hosts++; /* never reuse host_no (DB) */ ! 399: next_scsi_host++; ! 400: retval->host_queue = NULL; ! 401: retval->host_wait = NULL; ! 402: retval->last_reset = 0; ! 403: retval->irq = 0; ! 404: retval->dma_channel = 0xff; ! 405: ! 406: /* These three are default values which can be overridden */ ! 407: retval->max_channel = 0; ! 408: retval->max_id = 8; ! 409: retval->max_lun = 8; ! 410: ! 411: retval->unique_id = 0; ! 412: retval->io_port = 0; ! 413: retval->hostt = tpnt; ! 414: retval->next = NULL; ! 415: #ifdef DEBUG ! 416: printk("Register %x %x: %d\n", (int)retval, (int)retval->hostt, j); ! 417: #endif ! 418: ! 419: /* The next six are the default values which can be overridden ! 420: * if need be */ ! 421: retval->this_id = tpnt->this_id; ! 422: retval->can_queue = tpnt->can_queue; ! 423: retval->sg_tablesize = tpnt->sg_tablesize; ! 424: retval->cmd_per_lun = tpnt->cmd_per_lun; ! 425: retval->unchecked_isa_dma = tpnt->unchecked_isa_dma; ! 426: retval->use_clustering = tpnt->use_clustering; ! 427: ! 428: retval->select_queue_depths = NULL; ! 429: ! 430: if(!scsi_hostlist) ! 431: scsi_hostlist = retval; ! 432: else ! 433: { ! 434: shpnt = scsi_hostlist; ! 435: while(shpnt->next) shpnt = shpnt->next; ! 436: shpnt->next = retval; ! 437: } ! 438: ! 439: return retval; ! 440: } ! 441: ! 442: int ! 443: scsi_register_device(struct Scsi_Device_Template * sdpnt) ! 444: { ! 445: if(sdpnt->next) panic("Device already registered"); ! 446: sdpnt->next = scsi_devicelist; ! 447: scsi_devicelist = sdpnt; ! 448: return 0; ! 449: } ! 450: ! 451: unsigned int scsi_init() ! 452: { ! 453: static int called = 0; ! 454: int i, pcount; ! 455: Scsi_Host_Template * tpnt; ! 456: struct Scsi_Host * shpnt; ! 457: const char * name; ! 458: ! 459: if(called) return 0; ! 460: ! 461: called = 1; ! 462: for (tpnt = &builtin_scsi_hosts[0], i = 0; i < MAX_SCSI_HOSTS; ++i, tpnt++) ! 463: { ! 464: /* ! 465: * Initialize our semaphores. -1 is interpreted to mean ! 466: * "inactive" - where as 0 will indicate a time out condition. ! 467: */ ! 468: ! 469: pcount = next_scsi_host; ! 470: if ((tpnt->detect) && ! 471: (tpnt->present = ! 472: tpnt->detect(tpnt))) ! 473: { ! 474: /* The only time this should come up is when people use ! 475: * some kind of patched driver of some kind or another. */ ! 476: if(pcount == next_scsi_host) { ! 477: if(tpnt->present > 1) ! 478: panic("Failure to register low-level scsi driver"); ! 479: /* The low-level driver failed to register a driver. We ! 480: * can do this now. */ ! 481: scsi_register(tpnt,0); ! 482: } ! 483: tpnt->next = scsi_hosts; ! 484: scsi_hosts = tpnt; ! 485: ! 486: /* Add the driver to /proc/scsi */ ! 487: #if CONFIG_PROC_FS ! 488: build_proc_dir_entries(tpnt); ! 489: #endif ! 490: } ! 491: } ! 492: ! 493: for(shpnt=scsi_hostlist; shpnt; shpnt = shpnt->next) ! 494: { ! 495: if(shpnt->hostt->info) ! 496: name = shpnt->hostt->info(shpnt); ! 497: else ! 498: name = shpnt->hostt->name; ! 499: printk ("scsi%d : %s\n", /* And print a little message */ ! 500: shpnt->host_no, name); ! 501: } ! 502: ! 503: printk ("scsi : %d host%s.\n", next_scsi_host, ! 504: (next_scsi_host == 1) ? "" : "s"); ! 505: ! 506: scsi_make_blocked_list(); ! 507: ! 508: /* Now attach the high level drivers */ ! 509: #ifdef CONFIG_BLK_DEV_SD ! 510: scsi_register_device(&sd_template); ! 511: #endif ! 512: #ifdef CONFIG_BLK_DEV_SR ! 513: scsi_register_device(&sr_template); ! 514: #endif ! 515: #ifdef CONFIG_CHR_DEV_ST ! 516: scsi_register_device(&st_template); ! 517: #endif ! 518: #ifdef CONFIG_CHR_DEV_SG ! 519: scsi_register_device(&sg_template); ! 520: #endif ! 521: ! 522: #if 0 ! 523: max_scsi_hosts = next_scsi_host; ! 524: #endif ! 525: return 0; ! 526: } ! 527: ! 528: /* ! 529: * Overrides for Emacs so that we follow Linus's tabbing style. ! 530: * Emacs will notice this stuff at the end of the file and automatically ! 531: * adjust the settings for this buffer only. This must remain at the end ! 532: * of the file. ! 533: * --------------------------------------------------------------------------- ! 534: * Local variables: ! 535: * c-indent-level: 4 ! 536: * c-brace-imaginary-offset: 0 ! 537: * c-brace-offset: -4 ! 538: * c-argdecl-indent: 4 ! 539: * c-label-offset: -4 ! 540: * c-continued-statement-offset: 4 ! 541: * c-continued-brace-offset: 0 ! 542: * indent-tabs-mode: nil ! 543: * tab-width: 8 ! 544: * End: ! 545: */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.