/*
 * This software may be used and distributed according to the terms
 * of the GNU General Public License, incorporated herein by reference.
 *
 */

#include <linux/module.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include "includes.h"
#include "hardware.h"
#include "card.h"

MODULE_DESCRIPTION("ISDN4Linux: Driver for Spellcaster card");
MODULE_AUTHOR("Spellcaster Telecommunications Inc.");
MODULE_LICENSE("GPL");

board *sc_adapter[MAX_CARDS];
int cinst;

static char devname[] = "scX";
static const char version[] = "2.0b1";

static const char *boardname[] = { "DataCommute/BRI", "DataCommute/PRI", "TeleCommute/BRI" };

/* insmod set parameters */
static unsigned int io[] = {0, 0, 0, 0};
static unsigned char irq[] = {0, 0, 0, 0};
static unsigned long ram[] = {0, 0, 0, 0};
static bool do_reset;

module_param_array(io, int, NULL, 0);
module_param_array(irq, byte, NULL, 0);
module_param_array(ram, long, NULL, 0);
module_param(do_reset, bool, 0);

static int identify_board(unsigned long, unsigned int);

static int __init sc_init(void)
{
	int b = -1;
	int i, j;
	int status = -ENODEV;

	unsigned long memsize = 0;
	unsigned long features = 0;
	isdn_if *interface;
	unsigned char channels;
	unsigned char pgport;
	unsigned long magic;
	int model;
	int last_base = IOBASE_MIN;
	int probe_exhasted = 0;

#ifdef MODULE
	pr_info("SpellCaster ISA ISDN Adapter Driver rev. %s Loaded\n", version);
#else
	pr_info("SpellCaster ISA ISDN Adapter Driver rev. %s\n", version);
#endif
	pr_info("Copyright (C) 1996 SpellCaster Telecommunications Inc.\n");

	while (b++ < MAX_CARDS - 1) {
		pr_debug("Probing for adapter #%d\n", b);
		/*
		 * Initialize reusable variables
		 */
		model = -1;
		magic = 0;
		channels = 0;
		pgport = 0;

		/*
		 * See if we should probe for IO base
		 */
		pr_debug("I/O Base for board %d is 0x%x, %s probe\n", b, io[b],
			 io[b] == 0 ? "will" : "won't");
		if (io[b]) {
			/*
			 * No, I/O Base has been provided
			 */
			for (i = 0; i < MAX_IO_REGS - 1; i++) {
				if (!request_region(io[b] + i * 0x400, 1, "sc test")) {
					pr_debug("request_region for 0x%x failed\n", io[b] + i * 0x400);
					io[b] = 0;
					break;
				} else
					release_region(io[b] + i * 0x400, 1);
			}

			/*
			 * Confirm the I/O Address with a test
			 */
			if (io[b] == 0) {
				pr_debug("I/O Address invalid.\n");
				continue;
			}

			outb(0x18, io[b] + 0x400 * EXP_PAGE0);
			if (inb(io[b] + 0x400 * EXP_PAGE0) != 0x18) {
				pr_debug("I/O Base 0x%x fails test\n",
					 io[b] + 0x400 * EXP_PAGE0);
				continue;
			}
		} else {
			/*
			 * Yes, probe for I/O Base
			 */
			if (probe_exhasted) {
				pr_debug("All probe addresses exhausted, skipping\n");
				continue;
			}
			pr_debug("Probing for I/O...\n");
			for (i = last_base; i <= IOBASE_MAX; i += IOBASE_OFFSET) {
				int found_io = 1;
				if (i == IOBASE_MAX) {
					probe_exhasted = 1; /* No more addresses to probe */
					pr_debug("End of Probes\n");
				}
				last_base = i + IOBASE_OFFSET;
				pr_debug("  checking 0x%x...", i);
				for (j = 0; j < MAX_IO_REGS - 1; j++) {
					if (!request_region(i + j * 0x400, 1, "sc test")) {
						pr_debug("Failed\n");
						found_io = 0;
						break;
					} else
						release_region(i + j * 0x400, 1);
				}

				if (found_io) {
					io[b] = i;
					outb(0x18, io[b] + 0x400 * EXP_PAGE0);
					if (inb(io[b] + 0x400 * EXP_PAGE0) != 0x18) {
						pr_debug("Failed by test\n");
						continue;
					}
					pr_debug("Passed\n");
					break;
				}
			}
			if (probe_exhasted) {
				continue;
			}
		}

		/*
		 * See if we should probe for shared RAM
		 */
		if (do_reset) {
			pr_debug("Doing a SAFE probe reset\n");
			outb(0xFF, io[b] + RESET_OFFSET);
			msleep_interruptible(10000);
		}
		pr_debug("RAM Base for board %d is 0x%lx, %s probe\n", b,
			 ram[b], ram[b] == 0 ? "will" : "won't");

		if (ram[b]) {
			/*
			 * No, the RAM base has been provided
			 * Just look for a signature and ID the
			 * board model
			 */
			if (request_region(ram[b], SRAM_PAGESIZE, "sc test")) {
				pr_debug("request_region for RAM base 0x%lx succeeded\n", ram[b]);
				model = identify_board(ram[b], io[b]);
				release_region(ram[b], SRAM_PAGESIZE);
			}
		} else {
			/*
			 * Yes, probe for free RAM and look for
			 * a signature and id the board model
			 */
			for (i = SRAM_MIN; i < SRAM_MAX; i += SRAM_PAGESIZE) {
				pr_debug("Checking RAM address 0x%x...\n", i);
				if (request_region(i, SRAM_PAGESIZE, "sc test")) {
					pr_debug("  request_region succeeded\n");
					model = identify_board(i, io[b]);
					release_region(i, SRAM_PAGESIZE);
					if (model >= 0) {
						pr_debug("  Identified a %s\n",
							 boardname[model]);
						ram[b] = i;
						break;
					}
					pr_debug("  Unidentified or inaccessible\n");
					continue;
				}
				pr_debug("  request failed\n");
			}
		}
		/*
		 * See if we found free RAM and the board model
		 */
		if (!ram[b] || model < 0) {
			/*
			 * Nope, there was no place in RAM for the
			 * board, or it couldn't be identified
			 */
			pr_debug("Failed to find an adapter at 0x%lx\n", ram[b]);
			continue;
		}

		/*
		 * Set the board's magic number, memory size and page register
		 */
		switch (model) {
		case PRI_BOARD:
			channels = 23;
			magic = 0x20000;
			memsize = 0x100000;
			features = PRI_FEATURES;
			break;

		case BRI_BOARD:
		case POTS_BOARD:
			channels = 2;
			magic = 0x60000;
			memsize = 0x10000;
			features = BRI_FEATURES;
			break;
		}
		switch (ram[b] >> 12 & 0x0F) {
		case 0x0:
			pr_debug("RAM Page register set to EXP_PAGE0\n");
			pgport = EXP_PAGE0;
			break;

		case 0x4:
			pr_debug("RAM Page register set to EXP_PAGE1\n");
			pgport = EXP_PAGE1;
			break;

		case 0x8:
			pr_debug("RAM Page register set to EXP_PAGE2\n");
			pgport = EXP_PAGE2;
			break;

		case 0xC:
			pr_debug("RAM Page register set to EXP_PAGE3\n");
			pgport = EXP_PAGE3;
			break;

		default:
			pr_debug("RAM base address doesn't fall on 16K boundary\n");
			continue;
		}

		pr_debug("current IRQ: %d  b: %d\n", irq[b], b);

		/*
		 * Make sure we got an IRQ
		 */
		if (!irq[b]) {
			/*
			 * No interrupt could be used
			 */
			pr_debug("Failed to acquire an IRQ line\n");
			continue;
		}

		/*
		 * Horray! We found a board, Make sure we can register
		 * it with ISDN4Linux
		 */
		interface = kzalloc(sizeof(isdn_if), GFP_KERNEL);
		if (interface == NULL) {
			/*
			 * Oops, can't malloc isdn_if
			 */
			continue;
		}

		interface->owner = THIS_MODULE;
		interface->hl_hdrlen = 0;
		interface->channels = channels;
		interface->maxbufsize = BUFFER_SIZE;
		interface->features = features;
		interface->writebuf_skb = sndpkt;
		interface->writecmd = NULL;
		interface->command = command;
		strcpy(interface->id, devname);
		interface->id[2] = '0' + cinst;

		/*
		 * Allocate the board structure
		 */
		sc_adapter[cinst] = kzalloc(sizeof(board), GFP_KERNEL);
		if (sc_adapter[cinst] == NULL) {
			/*
			 * Oops, can't alloc memory for the board
			 */
			kfree(interface);
			continue;
		}
		spin_lock_init(&sc_adapter[cinst]->lock);

		if (!register_isdn(interface)) {
			/*
			 * Oops, couldn't register for some reason
			 */
			kfree(interface);
			kfree(sc_adapter[cinst]);
			continue;
		}

		sc_adapter[cinst]->card = interface;
		sc_adapter[cinst]->driverId = interface->channels;
		strcpy(sc_adapter[cinst]->devicename, interface->id);
		sc_adapter[cinst]->nChannels = channels;
		sc_adapter[cinst]->ramsize = memsize;
		sc_adapter[cinst]->shmem_magic = magic;
		sc_adapter[cinst]->shmem_pgport = pgport;
		sc_adapter[cinst]->StartOnReset = 1;

		/*
		 * Allocate channels status structures
		 */
		sc_adapter[cinst]->channel = kzalloc(sizeof(bchan) * channels, GFP_KERNEL);
		if (sc_adapter[cinst]->channel == NULL) {
			/*
			 * Oops, can't alloc memory for the channels
			 */
			indicate_status(cinst, ISDN_STAT_UNLOAD, 0, NULL);	/* Fix me */
			kfree(interface);
			kfree(sc_adapter[cinst]);
			continue;
		}

		/*
		 * Lock down the hardware resources
		 */
		sc_adapter[cinst]->interrupt = irq[b];
		if (request_irq(sc_adapter[cinst]->interrupt, interrupt_handler,
				0, interface->id,
				(void *)(unsigned long) cinst)) {
			kfree(sc_adapter[cinst]->channel);
			indicate_status(cinst, ISDN_STAT_UNLOAD, 0, NULL);	/* Fix me */
			kfree(interface);
			kfree(sc_adapter[cinst]);
			continue;

		}
		sc_adapter[cinst]->iobase = io[b];
		for (i = 0; i < MAX_IO_REGS - 1; i++) {
			sc_adapter[cinst]->ioport[i] = io[b] + i * 0x400;
			request_region(sc_adapter[cinst]->ioport[i], 1,
				       interface->id);
			pr_debug("Requesting I/O Port %#x\n",
				 sc_adapter[cinst]->ioport[i]);
		}
		sc_adapter[cinst]->ioport[IRQ_SELECT] = io[b] + 0x2;
		request_region(sc_adapter[cinst]->ioport[IRQ_SELECT], 1,
			       interface->id);
		pr_debug("Requesting I/O Port %#x\n",
			 sc_adapter[cinst]->ioport[IRQ_SELECT]);
		sc_adapter[cinst]->rambase = ram[b];
		request_region(sc_adapter[cinst]->rambase, SRAM_PAGESIZE,
			       interface->id);

		pr_info("  %s (%d) - %s %d channels IRQ %d, I/O Base 0x%x, RAM Base 0x%lx\n",
			sc_adapter[cinst]->devicename,
			sc_adapter[cinst]->driverId,
			boardname[model], channels, irq[b], io[b], ram[b]);

		/*
		 * reset the adapter to put things in motion
		 */
		reset(cinst);

		cinst++;
		status = 0;
	}
	if (status)
		pr_info("Failed to find any adapters, driver unloaded\n");
	return status;
}

