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.7 1999/04/16 21:21:52 peter 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 "opt_global.h" |
37#include <sys/param.h> 38#include <sys/systm.h> 39#include <sys/kernel.h> 40#include <sys/interrupt.h> 41#include <sys/conf.h> |
42#include <sys/module.h> 43#include <sys/bus.h> |
44#include <sys/buf.h> 45#include <sys/malloc.h> 46#include <sys/devicestat.h> 47#include <vm/vm.h> 48#include <vm/pmap.h> |
49#include <machine/resource.h> 50#include <machine/bus.h> 51#include <sys/rman.h> |
52#include <machine/clock.h> 53#ifdef __i386__ 54#include <machine/smp.h> 55#endif 56#include <pci/pcivar.h> 57#include <pci/pcireg.h> |
58#include <isa/isavar.h> |
59#include <isa/isareg.h> |
60#include <dev/ata/ata-all.h> 61#include <dev/ata/ata-disk.h> 62#include <dev/ata/atapi-all.h> 63 64/* misc defines */ 65#define UNIT(dev) (dev>>3 & 0x1f) /* assume 8 minor # per unit */ 66#define MIN(a,b) ((a)>(b)?(b):(a)) |
67#if SMP == 0 |
68#define isa_apic_irq(x) x 69#endif 70 71/* prototypes */ |
72#if NPCI > 0 |
73static void promise_intr(int32_t); 74#endif |
75static int32_t ata_probe(int32_t, int32_t, int32_t, device_t, int32_t *); |
76static void ataintr(int32_t); 77 |
78/* 79 * Ought to be handled by the devclass. 80 */ |
81static int32_t atanlun = 0; 82struct ata_softc *atadevices[MAXATA]; 83 |
84static devclass_t ata_devclass; |
85 |
86#if NISA > 0 87 88static int 89ata_isaprobe(device_t dev) |
90{ |
91 struct resource *port; 92 int rid; |
93 int32_t ctlr, res; |
94 int unit; 95 96 /* Allocate the port range */ 97 rid = 0; 98 port = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 0, ~0, 1, RF_ACTIVE); 99 if (!port) 100 return (ENOMEM); 101 |
102 for (ctlr = 0; ctlr < atanlun; ctlr++) { |
103 if (atadevices[ctlr]->ioaddr == rman_get_start(port)) { |
104 printf("ata-isa%d: already registered as ata%d\n", |
105 device_get_unit(dev), ctlr); 106 bus_release_resource(dev, SYS_RES_IOPORT, 0, port); 107 return ENXIO; |
108 } 109 } |
110 111 /* 112 * XXX not sure what to do with the unit. The new bus code will 113 * automatically assign unit numbers for both pci and isa. For 114 * now, store it in the softc. 115 */ 116 res = ata_probe(rman_get_start(port), rman_get_start(port) + ATA_ALTPORT, 117 0, dev, &unit); 118 *(int *) device_get_softc(dev) = unit; 119 120 bus_release_resource(dev, SYS_RES_IOPORT, 0, port); 121 122 if (res) { 123 isa_set_portsize(dev, res); 124 return 0; 125 } 126 127 return ENXIO; |
128} 129 |
130static int 131ata_isaattach(device_t dev) |
132{ |
133 struct resource *port; 134 struct resource *irq; 135 int rid, unit; 136 void *ih; 137 138 /* Allocate the port range and interrupt */ 139 rid = 0; 140 port = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 0, ~0, 1, RF_ACTIVE); 141 if (!port) 142 return (ENOMEM); 143 144 rid = 0; 145 irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 0, ~0, 1, RF_ACTIVE); 146 if (!irq) { 147 bus_release_resource(dev, SYS_RES_IOPORT, 0, port); 148 return (ENOMEM); 149 } 150 151 /* 152 * The interrupt code could be changed to take the ata_softc as 153 * its argument directly. 154 */ 155 unit = *(int *) device_get_softc(dev); 156 return bus_setup_intr(dev, irq, (driver_intr_t *) ataintr, 157 (void*)(uintptr_t) unit, &ih); |
158} |
159 |
160static device_method_t ata_isa_methods[] = { 161 /* Device interface */ 162 DEVMETHOD(device_probe, ata_isaprobe), 163 DEVMETHOD(device_attach, ata_isaattach), 164 { 0, 0 } |
165}; 166 |
167static driver_t ata_isa_driver = { 168 "ata", 169 ata_isa_methods, 170 DRIVER_TYPE_BIO, 171 sizeof(int), 172}; |
173 |
174DRIVER_MODULE(ata, isa, ata_isa_driver, ata_devclass, 0, 0); 175 176#endif 177 178#if NPCI > 0 179 |
180static const char * |
181ata_pcimatch(device_t dev) |
182{ 183 u_int32_t data; 184 |
185 data = pci_read_config(dev, PCI_CLASS_REG, 4); 186 if (pci_get_class(dev) == PCIC_STORAGE && 187 (pci_get_subclass(dev) == PCIS_STORAGE_IDE || 188 pci_get_subclass(dev) == PCIS_STORAGE_RAID)) { 189 switch (pci_get_devid(dev)) { |
190 case 0x12308086: 191 return "Intel PIIX IDE controller"; 192 case 0x70108086: 193 return "Intel PIIX3 IDE controller"; 194 case 0x71118086: 195 return "Intel PIIX4 IDE controller"; 196 case 0x4d33105a: 197 return "Promise Ultra/33 IDE controller"; 198 case 0x522910b9: 199 return "AcerLabs Aladdin IDE controller"; |
200#if 0 201 case 0x05711106: 202 return "VIA Apollo IDE controller"; |
203 case 0x06401095: 204 return "CMD 640 IDE controller"; 205 case 0x06461095: 206 return "CMD 646 IDE controller"; |
207 case 0xc6931080: 208 return "Cypress 82C693 IDE controller"; |
209 case 0x01021078: 210 return "Cyrix 5530 IDE controller"; 211#endif 212 default: 213 return "Unknown PCI IDE controller"; 214 } 215 } 216 return NULL; 217} 218 |
219static int 220ata_pciprobe(device_t dev) |
221{ |
222 const char *desc = ata_pcimatch(dev); 223 if (desc) { 224 device_set_desc(dev, desc); 225 return 0; 226 } 227 else 228 return ENXIO; 229} 230 231static int 232ata_pciattach(device_t dev) 233{ 234 int unit = device_get_unit(dev); 235 u_int32_t type; 236 u_int8_t class, subclass; 237 u_int32_t cmd; |
238 int32_t iobase_1, iobase_2, altiobase_1, altiobase_2; 239 int32_t bmaddr_1 = 0, bmaddr_2 = 0, sysctrl = 0, irq1, irq2; 240 int32_t lun; 241 242 /* set up vendor-specific stuff */ |
243 type = pci_get_devid(dev); 244 class = pci_get_class(dev); 245 subclass = pci_get_subclass(dev); 246 cmd = pci_read_config(dev, PCIR_COMMAND, 4); |
247 248#ifdef ATA_DEBUG |
249 printf("ata%d: type=%08x class=%02x subclass=%02x cmd=%08x\n", 250 unit, type, class, subclass, cmd); |
251#endif 252 253 /* if this is a Promise controller handle it specially */ 254 if (type == 0x4d33105a) { |
255 iobase_1 = pci_read_config(dev, 0x10, 4) & 0xfffc; 256 altiobase_1 = pci_read_config(dev, 0x14, 4) & 0xfffc; 257 iobase_2 = pci_read_config(dev, 0x18, 4) & 0xfffc; 258 altiobase_2 = pci_read_config(dev, 0x1c, 4) & 0xfffc; 259 irq1 = irq2 = pci_read_config(dev, PCI_INTERRUPT_REG, 4) & 0xff; 260 bmaddr_1 = pci_read_config(dev, 0x20, 4) & 0xfffc; |
261 bmaddr_2 = bmaddr_1 + ATA_BM_OFFSET1; |
262 sysctrl = (pci_read_config(dev, 0x20, 4) & 0xfffc) + 0x1c; |
263 outb(bmaddr_1 + 0x1f, inb(bmaddr_1 + 0x1f) | 0x01); 264 printf("ata-pci%d: Busmastering DMA supported\n", unit); 265 } 266 /* everybody else seems to do it this way */ 267 else { |
268 if ((unit == 0) && 269 (pci_get_progif(dev) & PCIP_STORAGE_IDE_MODEPRIM) == 0) { |
270 iobase_1 = IO_WD1; 271 altiobase_1 = iobase_1 + ATA_ALTPORT; 272 irq1 = 14; 273 } 274 else { |
275 iobase_1 = pci_read_config(dev, 0x10, 4) & 0xfffc; 276 altiobase_1 = pci_read_config(dev, 0x14, 4) & 0xfffc; 277 irq1 = pci_read_config(dev, PCI_INTERRUPT_REG, 4) & 0xff; |
278 } |
279 if ((unit == 0) && 280 (pci_get_progif(dev) & PCIP_STORAGE_IDE_MODESEC) == 0) { |
281 iobase_2 = IO_WD2; 282 altiobase_2 = iobase_2 + ATA_ALTPORT; 283 irq2 = 15; 284 } 285 else { |
286 iobase_2 = pci_read_config(dev, 0x18, 4) & 0xfffc; 287 altiobase_2 = pci_read_config(dev, 0x1c, 4) & 0xfffc; 288 irq2 = pci_read_config(dev, PCI_INTERRUPT_REG, 4) & 0xff; |
289 } 290 291 /* is this controller busmaster capable ? */ |
292 if (pci_get_progif(dev) & PCIP_STORAGE_IDE_MASTERDEV) { |
293 /* is busmastering support turned on ? */ |
294 if ((pci_read_config(dev, PCI_COMMAND_STATUS_REG, 4) & 5) == 5) { |
295 /* is there a valid port range to connect to ? */ |
296 if ((bmaddr_1 = pci_read_config(dev, 0x20, 4) & 0xfffc)) { |
297 bmaddr_2 = bmaddr_1 + ATA_BM_OFFSET1; 298 printf("ata-pci%d: Busmastering DMA supported\n", unit); 299 } 300 else 301 printf("ata-pci%d: Busmastering DMA not configured\n",unit); 302 } 303 else 304 printf("ata-pci%d: Busmastering DMA not enabled\n", unit); 305 } 306 else 307 printf("ata-pci%d: Busmastering DMA not supported\n", unit); 308 } 309 310 /* now probe the addresse found for "real" ATA/ATAPI hardware */ 311 lun = 0; |
312 if (ata_probe(iobase_1, altiobase_1, bmaddr_1, dev, &lun)) { |
313 if (iobase_1 == IO_WD1) 314#ifdef __i386__ |
315 register_intr(irq1,(int)"",0,(inthand2_t *)ataintr,&bio_imask,lun); 316#endif 317#ifdef __alpha__ |
318 alpha_platform_setup_ide_intr(0, ataintr, (void *)(intptr_t)lun); 319#endif 320 else { |
321 struct resource *irq; 322 int rid = 0; 323 void *ih; 324 325 irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 0, ~0,1,RF_ACTIVE); |
326 if (sysctrl) |
327 bus_setup_intr(dev, irq, (driver_intr_t *)promise_intr, 328 (void *)lun, &ih); |
329 else |
330 bus_setup_intr(dev, irq, (driver_intr_t *)ataintr, 331 (void *)lun, &ih); |
332 } 333 printf("ata%d at 0x%04x irq %d on ata-pci%d\n", 334 lun, iobase_1, isa_apic_irq(irq1), unit); 335 } 336 lun = 1; |
337 if (ata_probe(iobase_2, altiobase_2, bmaddr_2, dev, &lun)) { |
338 if (iobase_2 == IO_WD2) 339#ifdef __i386__ |
340 register_intr(irq2,(int)"",0,(inthand2_t *)ataintr,&bio_imask,lun); 341#endif 342#ifdef __alpha__ |
343 alpha_platform_setup_ide_intr(1, ataintr, (void *)(intptr_t)lun); 344#endif 345 else { |
346 struct resource *irq; 347 int rid = 0; 348 void *ih; 349 350 irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 0, ~0,1,RF_ACTIVE); |
351 if (!sysctrl) |
352 bus_setup_intr(dev, irq, (driver_intr_t *)ataintr, 353 (void *)lun, &ih); |
354 } 355 printf("ata%d at 0x%04x irq %d on ata-pci%d\n", 356 lun, iobase_2, isa_apic_irq(irq2), unit); 357 } |
358 return 0; |
359} 360 |
361static device_method_t ata_pci_methods[] = { 362 /* Device interface */ 363 DEVMETHOD(device_probe, ata_pciprobe), 364 DEVMETHOD(device_attach, ata_pciattach), 365 { 0, 0 } 366}; 367 368static driver_t ata_pci_driver = { 369 "ata", 370 ata_pci_methods, 371 DRIVER_TYPE_BIO, 372 sizeof(int), 373}; 374 375DRIVER_MODULE(ata, pci, ata_pci_driver, ata_devclass, 0, 0); 376 |
377static void 378promise_intr(int32_t unit) 379{ 380 struct ata_softc *scp = atadevices[unit]; |
381 int32_t channel = inl((pci_read_config(scp->dev, 0x20, 4) & 0xfffc) + 0x1c); |
382 383 if (channel & 0x00000400) 384 ataintr(unit); 385 386 if (channel & 0x00004000) 387 ataintr(unit+1); 388} 389#endif 390 391static int32_t 392ata_probe(int32_t ioaddr, int32_t altioaddr, int32_t bmaddr, |
393 device_t dev, int32_t *unit) |
394{ 395 struct ata_softc *scp = atadevices[atanlun]; 396 int32_t mask = 0; 397 int32_t timeout; 398 int32_t lun = atanlun; 399 u_int8_t status0, status1; 400 401#ifdef ATA_STATIC_ID --- 130 unchanged lines hidden (view full) --- 532#endif 533 if (!scp->devices) { 534 free(scp, M_DEVBUF); 535 return 0; 536 } 537 bufq_init(&scp->ata_queue); 538 TAILQ_INIT(&scp->atapi_queue); 539 *unit = scp->lun; |
540 scp->dev = dev; |
541 if (bmaddr) 542 scp->bmaddr = bmaddr; 543 atadevices[scp->lun] = scp; 544#ifndef ATA_STATIC_ID 545 atanlun++; 546#endif |
547 return ATA_IOSIZE; 548} 549 550static void 551ataintr(int32_t unit) 552{ 553 struct ata_softc *scp; 554 struct atapi_request *atapi_request; --- 207 unchanged lines hidden --- |