/*
 * 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;
	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_OFFSET);
	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_OFFSET);
	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_OFFSET);
	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);
