File: /usr/src/linux/drivers/scsi/aic7xxx/aic7770_linux.c
1 /*
2 * Linux driver attachment glue for aic7770 based controllers.
3 *
4 * Copyright (c) 2000 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. The name of the author may not be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * Alternatively, this software may be distributed under the terms of the
17 * GNU General Public License ("GPL").
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
23 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 *
31 * $Id: //depot/src/linux/drivers/scsi/aic7xxx/aic7770_linux.c#7 $
32 */
33
34 #include "aic7xxx_osm.h"
35
36 #define MINSLOT 1
37 #define NUMSLOTS 16
38 #define IDOFFSET 0x80
39
40 int
41 aic7770_linux_probe(Scsi_Host_Template *template)
42 {
43 #if defined(__i386__) || defined(__alpha__)
44 struct aic7770_identity *entry;
45 struct ahc_softc *ahc;
46 int i, slot;
47 int eisaBase;
48 int found;
49
50 if (aic7xxx_no_probe)
51 return (0);
52
53 eisaBase = 0x1000 + AHC_EISA_SLOT_OFFSET;
54 found = 0;
55 for (slot = 1; slot < NUMSLOTS; eisaBase+=0x1000, slot++) {
56 uint32_t eisa_id;
57 size_t id_size;
58
59 if (check_region(eisaBase, AHC_EISA_IOSIZE) != 0)
60 continue;
61
62 eisa_id = 0;
63 id_size = sizeof(eisa_id);
64 for (i = 0; i < 4; i++) {
65 /* VLcards require priming*/
66 outb(0x80 + i, eisaBase + IDOFFSET);
67 eisa_id |= inb(eisaBase + IDOFFSET + i)
68 << ((id_size-i-1) * 8);
69 }
70 if (eisa_id & 0x80000000)
71 continue; /* no EISA card in slot */
72
73 entry = aic7770_find_device(eisa_id);
74 if (entry != NULL) {
75 char buf[80];
76 char *name;
77 int error;
78
79 /*
80 * Allocate a softc for this card and
81 * set it up for attachment by our
82 * common detect routine.
83 */
84 sprintf(buf, "ahc_eisa:%d", slot);
85 name = malloc(strlen(buf) + 1, M_DEVBUF, M_NOWAIT);
86 if (name == NULL)
87 break;
88 strcpy(name, buf);
89 ahc = ahc_alloc(template, name);
90 if (ahc == NULL) {
91 /*
92 * If we can't allocate this one,
93 * chances are we won't be able to
94 * allocate future card structures.
95 */
96 break;
97 }
98 ahc->tag = BUS_SPACE_PIO;
99 ahc->bsh.ioport = eisaBase;
100 error = aic7770_config(ahc, entry);
101 if (error != 0) {
102 ahc_free(ahc);
103 continue;
104 }
105 found++;
106 }
107 }
108 return (found);
109 #else
110 return (0);
111 #endif
112 }
113
114 int
115 aic7770_map_registers(struct ahc_softc *ahc)
116 {
117 /*
118 * Lock out other contenders for our i/o space.
119 */
120 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
121 request_region(ahc->bsh.ioport, AHC_EISA_IOSIZE, "aic7xxx");
122 #else
123 if (request_region(ahc->bsh.ioport, AHC_EISA_IOSIZE, "aic7xxx") == 0)
124 return (ENOMEM);
125 #endif
126
127 return (0);
128 }
129
130 int
131 aic7770_map_int(struct ahc_softc *ahc, u_int irq)
132 {
133 int error;
134 int shared;
135
136 shared = 0;
137 if ((ahc->flags & AHC_EDGE_INTERRUPT) == 0)
138 shared = SA_SHIRQ;
139
140 ahc->platform_data->irq = irq;
141 error = request_irq(ahc->platform_data->irq, ahc_linux_isr,
142 shared, "aic7xxx", ahc);
143
144 return (-error);
145 }
146