18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: (GPL-2.0 OR MPL-1.1)
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * Driver for Future Domain-compatible PCMCIA SCSI cards
48c2ecf20Sopenharmony_ci * Copyright 2019 Ondrej Zary
58c2ecf20Sopenharmony_ci *
68c2ecf20Sopenharmony_ci * The initial developer of the original code is David A. Hinds
78c2ecf20Sopenharmony_ci * <dahinds@users.sourceforge.net>.  Portions created by David A. Hinds
88c2ecf20Sopenharmony_ci * are Copyright (C) 1999 David A. Hinds.  All Rights Reserved.
98c2ecf20Sopenharmony_ci */
108c2ecf20Sopenharmony_ci
118c2ecf20Sopenharmony_ci#include <linux/module.h>
128c2ecf20Sopenharmony_ci#include <linux/init.h>
138c2ecf20Sopenharmony_ci#include <scsi/scsi_host.h>
148c2ecf20Sopenharmony_ci#include <pcmcia/cistpl.h>
158c2ecf20Sopenharmony_ci#include <pcmcia/ds.h>
168c2ecf20Sopenharmony_ci#include "fdomain.h"
178c2ecf20Sopenharmony_ci
188c2ecf20Sopenharmony_ciMODULE_AUTHOR("Ondrej Zary, David Hinds");
198c2ecf20Sopenharmony_ciMODULE_DESCRIPTION("Future Domain PCMCIA SCSI driver");
208c2ecf20Sopenharmony_ciMODULE_LICENSE("Dual MPL/GPL");
218c2ecf20Sopenharmony_ci
228c2ecf20Sopenharmony_cistatic int fdomain_config_check(struct pcmcia_device *p_dev, void *priv_data)
238c2ecf20Sopenharmony_ci{
248c2ecf20Sopenharmony_ci	p_dev->io_lines = 10;
258c2ecf20Sopenharmony_ci	p_dev->resource[0]->end = FDOMAIN_REGION_SIZE;
268c2ecf20Sopenharmony_ci	p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
278c2ecf20Sopenharmony_ci	p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO;
288c2ecf20Sopenharmony_ci	return pcmcia_request_io(p_dev);
298c2ecf20Sopenharmony_ci}
308c2ecf20Sopenharmony_ci
318c2ecf20Sopenharmony_cistatic int fdomain_probe(struct pcmcia_device *link)
328c2ecf20Sopenharmony_ci{
338c2ecf20Sopenharmony_ci	int ret;
348c2ecf20Sopenharmony_ci	struct Scsi_Host *sh;
358c2ecf20Sopenharmony_ci
368c2ecf20Sopenharmony_ci	link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO;
378c2ecf20Sopenharmony_ci	link->config_regs = PRESENT_OPTION;
388c2ecf20Sopenharmony_ci
398c2ecf20Sopenharmony_ci	ret = pcmcia_loop_config(link, fdomain_config_check, NULL);
408c2ecf20Sopenharmony_ci	if (ret)
418c2ecf20Sopenharmony_ci		return ret;
428c2ecf20Sopenharmony_ci
438c2ecf20Sopenharmony_ci	ret = pcmcia_enable_device(link);
448c2ecf20Sopenharmony_ci	if (ret)
458c2ecf20Sopenharmony_ci		goto fail_disable;
468c2ecf20Sopenharmony_ci
478c2ecf20Sopenharmony_ci	if (!request_region(link->resource[0]->start, FDOMAIN_REGION_SIZE,
488c2ecf20Sopenharmony_ci			    "fdomain_cs")) {
498c2ecf20Sopenharmony_ci		ret = -EBUSY;
508c2ecf20Sopenharmony_ci		goto fail_disable;
518c2ecf20Sopenharmony_ci	}
528c2ecf20Sopenharmony_ci
538c2ecf20Sopenharmony_ci	sh = fdomain_create(link->resource[0]->start, link->irq, 7, &link->dev);
548c2ecf20Sopenharmony_ci	if (!sh) {
558c2ecf20Sopenharmony_ci		dev_err(&link->dev, "Controller initialization failed");
568c2ecf20Sopenharmony_ci		ret = -ENODEV;
578c2ecf20Sopenharmony_ci		goto fail_release;
588c2ecf20Sopenharmony_ci	}
598c2ecf20Sopenharmony_ci
608c2ecf20Sopenharmony_ci	link->priv = sh;
618c2ecf20Sopenharmony_ci
628c2ecf20Sopenharmony_ci	return 0;
638c2ecf20Sopenharmony_ci
648c2ecf20Sopenharmony_cifail_release:
658c2ecf20Sopenharmony_ci	release_region(link->resource[0]->start, FDOMAIN_REGION_SIZE);
668c2ecf20Sopenharmony_cifail_disable:
678c2ecf20Sopenharmony_ci	pcmcia_disable_device(link);
688c2ecf20Sopenharmony_ci	return ret;
698c2ecf20Sopenharmony_ci}
708c2ecf20Sopenharmony_ci
718c2ecf20Sopenharmony_cistatic void fdomain_remove(struct pcmcia_device *link)
728c2ecf20Sopenharmony_ci{
738c2ecf20Sopenharmony_ci	fdomain_destroy(link->priv);
748c2ecf20Sopenharmony_ci	release_region(link->resource[0]->start, FDOMAIN_REGION_SIZE);
758c2ecf20Sopenharmony_ci	pcmcia_disable_device(link);
768c2ecf20Sopenharmony_ci}
778c2ecf20Sopenharmony_ci
788c2ecf20Sopenharmony_cistatic const struct pcmcia_device_id fdomain_ids[] = {
798c2ecf20Sopenharmony_ci	PCMCIA_DEVICE_PROD_ID12("IBM Corp.", "SCSI PCMCIA Card", 0xe3736c88,
808c2ecf20Sopenharmony_ci				0x859cad20),
818c2ecf20Sopenharmony_ci	PCMCIA_DEVICE_PROD_ID1("SCSI PCMCIA Adapter Card", 0x8dacb57e),
828c2ecf20Sopenharmony_ci	PCMCIA_DEVICE_PROD_ID12(" SIMPLE TECHNOLOGY Corporation",
838c2ecf20Sopenharmony_ci				"SCSI PCMCIA Credit Card Controller",
848c2ecf20Sopenharmony_ci				0x182bdafe, 0xc80d106f),
858c2ecf20Sopenharmony_ci	PCMCIA_DEVICE_NULL,
868c2ecf20Sopenharmony_ci};
878c2ecf20Sopenharmony_ciMODULE_DEVICE_TABLE(pcmcia, fdomain_ids);
888c2ecf20Sopenharmony_ci
898c2ecf20Sopenharmony_cistatic struct pcmcia_driver fdomain_cs_driver = {
908c2ecf20Sopenharmony_ci	.owner		= THIS_MODULE,
918c2ecf20Sopenharmony_ci	.name		= "fdomain_cs",
928c2ecf20Sopenharmony_ci	.probe		= fdomain_probe,
938c2ecf20Sopenharmony_ci	.remove		= fdomain_remove,
948c2ecf20Sopenharmony_ci	.id_table       = fdomain_ids,
958c2ecf20Sopenharmony_ci};
968c2ecf20Sopenharmony_ci
978c2ecf20Sopenharmony_cimodule_pcmcia_driver(fdomain_cs_driver);
98