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

📄 aha152x.c

📁 基于组件方式开发操作系统的OSKIT源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
	Scsi_Cmnd *issue_SC;	Scsi_Cmnd *current_SC;	Scsi_Cmnd *disconnected_SC;	int aborting;	int abortion_complete;	int abort_result;	int commands;	int reconnect;	int parity;	int synchronous;	int delay;	int ext_trans;	int swint;	int service;	unsigned char syncrate[8];	unsigned char message[256];	int message_len;#ifdef DEBUG_AHA152X	int debug;#endif};static void aha152x_intr(int irq, void *dev_id, struct pt_regs *);void aha152x_done(struct Scsi_Host *shpnt, int error);void aha152x_setup(char *str, int *ints);int aha152x_checksetup(struct aha152x_setup *setup);static void aha152x_reset_ports(struct Scsi_Host *shpnt);static void aha152x_panic(struct Scsi_Host *shpnt, char *msg);static void disp_ports(struct Scsi_Host *shpnt);static void show_command(Scsi_Cmnd * ptr);static void show_queues(struct Scsi_Host *shpnt);static void disp_enintr(struct Scsi_Host *shpnt);#if defined(DEBUG_RACE)static void enter_driver(const char *);static void leave_driver(const char *);#endif/* possible i/o addresses for the AIC-6260 */static unsigned short ports[] ={	0x340,			/* default first */	0x140};#define PORT_COUNT (sizeof(ports) / sizeof(unsigned short))#if !defined(SKIP_BIOSTEST)/* possible locations for the Adaptec BIOS */static unsigned int addresses[] ={	0xdc000,		/* default first */	0xc8000,	0xcc000,	0xd0000,	0xd4000,	0xd8000,	0xe0000,	0xeb800,		/* VTech Platinum SMP */	0xf0000,};#define ADDRESS_COUNT (sizeof(addresses) / sizeof(unsigned int))/* signatures for various AIC-6[23]60 based controllers.   The point in detecting signatures is to avoid useless and maybe   harmful probes on ports. I'm not sure that all listed boards pass   auto-configuration. For those which fail the BIOS signature is   obsolete, because user intervention to supply the configuration is   needed anyway.  May be an information whether or not the BIOS supports   extended translation could be also useful here. */static struct signature {	unsigned char *signature;	int sig_offset;	int sig_length;} signatures[] ={	{		"Adaptec AHA-1520 BIOS", 0x102e, 21	},			/* Adaptec 152x */	{		"Adaptec AHA-1520B", 0x0b, 19	},			/* Adaptec 152x rev B */	{		"Adaptec ASW-B626 BIOS", 0x1029, 21	},			/* on-board controller */	{		"Adaptec BIOS: ASW-B626", 0x0f, 22	},			/* on-board controller */	{		"Adaptec ASW-B626 S2", 0x2e6c, 19	},			/* on-board controller */	{		"Adaptec BIOS:AIC-6360", 0xc, 21	},			/* on-board controller */	{		"ScsiPro SP-360 BIOS", 0x2873, 19	},			/* ScsiPro-Controller  */	{		"GA-400 LOCAL BUS SCSI BIOS", 0x102e, 26	},			/* Gigabyte Local-Bus-SCSI */	{		"Adaptec BIOS:AVA-282X", 0xc, 21	},			/* Adaptec 282x */	{		"Adaptec IBM Dock II SCSI", 0x2edd, 24	},			/* IBM Thinkpad Dock II */	{		"Adaptec BIOS:AHA-1532P", 0x1c, 22	},			/* IBM Thinkpad Dock II SCSI */	{		"DTC3520A Host Adapter BIOS", 0x318a, 26	},			/* DTC 3520A ISA SCSI */};#define SIGNATURE_COUNT (sizeof(signatures) / sizeof(struct signature))#endifstatic void do_pause(unsigned amount){				/* Pause for amount*10 milliseconds */	unsigned long the_time = jiffies + amount;	/* 0.01 seconds per jiffy */	while (time_before(jiffies, the_time))		barrier();}/* *  queue services: */static inline void append_SC(Scsi_Cmnd ** SC, Scsi_Cmnd * new_SC){	Scsi_Cmnd *end;	new_SC->host_scribble = (unsigned char *) NULL;	if (!*SC)		*SC = new_SC;	else {		for (end = *SC; end->host_scribble; end = (Scsi_Cmnd *) end->host_scribble);		end->host_scribble = (unsigned char *) new_SC;	}}static inline Scsi_Cmnd *remove_first_SC(Scsi_Cmnd ** SC){	Scsi_Cmnd *ptr;	ptr = *SC;	if (ptr)		*SC = (Scsi_Cmnd *) (*SC)->host_scribble;	return ptr;}static inline Scsi_Cmnd *remove_SC(Scsi_Cmnd ** SC, int target, int lun){	Scsi_Cmnd *ptr, *prev;	for (ptr = *SC, prev = NULL;	     ptr && ((ptr->target != target) || (ptr->lun != lun));	     prev = ptr, ptr = (Scsi_Cmnd *) ptr->host_scribble);	if (ptr) {		if (prev)			prev->host_scribble = ptr->host_scribble;		else			*SC = (Scsi_Cmnd *) ptr->host_scribble;	}	return ptr;}/* * read inbound byte and wait for ACK to get low */static void make_acklow(struct Scsi_Host *shpnt){	SETPORT(SXFRCTL0, CH1 | SPIOEN);	GETPORT(SCSIDAT);	SETPORT(SXFRCTL0, CH1);	while (TESTHI(SCSISIG, ACKI))		barrier();}/* * detect current phase more reliable: * phase is valid, when the target asserts REQ after we've deasserted ACK. * * return value is a valid phase or an error code. * * errorcodes: *   P_BUSFREE   BUS FREE phase detected *   P_PARITY    parity error in DATA phase */static int getphase(struct Scsi_Host *shpnt){	int phase, sstat1;	while (1) {		do {			while (!((sstat1 = GETPORT(SSTAT1)) & (BUSFREE | SCSIRSTI | REQINIT)))				barrier();			if (sstat1 & BUSFREE)				return P_BUSFREE;			if (sstat1 & SCSIRSTI) {				printk("aha152x: RESET IN\n");				SETPORT(SSTAT1, SCSIRSTI);			}		} while (TESTHI(SCSISIG, ACKI) || TESTLO(SSTAT1, REQINIT));		SETPORT(SSTAT1, CLRSCSIPERR);		phase = GETPORT(SCSISIG) & P_MASK;		if (TESTHI(SSTAT1, SCSIPERR)) {			if ((phase & (CDO | MSGO)) == 0)	/* DATA phase */				return P_PARITY;			make_acklow(shpnt);		} else			return phase;	}}/* called from init/main.c */void aha152x_setup(char *str, int *ints){	if (setup_count > 2)		panic("aha152x: you can only configure up to two controllers\n");	setup[setup_count].conf = str;	setup[setup_count].io_port = ints[0] >= 1 ? ints[1] : 0x340;	setup[setup_count].irq = ints[0] >= 2 ? ints[2] : 11;	setup[setup_count].scsiid = ints[0] >= 3 ? ints[3] : 7;	setup[setup_count].reconnect = ints[0] >= 4 ? ints[4] : 1;	setup[setup_count].parity = ints[0] >= 5 ? ints[5] : 1;	setup[setup_count].synchronous = ints[0] >= 6 ? ints[6] : 0 /* FIXME: 1 */ ;	setup[setup_count].delay = ints[0] >= 7 ? ints[7] : DELAY_DEFAULT;	setup[setup_count].ext_trans = ints[0] >= 8 ? ints[8] : 0;#ifdef DEBUG_AHA152X	setup[setup_count].debug = ints[0] >= 9 ? ints[9] : DEBUG_DEFAULT;	if (ints[0] > 9) {		printk("aha152x: usage: aha152x=<IOBASE>[,<IRQ>[,<SCSI ID>"		       "[,<RECONNECT>[,<PARITY>[,<SYNCHRONOUS>[,<DELAY>[,<EXT_TRANS>[,<DEBUG>]]]]]]]]\n");#else	if (ints[0] > 8) {		printk("aha152x: usage: aha152x=<IOBASE>[,<IRQ>[,<SCSI ID>"		       "[,<RECONNECT>[,<PARITY>[,<SYNCHRONOUS>[,<DELAY>[,<EXT_TRANS>]]]]]]]\n");#endif	} else		setup_count++;}/* * Test, if port_base is valid. */static int aha152x_porttest(int io_port){	int i;	if (check_region(io_port, IO_RANGE))		return 0;	SETPORT(io_port + O_DMACNTRL1, 0);	/* reset stack pointer */	for (i = 0; i < 16; i++)		SETPORT(io_port + O_STACK, i);	SETPORT(io_port + O_DMACNTRL1, 0);	/* reset stack pointer */	for (i = 0; i < 16 && GETPORT(io_port + O_STACK) == i; i++);	return (i == 16);}int aha152x_checksetup(struct aha152x_setup *setup){	int i;#ifndef PCMCIA	for (i = 0; i < PORT_COUNT && (setup->io_port != ports[i]); i++);	if (i == PORT_COUNT)		return 0;#endif	if (!aha152x_porttest(setup->io_port))		return 0;	if ((setup->irq < IRQ_MIN) || (setup->irq > IRQ_MAX))		return 0;	if ((setup->scsiid < 0) || (setup->scsiid > 7))		return 0;	if ((setup->reconnect < 0) || (setup->reconnect > 1))		return 0;	if ((setup->parity < 0) || (setup->parity > 1))		return 0;	if ((setup->synchronous < 0) || (setup->synchronous > 1))		return 0;	if ((setup->ext_trans < 0) || (setup->ext_trans > 1))		return 0;	return 1;}void aha152x_swintr(int irqno, void *dev_id, struct pt_regs *regs){	struct Scsi_Host *shpnt = aha152x_host[irqno - IRQ_MIN];	if (!shpnt)		panic("aha152x: catched software interrupt for unknown controller.\n");	HOSTDATA(shpnt)->swint++;}int aha152x_detect(Scsi_Host_Template * tpnt){	int i, j, ok;#if defined(AUTOCONF)	aha152x_config conf;#endif	tpnt->proc_dir = &proc_scsi_aha152x;	for (i = 0; i < IRQS; i++)		aha152x_host[i] = (struct Scsi_Host *) NULL;	if (setup_count) {		printk("aha152x: processing commandline: ");		for (i = 0; i < setup_count; i++)			if (!aha152x_checksetup(&setup[i])) {				printk("\naha152x: %s\n", setup[i].conf);				printk("aha152x: invalid line (controller=%d)\n", i + 1);			}		printk("ok\n");	}#ifdef SETUP0	if (setup_count < 2) {		struct aha152x_setup override = SETUP0;		if (setup_count == 0 || (override.io_port != setup[0].io_port))			if (!aha152x_checksetup(&override)) {				printk("\naha152x: invalid override SETUP0={0x%x,%d,%d,%d,%d,%d,%d,%d}\n",				       override.io_port,				       override.irq,				       override.scsiid,				       override.reconnect,				       override.parity,				       override.synchronous,				       override.delay,				       override.ext_trans);			} else				setup[setup_count++] = override;	}#endif#ifdef SETUP1	if (setup_count < 2) {		struct aha152x_setup override = SETUP1;		if (setup_count == 0 || (override.io_port != setup[0].io_port))			if (!aha152x_checksetup(&override)) {				printk("\naha152x: invalid override SETUP1={0x%x,%d,%d,%d,%d,%d,%d,%d}\n",				       override.io_port,				       override.irq,				       override.scsiid,				       override.reconnect,				       override.parity,				       override.synchronous,				       override.delay,				       override.ext_trans);			} else				setup[setup_count++] = override;	}#endif#if defined(MODULE)	if (setup_count < 2 && aha152x[0] != 0) {		setup[setup_count].conf = "";		setup[setup_count].io_port = aha152x[0];		setup[setup_count].irq = aha152x[1];		setup[setup_count].scsiid = aha152x[2];		setup[setup_count].reconnect = aha152x[3];		setup[setup_count].parity = aha152x[4];		setup[setup_count].synchronous = aha152x[5];		setup[setup_count].delay = aha152x[6];		setup[setup_count].ext_trans = aha152x[7];#ifdef DEBUG_AHA152X		setup[setup_count].debug = aha152x[8];#endif		if (aha152x_checksetup(&setup[setup_count]))			setup_count++;		else			printk("\naha152x: invalid module argument aha152x=0x%x,%d,%d,%d,%d,%d,%d,%d\n",			       setup[setup_count].io_port,			       setup[setup_count].irq,			       setup[setup_count].scsiid,			       setup[setup_count].reconnect,			       setup[setup_count].parity,			       setup[setup_count].synchronous,			       setup[setup_count].delay,			       setup[setup_count].ext_trans);	}	if (setup_count < 2 && aha152x1[0] != 0) {		setup[setup_count].conf = "";		setup[setup_count].io_port = aha152x1[0];		setup[setup_count].irq = aha152x1[1];		setup[setup_count].scsiid = aha152x1[2];		setup[setup_count].reconnect = aha152x1[3];		setup[setup_count].parity = aha152x1[4];		setup[setup_count].synchronous = aha152x1[5];		setup[setup_count].delay = aha152x1[6];		setup[setup_count].ext_trans = aha152x1[7];#ifdef DEBUG_AHA152X		setup[setup_count].debug = aha152x1[8];#endif		if (aha152x_checksetup(&setup[setup_count]))			setup_count++;		else			printk("\naha152x: invalid module argument aha152x1=0x%x,%d,%d,%d,%d,%d,%d,%d\n",			       setup[setup_count].io_port,			       setup[setup_count].irq,			       setup[setup_count].scsiid,			       setup[setup_count].reconnect,			       setup[setup_count].parity,			       setup[setup_count].synchronous,			       setup[setup_count].delay,			       setup[setup_count].ext_trans);	}#endif#if defined(AUTOCONF)	if (setup_count < 2) {#if !defined(SKIP_BIOSTEST)		ok = 0;		for (i = 0; i < ADDRESS_COUNT && !ok; i++)			for (j = 0; (j < SIGNATURE_COUNT) && !ok; j++)				ok = check_signature(addresses[i] + signatures[j].sig_offset,						     signatures[j].signature, signatures[j].sig_length);		if (!ok && setup_count == 0)			return 0;		printk("aha152x: BIOS test: passed, ");#else		printk("aha152x: ");#endif				/* !SKIP_BIOSTEST */		ok = 0;		for (i = 0; i < PORT_COUNT && setup_count < 2; i++) {			if ((setup_count == 1) && (setup[0].io_port == ports[i]))				continue;			if (aha152x_porttest(ports[i])) {				ok++;				setup[setup_count].io_port = ports[i];				conf.cf_port =				    (GETPORT(ports[i] + O_PORTA) << 8) + GETPORT(ports[i] + O_PORTB);				setup[setup_count].irq = IRQ_MIN + conf.cf_irq;				setup[setup_count].scsiid = conf.cf_id;				setup[setup_count].reconnect = conf.cf_tardisc;				setup[setup_count].parity = !conf.cf_parity;				setup[setup_count].synchronous = 0 /* FIXME: conf.cf_syncneg */ ;				setup[setup_count].delay = DELAY_DEFAULT;				setup[setup_count].ext_trans = 0;#ifdef DEBUG_AHA152X				setup[setup_count].debug = DEBUG_DEFAULT;#endif				setup_count++;			}		}		if (ok)			printk("auto configuration: ok, ");

⌨️ 快捷键说明

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