static void __exit sc_exit(void)
{
	int i, j;

	for (i = 0; i < cinst; i++) {
		pr_debug("Cleaning up after adapter %d\n", i);
		/*
		 * kill the timers
		 */
		del_timer_sync(&(sc_adapter[i]->reset_timer));
		del_timer_sync(&(sc_adapter[i]->stat_timer));

		/*
		 * Tell I4L we're toast
		 */
		indicate_status(i, ISDN_STAT_STOP, 0, NULL);
		indicate_status(i, ISDN_STAT_UNLOAD, 0, NULL);

		/*
		 * Release shared RAM
		 */
		release_region(sc_adapter[i]->rambase, SRAM_PAGESIZE);

		/*
		 * Release the IRQ
		 */
		free_irq(sc_adapter[i]->interrupt, NULL);

		/*
		 * Reset for a clean start
		 */
		outb(0xFF, sc_adapter[i]->ioport[SFT_RESET]);

		/*
		 * Release the I/O Port regions
		 */
		for (j = 0; j < MAX_IO_REGS - 1; j++) {
			release_region(sc_adapter[i]->ioport[j], 1);
			pr_debug("Releasing I/O Port %#x\n",
				 sc_adapter[i]->ioport[j]);
		}
		release_region(sc_adapter[i]->ioport[IRQ_SELECT], 1);
		pr_debug("Releasing I/O Port %#x\n",
			 sc_adapter[i]->ioport[IRQ_SELECT]);

		/*
		 * Release any memory we alloced
		 */
		kfree(sc_adapter[i]->channel);
		kfree(sc_adapter[i]->card);
		kfree(sc_adapter[i]);
	}
	pr_info("SpellCaster ISA ISDN Adapter Driver Unloaded.\n");
}

