162306a36Sopenharmony_ci/*
262306a36Sopenharmony_ci * Linux driver attachment glue for aic7770 based controllers.
362306a36Sopenharmony_ci *
462306a36Sopenharmony_ci * Copyright (c) 2000-2003 Adaptec Inc.
562306a36Sopenharmony_ci * All rights reserved.
662306a36Sopenharmony_ci *
762306a36Sopenharmony_ci * Redistribution and use in source and binary forms, with or without
862306a36Sopenharmony_ci * modification, are permitted provided that the following conditions
962306a36Sopenharmony_ci * are met:
1062306a36Sopenharmony_ci * 1. Redistributions of source code must retain the above copyright
1162306a36Sopenharmony_ci *    notice, this list of conditions, and the following disclaimer,
1262306a36Sopenharmony_ci *    without modification.
1362306a36Sopenharmony_ci * 2. Redistributions in binary form must reproduce at minimum a disclaimer
1462306a36Sopenharmony_ci *    substantially similar to the "NO WARRANTY" disclaimer below
1562306a36Sopenharmony_ci *    ("Disclaimer") and any redistribution must be conditioned upon
1662306a36Sopenharmony_ci *    including a substantially similar Disclaimer requirement for further
1762306a36Sopenharmony_ci *    binary redistribution.
1862306a36Sopenharmony_ci * 3. Neither the names of the above-listed copyright holders nor the names
1962306a36Sopenharmony_ci *    of any contributors may be used to endorse or promote products derived
2062306a36Sopenharmony_ci *    from this software without specific prior written permission.
2162306a36Sopenharmony_ci *
2262306a36Sopenharmony_ci * Alternatively, this software may be distributed under the terms of the
2362306a36Sopenharmony_ci * GNU General Public License ("GPL") version 2 as published by the Free
2462306a36Sopenharmony_ci * Software Foundation.
2562306a36Sopenharmony_ci *
2662306a36Sopenharmony_ci * NO WARRANTY
2762306a36Sopenharmony_ci * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
2862306a36Sopenharmony_ci * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
2962306a36Sopenharmony_ci * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
3062306a36Sopenharmony_ci * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
3162306a36Sopenharmony_ci * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
3262306a36Sopenharmony_ci * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
3362306a36Sopenharmony_ci * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
3462306a36Sopenharmony_ci * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
3562306a36Sopenharmony_ci * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
3662306a36Sopenharmony_ci * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
3762306a36Sopenharmony_ci * POSSIBILITY OF SUCH DAMAGES.
3862306a36Sopenharmony_ci *
3962306a36Sopenharmony_ci * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7770_osm.c#14 $
4062306a36Sopenharmony_ci */
4162306a36Sopenharmony_ci
4262306a36Sopenharmony_ci#include "aic7xxx_osm.h"
4362306a36Sopenharmony_ci
4462306a36Sopenharmony_ci#include <linux/device.h>
4562306a36Sopenharmony_ci#include <linux/eisa.h>
4662306a36Sopenharmony_ci
4762306a36Sopenharmony_ciint
4862306a36Sopenharmony_ciaic7770_map_registers(struct ahc_softc *ahc, u_int port)
4962306a36Sopenharmony_ci{
5062306a36Sopenharmony_ci	/*
5162306a36Sopenharmony_ci	 * Lock out other contenders for our i/o space.
5262306a36Sopenharmony_ci	 */
5362306a36Sopenharmony_ci	if (!request_region(port, AHC_EISA_IOSIZE, "aic7xxx"))
5462306a36Sopenharmony_ci		return (ENOMEM);
5562306a36Sopenharmony_ci	ahc->tag = BUS_SPACE_PIO;
5662306a36Sopenharmony_ci	ahc->bsh.ioport = port;
5762306a36Sopenharmony_ci	return (0);
5862306a36Sopenharmony_ci}
5962306a36Sopenharmony_ci
6062306a36Sopenharmony_ciint
6162306a36Sopenharmony_ciaic7770_map_int(struct ahc_softc *ahc, u_int irq)
6262306a36Sopenharmony_ci{
6362306a36Sopenharmony_ci	int error;
6462306a36Sopenharmony_ci	int shared;
6562306a36Sopenharmony_ci
6662306a36Sopenharmony_ci	shared = 0;
6762306a36Sopenharmony_ci	if ((ahc->flags & AHC_EDGE_INTERRUPT) == 0)
6862306a36Sopenharmony_ci		shared = IRQF_SHARED;
6962306a36Sopenharmony_ci
7062306a36Sopenharmony_ci	error = request_irq(irq, ahc_linux_isr, shared, "aic7xxx", ahc);
7162306a36Sopenharmony_ci	if (error == 0)
7262306a36Sopenharmony_ci		ahc->platform_data->irq = irq;
7362306a36Sopenharmony_ci
7462306a36Sopenharmony_ci	return (-error);
7562306a36Sopenharmony_ci}
7662306a36Sopenharmony_ci
7762306a36Sopenharmony_cistatic int
7862306a36Sopenharmony_ciaic7770_probe(struct device *dev)
7962306a36Sopenharmony_ci{
8062306a36Sopenharmony_ci	struct eisa_device *edev = to_eisa_device(dev);
8162306a36Sopenharmony_ci	u_int eisaBase = edev->base_addr+AHC_EISA_SLOT_OFFSET;
8262306a36Sopenharmony_ci	struct	ahc_softc *ahc;
8362306a36Sopenharmony_ci	char	buf[80];
8462306a36Sopenharmony_ci	char   *name;
8562306a36Sopenharmony_ci	int	error;
8662306a36Sopenharmony_ci
8762306a36Sopenharmony_ci	sprintf(buf, "ahc_eisa:%d", eisaBase >> 12);
8862306a36Sopenharmony_ci	name = kstrdup(buf, GFP_ATOMIC);
8962306a36Sopenharmony_ci	if (name == NULL)
9062306a36Sopenharmony_ci		return (ENOMEM);
9162306a36Sopenharmony_ci	ahc = ahc_alloc(&aic7xxx_driver_template, name);
9262306a36Sopenharmony_ci	if (ahc == NULL)
9362306a36Sopenharmony_ci		return (ENOMEM);
9462306a36Sopenharmony_ci	ahc->dev = dev;
9562306a36Sopenharmony_ci	error = aic7770_config(ahc, aic7770_ident_table + edev->id.driver_data,
9662306a36Sopenharmony_ci			       eisaBase);
9762306a36Sopenharmony_ci	if (error != 0) {
9862306a36Sopenharmony_ci		ahc->bsh.ioport = 0;
9962306a36Sopenharmony_ci		ahc_free(ahc);
10062306a36Sopenharmony_ci		return (error);
10162306a36Sopenharmony_ci	}
10262306a36Sopenharmony_ci
10362306a36Sopenharmony_ci 	dev_set_drvdata(dev, ahc);
10462306a36Sopenharmony_ci
10562306a36Sopenharmony_ci	error = ahc_linux_register_host(ahc, &aic7xxx_driver_template);
10662306a36Sopenharmony_ci	return (error);
10762306a36Sopenharmony_ci}
10862306a36Sopenharmony_ci
10962306a36Sopenharmony_cistatic int
11062306a36Sopenharmony_ciaic7770_remove(struct device *dev)
11162306a36Sopenharmony_ci{
11262306a36Sopenharmony_ci	struct ahc_softc *ahc = dev_get_drvdata(dev);
11362306a36Sopenharmony_ci	u_long s;
11462306a36Sopenharmony_ci
11562306a36Sopenharmony_ci	if (ahc->platform_data && ahc->platform_data->host)
11662306a36Sopenharmony_ci			scsi_remove_host(ahc->platform_data->host);
11762306a36Sopenharmony_ci
11862306a36Sopenharmony_ci	ahc_lock(ahc, &s);
11962306a36Sopenharmony_ci	ahc_intr_enable(ahc, FALSE);
12062306a36Sopenharmony_ci	ahc_unlock(ahc, &s);
12162306a36Sopenharmony_ci
12262306a36Sopenharmony_ci	ahc_free(ahc);
12362306a36Sopenharmony_ci	return 0;
12462306a36Sopenharmony_ci}
12562306a36Sopenharmony_ci
12662306a36Sopenharmony_cistatic struct eisa_device_id aic7770_ids[] = {
12762306a36Sopenharmony_ci	{ "ADP7771", 0 }, /* AHA 274x */
12862306a36Sopenharmony_ci	{ "ADP7756", 1 }, /* AHA 284x BIOS enabled */
12962306a36Sopenharmony_ci	{ "ADP7757", 2 }, /* AHA 284x BIOS disabled */
13062306a36Sopenharmony_ci	{ "ADP7782", 3 }, /* AHA 274x Olivetti OEM */
13162306a36Sopenharmony_ci	{ "ADP7783", 4 }, /* AHA 274x Olivetti OEM (Differential) */
13262306a36Sopenharmony_ci	{ "ADP7770", 5 }, /* AIC7770 generic */
13362306a36Sopenharmony_ci	{ "" }
13462306a36Sopenharmony_ci};
13562306a36Sopenharmony_ciMODULE_DEVICE_TABLE(eisa, aic7770_ids);
13662306a36Sopenharmony_ci
13762306a36Sopenharmony_cistatic struct eisa_driver aic7770_driver = {
13862306a36Sopenharmony_ci	.id_table	= aic7770_ids,
13962306a36Sopenharmony_ci	.driver = {
14062306a36Sopenharmony_ci		.name   = "aic7xxx",
14162306a36Sopenharmony_ci		.probe  = aic7770_probe,
14262306a36Sopenharmony_ci		.remove = aic7770_remove,
14362306a36Sopenharmony_ci	}
14462306a36Sopenharmony_ci};
14562306a36Sopenharmony_ci
14662306a36Sopenharmony_ciint
14762306a36Sopenharmony_ciahc_linux_eisa_init(void)
14862306a36Sopenharmony_ci{
14962306a36Sopenharmony_ci	return eisa_driver_register(&aic7770_driver);
15062306a36Sopenharmony_ci}
15162306a36Sopenharmony_ci
15262306a36Sopenharmony_civoid
15362306a36Sopenharmony_ciahc_linux_eisa_exit(void)
15462306a36Sopenharmony_ci{
15562306a36Sopenharmony_ci	eisa_driver_unregister(&aic7770_driver);
15662306a36Sopenharmony_ci}
157