xref: /openbmc/linux/drivers/scsi/aic7xxx/aic7770_osm.c (revision 597473720f4dc69749542bfcfed4a927a43d935e)
11da177e4SLinus Torvalds /*
21da177e4SLinus Torvalds  * Linux driver attachment glue for aic7770 based controllers.
31da177e4SLinus Torvalds  *
41da177e4SLinus Torvalds  * Copyright (c) 2000-2003 Adaptec Inc.
51da177e4SLinus Torvalds  * All rights reserved.
61da177e4SLinus Torvalds  *
71da177e4SLinus Torvalds  * Redistribution and use in source and binary forms, with or without
81da177e4SLinus Torvalds  * modification, are permitted provided that the following conditions
91da177e4SLinus Torvalds  * are met:
101da177e4SLinus Torvalds  * 1. Redistributions of source code must retain the above copyright
111da177e4SLinus Torvalds  *    notice, this list of conditions, and the following disclaimer,
121da177e4SLinus Torvalds  *    without modification.
131da177e4SLinus Torvalds  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
141da177e4SLinus Torvalds  *    substantially similar to the "NO WARRANTY" disclaimer below
151da177e4SLinus Torvalds  *    ("Disclaimer") and any redistribution must be conditioned upon
161da177e4SLinus Torvalds  *    including a substantially similar Disclaimer requirement for further
171da177e4SLinus Torvalds  *    binary redistribution.
181da177e4SLinus Torvalds  * 3. Neither the names of the above-listed copyright holders nor the names
191da177e4SLinus Torvalds  *    of any contributors may be used to endorse or promote products derived
201da177e4SLinus Torvalds  *    from this software without specific prior written permission.
211da177e4SLinus Torvalds  *
221da177e4SLinus Torvalds  * Alternatively, this software may be distributed under the terms of the
231da177e4SLinus Torvalds  * GNU General Public License ("GPL") version 2 as published by the Free
241da177e4SLinus Torvalds  * Software Foundation.
251da177e4SLinus Torvalds  *
261da177e4SLinus Torvalds  * NO WARRANTY
271da177e4SLinus Torvalds  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
281da177e4SLinus Torvalds  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
291da177e4SLinus Torvalds  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
301da177e4SLinus Torvalds  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
311da177e4SLinus Torvalds  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
321da177e4SLinus Torvalds  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
331da177e4SLinus Torvalds  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
341da177e4SLinus Torvalds  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
351da177e4SLinus Torvalds  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
361da177e4SLinus Torvalds  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
371da177e4SLinus Torvalds  * POSSIBILITY OF SUCH DAMAGES.
381da177e4SLinus Torvalds  *
391da177e4SLinus Torvalds  * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7770_osm.c#14 $
401da177e4SLinus Torvalds  */
411da177e4SLinus Torvalds 
421da177e4SLinus Torvalds #include "aic7xxx_osm.h"
431da177e4SLinus Torvalds 
441da177e4SLinus Torvalds #include <linux/device.h>
451da177e4SLinus Torvalds #include <linux/eisa.h>
461da177e4SLinus Torvalds 
471da177e4SLinus Torvalds int
aic7770_map_registers(struct ahc_softc * ahc,u_int port)481da177e4SLinus Torvalds aic7770_map_registers(struct ahc_softc *ahc, u_int port)
491da177e4SLinus Torvalds {
501da177e4SLinus Torvalds 	/*
511da177e4SLinus Torvalds 	 * Lock out other contenders for our i/o space.
521da177e4SLinus Torvalds 	 */
53172c122dSHarvey Harrison 	if (!request_region(port, AHC_EISA_IOSIZE, "aic7xxx"))
541da177e4SLinus Torvalds 		return (ENOMEM);
551da177e4SLinus Torvalds 	ahc->tag = BUS_SPACE_PIO;
561da177e4SLinus Torvalds 	ahc->bsh.ioport = port;
571da177e4SLinus Torvalds 	return (0);
581da177e4SLinus Torvalds }
591da177e4SLinus Torvalds 
601da177e4SLinus Torvalds int
aic7770_map_int(struct ahc_softc * ahc,u_int irq)611da177e4SLinus Torvalds aic7770_map_int(struct ahc_softc *ahc, u_int irq)
621da177e4SLinus Torvalds {
631da177e4SLinus Torvalds 	int error;
641da177e4SLinus Torvalds 	int shared;
651da177e4SLinus Torvalds 
661da177e4SLinus Torvalds 	shared = 0;
671da177e4SLinus Torvalds 	if ((ahc->flags & AHC_EDGE_INTERRUPT) == 0)
681d6f359aSThomas Gleixner 		shared = IRQF_SHARED;
691da177e4SLinus Torvalds 
701da177e4SLinus Torvalds 	error = request_irq(irq, ahc_linux_isr, shared, "aic7xxx", ahc);
711da177e4SLinus Torvalds 	if (error == 0)
721da177e4SLinus Torvalds 		ahc->platform_data->irq = irq;
731da177e4SLinus Torvalds 
741da177e4SLinus Torvalds 	return (-error);
751da177e4SLinus Torvalds }
761da177e4SLinus Torvalds 
771da177e4SLinus Torvalds static int
aic7770_probe(struct device * dev)78d6cbbad7SChristoph Hellwig aic7770_probe(struct device *dev)
791da177e4SLinus Torvalds {
80d6cbbad7SChristoph Hellwig 	struct eisa_device *edev = to_eisa_device(dev);
81d6cbbad7SChristoph Hellwig 	u_int eisaBase = edev->base_addr+AHC_EISA_SLOT_OFFSET;
82d6cbbad7SChristoph Hellwig 	struct	ahc_softc *ahc;
83d6cbbad7SChristoph Hellwig 	char	buf[80];
84d6cbbad7SChristoph Hellwig 	char   *name;
85d6cbbad7SChristoph Hellwig 	int	error;
861da177e4SLinus Torvalds 
87d6cbbad7SChristoph Hellwig 	sprintf(buf, "ahc_eisa:%d", eisaBase >> 12);
881f3d2d9eSHimangi Saraogi 	name = kstrdup(buf, GFP_ATOMIC);
89d6cbbad7SChristoph Hellwig 	if (name == NULL)
90d6cbbad7SChristoph Hellwig 		return (ENOMEM);
91d6cbbad7SChristoph Hellwig 	ahc = ahc_alloc(&aic7xxx_driver_template, name);
92d6cbbad7SChristoph Hellwig 	if (ahc == NULL)
93d6cbbad7SChristoph Hellwig 		return (ENOMEM);
94*144ec974SChristoph Hellwig 	ahc->dev = dev;
95d6cbbad7SChristoph Hellwig 	error = aic7770_config(ahc, aic7770_ident_table + edev->id.driver_data,
96d6cbbad7SChristoph Hellwig 			       eisaBase);
97d6cbbad7SChristoph Hellwig 	if (error != 0) {
98d6cbbad7SChristoph Hellwig 		ahc->bsh.ioport = 0;
99d6cbbad7SChristoph Hellwig 		ahc_free(ahc);
100d6cbbad7SChristoph Hellwig 		return (error);
101d6cbbad7SChristoph Hellwig 	}
102d6cbbad7SChristoph Hellwig 
103d6cbbad7SChristoph Hellwig  	dev_set_drvdata(dev, ahc);
104d6cbbad7SChristoph Hellwig 
105d6cbbad7SChristoph Hellwig 	error = ahc_linux_register_host(ahc, &aic7xxx_driver_template);
106d6cbbad7SChristoph Hellwig 	return (error);
1071da177e4SLinus Torvalds }
1081da177e4SLinus Torvalds 
1091da177e4SLinus Torvalds static int
aic7770_remove(struct device * dev)110d6cbbad7SChristoph Hellwig aic7770_remove(struct device *dev)
1111da177e4SLinus Torvalds {
112d6cbbad7SChristoph Hellwig 	struct ahc_softc *ahc = dev_get_drvdata(dev);
1131da177e4SLinus Torvalds 	u_long s;
1141da177e4SLinus Torvalds 
11597af50f6SJames Bottomley 	if (ahc->platform_data && ahc->platform_data->host)
11697af50f6SJames Bottomley 			scsi_remove_host(ahc->platform_data->host);
11797af50f6SJames Bottomley 
1181da177e4SLinus Torvalds 	ahc_lock(ahc, &s);
1191da177e4SLinus Torvalds 	ahc_intr_enable(ahc, FALSE);
1201da177e4SLinus Torvalds 	ahc_unlock(ahc, &s);
1211da177e4SLinus Torvalds 
122d6cbbad7SChristoph Hellwig 	ahc_free(ahc);
123d6cbbad7SChristoph Hellwig 	return 0;
124d6cbbad7SChristoph Hellwig }
125d6cbbad7SChristoph Hellwig 
126d6cbbad7SChristoph Hellwig static struct eisa_device_id aic7770_ids[] = {
127d6cbbad7SChristoph Hellwig 	{ "ADP7771", 0 }, /* AHA 274x */
128d6cbbad7SChristoph Hellwig 	{ "ADP7756", 1 }, /* AHA 284x BIOS enabled */
129d6cbbad7SChristoph Hellwig 	{ "ADP7757", 2 }, /* AHA 284x BIOS disabled */
130d6cbbad7SChristoph Hellwig 	{ "ADP7782", 3 }, /* AHA 274x Olivetti OEM */
131d6cbbad7SChristoph Hellwig 	{ "ADP7783", 4 }, /* AHA 274x Olivetti OEM (Differential) */
132d6cbbad7SChristoph Hellwig 	{ "ADP7770", 5 }, /* AIC7770 generic */
133d6cbbad7SChristoph Hellwig 	{ "" }
134d6cbbad7SChristoph Hellwig };
13507563c71SMichael Tokarev MODULE_DEVICE_TABLE(eisa, aic7770_ids);
136d6cbbad7SChristoph Hellwig 
137d6cbbad7SChristoph Hellwig static struct eisa_driver aic7770_driver = {
138d6cbbad7SChristoph Hellwig 	.id_table	= aic7770_ids,
139d6cbbad7SChristoph Hellwig 	.driver = {
140d6cbbad7SChristoph Hellwig 		.name   = "aic7xxx",
141d6cbbad7SChristoph Hellwig 		.probe  = aic7770_probe,
142d6cbbad7SChristoph Hellwig 		.remove = aic7770_remove,
143d6cbbad7SChristoph Hellwig 	}
144d6cbbad7SChristoph Hellwig };
145d6cbbad7SChristoph Hellwig 
146d6cbbad7SChristoph Hellwig int
ahc_linux_eisa_init(void)147d6cbbad7SChristoph Hellwig ahc_linux_eisa_init(void)
148d6cbbad7SChristoph Hellwig {
149d6cbbad7SChristoph Hellwig 	return eisa_driver_register(&aic7770_driver);
150d6cbbad7SChristoph Hellwig }
151d6cbbad7SChristoph Hellwig 
152d6cbbad7SChristoph Hellwig void
ahc_linux_eisa_exit(void)153d6cbbad7SChristoph Hellwig ahc_linux_eisa_exit(void)
154d6cbbad7SChristoph Hellwig {
155d6cbbad7SChristoph Hellwig 	eisa_driver_unregister(&aic7770_driver);
1561da177e4SLinus Torvalds }
157