Deleted Added
sdiff udiff text old ( 44566 ) new ( 45095 )
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.3 1999/03/05 09:43:30 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 <machine/clock.h>
45#include <pci/pcivar.h>
46#include <pci/pcireg.h>
47#include <i386/isa/icu.h>
48#include <i386/isa/isa.h>
49#include <i386/isa/isa_device.h>
50#include <dev/ata/ata-all.h>
51#include <dev/ata/ata-disk.h>
52#include <dev/ata/atapi-all.h>
53
54/* misc defines */
55#define UNIT(dev) (dev>>3 & 0x1f) /* assume 8 minor # per unit */
56
57/* prototypes */
58#if NISA > 0
59static int32_t ata_isaprobe(struct isa_device *);
60static int32_t ata_isaattach(struct isa_device *);
61#endif
62#if NPCI > 0
63static const char *ata_pciprobe(pcici_t, pcidi_t);
64static void ata_pciattach(pcici_t, int32_t);
65static void promise_intr(int32_t);
66#endif
67static int32_t ata_probe(int32_t, int32_t, int32_t *);
68static void ataintr(int32_t);
69
70static int32_t atanlun = 0, sysctrl = 0;
71struct ata_softc *atadevices[MAXATA];
72struct isa_driver atadriver = { ata_isaprobe, ata_isaattach, "ata" };
73
74#if NISA > 0
75static int32_t
76ata_isaprobe(struct isa_device *devp)
77{
78 int32_t ctlr, res;
79
80 for (ctlr = 0; ctlr < atanlun; ctlr++) {
81 if (atadevices[ctlr]->ioaddr == devp->id_iobase) {
82 printf("ata-isa%d: already registered as ata%d\n",
83 devp->id_unit, ctlr);
84 return 0;
85 }
86 }
87 res=ata_probe(devp->id_iobase, devp->id_iobase+ATA_ALTPORT, &devp->id_unit);
88 if (res)
89 devp->id_intr = (inthand2_t *)ataintr;
90 return res;
91}
92
93static int32_t
94ata_isaattach(struct isa_device *devp)
95{

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

110{
111 u_int32_t data;
112
113 data = pci_conf_read(tag, PCI_CLASS_REG);
114 if ((data & PCI_CLASS_MASK) == PCI_CLASS_MASS_STORAGE &&
115 ((data & PCI_SUBCLASS_MASK) == 0x00010000 ||
116 ((data & PCI_SUBCLASS_MASK) == 0x00040000))) {
117 switch (type) {
118 case 0x71118086:
119 return "Intel PIIX4 IDE controller";
120 case 0x70108086:
121 return "Intel PIIX3 IDE controller";
122 case 0x12308086:
123 return "Intel PIIX IDE controller";
124 case 0x4d33105a:
125 return "Promise Ultra/33 IDE controller";
126 case 0x05711106:
127 return "VIA Apollo IDE controller";
128 case 0x01021078:
129 return "Cyrix 5530 IDE controller";
130 case 0x522910b9:
131 return "Acer Aladdin IV/V IDE controller";
132 default:
133 return "Unknown PCI IDE controller";
134 }
135 }
136 return NULL;
137}
138
139static void
140ata_pciattach(pcici_t tag, int32_t unit)
141{
142 pcidi_t type, class, cmd;
143 int32_t iobase_1, iobase_2, altiobase_1, altiobase_2, irq1, irq2;
144 int32_t lun;
145
146 /* set up vendor-specific stuff */
147 type = pci_conf_read(tag, PCI_ID_REG);
148 class = pci_conf_read(tag, PCI_CLASS_REG);
149 cmd = pci_conf_read(tag, PCI_COMMAND_STATUS_REG);
150
151#ifdef ATA_DEBUG
152 printf("ata: type=%08x class=%08x cmd=%08x\n", type, class, cmd);
153#endif
154
155 switch (type) {
156 case 0x71118086:
157 case 0x70108086:
158 case 0x12308086: /* Intel PIIX, PIIX3, PIIX4 */
159 break;
160
161 case 0x05711106: /* VIA Apollo chipset family */
162 break;
163
164 case 0x4d33105a: /* Promise controllers */
165 break;
166
167 case 0x01021078: /* Cyrix 5530 */
168 break;
169
170 case 0x522910B9: /* Acer Aladdin IV/V (M5229) */
171 break;
172 default:
173 /* everybody else */
174 break;
175 }
176
177 if (type == 0x4d33105a) { /* the Promise is special */
178 iobase_1 = pci_conf_read(tag, 0x10) & 0xfffc;
179 altiobase_1 = pci_conf_read(tag, 0x14) & 0xfffc;
180 iobase_2 = pci_conf_read(tag, 0x18) & 0xfffc;
181 altiobase_2 = pci_conf_read(tag, 0x1c) & 0xfffc;
182 irq1 = irq2 = pci_conf_read(tag, PCI_INTERRUPT_REG) & 0xff;
183 sysctrl = (pci_conf_read(tag, 0x20) & 0xfffc) + 0x1c;
184 }
185 else {
186 if ((class & 0x100) == 0) {
187 iobase_1 = IO_WD1;
188 altiobase_1 = iobase_1 + ATA_ALTPORT;
189 irq1 = 14;
190 }
191 else {
192 iobase_1 = pci_conf_read(tag, 0x10) & 0xfffc;

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

198 altiobase_2 = iobase_2 + ATA_ALTPORT;
199 irq2 = 15;
200 }
201 else {
202 iobase_2 = pci_conf_read(tag, 0x18) & 0xfffc;
203 altiobase_2 = pci_conf_read(tag, 0x1c) & 0xfffc;
204 irq2 = pci_conf_read(tag, PCI_INTERRUPT_REG) & 0xff;
205 }
206 }
207
208 /* now probe the addresse found for "real" ATA/ATAPI hardware */
209 if (ata_probe(iobase_1, altiobase_1, &lun)) {
210 if (iobase_1 == IO_WD1)
211 register_intr(irq1, 0, 0, (inthand2_t *)ataintr, &bio_imask, lun);
212 else {
213 if (sysctrl)
214 pci_map_int(tag, (inthand2_t *)promise_intr,
215 (void *)lun, &bio_imask);
216 else
217 pci_map_int(tag, (inthand2_t *)ataintr, (void *)lun,&bio_imask);
218 }
219 printf("ata%d at 0x%04x irq %d on ata-pci%d\n",
220 lun, iobase_1, irq1, unit);
221 }
222 if (ata_probe(iobase_2, altiobase_2, &lun)) {
223 if (iobase_2 == IO_WD2)
224 register_intr(irq2, 0, 0, (inthand2_t *)ataintr, &bio_imask, lun);
225 else {
226 if (!sysctrl)
227 pci_map_int(tag, (inthand2_t *)ataintr, (void *)lun,&bio_imask);
228 }
229 printf("ata%d at 0x%04x irq %d on ata-pci%d\n",
230 lun, iobase_2, irq2, unit);
231 }
232}
233
234static void
235promise_intr(int32_t unit)
236{
237 if (inl(sysctrl) & 0x00000400)
238 ataintr(unit);
239 if (inl(sysctrl) & 0x00004000)
240 ataintr(unit+1);
241}
242#endif
243
244static int32_t
245ata_probe(int32_t ioaddr, int32_t altioaddr, int32_t *unit)
246{
247 struct ata_softc *scp = atadevices[atanlun];
248 int32_t mask = 0;
249 int32_t timeout;
250 int32_t lun = atanlun;
251 u_int8_t status0, status1;
252
253#ifdef ATA_STATIC_ID
254 atanlun++;
255#endif
256 if (lun > MAXATA) {
257 printf("ata: unit of of range(%d)\n", lun);
258 return 0;
259 }
260 if (scp) {
261 printf("ata%d: unit already attached\n", lun);
262 return 0;
263 }
264 scp = malloc(sizeof(struct ata_softc), M_DEVBUF, M_NOWAIT);
265 if (scp == NULL) {
266 printf("ata%d: failed to allocate driver storage\n", lun);
267 return 0;
268 }
269 bzero(scp, sizeof(struct ata_softc));
270
271 scp->unit = lun;
272 scp->ioaddr = ioaddr;
273 scp->altioaddr = altioaddr;
274 scp->active = ATA_IDLE;
275
276#ifdef ATA_DEBUG
277 printf("ata%d: iobase=0x%04x altiobase=0x%04x\n",
278 scp->unit, scp->ioaddr, scp->altioaddr);
279#endif
280
281 /* do we have any signs of ATA/ATAPI HW being present ? */
282 outb(scp->ioaddr + ATA_DRIVE, ATA_D_IBM | ATA_MASTER);
283 DELAY(1);
284 status0 = inb(scp->ioaddr + ATA_STATUS);
285 outb(scp->ioaddr + ATA_DRIVE, ATA_D_IBM | ATA_SLAVE);
286 DELAY(1);
287 status1 = inb(scp->ioaddr + ATA_STATUS);
288 if ((status0 & 0xf8) != 0xf8)
289 mask |= 0x01;
290 if ((status1 & 0xf8) != 0xf8)
291 mask |= 0x02;
292#ifdef ATA_DEBUG
293 printf("ata%d: mask=%02x status0=%02x status1=%02x\n",
294 scp->unit, mask, status0, status1);
295#endif
296 if (!mask) {
297 free(scp, M_DEVBUF);
298 return 0;
299 }
300 /* assert reset for devices and wait for completition */
301 outb(scp->ioaddr + ATA_DRIVE, ATA_D_IBM | ATA_MASTER);
302 DELAY(1);
303 outb(scp->altioaddr, ATA_A_IDS | ATA_A_RESET);
304 DELAY(1000);
305 outb(scp->altioaddr, ATA_A_IDS);
306 DELAY(1000);
307 inb(scp->ioaddr + ATA_ERROR);
308 outb(scp->altioaddr, ATA_A_4BIT);
309 DELAY(1);
310
311 /* wait for BUSY to go inactive */
312 for (timeout = 0; timeout < 30000*10; timeout++) {
313 outb(scp->ioaddr + ATA_DRIVE, ATA_D_IBM | ATA_MASTER);
314 DELAY(1);
315 status0 = inb(scp->ioaddr + ATA_STATUS);

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

328 DELAY(100);
329 }
330 if (status0 & ATA_S_BSY)
331 mask &= ~0x01;
332 if (status1 & ATA_S_BSY)
333 mask &= ~0x02;
334#ifdef ATA_DEBUG
335 printf("ata%d: mask=%02x status0=%02x status1=%02x\n",
336 scp->unit, mask, status0, status1);
337#endif
338 if (!mask) {
339 free(scp, M_DEVBUF);
340 return 0;
341 }
342 /*
343 * OK, we have at least one device on the chain,
344 * check for ATAPI signatures, if none check if its

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

373 outb(scp->ioaddr + ATA_ERROR, 0x58);
374 outb(scp->ioaddr + ATA_CYL_LSB, 0xa5);
375 if (inb(scp->ioaddr + ATA_ERROR) != 0x58 &&
376 inb(scp->ioaddr + ATA_CYL_LSB) == 0xa5) {
377 scp->devices |= ATA_ATA_SLAVE;
378 }
379 }
380#ifdef ATA_DEBUG
381 printf("ata%d: devices = 0x%x\n", scp->unit, scp->devices);
382#endif
383 if (!(scp->devices & (ATA_ATA_MASTER|ATA_ATAPI_MASTER)))
384 scp->flags |= ATA_F_SLAVE_ONLY;
385 if (!scp->devices) {
386 free(scp, M_DEVBUF);
387 return 0;
388 }
389 bufq_init(&scp->ata_queue);
390 TAILQ_INIT(&scp->atapi_queue);
391 *unit = scp->unit;
392 atadevices[scp->unit] = scp;
393#ifndef ATA_STATIC_ID
394 atanlun++;
395#endif
396 return ATA_IOSIZE;
397}
398
399static void
400ataintr(int32_t unit)
401{
402 struct ata_softc *scp;
403 struct atapi_request *atapi_request;
404 struct buf *ata_request;
405
406 static int32_t intcount = 0;
407
408#ifdef ATA_DEBUG
409 printf("ataintr: entered unit=%d\n", unit);
410#endif
411 if (unit < 0 || unit > atanlun) {
412 printf("ataintr: unit %d unusable\n", unit);
413 return;
414 }
415
416 scp = atadevices[unit];
417
418 /* find & call the responsible driver to process this interrupt */

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

434 wakeup((caddr_t)scp);
435 break;
436
437 case ATA_IGNORE_INTR:
438 break;
439
440 default:
441 case ATA_IDLE:
442 if (intcount++ < 5)
443 printf("ata%d: unwanted interrupt\n", unit);
444 return;
445 }
446 scp->active = ATA_IDLE;
447 ata_start(scp);
448}
449
450void
451ata_start(struct ata_softc *scp)
452{
453 struct buf *ata_request;
454 struct atapi_request *atapi_request;
455
456#ifdef ATA_DEBUG
457 printf("ata_start: entered\n");
458#endif
459 if (scp->active) {
460 printf("ata: unwanted ata_start\n");
461 return;
462 }
463
464 /* find & call the responsible driver if anything on ATA queue */
465 if ((ata_request = bufq_first(&scp->ata_queue))) {
466 scp->active = ATA_ACTIVE_ATA;
467 ad_transfer(ata_request);
468 }
469
470 /* find & call the responsible driver if anything on ATAPI queue */
471 if ((atapi_request = TAILQ_FIRST(&scp->atapi_queue))) {
472 scp->active = ATA_ACTIVE_ATAPI;
473 atapi_transfer(atapi_request);
474 }
475}
476
477int32_t
478ata_wait(struct ata_softc *scp, u_int8_t mask)
479{
480 u_int8_t status;
481 u_int32_t timeout = 0;
482
483 while (timeout++ <= 50000) { /* timeout 5 secs */
484 status = inb(scp->ioaddr + ATA_STATUS);
485 if ((status == 0xff) && (scp->flags & ATA_F_SLAVE_ONLY)) {
486 outb(scp->ioaddr + ATA_DRIVE, ATA_D_IBM | ATA_SLAVE);
487 DELAY(1);
488 status = inb(scp->ioaddr + ATA_STATUS);
489 }
490 if (status == 0xff)
491 return -1;
492 scp->status = status;
493 if (!(status & ATA_S_BSY)) {
494 if (status & ATA_S_ERROR)

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

502 DELAY(10);
503 }
504 return -1;
505}
506
507int32_t
508ata_command(struct ata_softc *scp, int32_t device, u_int32_t command,
509 u_int32_t cylinder, u_int32_t head, u_int32_t sector,
510 u_int32_t count, int32_t flags)
511{
512 /* ready to issue command ? */
513 if (ata_wait(scp, 0) < 0) {
514 printf("ata_command: timeout waiting to give command");
515 return -1;
516 }
517 outb(scp->ioaddr + ATA_DRIVE, ATA_D_IBM | device | head);
518 outb(scp->ioaddr + ATA_PRECOMP, 0); /* no precompensation */
519 outb(scp->ioaddr + ATA_CYL_LSB, cylinder);
520 outb(scp->ioaddr + ATA_CYL_MSB, cylinder >> 8);
521 outb(scp->ioaddr + ATA_SECTOR, sector);
522 outb(scp->ioaddr + ATA_COUNT, count);
523
524 if (scp->active && flags != ATA_IMMEDIATE)
525 printf("DANGER active=%d\n", scp->active);
526
527 switch (flags) {
528 case ATA_WAIT_INTR:
529 scp->active = ATA_WAIT_INTR;
530 outb(scp->ioaddr + ATA_CMD, command);
531 if (tsleep((caddr_t)scp, PRIBIO, "atacmd", 500)) {
532 printf("ata_command: timeout waiting for interrupt");

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

540 outb(scp->ioaddr + ATA_CMD, command);
541 break;
542
543 case ATA_IMMEDIATE:
544 default:
545 outb(scp->ioaddr + ATA_CMD, command);
546 break;
547 }
548 return 0;
549}
550
551void
552bswap(int8_t *buf, int32_t len)
553{
554 u_int16_t *p = (u_int16_t*)(buf + len);
555

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

582 continue;
583 }
584 if (src[i] == ' ')
585 blank = 1;
586 dst[j++] = src[i];
587 }
588 dst[j] = 0x00;
589}
590#endif