Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
aic7770_osm.c
Go to the documentation of this file.
1 /*
2  * Linux driver attachment glue for aic7770 based controllers.
3  *
4  * Copyright (c) 2000-2003 Adaptec Inc.
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  * notice, this list of conditions, and the following disclaimer,
12  * without modification.
13  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
14  * substantially similar to the "NO WARRANTY" disclaimer below
15  * ("Disclaimer") and any redistribution must be conditioned upon
16  * including a substantially similar Disclaimer requirement for further
17  * binary redistribution.
18  * 3. Neither the names of the above-listed copyright holders nor the names
19  * of any contributors may be used to endorse or promote products derived
20  * from this software without specific prior written permission.
21  *
22  * Alternatively, this software may be distributed under the terms of the
23  * GNU General Public License ("GPL") version 2 as published by the Free
24  * Software Foundation.
25  *
26  * NO WARRANTY
27  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
28  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
29  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
30  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
31  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
32  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
33  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
34  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
35  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
36  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
37  * POSSIBILITY OF SUCH DAMAGES.
38  *
39  * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7770_osm.c#14 $
40  */
41 
42 #include "aic7xxx_osm.h"
43 
44 #include <linux/device.h>
45 #include <linux/eisa.h>
46 
47 int
49 {
50  /*
51  * Lock out other contenders for our i/o space.
52  */
53  if (!request_region(port, AHC_EISA_IOSIZE, "aic7xxx"))
54  return (ENOMEM);
55  ahc->tag = BUS_SPACE_PIO;
56  ahc->bsh.ioport = port;
57  return (0);
58 }
59 
60 int
61 aic7770_map_int(struct ahc_softc *ahc, u_int irq)
62 {
63  int error;
64  int shared;
65 
66  shared = 0;
67  if ((ahc->flags & AHC_EDGE_INTERRUPT) == 0)
68  shared = IRQF_SHARED;
69 
70  error = request_irq(irq, ahc_linux_isr, shared, "aic7xxx", ahc);
71  if (error == 0)
72  ahc->platform_data->irq = irq;
73 
74  return (-error);
75 }
76 
77 static int
78 aic7770_probe(struct device *dev)
79 {
80  struct eisa_device *edev = to_eisa_device(dev);
81  u_int eisaBase = edev->base_addr+AHC_EISA_SLOT_OFFSET;
82  struct ahc_softc *ahc;
83  char buf[80];
84  char *name;
85  int error;
86 
87  sprintf(buf, "ahc_eisa:%d", eisaBase >> 12);
88  name = kmalloc(strlen(buf) + 1, GFP_ATOMIC);
89  if (name == NULL)
90  return (ENOMEM);
91  strcpy(name, buf);
92  ahc = ahc_alloc(&aic7xxx_driver_template, name);
93  if (ahc == NULL)
94  return (ENOMEM);
95  error = aic7770_config(ahc, aic7770_ident_table + edev->id.driver_data,
96  eisaBase);
97  if (error != 0) {
98  ahc->bsh.ioport = 0;
99  ahc_free(ahc);
100  return (error);
101  }
102 
103  dev_set_drvdata(dev, ahc);
104 
106  return (error);
107 }
108 
109 static int
110 aic7770_remove(struct device *dev)
111 {
112  struct ahc_softc *ahc = dev_get_drvdata(dev);
113  u_long s;
114 
115  if (ahc->platform_data && ahc->platform_data->host)
116  scsi_remove_host(ahc->platform_data->host);
117 
118  ahc_lock(ahc, &s);
119  ahc_intr_enable(ahc, FALSE);
120  ahc_unlock(ahc, &s);
121 
122  ahc_free(ahc);
123  return 0;
124 }
125 
126 static struct eisa_device_id aic7770_ids[] = {
127  { "ADP7771", 0 }, /* AHA 274x */
128  { "ADP7756", 1 }, /* AHA 284x BIOS enabled */
129  { "ADP7757", 2 }, /* AHA 284x BIOS disabled */
130  { "ADP7782", 3 }, /* AHA 274x Olivetti OEM */
131  { "ADP7783", 4 }, /* AHA 274x Olivetti OEM (Differential) */
132  { "ADP7770", 5 }, /* AIC7770 generic */
133  { "" }
134 };
135 MODULE_DEVICE_TABLE(eisa, aic7770_ids);
136 
137 static struct eisa_driver aic7770_driver = {
138  .id_table = aic7770_ids,
139  .driver = {
140  .name = "aic7xxx",
141  .probe = aic7770_probe,
142  .remove = aic7770_remove,
143  }
144 };
145 
146 int
148 {
149  return eisa_driver_register(&aic7770_driver);
150 }
151 
152 void
154 {
155  eisa_driver_unregister(&aic7770_driver);
156 }