static int identify_board(unsigned long rambase, unsigned int iobase)
{
	unsigned int pgport;
	unsigned long sig;
	DualPortMemory *dpm;
	RspMessage rcvmsg;
	ReqMessage sndmsg;
	HWConfig_pl hwci;
	void __iomem *rambase_sig = (void __iomem *)rambase + SIG_OFFSET;
	int x;

	pr_debug("Attempting to identify adapter @ 0x%lx io 0x%x\n",
		 rambase, iobase);

	/*
	 * Enable the base pointer
	 */
	outb(rambase >> 12, iobase + 0x2c00);

	switch (rambase >> 12 & 0x0F) {
	case 0x0:
		pgport = iobase + PG0_OFFSET;
		pr_debug("Page Register offset is 0x%x\n", PG0_OFFSET);
		break;

	case 0x4:
		pgport = iobase + PG1_OFFSET;
		pr_debug("Page Register offset is 0x%x\n", PG1_OFFSET);
		break;

	case 0x8:
		pgport = iobase + PG2_OFFSET;
		pr_debug("Page Register offset is 0x%x\n", PG2_OFFSET);
		break;

	case 0xC:
		pgport = iobase + PG3_OFFSET;
		pr_debug("Page Register offset is 0x%x\n", PG3_OFFSET);
		break;
	default:
		pr_debug("Invalid rambase 0x%lx\n", rambase);
		return -1;
	}

	/*
	 * Try to identify a PRI card
	 */
	outb(PRI_BASEPG_VAL, pgport);
	msleep_interruptible(1000);
	sig = readl(rambase_sig);
	pr_debug("Looking for a signature, got 0x%lx\n", sig);
	if (sig == SIGNATURE)
		return PRI_BOARD;

	/*
	 * Try to identify a PRI card
	 */
	outb(BRI_BASEPG_VAL, pgport);
	msleep_interruptible(1000);
	sig = readl(rambase_sig);
	pr_debug("Looking for a signature, got 0x%lx\n", sig);
	if (sig == SIGNATURE)
		return BRI_BOARD;

	return -1;

	/*
	 * Try to spot a card
	 */
	sig = readl(rambase_sig);
	pr_debug("Looking for a signature, got 0x%lx\n", sig);
	if (sig != SIGNATURE)
		return -1;

	dpm = (DualPortMemory *) rambase;

	memset(&sndmsg, 0, MSG_LEN);
	sndmsg.msg_byte_cnt = 3;
	sndmsg.type = cmReqType1;
	sndmsg.class = cmReqClass0;
	sndmsg.code = cmReqHWConfig;
	memcpy_toio(&(dpm->req_queue[dpm->req_head++]), &sndmsg, MSG_LEN);
	outb(0, iobase + 0x400);
	pr_debug("Sent HWConfig message\n");
	/*
	 * Wait for the response
	 */
	x = 0;
	while ((inb(iobase + FIFOSTAT_OFFSET) & RF_HAS_DATA) && x < 100) {
		schedule_timeout_interruptible(1);
		x++;
	}
	if (x == 100) {
		pr_debug("Timeout waiting for response\n");
		return -1;
	}

	memcpy_fromio(&rcvmsg, &(dpm->rsp_queue[dpm->rsp_tail]), MSG_LEN);
	pr_debug("Got HWConfig response, status = 0x%x\n", rcvmsg.rsp_status);
	memcpy(&hwci, &(rcvmsg.msg_data.HWCresponse), sizeof(HWConfig_pl));
	pr_debug("Hardware Config: Interface: %s, RAM Size: %ld, Serial: %s\n"
		 "                 Part: %s, Rev: %s\n",
		 hwci.st_u_sense ? "S/T" : "U", hwci.ram_size,
		 hwci.serial_no, hwci.part_no, hwci.rev_no);

	if (!strncmp(PRI_PARTNO, hwci.part_no, 6))
		return PRI_BOARD;
	if (!strncmp(BRI_PARTNO, hwci.part_no, 6))
		return BRI_BOARD;

	return -1;
}

module_init(sc_init);
module_exit(sc_exit);
