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

📄 aha1542.c

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
	if ((mbenable_result[0] & 0x08) || mbenable_result[1]) {		mbenable_cmd[0] = CMD_MBENABLE;		mbenable_cmd[1] = 0;		mbenable_cmd[2] = mbenable_result[1];		if ((mbenable_result[0] & 0x08) && (mbenable_result[1] & 0x03))			retval = BIOS_TRANSLATION_25563;		aha1542_out(base, mbenable_cmd, 3);		WAIT(INTRFLAGS(base), INTRMASK, HACC, 0);	};	while (0) {fail:		printk(KERN_ERR "aha1542_mbenable: Mailbox init failed\n");	}	aha1542_intr_reset(base);	return retval;}/* Query the board to find out if it is a 1542 or a 1740, or whatever. */static int aha1542_query(int base_io, int *transl){	unchar inquiry_cmd[] = {CMD_INQUIRY};	unchar inquiry_result[4];	int i;	i = inb(STATUS(base_io));	if (i & DF) {		i = inb(DATA(base_io));	};	aha1542_out(base_io, inquiry_cmd, 1);	aha1542_in(base_io, inquiry_result, 4);	WAIT(INTRFLAGS(base_io), INTRMASK, HACC, 0);	while (0) {fail:		printk(KERN_ERR "aha1542_detect: query card type\n");	}	aha1542_intr_reset(base_io);	*transl = BIOS_TRANSLATION_6432;	/* Default case */	/* For an AHA1740 series board, we ignore the board since there is a	   hardware bug which can lead to wrong blocks being returned if the board	   is operating in the 1542 emulation mode.  Since there is an extended mode	   driver, we simply ignore the board and let the 1740 driver pick it up.	 */	if (inquiry_result[0] == 0x43) {		printk(KERN_INFO "aha1542.c: Emulation mode not supported for AHA 174N hardware.\n");		return 1;	};	/* Always call this - boards that do not support extended bios translation	   will ignore the command, and we will set the proper default */	*transl = aha1542_mbenable(base_io);	return 0;}/* called from init/main.c */void __init aha1542_setup(char *str, int *ints){	const char *ahausage = "aha1542: usage: aha1542=<PORTBASE>[,<BUSON>,<BUSOFF>[,<DMASPEED>]]\n";	static int setup_idx = 0;	int setup_portbase;	if (setup_idx >= MAXBOARDS) {		printk(KERN_ERR "aha1542: aha1542_setup called too many times! Bad LILO params ?\n");		printk(KERN_ERR "   Entryline 1: %s\n", setup_str[0]);		printk(KERN_ERR "   Entryline 2: %s\n", setup_str[1]);		printk(KERN_ERR "   This line:   %s\n", str);		return;	}	if (ints[0] < 1 || ints[0] > 4) {		printk(KERN_ERR "aha1542: %s\n", str);		printk(ahausage);		printk(KERN_ERR "aha1542: Wrong parameters may cause system malfunction.. We try anyway..\n");	}	setup_called[setup_idx] = ints[0];	setup_str[setup_idx] = str;	setup_portbase = ints[0] >= 1 ? ints[1] : 0;	/* Preserve the default value.. */	setup_buson[setup_idx] = ints[0] >= 2 ? ints[2] : 7;	setup_busoff[setup_idx] = ints[0] >= 3 ? ints[3] : 5;	if (ints[0] >= 4) 	{		int atbt = -1;		switch (ints[4]) {		case 5:			atbt = 0x00;			break;		case 6:			atbt = 0x04;			break;		case 7:			atbt = 0x01;			break;		case 8:			atbt = 0x02;			break;		case 10:			atbt = 0x03;			break;		default:			printk(KERN_ERR "aha1542: %s\n", str);			printk(ahausage);			printk(KERN_ERR "aha1542: Valid values for DMASPEED are 5-8, 10 MB/s.  Using jumper defaults.\n");			break;		}		setup_dmaspeed[setup_idx] = atbt;	}	if (setup_portbase != 0)		bases[setup_idx] = setup_portbase;	++setup_idx;}/* return non-zero on detection */int aha1542_detect(Scsi_Host_Template * tpnt){	unsigned char dma_chan;	unsigned char irq_level;	unsigned char scsi_id;	unsigned long flags;	unsigned int base_io;	int trans;	struct Scsi_Host *shpnt = NULL;	int count = 0;	int indx;	DEB(printk("aha1542_detect: \n"));	tpnt->proc_name = "aha1542";#ifdef MODULE	bases[0] = aha1542[0];	setup_buson[0]=aha1542[1];	setup_busoff[0] = aha1542[2];	{		int atbt = -1;		switch (aha1542[3]) {		case 5:			atbt = 0x00;			break;		case 6:			atbt = 0x04;			break;		case 7:			atbt = 0x01;			break;		case 8:			atbt = 0x02;			break;		case 10:			atbt = 0x03;			break;		};		setup_dmaspeed[0] = atbt;	}#endif	/*	 *	Find MicroChannel cards (AHA1640)	 */#ifdef CONFIG_MCA	if(MCA_bus) {		int slot = 0;		int pos = 0;		for (indx = 0; (slot !=  MCA_NOTFOUND) && 			     (indx < sizeof(bases)/sizeof(bases[0])); indx++) {			if (bases[indx])				continue;			/* Detect only AHA-1640 cards -- MCA ID 0F1F */			slot = mca_find_unused_adapter(0x0f1f, slot);			if (slot == MCA_NOTFOUND)				break;						/* Found one */			pos = mca_read_stored_pos(slot, 3);						/* Decode address */			if (pos & 0x80) {				if (pos & 0x02) {					if (pos & 0x01)						bases[indx] = 0x334;					else						bases[indx] = 0x234;				} else {					if (pos & 0x01)						bases[indx] = 0x134;				}			} else {				if (pos & 0x02) {					if (pos & 0x01)						bases[indx] = 0x330;					else						bases[indx] = 0x230;				} else {					if (pos & 0x01)						bases[indx] = 0x130;				}			}			/* No need to decode IRQ and Arb level -- those are			 * read off the card later.			 */			printk(KERN_INFO "Found an AHA-1640 in MCA slot %d, I/O 0x%04x\n", slot, bases[indx]);			mca_set_adapter_name(slot, "Adapter AHA-1640");			mca_set_adapter_procfn(slot, NULL, NULL);			mca_mark_as_used(slot);						/* Go on */			slot++;		}			}#endif	/*	 *	Hunt for ISA Plug'n'Pray Adaptecs (AHA1535)	 */	 	if(isapnp)	{		struct pci_dev *pdev = NULL;		for(indx = 0; indx <sizeof(bases)/sizeof(bases[0]);indx++)		{			if(bases[indx])				continue;			pdev = isapnp_find_dev(NULL, ISAPNP_VENDOR('A', 'D', 'P'), 				ISAPNP_FUNCTION(0x1542), pdev);			if(pdev==NULL)				break;			/*			 *	Activate the PnP card			 */			 			if(pdev->prepare(pdev)<0)				continue;							if(!(pdev->resource[0].flags&IORESOURCE_IO))				continue;							pdev->resource[0].flags|=IORESOURCE_AUTO;			if(pdev->activate(pdev)<0)				continue;							bases[indx] = pdev->resource[0].start;						/* The card can be queried for its DMA, we have 			   the DMA set up that is enough */			   			printk(KERN_INFO "ISAPnP found an AHA1535 at I/O 0x%03X\n", bases[indx]);		}	}	for (indx = 0; indx < sizeof(bases) / sizeof(bases[0]); indx++)		if (bases[indx] != 0 && !check_region(bases[indx], 4)) {			shpnt = scsi_register(tpnt,					sizeof(struct aha1542_hostdata));			if(shpnt==NULL)				continue;			/* For now we do this - until kmalloc is more intelligent			   we are resigned to stupid hacks like this */			if (SCSI_PA(shpnt) >= ISA_DMA_THRESHOLD) {				printk(KERN_ERR "Invalid address for shpnt with 1542.\n");				goto unregister;			}			if (!aha1542_test_port(bases[indx], shpnt))				goto unregister;			base_io = bases[indx];			/* Set the Bus on/off-times as not to ruin floppy performance */			{				unchar oncmd[] = {CMD_BUSON_TIME, 7};				unchar offcmd[] = {CMD_BUSOFF_TIME, 5};				if (setup_called[indx]) {					oncmd[1] = setup_buson[indx];					offcmd[1] = setup_busoff[indx];				}				aha1542_intr_reset(base_io);				aha1542_out(base_io, oncmd, 2);				WAIT(INTRFLAGS(base_io), INTRMASK, HACC, 0);				aha1542_intr_reset(base_io);				aha1542_out(base_io, offcmd, 2);				WAIT(INTRFLAGS(base_io), INTRMASK, HACC, 0);				if (setup_dmaspeed[indx] >= 0) {					unchar dmacmd[] = {CMD_DMASPEED, 0};					dmacmd[1] = setup_dmaspeed[indx];					aha1542_intr_reset(base_io);					aha1542_out(base_io, dmacmd, 2);					WAIT(INTRFLAGS(base_io), INTRMASK, HACC, 0);				}				while (0) {fail:					printk(KERN_ERR "aha1542_detect: setting bus on/off-time failed\n");				}				aha1542_intr_reset(base_io);			}			if (aha1542_query(base_io, &trans))				goto unregister;			if (aha1542_getconfig(base_io, &irq_level, &dma_chan, &scsi_id) == -1)				goto unregister;			printk(KERN_INFO "Configuring Adaptec (SCSI-ID %d) at IO:%x, IRQ %d", scsi_id, base_io, irq_level);			if (dma_chan != 0xFF)				printk(", DMA priority %d", dma_chan);			printk("\n");			DEB(aha1542_stat());			setup_mailboxes(base_io, shpnt);			DEB(aha1542_stat());			DEB(printk("aha1542_detect: enable interrupt channel %d\n", irq_level));			save_flags(flags);			cli();			if (request_irq(irq_level, do_aha1542_intr_handle, 0, "aha1542", NULL)) {				printk(KERN_ERR "Unable to allocate IRQ for adaptec controller.\n");				restore_flags(flags);				goto unregister;			}			if (dma_chan != 0xFF) {				if (request_dma(dma_chan, "aha1542")) {					printk(KERN_ERR "Unable to allocate DMA channel for Adaptec.\n");					free_irq(irq_level, NULL);					restore_flags(flags);					goto unregister;				}				if (dma_chan == 0 || dma_chan >= 5) {					set_dma_mode(dma_chan, DMA_MODE_CASCADE);					enable_dma(dma_chan);				}			}			aha_host[irq_level - 9] = shpnt;			shpnt->this_id = scsi_id;			shpnt->unique_id = base_io;			shpnt->io_port = base_io;			shpnt->n_io_port = 4;	/* Number of bytes of I/O space used */			shpnt->dma_channel = dma_chan;			shpnt->irq = irq_level;			HOSTDATA(shpnt)->bios_translation = trans;			if (trans == BIOS_TRANSLATION_25563)				printk(KERN_INFO "aha1542.c: Using extended bios translation\n");			HOSTDATA(shpnt)->aha1542_last_mbi_used = (2 * AHA1542_MAILBOXES - 1);			HOSTDATA(shpnt)->aha1542_last_mbo_used = (AHA1542_MAILBOXES - 1);			memset(HOSTDATA(shpnt)->SCint, 0, sizeof(HOSTDATA(shpnt)->SCint));			restore_flags(flags);#if 0			DEB(printk(" *** READ CAPACITY ***\n"));			{				unchar buf[8];				static unchar cmd[] = { READ_CAPACITY, 0, 0, 0, 0, 0, 0, 0, 0, 0 };				int i;				for (i = 0; i < sizeof(buf); ++i)					buf[i] = 0x87;				for (i = 0; i < 2; ++i)					if (!aha1542_command(i, cmd, buf, sizeof(buf))) {						printk(KERN_DEBUG "aha_detect: LU %d sector_size %d device_size %d\n",						       i, xscsi2int(buf + 4), xscsi2int(buf));					}			}			DEB(printk(" *** NOW RUNNING MY OWN TEST *** \n"));			for (i = 0; i < 4; ++i) {				unsigned char cmd[10];				static buffer[512];				cmd[0] = READ_10;				cmd[1] = 0;				xany2scsi(cmd + 2, i);				cmd[6] = 0;				cmd[7] = 0;				cmd[8] = 1;				cmd[9] = 0;				aha1542_command(0, cmd, buffer, 512);			}#endif			request_region(bases[indx], 4, "aha1542");	/* Register the IO ports that we use */			count++;			continue;unregister:			scsi_unregister(shpnt);			continue;		};	return count;}static int aha1542_restart(struct Scsi_Host *shost){	int i;	int count = 0;#if 0	unchar ahacmd = CMD_START_SCSI;#endif	for (i = 0; i < AHA1542_MAILBOXES; i++)		if (HOSTDATA(shost)->SCint[i] &&		    !(HOSTDATA(shost)->SCint[i]->device->soft_reset)) {#if 0			HOSTDATA(shost)->mb[i].status = 1;	/* Indicate ready to restart... */#endif			count++;		}	printk(KERN_DEBUG "Potential to restart %d stalled commands...\n", count);#if 0	/* start scsi command */	if (count)		aha1542_out(shost->io_port, &ahacmd, 1);#endif	return 0;}int aha1542_abort(Scsi_Cmnd * SCpnt){	/*	 * The abort command does not leave the device in a clean state where	 *  it is available to be used again.  Until this gets worked out, we	 * will leave it commented out.  	 */	printk(KERN_ERR "aha1542.c: Unable to abort command for target %d\n",	       SCpnt->target);	return FAILED;}/* * This is a device reset.  This is handled by sending a special command * to the device.

⌨️ 快捷键说明

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