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

📄 ide-ics.c

📁 arm平台上的uclinux系统全部源代码
💻 C
字号:
/* * linux/arch/arm/drivers/block/ide-ics.c * * Copyright (c) 1996,1997 Russell King. * * Changelog: *  08-06-1996	RMK	Created *  12-09-1997	RMK	Added interrupt enable/disable */#include <linux/module.h>#include <linux/malloc.h>#include <linux/blkdev.h>#include <linux/errno.h>#include <asm/dma.h>#include <asm/ecard.h>#include <asm/io.h>#include "ide.h"/* * Maximum number of interfaces per card */#define MAX_IFS	2#define ICS_IDENT_OFFSET		0x8a0#define ICS_ARCIN_V5_INTRSTAT		0x000#define ICS_ARCIN_V5_INTROFFSET		0x001#define ICS_ARCIN_V5_IDEOFFSET		0xa00#define ICS_ARCIN_V5_IDEALTOFFSET	0xae0#define ICS_ARCIN_V5_IDESTEPPING	4#define ICS_ARCIN_V6_IDEOFFSET_1	0x800#define ICS_ARCIN_V6_INTROFFSET_1	0x880#define ICS_ARCIN_V6_INTRSTAT_1		0x8a4#define ICS_ARCIN_V6_IDEALTOFFSET_1	0x8e0#define ICS_ARCIN_V6_IDEOFFSET_2	0xc00#define ICS_ARCIN_V6_INTROFFSET_2	0xc80#define ICS_ARCIN_V6_INTRSTAT_2		0xca4#define ICS_ARCIN_V6_IDEALTOFFSET_2	0xce0#define ICS_ARCIN_V6_IDESTEPPING	4static const card_ids icside_cids[] = {	{ MANU_ICS, PROD_ICS_IDE },	{ MANU_ICS2, PROD_ICS2_IDE },	{ 0xffff, 0xffff }};typedef enum {	ics_if_unknown,	ics_if_arcin_v5,	ics_if_arcin_v6} iftype_t;static struct expansion_card *ec[MAX_ECARDS];static int result[MAX_ECARDS][MAX_IFS];/* ---------------- Version 5 PCB Support Functions --------------------- *//* Prototype: icside_irqenable_arcin_v5 (struct expansion_card *ec, int irqnr) * Purpose  : enable interrupts from card */static void icside_irqenable_arcin_v5 (struct expansion_card *ec, int irqnr){	unsigned int memc_port = (unsigned int)ec->irq_data;	outb (0, memc_port + ICS_ARCIN_V5_INTROFFSET);}/* Prototype: icside_irqdisable_arcin_v5 (struct expansion_card *ec, int irqnr) * Purpose  : disable interrupts from card */static void icside_irqdisable_arcin_v5 (struct expansion_card *ec, int irqnr){	unsigned int memc_port = (unsigned int)ec->irq_data;	inb (memc_port + ICS_ARCIN_V5_INTROFFSET);}static const expansioncard_ops_t icside_ops_arcin_v5 = {	icside_irqenable_arcin_v5,	icside_irqdisable_arcin_v5,	NULL,	NULL,	NULL,	NULL};/* ---------------- Version 6 PCB Support Functions --------------------- *//* Prototype: icside_irqenable_arcin_v6 (struct expansion_card *ec, int irqnr) * Purpose  : enable interrupts from card */static void icside_irqenable_arcin_v6 (struct expansion_card *ec, int irqnr){	unsigned int ide_base_port = (unsigned int)ec->irq_data;	outb (0, ide_base_port + ICS_ARCIN_V6_INTROFFSET_1);	outb (0, ide_base_port + ICS_ARCIN_V6_INTROFFSET_2);}/* Prototype: icside_irqdisable_arcin_v6 (struct expansion_card *ec, int irqnr) * Purpose  : disable interrupts from card */static void icside_irqdisable_arcin_v6 (struct expansion_card *ec, int irqnr){	unsigned int ide_base_port = (unsigned int)ec->irq_data;	inb (ide_base_port + ICS_ARCIN_V6_INTROFFSET_1);	inb (ide_base_port + ICS_ARCIN_V6_INTROFFSET_2);}/* Prototype: icside_irqprobe(struct expansion_card *ec) * Purpose  : detect an active interrupt from card */static int icside_irqprobe_arcin_v6(struct expansion_card *ec){	unsigned int ide_base_port = (unsigned int)ec->irq_data;	return inb(ide_base_port + ICS_ARCIN_V6_INTRSTAT_1) & 1 ||	       inb(ide_base_port + ICS_ARCIN_V6_INTRSTAT_2) & 1;}static const expansioncard_ops_t icside_ops_arcin_v6 = {	icside_irqenable_arcin_v6,	icside_irqdisable_arcin_v6,	icside_irqprobe_arcin_v6,	NULL,	NULL,	NULL};/* Prototype: icside_identifyif (struct expansion_card *ec) * Purpose  : identify IDE interface type * Notes    : checks the description string */static iftype_t icside_identifyif (struct expansion_card *ec){	unsigned int addr;	iftype_t iftype;	int id = 0;	iftype = ics_if_unknown;	addr = ecard_address (ec, ECARD_IOC, ECARD_FAST) + ICS_IDENT_OFFSET;	id = inb (addr) & 1;	id |= (inb (addr + 1) & 1) << 1;	id |= (inb (addr + 2) & 1) << 2;	id |= (inb (addr + 3) & 1) << 3;	switch (id) {	case 0: /* A3IN */		printk ("icside: A3IN unsupported\n");		break;	case 1: /* A3USER */		printk ("icside: A3USER unsupported\n");		break;	case 3:	/* ARCIN V6 */		printk ("icside: detected ARCIN V6 in slot %d\n", ec->slot_no);		iftype = ics_if_arcin_v6;		break;	case 15:/* ARCIN V5 (no id) */		printk ("icside: detected ARCIN V5 in slot %d\n", ec->slot_no);		iftype = ics_if_arcin_v5;		break;	default:/* we don't know - complain very loudly */		printk ("icside: ***********************************\n");		printk ("icside: *** UNKNOWN ICS INTERFACE id=%d ***\n", id);		printk ("icside: ***********************************\n");		printk ("icside: please report this to: linux@arm.linux.org.uk\n");		break;	}	return iftype;}/* Prototype: icside_register (struct expansion_card *ec) * Purpose  : register an ICS IDE card with the IDE driver * Notes    : we make sure that interrupts are disabled from the card */static inline void icside_register (struct expansion_card *ec, int index){	unsigned long port = 0, latch;	result[index][0] = -1;	result[index][1] = -1;	switch (icside_identifyif (ec)) {	case ics_if_unknown:	default:		printk ("icside: *** Warning: ICS IDE Interface unrecognised! ***\n");		break;	case ics_if_arcin_v5:		port = ecard_address (ec, ECARD_MEMC, 0);		ec->irqaddr = (unsigned char *)ioaddr(port + ICS_ARCIN_V5_INTRSTAT);		ec->irqmask = 1;		ec->irq_data = (void *)port;		ec->ops = (expansioncard_ops_t *)&icside_ops_arcin_v5;		/*		 * Be on the safe side - disable interrupts		 */		inb (port + ICS_ARCIN_V5_INTROFFSET);		result[index][0] =			ide_register_port(port + ICS_ARCIN_V5_IDEOFFSET,					  port + ICS_ARCIN_V5_IDEALTOFFSET,					  ICS_ARCIN_V5_IDESTEPPING,					  ec->irq);		break;	case ics_if_arcin_v6:		latch = ecard_address (ec, ECARD_IOC, ECARD_FAST);		if (ec->dma == NO_DMA)			port = ecard_address (ec, ECARD_EASI, ECARD_FAST);		if (port)			outb(0x20, latch);		else {			port = latch;			outb(0, port);		}		ec->irq_data = (void *)port;		ec->ops = (expansioncard_ops_t *)&icside_ops_arcin_v6;		/*		 * Be on the safe side - disable interrupts		 */		inb (port + ICS_ARCIN_V6_INTROFFSET_1);		inb (port + ICS_ARCIN_V6_INTROFFSET_2);		result[index][0] =			ide_register_port(port + ICS_ARCIN_V6_IDEOFFSET_1,					  port + ICS_ARCIN_V6_IDEALTOFFSET_1,					  ICS_ARCIN_V6_IDESTEPPING,					  ec->irq);		result[index][1] =			ide_register_port(port + ICS_ARCIN_V6_IDEOFFSET_2,					  port + ICS_ARCIN_V6_IDEALTOFFSET_2,					  ICS_ARCIN_V6_IDESTEPPING,					  ec->irq);		break;	}		}int icside_init (void){	int i;	for (i = 0; i < MAX_ECARDS; i++)		ec[i] = NULL;	ecard_startfind ();	for (i = 0; ; i++) {		if ((ec[i] = ecard_find (0, icside_cids)) == NULL)			break;		ecard_claim (ec[i]);		icside_register (ec[i], i);	}	for (i = 0; i < MAX_ECARDS; i++)		if (ec[i] && result[i][0] < 0 && result[i][1] < 0) {			ecard_release (ec[i]);			ec[i] = NULL;		}	return 0;}#ifdef MODULEint init_module (void){	return icside_init();}void cleanup_module (void){	int i;	for (i = 0; i < MAX_ECARDS; i++)		if (ec[i]) {			if (result[i][0] >= 0)				ide_unregister (result[i][0]);			if (result[i][1] >= 0)				ide_unregister (result[i][1]);							ecard_release (ec[i]);			ec[i] = NULL;		}}#endif

⌨️ 快捷键说明

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