drivers/char/applicom.c

Source file repositories/reference/linux-study-clean/drivers/char/applicom.c

File Facts

System
Linux kernel
Corpus path
drivers/char/applicom.c
Extension
.c
Size
24712 bytes
Lines
858
Domain
Driver Families
Bucket
drivers/char
Inferred role
Driver Families: operation-table or driver-model contract
Status
pattern implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

static const struct file_operations ac_fops = {
	.owner = THIS_MODULE,
	.read = ac_read,
	.write = ac_write,
	.unlocked_ioctl = ac_ioctl,
};

static struct miscdevice ac_miscdev = {
	AC_MINOR,
	"ac",
	&ac_fops
};

static int dummy;	/* dev_id for request_irq() */

static int ac_register_board(unsigned long physloc, void __iomem *loc, 
		      unsigned char boardno)
{
	volatile unsigned char byte_reset_it;

	if((readb(loc + CONF_END_TEST)     != 0x00) ||
	   (readb(loc + CONF_END_TEST + 1) != 0x55) ||
	   (readb(loc + CONF_END_TEST + 2) != 0xAA) ||
	   (readb(loc + CONF_END_TEST + 3) != 0xFF))
		return 0;

	if (!boardno)
		boardno = readb(loc + NUMCARD_OWNER_TO_PC);

	if (!boardno || boardno > MAX_BOARD) {
		printk(KERN_WARNING "Board #%d (at 0x%lx) is out of range (1 <= x <= %d).\n",
		       boardno, physloc, MAX_BOARD);
		return 0;
	}

	if (apbs[boardno - 1].RamIO) {
		printk(KERN_WARNING "Board #%d (at 0x%lx) conflicts with previous board #%d (at 0x%lx)\n", 
		       boardno, physloc, boardno, apbs[boardno-1].PhysIO);
		return 0;
	}

	boardno--;

	apbs[boardno].PhysIO = physloc;
	apbs[boardno].RamIO = loc;
	init_waitqueue_head(&apbs[boardno].FlagSleepSend);
	spin_lock_init(&apbs[boardno].mutex);
	byte_reset_it = readb(loc + RAM_IT_TO_PC);

	numboards++;
	return boardno + 1;
}

static void __exit applicom_exit(void)
{
	unsigned int i;

	misc_deregister(&ac_miscdev);

	for (i = 0; i < MAX_BOARD; i++) {

		if (!apbs[i].RamIO)
			continue;

		if (apbs[i].irq)
			free_irq(apbs[i].irq, &dummy);

		iounmap(apbs[i].RamIO);
	}
}

static int __init applicom_init(void)
{
	int i, numisa = 0;
	struct pci_dev *dev = NULL;
	void __iomem *RamIO;
	int boardno, ret;

	printk(KERN_INFO "Applicom driver: $Id: ac.c,v 1.30 2000/03/22 16:03:57 dwmw2 Exp $\n");

	/* No mem and irq given - check for a PCI card */

	while ( (dev = pci_get_class(PCI_CLASS_OTHERS << 16, dev))) {

		if (!pci_match_id(applicom_pci_tbl, dev))
			continue;
		
		if (pci_enable_device(dev)) {
			pci_dev_put(dev);
			return -EIO;

Annotation

Implementation Notes