Deleted Added
sdiff udiff text old ( 45720 ) new ( 45798 )
full compact
1/*-
2 * Copyright (c) 1998,1999 S�ren Schmidt
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 11 unchanged lines hidden (view full) ---

20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 * $Id: ata-all.c,v 1.6 1999/04/10 18:53:35 sos Exp $
29 */
30
31#include "ata.h"
32#if NATA > 0
33#include "isa.h"
34#include "pci.h"
35#include "atadisk.h"
36#include <sys/param.h>
37#include <sys/systm.h>
38#include <sys/kernel.h>
39#include <sys/interrupt.h>
40#include <sys/conf.h>
41#include <sys/buf.h>
42#include <sys/malloc.h>
43#include <sys/devicestat.h>
44#include <vm/vm.h>
45#include <vm/pmap.h>
46#include <machine/clock.h>
47#ifdef __i386__
48#include <machine/smp.h>
49#endif
50#include <pci/pcivar.h>
51#include <pci/pcireg.h>
52#ifdef __i386__
53#include <i386/isa/icu.h>
54#include <i386/isa/isa.h>
55#include <i386/isa/isa_device.h>
56#else
57#include <isa/isareg.h>
58#endif
59#include <dev/ata/ata-all.h>
60#include <dev/ata/ata-disk.h>
61#include <dev/ata/atapi-all.h>
62
63/* misc defines */
64#define UNIT(dev) (dev>>3 & 0x1f) /* assume 8 minor # per unit */
65#define MIN(a,b) ((a)>(b)?(b):(a))
66#if NSMP == 0
67#define isa_apic_irq(x) x
68#endif
69
70/* prototypes */
71#if NISA > 0 && defined(__i386__)
72static int32_t ata_isaprobe(struct isa_device *);
73static int32_t ata_isaattach(struct isa_device *);
74#endif
75#if NPCI > 0
76static const char *ata_pciprobe(pcici_t, pcidi_t);
77static void ata_pciattach(pcici_t, int32_t);
78static void promise_intr(int32_t);
79#endif
80static int32_t ata_probe(int32_t, int32_t, int32_t, pcici_t, int32_t *);
81static void ataintr(int32_t);
82
83static int32_t atanlun = 0;
84struct ata_softc *atadevices[MAXATA];
85
86#if NISA > 0 && defined(__i386__)
87struct isa_driver atadriver = { ata_isaprobe, ata_isaattach, "ata" };
88
89static int32_t
90ata_isaprobe(struct isa_device *devp)
91{
92 int32_t ctlr, res;
93
94 for (ctlr = 0; ctlr < atanlun; ctlr++) {
95 if (atadevices[ctlr]->ioaddr == devp->id_iobase) {
96 printf("ata-isa%d: already registered as ata%d\n",
97 devp->id_unit, ctlr);
98 return 0;
99 }
100 }
101 res = ata_probe(devp->id_iobase, devp->id_iobase + ATA_ALTPORT, 0, 0,
102 &devp->id_unit);
103 if (res)
104 devp->id_intr = (inthand2_t *)ataintr;
105 return res;
106}
107
108static int32_t
109ata_isaattach(struct isa_device *devp)
110{
111 return 1;
112}
113#endif
114
115#if NPCI > 0
116static u_long ata_pcicount;
117static struct pci_device ata_pcidevice = {
118 "ata-pci", ata_pciprobe, ata_pciattach, &ata_pcicount, 0
119};
120
121DATA_SET(pcidevice_set, ata_pcidevice);
122
123static const char *
124ata_pciprobe(pcici_t tag, pcidi_t type)
125{
126 u_int32_t data;
127
128 data = pci_conf_read(tag, PCI_CLASS_REG);
129 if ((data & PCI_CLASS_MASK) == PCI_CLASS_MASS_STORAGE &&
130 ((data & PCI_SUBCLASS_MASK) == 0x00010000 ||
131 ((data & PCI_SUBCLASS_MASK) == 0x00040000))) {
132 switch (type) {
133 case 0x12308086:
134 return "Intel PIIX IDE controller";
135 case 0x70108086:
136 return "Intel PIIX3 IDE controller";
137 case 0x71118086:
138 return "Intel PIIX4 IDE controller";
139 case 0x4d33105a:
140 return "Promise Ultra/33 IDE controller";
141 case 0x522910b9:
142 return "AcerLabs Aladdin IDE controller";
143 case 0x06401095:
144 return "CMD 640 IDE controller";
145 case 0x06461095:
146 return "CMD 646 IDE controller";
147#if 0
148 case 0x05711106:
149 return "VIA Apollo IDE controller";
150 case 0x01021078:
151 return "Cyrix 5530 IDE controller";
152#endif
153 default:
154 return "Unknown PCI IDE controller";
155 }
156 }
157 return NULL;
158}
159
160static void
161ata_pciattach(pcici_t tag, int32_t unit)
162{
163 pcidi_t type, class, cmd;
164 int32_t iobase_1, iobase_2, altiobase_1, altiobase_2;
165 int32_t bmaddr_1 = 0, bmaddr_2 = 0, sysctrl = 0, irq1, irq2;
166 int32_t lun;
167
168 /* set up vendor-specific stuff */
169 type = pci_conf_read(tag, PCI_ID_REG);
170 class = pci_conf_read(tag, PCI_CLASS_REG);
171 cmd = pci_conf_read(tag, PCI_COMMAND_STATUS_REG);
172
173#ifdef ATA_DEBUG
174 printf("ata%d: type=%08x class=%08x cmd=%08x\n", unit, type, class, cmd);
175#endif
176
177 /* if this is a Promise controller handle it specially */
178 if (type == 0x4d33105a) {
179 iobase_1 = pci_conf_read(tag, 0x10) & 0xfffc;
180 altiobase_1 = pci_conf_read(tag, 0x14) & 0xfffc;
181 iobase_2 = pci_conf_read(tag, 0x18) & 0xfffc;
182 altiobase_2 = pci_conf_read(tag, 0x1c) & 0xfffc;
183 irq1 = irq2 = pci_conf_read(tag, PCI_INTERRUPT_REG) & 0xff;
184 bmaddr_1 = pci_conf_read(tag, 0x20) & 0xfffc;
185 bmaddr_2 = bmaddr_1 + ATA_BM_OFFSET1;
186 sysctrl = (pci_conf_read(tag, 0x20) & 0xfffc) + 0x1c;
187 outb(bmaddr_1 + 0x1f, inb(bmaddr_1 + 0x1f) | 0x01);
188 printf("ata-pci%d: Busmastering DMA supported\n", unit);
189 }
190 /* everybody else seems to do it this way */
191 else {
192 if ((class & 0x100) == 0) {
193 iobase_1 = IO_WD1;
194 altiobase_1 = iobase_1 + ATA_ALTPORT;
195 irq1 = 14;
196 }
197 else {
198 iobase_1 = pci_conf_read(tag, 0x10) & 0xfffc;
199 altiobase_1 = pci_conf_read(tag, 0x14) & 0xfffc;
200 irq1 = pci_conf_read(tag, PCI_INTERRUPT_REG) & 0xff;
201 }
202 if ((class & 0x400) == 0) {
203 iobase_2 = IO_WD2;
204 altiobase_2 = iobase_2 + ATA_ALTPORT;
205 irq2 = 15;
206 }
207 else {
208 iobase_2 = pci_conf_read(tag, 0x18) & 0xfffc;
209 altiobase_2 = pci_conf_read(tag, 0x1c) & 0xfffc;
210 irq2 = pci_conf_read(tag, PCI_INTERRUPT_REG) & 0xff;
211 }
212
213 /* is this controller busmaster capable ? */
214 if (pci_conf_read(tag, PCI_CLASS_REG) & 0x8000) {
215 /* is busmastering support turned on ? */
216 if ((pci_conf_read(tag, PCI_COMMAND_STATUS_REG) & 5) == 5) {
217 /* is there a valid port range to connect to ? */
218 if ((bmaddr_1 = pci_conf_read(tag, 0x20) & 0xfffc)) {
219 bmaddr_2 = bmaddr_1 + ATA_BM_OFFSET1;
220 printf("ata-pci%d: Busmastering DMA supported\n", unit);
221 }
222 else
223 printf("ata-pci%d: Busmastering DMA not configured\n",unit);
224 }
225 else
226 printf("ata-pci%d: Busmastering DMA not enabled\n", unit);
227 }
228 else
229 printf("ata-pci%d: Busmastering DMA not supported\n", unit);
230 }
231
232 /* now probe the addresse found for "real" ATA/ATAPI hardware */
233 lun = 0;
234 if (ata_probe(iobase_1, altiobase_1, bmaddr_1, tag, &lun)) {
235 if (iobase_1 == IO_WD1)
236#ifdef __i386__
237 register_intr(irq1, (int)"", 0, (inthand2_t *)ataintr,
238 &bio_imask, lun);
239#else
240 alpha_platform_setup_ide_intr(0, ataintr, (void *)(intptr_t)lun);
241#endif
242 else {
243 if (sysctrl)
244 pci_map_int(tag, (inthand2_t *)promise_intr,
245 (void *)(intptr_t)lun, &bio_imask);
246 else
247 pci_map_int(tag, (inthand2_t *)ataintr, (void *)(intptr_t)lun,&bio_imask);
248 }
249 printf("ata%d at 0x%04x irq %d on ata-pci%d\n",
250 lun, iobase_1, isa_apic_irq(irq1), unit);
251 }
252 lun = 1;
253 if (ata_probe(iobase_2, altiobase_2, bmaddr_2, tag, &lun)) {
254 if (iobase_2 == IO_WD2)
255#ifdef __i386__
256 register_intr(irq2, (int)"", 0, (inthand2_t *)ataintr,
257 &bio_imask, lun);
258#else
259 alpha_platform_setup_ide_intr(1, ataintr, (void *)(intptr_t)lun);
260#endif
261 else {
262 if (!sysctrl)
263 pci_map_int(tag, (inthand2_t *)ataintr, (void *)(intptr_t)lun,&bio_imask);
264 }
265 printf("ata%d at 0x%04x irq %d on ata-pci%d\n",
266 lun, iobase_2, isa_apic_irq(irq2), unit);
267 }
268}
269
270static void
271promise_intr(int32_t unit)
272{
273 struct ata_softc *scp = atadevices[unit];
274 int32_t channel = inl((pci_conf_read(scp->tag, 0x20) & 0xfffc) + 0x1c);
275
276 if (channel & 0x00000400)
277 ataintr(unit);
278
279 if (channel & 0x00004000)
280 ataintr(unit+1);
281}
282#endif
283
284static int32_t
285ata_probe(int32_t ioaddr, int32_t altioaddr, int32_t bmaddr,
286 pcici_t tag, int32_t *unit)
287{
288 struct ata_softc *scp = atadevices[atanlun];
289 int32_t mask = 0;
290 int32_t timeout;
291 int32_t lun = atanlun;
292 u_int8_t status0, status1;
293
294#ifdef ATA_STATIC_ID

--- 130 unchanged lines hidden (view full) ---

425#endif
426 if (!scp->devices) {
427 free(scp, M_DEVBUF);
428 return 0;
429 }
430 bufq_init(&scp->ata_queue);
431 TAILQ_INIT(&scp->atapi_queue);
432 *unit = scp->lun;
433 scp->tag = tag;
434 if (bmaddr)
435 scp->bmaddr = bmaddr;
436 atadevices[scp->lun] = scp;
437#ifndef ATA_STATIC_ID
438 atanlun++;
439#endif
440 outb(scp->ioaddr + ATA_DRIVE, ATA_D_IBM | ATA_MASTER);
441 return ATA_IOSIZE;
442}
443
444static void
445ataintr(int32_t unit)
446{
447 struct ata_softc *scp;
448 struct atapi_request *atapi_request;

--- 207 unchanged lines hidden ---