⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 53c7,8xx.c

📁 基于组件方式开发操作系统的OSKIT源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
    	return -1;    } else {	if (host->io_port)  {	    host->n_io_port = 128;	    request_region (host->io_port, host->n_io_port, "ncr53c7,8xx");	}    }        if (NCR53c7x0_read8 (SBCL_REG) & SBCL_BSY) {	printk ("scsi%d : bus wedge, doing SCSI reset\n", host->host_no);	hard_reset (host);    }    return 0;}/*  * Function : static int normal_init(Scsi_Host_Template *tpnt, int board,  *	int chip, u32 base, int io_port, int irq, int dma, int pcivalid, *	unsigned char pci_bus, unsigned char pci_device_fn, *	long long options); * * Purpose : initializes a NCR53c7,8x0 based on base addresses, *	IRQ, and DMA channel.	 *	 *	Useful where a new NCR chip is backwards compatible with *	a supported chip, but the DEVICE ID has changed so it  *	doesn't show up when the autoprobe does a pcibios_find_device. * * Inputs : tpnt - Template for this SCSI adapter, board - board level *	product, chip - 810, 820, or 825, bus - PCI bus, device_fn - *	device and function encoding as used by PCI BIOS calls. *  * Returns : 0 on success, -1 on failure. * */__initfunc(static int normal_init (Scsi_Host_Template *tpnt, int board, int chip,     u32 base, int io_port, int irq, int dma, int pci_valid,     unsigned char pci_bus, unsigned char pci_device_fn, long long options)) {    struct Scsi_Host *instance;    struct NCR53c7x0_hostdata *hostdata;    char chip_str[80];    int script_len = 0, dsa_len = 0, size = 0, max_cmd_size = 0, 	schedule_size = 0, ok = 0;    void *tmp;    options |= perm_options;    switch (chip) {    case 825:    case 820:    case 815:    case 810:	schedule_size = (tpnt->can_queue + 1) * 8 /* JUMP instruction size */;	script_len = NCR53c8xx_script_len;    	dsa_len = NCR53c8xx_dsa_len;    	options |= OPTION_INTFLY;    	sprintf (chip_str, "NCR53c%d", chip);    	break;    default:    	printk("scsi-ncr53c7,8xx : unsupported SCSI chip %d\n", chip);    	return -1;    }    printk("scsi-ncr53c7,8xx : %s at memory 0x%x, io 0x%x, irq %d",    	chip_str, (unsigned) base, io_port, irq);    if (dma == DMA_NONE)    	printk("\n");    else     	printk(", dma %d\n", dma);    if ((chip / 100 == 8) && !pci_valid) 	printk ("scsi-ncr53c7,8xx : for better reliability and performance, please use the\n" 		"        PCI override instead.\n"		"	 Syntax : ncr53c8{10,15,20,25}=pci,<bus>,<device>,<function>\n"		"                 <bus> and <device> are usually 0.\n");    if (options & OPTION_DEBUG_PROBE_ONLY) {    	printk ("scsi-ncr53c7,8xx : probe only enabled, aborting initialization\n");    	return -1;    }    max_cmd_size = sizeof(struct NCR53c7x0_cmd) + dsa_len +    	/* Size of dynamic part of command structure : */	2 * /* Worst case : we don't know if we need DATA IN or DATA out */		( 2 * /* Current instructions per scatter/gather segment */         	  tpnt->sg_tablesize +                   3 /* Current startup / termination required per phase */		) *	8 /* Each instruction is eight bytes */;    /* Allocate fixed part of hostdata, dynamic part to hold appropriate       SCSI SCRIPT(tm) plus a single, maximum-sized NCR53c7x0_cmd structure.       We need a NCR53c7x0_cmd structure for scan_scsis() when we are        not loaded as a module, and when we're loaded as a module, we        can't use a non-dynamically allocated structure because modules       are vmalloc()'d, which can allow structures to cross page        boundaries and breaks our physical/virtual address assumptions       for DMA.       So, we stick it past the end of our hostdata structure.       ASSUMPTION :        	 Regardless of how many simultaneous SCSI commands we allow,	 the probe code only executes a _single_ instruction at a time,	 so we only need one here, and don't need to allocate NCR53c7x0_cmd	 structures for each target until we are no longer in scan_scsis	 and kmalloc() has become functional (memory_init() happens 	 after all device driver initialization).    */    size = sizeof(struct NCR53c7x0_hostdata) + script_len +     /* Note that alignment will be guaranteed, since we put the command       allocated at probe time after the fixed-up SCSI script, which        consists of 32 bit words, aligned on a 32 bit boundary.  But       on a 64bit machine we need 8 byte alignment for hostdata->free, so       we add in another 4 bytes to take care of potential misalignment       */	(sizeof(void *) - sizeof(u32)) + max_cmd_size + schedule_size;    instance = scsi_register (tpnt, size);    if (!instance)	return -1;    /* FIXME : if we ever support an ISA NCR53c7xx based board, we       need to check if the chip is running in a 16 bit mode, and if so        unregister it if it is past the 16M (0x1000000) mark */   	    hostdata = (struct NCR53c7x0_hostdata *)     	instance->hostdata;    hostdata->size = size;    hostdata->script_count = script_len / sizeof(u32);    hostdata = (struct NCR53c7x0_hostdata *) instance->hostdata;    hostdata->board = board;    hostdata->chip = chip;    if ((hostdata->pci_valid = pci_valid)) {	hostdata->pci_bus = pci_bus;	hostdata->pci_device_fn = pci_device_fn;    }    /*     * Being memory mapped is more desirable, since      *     * - Memory accesses may be faster.     *     * - The destination and source address spaces are the same for      *	 all instructions, meaning we don't have to twiddle dmode or      *	 any other registers.     *     * So, we try for memory mapped, and if we don't get it,     * we go for port mapped, and that failing we tell the user     * it can't work.     */    if (base) {	instance->base = (unsigned char *) (unsigned long) base;	/* Check for forced I/O mapping */    	if (!(options & OPTION_IO_MAPPED)) {	    options |= OPTION_MEMORY_MAPPED;	    ok = 1;	}    } else {	options &= ~OPTION_MEMORY_MAPPED;    }    if (io_port) {	instance->io_port = io_port;	options |= OPTION_IO_MAPPED;	ok = 1;    } else {	options &= ~OPTION_IO_MAPPED;    }    if (!ok) {	printk ("scsi%d : not initializing, no I/O or memory mapping known \n",	    instance->host_no);	scsi_unregister (instance);	return -1;    }    instance->irq = irq;    instance->dma_channel = dma;    hostdata->options = options;    hostdata->dsa_len = dsa_len;    hostdata->max_cmd_size = max_cmd_size;    hostdata->num_cmds = 1;    /* Initialize single command */    tmp = (hostdata->script + hostdata->script_count);    hostdata->free = ROUNDUP(tmp, void *);    hostdata->free->real = tmp;    hostdata->free->size = max_cmd_size;    hostdata->free->free = NULL;    hostdata->free->next = NULL;    hostdata->extra_allocate = 0;    /* Allocate command start code space */    hostdata->schedule = (chip == 700 || chip == 70066) ?	NULL : (u32 *) ((char *)hostdata->free + max_cmd_size);/*  * For diagnostic purposes, we don't really care how fast things blaze. * For profiling, we want to access the 800ns resolution system clock, * using a 'C' call on the host processor. * * Therefore, there's no need for the NCR chip to directly manipulate * this data, and we should put it wherever is most convenient for  * Linux. */    if (track_events) 	hostdata->events = (struct NCR53c7x0_event *) (track_events ? 	    vmalloc (sizeof (struct NCR53c7x0_event) * track_events) : NULL);    else	hostdata->events = NULL;    if (hostdata->events) {	memset ((void *) hostdata->events, 0, sizeof(struct NCR53c7x0_event) *	    track_events);		hostdata->event_size = track_events;	hostdata->event_index = 0;    } else 	hostdata->event_size = 0;    return NCR53c7x0_init(instance);}/*  * Function : static int ncr_pci_init(Scsi_Host_Template *tpnt, int board,  *	int chip, int bus, int device_fn, long long options) * * Purpose : initializes a NCR53c800 family based on the PCI *	bus, device, and function location of it.  Allows  * 	reprogramming of latency timer and determining addresses *	and whether bus mastering, etc. are OK. *	 *	Useful where a new NCR chip is backwards compatible with *	a supported chip, but the DEVICE ID has changed so it  *	doesn't show up when the autoprobe does a pcibios_find_device. * * Inputs : tpnt - Template for this SCSI adapter, board - board level *	product, chip - 810, 820, or 825, bus - PCI bus, device_fn - *	device and function encoding as used by PCI BIOS calls. *  * Returns : 0 on success, -1 on failure. * */__initfunc(static int ncr_pci_init (Scsi_Host_Template *tpnt, int board, int chip,     unsigned char bus, unsigned char device_fn, long long options)) {    unsigned short command;#ifdef LINUX_1_2    unsigned long#else    unsigned int #endif	base, io_port;     unsigned char revision;    int error, expected_chip;    int expected_id = -1, max_revision = -1, min_revision = -1;    int i, irq;    struct pci_dev *pdev = pci_find_slot(bus, device_fn);    printk("scsi-ncr53c7,8xx : at PCI bus %d, device %d,  function %d\n",	bus, (int) (device_fn & 0xf8) >> 3,     	(int) device_fn & 7);    if (!pdev) {	printk("scsi-ncr53c7,8xx : not initializing -- PCI device not found,\n"	       "        try using memory, port, irq override instead.\n");	return -1;    }    if ((error = pcibios_read_config_word (bus, device_fn, PCI_COMMAND, 	    &command)) ||	(error = pcibios_read_config_byte (bus, device_fn, PCI_CLASS_REVISION,	    &revision))) {	printk ("scsi-ncr53c7,8xx : error %d not initializing due to error reading configuration space\n"		"	 perhaps you specified an incorrect PCI bus, device, or function.\n", error);	return -1;    }    io_port = pdev->base_address[0];    base = pdev->base_address[1];    irq = pdev->irq;    /* If any one ever clones the NCR chips, this will have to change */    if (pdev->vendor != PCI_VENDOR_ID_NCR) {	printk ("scsi-ncr53c7,8xx : not initializing, 0x%04x is not NCR vendor ID\n",	    (int) pdev->vendor);	return -1;    }#ifdef __powerpc__    if ( ! (command & PCI_COMMAND_MASTER)) {      printk("SCSI: PCI Master Bit has not been set. Setting...\n");      command |= PCI_COMMAND_MASTER|PCI_COMMAND_IO;      pci_write_config_word(pdev, PCI_COMMAND, command);      if (io_port >= 0x10000000 && is_prep ) {	      /* Mapping on PowerPC can't handle this! */	      unsigned long new_io_port;	      new_io_port = (io_port & 0x00FFFFFF) | 0x01000000;	      printk("SCSI: I/O moved from %08X to %08x\n", io_port, new_io_port);	      io_port = new_io_port;	      pci_write_config_dword(pdev, PCI_BASE_ADDRESS_0, io_port);	      pdev->base_address[0] = io_port;      }    }#endif    /*      * Bit 0 is the address space indicator and must be one for I/O     * space mappings, bit 1 is reserved, discard them after checking     * that they have the correct value of 1.     */    if (command & PCI_COMMAND_IO) { 	if ((io_port & 3) != 1) {	    printk ("scsi-ncr53c7,8xx : disabling I/O mapping since base address 0 (0x%x)\n"    	    	    "        bits 0..1 indicate a non-IO mapping\n",		(unsigned) io_port);	    io_port = 0;	} else	    io_port &= PCI_BASE_ADDRESS_IO_MASK;    } else {    	io_port = 0;    }    if (command & PCI_COMMAND_MEMORY) {	if ((base & PCI_BASE_ADDRESS_SPACE) != PCI_BASE_ADDRESS_SPACE_MEMORY) {	    printk("scsi-ncr53c7,8xx : disabling memory mapping since base address 1\n"		   "        contains a non-memory mapping\n");	    base = 0;	} else 	    base &= PCI_BASE_ADDRESS_MEM_MASK;    } else {	base = 0;    }	    if (!io_port && !base) {	printk ("scsi-ncr53c7,8xx : not initializing, both I/O and memory mappings disabled\n");	return -1;    }	    if (!(command & PCI_COMMAND_MASTER)) {	printk ("scsi-ncr53c7,8xx : not initializing, BUS MASTERING was disabled\n");	return -1;    }    for (i = 0; i < NPCI_CHIP_IDS; ++i) {	if (pdev->device == pci_chip_ids[i].pci_device_id) {	    max_revision = pci_chip_ids[i].max_revision;	    min_revision = pci_chip_ids[i].min_revision;	    expected_chip = pci_chip_ids[i].chip;	}	if (chip == pci_chip_ids[i].chip)	    expected_id = pci_chip_ids[i].pci_device_id;    }    if (chip && pdev->device != expected_id) 	printk ("scsi-ncr53c7,8xx : warning : device id of 0x%04x doesn't\n"                "                   match expected 0x%04x\n",	    (unsigned int) pdev->device, (unsigned int) expected_id );        if (max_revision != -1 && revision > max_revision) 	printk ("scsi-ncr53c7,8xx : warning : revision of %d is greater than %d.\n",	    (int) revision, max_revision);    else if (min_revision != -1 && revision < min_revision)	printk ("scsi-ncr53c7,8xx : warning : revision of %d is less than %d.\n",	    (int) revision, min_revision);    if (io_port && check_region (io_port, 128)) {	printk ("scsi-ncr53c7,8xx : IO region 0x%x to 0x%x is in use\n",	    (unsigned) io_port, (unsigned) io_port + 127);	return -1;    }    return normal_init (tpnt, board, chip, (int) base, io_port, 	(int) irq, DMA_NONE, 1, bus, device_fn, options);}/*  * Function : int NCR53c7xx_detect(Scsi_Host_Template *tpnt) *

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -