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
9 * notice, this list of conditions and the following disclaimer,
10 * without modification, immediately at the beginning of the file.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
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.5 1999/03/28 18:57:18 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#include <machine/smp.h>
48#include <pci/pcivar.h>
49#include <pci/pcireg.h>
50#include <i386/isa/icu.h>
51#include <i386/isa/isa.h>
52#include <i386/isa/isa_device.h>
53#include <dev/ata/ata-all.h>
54#include <dev/ata/ata-disk.h>
55#include <dev/ata/atapi-all.h>
56
57/* misc defines */
58#define UNIT(dev) (dev>>3 & 0x1f) /* assume 8 minor # per unit */
59#define MIN(a,b) ((a)>(b)?(b):(a))
60#if NSMP == 0
61#define isa_apic_irq(x) x
62#endif
63
64/* prototypes */
65#if NISA > 0
66static int32_t ata_isaprobe(struct isa_device *);
67static int32_t ata_isaattach(struct isa_device *);
68#endif
69#if NPCI > 0
70static const char *ata_pciprobe(pcici_t, pcidi_t);
71static void ata_pciattach(pcici_t, int32_t);
72static void promise_intr(int32_t);
73#endif
74static int32_t ata_probe(int32_t, int32_t, int32_t, pcici_t, int32_t *);
75static void ataintr(int32_t);
76
77static int32_t atanlun = 0;
78struct ata_softc *atadevices[MAXATA];
79struct isa_driver atadriver = { ata_isaprobe, ata_isaattach, "ata" };
80
81#if NISA > 0
82static int32_t
83ata_isaprobe(struct isa_device *devp)
84{
85 int32_t ctlr, res;
86
87 for (ctlr = 0; ctlr < atanlun; ctlr++) {
88 if (atadevices[ctlr]->ioaddr == devp->id_iobase) {
89 printf("ata-isa%d: already registered as ata%d\n",
90 devp->id_unit, ctlr);
91 return 0;
92 }
93 }
94 res = ata_probe(devp->id_iobase, devp->id_iobase + ATA_ALTPORT, 0, 0,
95 &devp->id_unit);
96 if (res)
97 devp->id_intr = (inthand2_t *)ataintr;
98 return res;
99}
100
101static int32_t
102ata_isaattach(struct isa_device *devp)
103{
104 return 1;
105}
106#endif
107
108#if NPCI > 0
109static u_long ata_pcicount;
110static struct pci_device ata_pcidevice = {
111 "ata-pci", ata_pciprobe, ata_pciattach, &ata_pcicount, 0
112};
113
114DATA_SET(pcidevice_set, ata_pcidevice);
115
116static const char *
117ata_pciprobe(pcici_t tag, pcidi_t type)
118{
119 u_int32_t data;
120
121 data = pci_conf_read(tag, PCI_CLASS_REG);
122 if ((data & PCI_CLASS_MASK) == PCI_CLASS_MASS_STORAGE &&
123 ((data & PCI_SUBCLASS_MASK) == 0x00010000 ||
124 ((data & PCI_SUBCLASS_MASK) == 0x00040000))) {
125 switch (type) {
126 case 0x12308086:
127 return "Intel PIIX IDE controller";
128 case 0x70108086:
129 return "Intel PIIX3 IDE controller";
130 case 0x71118086:
131 return "Intel PIIX4 IDE controller";
132 case 0x4d33105a:
133 return "Promise Ultra/33 IDE controller";
134 case 0x522910b9:
135 return "AcerLabs Aladdin IDE controller";
136#if 0
137 case 0x05711106:
138 return "VIA Apollo IDE controller";
139 case 0x01021078:
140 return "Cyrix 5530 IDE controller";
141#endif
142 default:
143 return "Unknown PCI IDE controller";
144 }
145 }
146 return NULL;
147}
148
149static void
150ata_pciattach(pcici_t tag, int32_t unit)
151{
152 pcidi_t type, class, cmd;
153 int32_t iobase_1, iobase_2, altiobase_1, altiobase_2;
154 int32_t bmaddr_1 = 0, bmaddr_2 = 0, sysctrl = 0, irq1, irq2;
155 int32_t lun;
156
157 /* set up vendor-specific stuff */
158 type = pci_conf_read(tag, PCI_ID_REG);
159 class = pci_conf_read(tag, PCI_CLASS_REG);
160 cmd = pci_conf_read(tag, PCI_COMMAND_STATUS_REG);
161
162#ifdef ATA_DEBUG
163 printf("ata%d: type=%08x class=%08x cmd=%08x\n", unit, type, class, cmd);
164#endif
165
166 /* if this is a Promise controller handle it specially */
167 if (type == 0x4d33105a) {
168 iobase_1 = pci_conf_read(tag, 0x10) & 0xfffc;
169 altiobase_1 = pci_conf_read(tag, 0x14) & 0xfffc;
170 iobase_2 = pci_conf_read(tag, 0x18) & 0xfffc;
171 altiobase_2 = pci_conf_read(tag, 0x1c) & 0xfffc;
172 irq1 = irq2 = pci_conf_read(tag, PCI_INTERRUPT_REG) & 0xff;
173 bmaddr_1 = pci_conf_read(tag, 0x20) & 0xfffc;
174 bmaddr_2 = bmaddr_1 + ATA_BM_OFFSET1;
175 sysctrl = (pci_conf_read(tag, 0x20) & 0xfffc) + 0x1c;
176 outb(bmaddr_1 + 0x1f, inb(bmaddr_1 + 0x1f) | 0x01);
177 printf("ata-pci%d: Busmastering DMA supported\n", unit);
178 }
179 /* everybody else seems to do it this way */
180 else {
181 if ((class & 0x100) == 0) {
182 iobase_1 = IO_WD1;
183 altiobase_1 = iobase_1 + ATA_ALTPORT;
184 irq1 = 14;
185 }
186 else {
187 iobase_1 = pci_conf_read(tag, 0x10) & 0xfffc;
188 altiobase_1 = pci_conf_read(tag, 0x14) & 0xfffc;
189 irq1 = pci_conf_read(tag, PCI_INTERRUPT_REG) & 0xff;
190 }
191 if ((class & 0x400) == 0) {
192 iobase_2 = IO_WD2;
193 altiobase_2 = iobase_2 + ATA_ALTPORT;
194 irq2 = 15;
195 }
196 else {
197 iobase_2 = pci_conf_read(tag, 0x18) & 0xfffc;
198 altiobase_2 = pci_conf_read(tag, 0x1c) & 0xfffc;
199 irq2 = pci_conf_read(tag, PCI_INTERRUPT_REG) & 0xff;
200 }
201
202 /* is this controller busmaster capable ? */
203 if (pci_conf_read(tag, PCI_CLASS_REG) & 0x8000) {
204 /* is busmastering support turned on ? */
205 if ((pci_conf_read(tag, PCI_COMMAND_STATUS_REG) & 5) == 5) {
206 /* is there a valid port range to connect to ? */
207 if ((bmaddr_1 = pci_conf_read(tag, 0x20) & 0xfffc)) {
208 bmaddr_2 = bmaddr_1 + ATA_BM_OFFSET1;
209 printf("ata-pci%d: Busmastering DMA supported\n", unit);
210 }
211 else
212 printf("ata-pci%d: Busmastering DMA not configured\n",unit);
213 }
214 else
215 printf("ata-pci%d: Busmastering DMA not enabled\n", unit);
216 }
217 else
218 printf("ata-pci%d: Busmastering DMA not supported\n", unit);
219 }
220
221 /* now probe the addresse found for "real" ATA/ATAPI hardware */
222 lun = 0;
223 if (ata_probe(iobase_1, altiobase_1, bmaddr_1, tag, &lun)) {
224 if (iobase_1 == IO_WD1)
225 register_intr(irq1, (int)"", 0, (inthand2_t *)ataintr,
226 &bio_imask, lun);
227 else {
228 if (sysctrl)
229 pci_map_int(tag, (inthand2_t *)promise_intr,
230 (void *)lun, &bio_imask);
231 else
232 pci_map_int(tag, (inthand2_t *)ataintr, (void *)lun,&bio_imask);
233 }
234 printf("ata%d at 0x%04x irq %d on ata-pci%d\n",
235 lun, iobase_1, isa_apic_irq(irq1), unit);
236 }
237 lun = 1;
238 if (ata_probe(iobase_2, altiobase_2, bmaddr_2, tag, &lun)) {
239 if (iobase_2 == IO_WD2)
240 register_intr(irq2, (int)"", 0, (inthand2_t *)ataintr,
241 &bio_imask, lun);
242 else {
243 if (!sysctrl)
244 pci_map_int(tag, (inthand2_t *)ataintr, (void *)lun,&bio_imask);
245 }
246 printf("ata%d at 0x%04x irq %d on ata-pci%d\n",
247 lun, iobase_2, isa_apic_irq(irq2), unit);
248 }
249}
250
251static void
252promise_intr(int32_t unit)
253{
254 struct ata_softc *scp = atadevices[unit];
255 int32_t channel = inl((pci_conf_read(scp->tag, 0x20) & 0xfffc) + 0x1c);
256
257 if (channel & 0x00000400)
258 ataintr(unit);
259
260 if (channel & 0x00004000)
261 ataintr(unit+1);
262}
263#endif
264
265static int32_t
266ata_probe(int32_t ioaddr, int32_t altioaddr, int32_t bmaddr,
267 pcici_t tag, int32_t *unit)
268{
269 struct ata_softc *scp = atadevices[atanlun];
270 int32_t mask = 0;
271 int32_t timeout;
272 int32_t lun = atanlun;
273 u_int8_t status0, status1;
274
275#ifdef ATA_STATIC_ID
276 atanlun++;
277#endif
278 if (lun > MAXATA) {
279 printf("ata: unit out of range(%d)\n", lun);
280 return 0;
281 }
282 if (scp) {
283 printf("ata%d: unit already attached\n", lun);
284 return 0;
285 }
286 scp = malloc(sizeof(struct ata_softc), M_DEVBUF, M_NOWAIT);
287 if (scp == NULL) {
288 printf("ata%d: failed to allocate driver storage\n", lun);
289 return 0;
290 }
291 bzero(scp, sizeof(struct ata_softc));
292
293 scp->unit = *unit;
294 scp->lun = lun;
295 scp->ioaddr = ioaddr;
296 scp->altioaddr = altioaddr;
297 scp->active = ATA_IDLE;
298
299#ifdef ATA_DEBUG
300 printf("ata%d: iobase=0x%04x altiobase=0x%04x\n",
301 scp->lun, scp->ioaddr, scp->altioaddr);
302#endif
303
304 /* do we have any signs of ATA/ATAPI HW being present ? */
305 outb(scp->ioaddr + ATA_DRIVE, ATA_D_IBM | ATA_MASTER);
306 DELAY(1);
307 status0 = inb(scp->ioaddr + ATA_STATUS);
308 outb(scp->ioaddr + ATA_DRIVE, ATA_D_IBM | ATA_SLAVE);
309 DELAY(1);
310 status1 = inb(scp->ioaddr + ATA_STATUS);
311 if ((status0 & 0xf8) != 0xf8)
312 mask |= 0x01;
313 if ((status1 & 0xf8) != 0xf8)
314 mask |= 0x02;
315#ifdef ATA_DEBUG
316 printf("ata%d: mask=%02x status0=%02x status1=%02x\n",
317 scp->lun, mask, status0, status1);
318#endif
319 if (!mask) {
320 free(scp, M_DEVBUF);
321 return 0;
322 }
323 /* assert reset for devices and wait for completition */
324 outb(scp->ioaddr + ATA_DRIVE, ATA_D_IBM | ATA_MASTER);
325 DELAY(1);
326 outb(scp->altioaddr, ATA_A_IDS | ATA_A_RESET);
327 DELAY(1000);
328 outb(scp->altioaddr, ATA_A_IDS);
329 DELAY(1000);
330 inb(scp->ioaddr + ATA_ERROR);
331 DELAY(1);
332 outb(scp->altioaddr, ATA_A_4BIT);
333 DELAY(1);
334
335 /* wait for BUSY to go inactive */
336 for (timeout = 0; timeout < 30000*10; timeout++) {
337 outb(scp->ioaddr + ATA_DRIVE, ATA_D_IBM | ATA_MASTER);
338 DELAY(1);
339 status0 = inb(scp->ioaddr + ATA_STATUS);
340 outb(scp->ioaddr + ATA_DRIVE, ATA_D_IBM | ATA_SLAVE);
341 DELAY(1);
342 status1 = inb(scp->ioaddr + ATA_STATUS);
343 if (mask == 0x01) /* wait for master only */
344 if (!(status0 & ATA_S_BSY))
345 break;
346 if (mask == 0x02) /* wait for slave only */
347 if (!(status1 & ATA_S_BSY))
348 break;
349 if (mask == 0x03) /* wait for both master & slave */
350 if (!(status0 & ATA_S_BSY) && !(status1 & ATA_S_BSY))
351 break;
352 DELAY(100);
353 }
354 if (status0 & ATA_S_BSY)
355 mask &= ~0x01;
356 if (status1 & ATA_S_BSY)
357 mask &= ~0x02;
358#ifdef ATA_DEBUG
359 printf("ata%d: mask=%02x status0=%02x status1=%02x\n",
360 scp->lun, mask, status0, status1);
361#endif
362 if (!mask) {
363 free(scp, M_DEVBUF);
364 return 0;
365 }
366 /*
367 * OK, we have at least one device on the chain,
368 * check for ATAPI signatures, if none check if its
369 * a good old ATA device.
370 */
371
372 outb(scp->ioaddr + ATA_DRIVE, (ATA_D_IBM | ATA_MASTER));
373 DELAY(1);
374 if (inb(scp->ioaddr + ATA_CYL_LSB) == ATAPI_MAGIC_LSB &&
375 inb(scp->ioaddr + ATA_CYL_MSB) == ATAPI_MAGIC_MSB) {
376 scp->devices |= ATA_ATAPI_MASTER;
377 }
378 outb(scp->ioaddr + ATA_DRIVE, (ATA_D_IBM | ATA_SLAVE));
379 DELAY(1);
380 if (inb(scp->ioaddr + ATA_CYL_LSB) == ATAPI_MAGIC_LSB &&
381 inb(scp->ioaddr + ATA_CYL_MSB) == ATAPI_MAGIC_MSB) {
382 scp->devices |= ATA_ATAPI_SLAVE;
383 }
384 if (status0 != 0x00 && !(scp->devices & ATA_ATAPI_MASTER)) {
385 outb(scp->ioaddr + ATA_DRIVE, (ATA_D_IBM | ATA_MASTER));
386 DELAY(1);
387 outb(scp->ioaddr + ATA_ERROR, 0x58);
388 outb(scp->ioaddr + ATA_CYL_LSB, 0xa5);
389 if (inb(scp->ioaddr + ATA_ERROR) != 0x58 &&
390 inb(scp->ioaddr + ATA_CYL_LSB) == 0xa5) {
391 scp->devices |= ATA_ATA_MASTER;
392 }
393 }
394 if (status1 != 0x00 && !(scp->devices & ATA_ATAPI_SLAVE)) {
395 outb(scp->ioaddr + ATA_DRIVE, (ATA_D_IBM | ATA_SLAVE));
396 DELAY(1);
397 outb(scp->ioaddr + ATA_ERROR, 0x58);
398 outb(scp->ioaddr + ATA_CYL_LSB, 0xa5);
399 if (inb(scp->ioaddr + ATA_ERROR) != 0x58 &&
400 inb(scp->ioaddr + ATA_CYL_LSB) == 0xa5) {
401 scp->devices |= ATA_ATA_SLAVE;
402 }
403 }
404#ifdef ATA_DEBUG
405 printf("ata%d: devices = 0x%x\n", scp->lun, scp->devices);
406#endif
407 if (!scp->devices) {
408 free(scp, M_DEVBUF);
409 return 0;
410 }
411 bufq_init(&scp->ata_queue);
412 TAILQ_INIT(&scp->atapi_queue);
413 *unit = scp->lun;
414 scp->tag = tag;
415 if (bmaddr)
416 scp->bmaddr = bmaddr;
417 atadevices[scp->lun] = scp;
418#ifndef ATA_STATIC_ID
419 atanlun++;
420#endif
421 return ATA_IOSIZE;
422}
423
424static void
425ataintr(int32_t unit)
426{
427 struct ata_softc *scp;
428 struct atapi_request *atapi_request;
429 struct buf *ata_request;
430 u_int8_t status;
431 static int32_t intr_count = 0;
432
433 if (unit < 0 || unit > atanlun) {
434 printf("ataintr: unit %d unusable\n", unit);
435 return;
436 }
437
438 scp = atadevices[unit];
439
440 /* find & call the responsible driver to process this interrupt */
441 switch (scp->active) {
442#if NATADISK > 0
443 case ATA_ACTIVE_ATA:
444 if ((ata_request = bufq_first(&scp->ata_queue)))
445 if (ad_interrupt(ata_request) == ATA_OP_CONTINUES)
446 return;
447 break;
448#endif
449 case ATA_ACTIVE_ATAPI:
450 if ((atapi_request = TAILQ_FIRST(&scp->atapi_queue)))
451 if (atapi_interrupt(atapi_request) == ATA_OP_CONTINUES)
452 return;
453 break;
454
455 case ATA_WAIT_INTR:
456 wakeup((caddr_t)scp);
457 break;
458
459 case ATA_IGNORE_INTR:
460 break;
461
462 default:
463 case ATA_IDLE:
464 status = inb(scp->ioaddr + ATA_STATUS);
465 if (intr_count++ < 10)
466 printf("ata%d: unwanted interrupt %d status = %02x\n",
467 unit, intr_count, status);
468 return;
469 }
470 scp->active = ATA_IDLE;
471 ata_start(scp);
472}
473
474void
475ata_start(struct ata_softc *scp)
476{
477 struct buf *ata_request;
478 struct atapi_request *atapi_request;
479
480#ifdef ATA_DEBUG
481 printf("ata_start: entered\n");
482#endif
483 if (scp->active != ATA_IDLE) {
484 printf("ata: unwanted ata_start\n");
485 return;
486 }
487
488#if NATADISK > 0
489 /* find & call the responsible driver if anything on ATA queue */
490 if ((ata_request = bufq_first(&scp->ata_queue))) {
491 scp->active = ATA_ACTIVE_ATA;
492 ad_transfer(ata_request);
493#ifdef ATA_DEBUG
494 printf("ata_start: started ata, leaving\n");
495#endif
496 return;
497 }
498#endif
499
500 /* find & call the responsible driver if anything on ATAPI queue */
501 if ((atapi_request = TAILQ_FIRST(&scp->atapi_queue))) {
502 scp->active = ATA_ACTIVE_ATAPI;
503 atapi_transfer(atapi_request);
504#ifdef ATA_DEBUG
505 printf("ata_start: started atapi, leaving\n");
506#endif
507 return;
508 }
509}
510
511int32_t
512ata_wait(struct ata_softc *scp, int32_t device, u_int8_t mask)
513{
514 u_int8_t status;
515 u_int32_t timeout = 0;
516
517 while (timeout++ <= 500000) { /* timeout 5 secs */
518 status = inb(scp->ioaddr + ATA_STATUS);
519
520 /* if drive fails status, reselect the drive just to be sure */
521 if (status == 0xff) {
522 printf("ata%d: %s: no status, reselecting device\n",
523 scp->lun, device?"slave":"master");
524 outb(scp->ioaddr + ATA_DRIVE, ATA_D_IBM | device);
525 DELAY(1);
526 status = inb(scp->ioaddr + ATA_STATUS);
527 }
528 if (status == 0xff)
529 return -1;
530 scp->status = status;
531 if (!(status & ATA_S_BSY)) {
532 if (status & ATA_S_ERROR)
533 scp->error = inb(scp->ioaddr + ATA_ERROR);
534 if ((status & mask) == mask)
535 return (status & ATA_S_ERROR);
536 }
537 if (timeout > 1000)
538 DELAY(1000);
539 else
540 DELAY(10);
541 }
542 return -1;
543}
544
545int32_t
546ata_command(struct ata_softc *scp, int32_t device, u_int32_t command,
547 u_int32_t cylinder, u_int32_t head, u_int32_t sector,
548 u_int32_t count, u_int32_t feature, int32_t flags)
549{
550#ifdef ATA_DEBUG
551printf("ata_command: addr=%04x, device=%02x, cmd=%02x, c=%d, h=%d, s=%d, count=%d, flags=%02x\n", scp->ioaddr, device, command, cylinder, head, sector, count, flags);
552#endif
553
554 /* ready to issue command ? */
555 if (ata_wait(scp, device, 0) < 0) {
556 printf("ata%d: %s: timeout waiting to give command s=%02x e=%02x\n",
557 scp->lun, device?"slave":"master", scp->status, scp->error);
558 }
559 outb(scp->ioaddr + ATA_FEATURE, feature);
560 outb(scp->ioaddr + ATA_CYL_LSB, cylinder);
561 outb(scp->ioaddr + ATA_CYL_MSB, cylinder >> 8);
562 outb(scp->ioaddr + ATA_DRIVE, ATA_D_IBM | device | head);
563 outb(scp->ioaddr + ATA_SECTOR, sector);
564 outb(scp->ioaddr + ATA_COUNT, count);
565
566 if (scp->active != ATA_IDLE && flags != ATA_IMMEDIATE)
567 printf("DANGER active=%d\n", scp->active);
568
569 switch (flags) {
570 case ATA_WAIT_INTR:
571 scp->active = ATA_WAIT_INTR;
572 outb(scp->ioaddr + ATA_CMD, command);
573 if (tsleep((caddr_t)scp, PRIBIO, "atacmd", 500)) {
574 printf("ata_command: timeout waiting for interrupt");
575 scp->active = ATA_IDLE;
576 return -1;
577 }
578 break;
579
580 case ATA_IGNORE_INTR:
581 scp->active = ATA_IGNORE_INTR;
582 outb(scp->ioaddr + ATA_CMD, command);
583 break;
584
585 case ATA_IMMEDIATE:
586 default:
587 outb(scp->ioaddr + ATA_CMD, command);
588 break;
589 }
590#ifdef ATA_DEBUG
591printf("ata_command: leaving\n");
592#endif
593 return 0;
594}
595
596void
597bswap(int8_t *buf, int32_t len)
598{
599 u_int16_t *p = (u_int16_t*)(buf + len);
600
601 while (--p >= (u_int16_t*)buf)
602 *p = ntohs(*p);
603}
604
605void
606btrim(int8_t *buf, int32_t len)
607{
608 int8_t *p;
609
610 for (p = buf; p < buf+len; ++p)
611 if (!*p)
612 *p = ' ';
613 for (p = buf + len - 1; p >= buf && *p == ' '; --p)
614 *p = 0;
615}
616
617void
618bpack(int8_t *src, int8_t *dst, int32_t len)
619{
620 int32_t i, j, blank;
621
622 for (i = j = blank = 0 ; i < len-1; i++) {
623 if (blank && src[i] == ' ') continue;
624 if (blank && src[i] != ' ') {
625 dst[j++] = src[i];
626 blank = 0;
627 continue;
628 }
629 if (src[i] == ' ')
630 blank = 1;
631 dst[j++] = src[i];
632 }
633 dst[j] = 0x00;
634}
635#endif /* NATA > 0 */
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
9 * notice, this list of conditions and the following disclaimer,
10 * without modification, immediately at the beginning of the file.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
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.5 1999/03/28 18:57:18 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#include <machine/smp.h>
48#include <pci/pcivar.h>
49#include <pci/pcireg.h>
50#include <i386/isa/icu.h>
51#include <i386/isa/isa.h>
52#include <i386/isa/isa_device.h>
53#include <dev/ata/ata-all.h>
54#include <dev/ata/ata-disk.h>
55#include <dev/ata/atapi-all.h>
56
57/* misc defines */
58#define UNIT(dev) (dev>>3 & 0x1f) /* assume 8 minor # per unit */
59#define MIN(a,b) ((a)>(b)?(b):(a))
60#if NSMP == 0
61#define isa_apic_irq(x) x
62#endif
63
64/* prototypes */
65#if NISA > 0
66static int32_t ata_isaprobe(struct isa_device *);
67static int32_t ata_isaattach(struct isa_device *);
68#endif
69#if NPCI > 0
70static const char *ata_pciprobe(pcici_t, pcidi_t);
71static void ata_pciattach(pcici_t, int32_t);
72static void promise_intr(int32_t);
73#endif
74static int32_t ata_probe(int32_t, int32_t, int32_t, pcici_t, int32_t *);
75static void ataintr(int32_t);
76
77static int32_t atanlun = 0;
78struct ata_softc *atadevices[MAXATA];
79struct isa_driver atadriver = { ata_isaprobe, ata_isaattach, "ata" };
80
81#if NISA > 0
82static int32_t
83ata_isaprobe(struct isa_device *devp)
84{
85 int32_t ctlr, res;
86
87 for (ctlr = 0; ctlr < atanlun; ctlr++) {
88 if (atadevices[ctlr]->ioaddr == devp->id_iobase) {
89 printf("ata-isa%d: already registered as ata%d\n",
90 devp->id_unit, ctlr);
91 return 0;
92 }
93 }
94 res = ata_probe(devp->id_iobase, devp->id_iobase + ATA_ALTPORT, 0, 0,
95 &devp->id_unit);
96 if (res)
97 devp->id_intr = (inthand2_t *)ataintr;
98 return res;
99}
100
101static int32_t
102ata_isaattach(struct isa_device *devp)
103{
104 return 1;
105}
106#endif
107
108#if NPCI > 0
109static u_long ata_pcicount;
110static struct pci_device ata_pcidevice = {
111 "ata-pci", ata_pciprobe, ata_pciattach, &ata_pcicount, 0
112};
113
114DATA_SET(pcidevice_set, ata_pcidevice);
115
116static const char *
117ata_pciprobe(pcici_t tag, pcidi_t type)
118{
119 u_int32_t data;
120
121 data = pci_conf_read(tag, PCI_CLASS_REG);
122 if ((data & PCI_CLASS_MASK) == PCI_CLASS_MASS_STORAGE &&
123 ((data & PCI_SUBCLASS_MASK) == 0x00010000 ||
124 ((data & PCI_SUBCLASS_MASK) == 0x00040000))) {
125 switch (type) {
126 case 0x12308086:
127 return "Intel PIIX IDE controller";
128 case 0x70108086:
129 return "Intel PIIX3 IDE controller";
130 case 0x71118086:
131 return "Intel PIIX4 IDE controller";
132 case 0x4d33105a:
133 return "Promise Ultra/33 IDE controller";
134 case 0x522910b9:
135 return "AcerLabs Aladdin IDE controller";
136#if 0
137 case 0x05711106:
138 return "VIA Apollo IDE controller";
139 case 0x01021078:
140 return "Cyrix 5530 IDE controller";
141#endif
142 default:
143 return "Unknown PCI IDE controller";
144 }
145 }
146 return NULL;
147}
148
149static void
150ata_pciattach(pcici_t tag, int32_t unit)
151{
152 pcidi_t type, class, cmd;
153 int32_t iobase_1, iobase_2, altiobase_1, altiobase_2;
154 int32_t bmaddr_1 = 0, bmaddr_2 = 0, sysctrl = 0, irq1, irq2;
155 int32_t lun;
156
157 /* set up vendor-specific stuff */
158 type = pci_conf_read(tag, PCI_ID_REG);
159 class = pci_conf_read(tag, PCI_CLASS_REG);
160 cmd = pci_conf_read(tag, PCI_COMMAND_STATUS_REG);
161
162#ifdef ATA_DEBUG
163 printf("ata%d: type=%08x class=%08x cmd=%08x\n", unit, type, class, cmd);
164#endif
165
166 /* if this is a Promise controller handle it specially */
167 if (type == 0x4d33105a) {
168 iobase_1 = pci_conf_read(tag, 0x10) & 0xfffc;
169 altiobase_1 = pci_conf_read(tag, 0x14) & 0xfffc;
170 iobase_2 = pci_conf_read(tag, 0x18) & 0xfffc;
171 altiobase_2 = pci_conf_read(tag, 0x1c) & 0xfffc;
172 irq1 = irq2 = pci_conf_read(tag, PCI_INTERRUPT_REG) & 0xff;
173 bmaddr_1 = pci_conf_read(tag, 0x20) & 0xfffc;
174 bmaddr_2 = bmaddr_1 + ATA_BM_OFFSET1;
175 sysctrl = (pci_conf_read(tag, 0x20) & 0xfffc) + 0x1c;
176 outb(bmaddr_1 + 0x1f, inb(bmaddr_1 + 0x1f) | 0x01);
177 printf("ata-pci%d: Busmastering DMA supported\n", unit);
178 }
179 /* everybody else seems to do it this way */
180 else {
181 if ((class & 0x100) == 0) {
182 iobase_1 = IO_WD1;
183 altiobase_1 = iobase_1 + ATA_ALTPORT;
184 irq1 = 14;
185 }
186 else {
187 iobase_1 = pci_conf_read(tag, 0x10) & 0xfffc;
188 altiobase_1 = pci_conf_read(tag, 0x14) & 0xfffc;
189 irq1 = pci_conf_read(tag, PCI_INTERRUPT_REG) & 0xff;
190 }
191 if ((class & 0x400) == 0) {
192 iobase_2 = IO_WD2;
193 altiobase_2 = iobase_2 + ATA_ALTPORT;
194 irq2 = 15;
195 }
196 else {
197 iobase_2 = pci_conf_read(tag, 0x18) & 0xfffc;
198 altiobase_2 = pci_conf_read(tag, 0x1c) & 0xfffc;
199 irq2 = pci_conf_read(tag, PCI_INTERRUPT_REG) & 0xff;
200 }
201
202 /* is this controller busmaster capable ? */
203 if (pci_conf_read(tag, PCI_CLASS_REG) & 0x8000) {
204 /* is busmastering support turned on ? */
205 if ((pci_conf_read(tag, PCI_COMMAND_STATUS_REG) & 5) == 5) {
206 /* is there a valid port range to connect to ? */
207 if ((bmaddr_1 = pci_conf_read(tag, 0x20) & 0xfffc)) {
208 bmaddr_2 = bmaddr_1 + ATA_BM_OFFSET1;
209 printf("ata-pci%d: Busmastering DMA supported\n", unit);
210 }
211 else
212 printf("ata-pci%d: Busmastering DMA not configured\n",unit);
213 }
214 else
215 printf("ata-pci%d: Busmastering DMA not enabled\n", unit);
216 }
217 else
218 printf("ata-pci%d: Busmastering DMA not supported\n", unit);
219 }
220
221 /* now probe the addresse found for "real" ATA/ATAPI hardware */
222 lun = 0;
223 if (ata_probe(iobase_1, altiobase_1, bmaddr_1, tag, &lun)) {
224 if (iobase_1 == IO_WD1)
225 register_intr(irq1, (int)"", 0, (inthand2_t *)ataintr,
226 &bio_imask, lun);
227 else {
228 if (sysctrl)
229 pci_map_int(tag, (inthand2_t *)promise_intr,
230 (void *)lun, &bio_imask);
231 else
232 pci_map_int(tag, (inthand2_t *)ataintr, (void *)lun,&bio_imask);
233 }
234 printf("ata%d at 0x%04x irq %d on ata-pci%d\n",
235 lun, iobase_1, isa_apic_irq(irq1), unit);
236 }
237 lun = 1;
238 if (ata_probe(iobase_2, altiobase_2, bmaddr_2, tag, &lun)) {
239 if (iobase_2 == IO_WD2)
240 register_intr(irq2, (int)"", 0, (inthand2_t *)ataintr,
241 &bio_imask, lun);
242 else {
243 if (!sysctrl)
244 pci_map_int(tag, (inthand2_t *)ataintr, (void *)lun,&bio_imask);
245 }
246 printf("ata%d at 0x%04x irq %d on ata-pci%d\n",
247 lun, iobase_2, isa_apic_irq(irq2), unit);
248 }
249}
250
251static void
252promise_intr(int32_t unit)
253{
254 struct ata_softc *scp = atadevices[unit];
255 int32_t channel = inl((pci_conf_read(scp->tag, 0x20) & 0xfffc) + 0x1c);
256
257 if (channel & 0x00000400)
258 ataintr(unit);
259
260 if (channel & 0x00004000)
261 ataintr(unit+1);
262}
263#endif
264
265static int32_t
266ata_probe(int32_t ioaddr, int32_t altioaddr, int32_t bmaddr,
267 pcici_t tag, int32_t *unit)
268{
269 struct ata_softc *scp = atadevices[atanlun];
270 int32_t mask = 0;
271 int32_t timeout;
272 int32_t lun = atanlun;
273 u_int8_t status0, status1;
274
275#ifdef ATA_STATIC_ID
276 atanlun++;
277#endif
278 if (lun > MAXATA) {
279 printf("ata: unit out of range(%d)\n", lun);
280 return 0;
281 }
282 if (scp) {
283 printf("ata%d: unit already attached\n", lun);
284 return 0;
285 }
286 scp = malloc(sizeof(struct ata_softc), M_DEVBUF, M_NOWAIT);
287 if (scp == NULL) {
288 printf("ata%d: failed to allocate driver storage\n", lun);
289 return 0;
290 }
291 bzero(scp, sizeof(struct ata_softc));
292
293 scp->unit = *unit;
294 scp->lun = lun;
295 scp->ioaddr = ioaddr;
296 scp->altioaddr = altioaddr;
297 scp->active = ATA_IDLE;
298
299#ifdef ATA_DEBUG
300 printf("ata%d: iobase=0x%04x altiobase=0x%04x\n",
301 scp->lun, scp->ioaddr, scp->altioaddr);
302#endif
303
304 /* do we have any signs of ATA/ATAPI HW being present ? */
305 outb(scp->ioaddr + ATA_DRIVE, ATA_D_IBM | ATA_MASTER);
306 DELAY(1);
307 status0 = inb(scp->ioaddr + ATA_STATUS);
308 outb(scp->ioaddr + ATA_DRIVE, ATA_D_IBM | ATA_SLAVE);
309 DELAY(1);
310 status1 = inb(scp->ioaddr + ATA_STATUS);
311 if ((status0 & 0xf8) != 0xf8)
312 mask |= 0x01;
313 if ((status1 & 0xf8) != 0xf8)
314 mask |= 0x02;
315#ifdef ATA_DEBUG
316 printf("ata%d: mask=%02x status0=%02x status1=%02x\n",
317 scp->lun, mask, status0, status1);
318#endif
319 if (!mask) {
320 free(scp, M_DEVBUF);
321 return 0;
322 }
323 /* assert reset for devices and wait for completition */
324 outb(scp->ioaddr + ATA_DRIVE, ATA_D_IBM | ATA_MASTER);
325 DELAY(1);
326 outb(scp->altioaddr, ATA_A_IDS | ATA_A_RESET);
327 DELAY(1000);
328 outb(scp->altioaddr, ATA_A_IDS);
329 DELAY(1000);
330 inb(scp->ioaddr + ATA_ERROR);
331 DELAY(1);
332 outb(scp->altioaddr, ATA_A_4BIT);
333 DELAY(1);
334
335 /* wait for BUSY to go inactive */
336 for (timeout = 0; timeout < 30000*10; timeout++) {
337 outb(scp->ioaddr + ATA_DRIVE, ATA_D_IBM | ATA_MASTER);
338 DELAY(1);
339 status0 = inb(scp->ioaddr + ATA_STATUS);
340 outb(scp->ioaddr + ATA_DRIVE, ATA_D_IBM | ATA_SLAVE);
341 DELAY(1);
342 status1 = inb(scp->ioaddr + ATA_STATUS);
343 if (mask == 0x01) /* wait for master only */
344 if (!(status0 & ATA_S_BSY))
345 break;
346 if (mask == 0x02) /* wait for slave only */
347 if (!(status1 & ATA_S_BSY))
348 break;
349 if (mask == 0x03) /* wait for both master & slave */
350 if (!(status0 & ATA_S_BSY) && !(status1 & ATA_S_BSY))
351 break;
352 DELAY(100);
353 }
354 if (status0 & ATA_S_BSY)
355 mask &= ~0x01;
356 if (status1 & ATA_S_BSY)
357 mask &= ~0x02;
358#ifdef ATA_DEBUG
359 printf("ata%d: mask=%02x status0=%02x status1=%02x\n",
360 scp->lun, mask, status0, status1);
361#endif
362 if (!mask) {
363 free(scp, M_DEVBUF);
364 return 0;
365 }
366 /*
367 * OK, we have at least one device on the chain,
368 * check for ATAPI signatures, if none check if its
369 * a good old ATA device.
370 */
371
372 outb(scp->ioaddr + ATA_DRIVE, (ATA_D_IBM | ATA_MASTER));
373 DELAY(1);
374 if (inb(scp->ioaddr + ATA_CYL_LSB) == ATAPI_MAGIC_LSB &&
375 inb(scp->ioaddr + ATA_CYL_MSB) == ATAPI_MAGIC_MSB) {
376 scp->devices |= ATA_ATAPI_MASTER;
377 }
378 outb(scp->ioaddr + ATA_DRIVE, (ATA_D_IBM | ATA_SLAVE));
379 DELAY(1);
380 if (inb(scp->ioaddr + ATA_CYL_LSB) == ATAPI_MAGIC_LSB &&
381 inb(scp->ioaddr + ATA_CYL_MSB) == ATAPI_MAGIC_MSB) {
382 scp->devices |= ATA_ATAPI_SLAVE;
383 }
384 if (status0 != 0x00 && !(scp->devices & ATA_ATAPI_MASTER)) {
385 outb(scp->ioaddr + ATA_DRIVE, (ATA_D_IBM | ATA_MASTER));
386 DELAY(1);
387 outb(scp->ioaddr + ATA_ERROR, 0x58);
388 outb(scp->ioaddr + ATA_CYL_LSB, 0xa5);
389 if (inb(scp->ioaddr + ATA_ERROR) != 0x58 &&
390 inb(scp->ioaddr + ATA_CYL_LSB) == 0xa5) {
391 scp->devices |= ATA_ATA_MASTER;
392 }
393 }
394 if (status1 != 0x00 && !(scp->devices & ATA_ATAPI_SLAVE)) {
395 outb(scp->ioaddr + ATA_DRIVE, (ATA_D_IBM | ATA_SLAVE));
396 DELAY(1);
397 outb(scp->ioaddr + ATA_ERROR, 0x58);
398 outb(scp->ioaddr + ATA_CYL_LSB, 0xa5);
399 if (inb(scp->ioaddr + ATA_ERROR) != 0x58 &&
400 inb(scp->ioaddr + ATA_CYL_LSB) == 0xa5) {
401 scp->devices |= ATA_ATA_SLAVE;
402 }
403 }
404#ifdef ATA_DEBUG
405 printf("ata%d: devices = 0x%x\n", scp->lun, scp->devices);
406#endif
407 if (!scp->devices) {
408 free(scp, M_DEVBUF);
409 return 0;
410 }
411 bufq_init(&scp->ata_queue);
412 TAILQ_INIT(&scp->atapi_queue);
413 *unit = scp->lun;
414 scp->tag = tag;
415 if (bmaddr)
416 scp->bmaddr = bmaddr;
417 atadevices[scp->lun] = scp;
418#ifndef ATA_STATIC_ID
419 atanlun++;
420#endif
421 return ATA_IOSIZE;
422}
423
424static void
425ataintr(int32_t unit)
426{
427 struct ata_softc *scp;
428 struct atapi_request *atapi_request;
429 struct buf *ata_request;
430 u_int8_t status;
431 static int32_t intr_count = 0;
432
433 if (unit < 0 || unit > atanlun) {
434 printf("ataintr: unit %d unusable\n", unit);
435 return;
436 }
437
438 scp = atadevices[unit];
439
440 /* find & call the responsible driver to process this interrupt */
441 switch (scp->active) {
442#if NATADISK > 0
443 case ATA_ACTIVE_ATA:
444 if ((ata_request = bufq_first(&scp->ata_queue)))
445 if (ad_interrupt(ata_request) == ATA_OP_CONTINUES)
446 return;
447 break;
448#endif
449 case ATA_ACTIVE_ATAPI:
450 if ((atapi_request = TAILQ_FIRST(&scp->atapi_queue)))
451 if (atapi_interrupt(atapi_request) == ATA_OP_CONTINUES)
452 return;
453 break;
454
455 case ATA_WAIT_INTR:
456 wakeup((caddr_t)scp);
457 break;
458
459 case ATA_IGNORE_INTR:
460 break;
461
462 default:
463 case ATA_IDLE:
464 status = inb(scp->ioaddr + ATA_STATUS);
465 if (intr_count++ < 10)
466 printf("ata%d: unwanted interrupt %d status = %02x\n",
467 unit, intr_count, status);
468 return;
469 }
470 scp->active = ATA_IDLE;
471 ata_start(scp);
472}
473
474void
475ata_start(struct ata_softc *scp)
476{
477 struct buf *ata_request;
478 struct atapi_request *atapi_request;
479
480#ifdef ATA_DEBUG
481 printf("ata_start: entered\n");
482#endif
483 if (scp->active != ATA_IDLE) {
484 printf("ata: unwanted ata_start\n");
485 return;
486 }
487
488#if NATADISK > 0
489 /* find & call the responsible driver if anything on ATA queue */
490 if ((ata_request = bufq_first(&scp->ata_queue))) {
491 scp->active = ATA_ACTIVE_ATA;
492 ad_transfer(ata_request);
493#ifdef ATA_DEBUG
494 printf("ata_start: started ata, leaving\n");
495#endif
496 return;
497 }
498#endif
499
500 /* find & call the responsible driver if anything on ATAPI queue */
501 if ((atapi_request = TAILQ_FIRST(&scp->atapi_queue))) {
502 scp->active = ATA_ACTIVE_ATAPI;
503 atapi_transfer(atapi_request);
504#ifdef ATA_DEBUG
505 printf("ata_start: started atapi, leaving\n");
506#endif
507 return;
508 }
509}
510
511int32_t
512ata_wait(struct ata_softc *scp, int32_t device, u_int8_t mask)
513{
514 u_int8_t status;
515 u_int32_t timeout = 0;
516
517 while (timeout++ <= 500000) { /* timeout 5 secs */
518 status = inb(scp->ioaddr + ATA_STATUS);
519
520 /* if drive fails status, reselect the drive just to be sure */
521 if (status == 0xff) {
522 printf("ata%d: %s: no status, reselecting device\n",
523 scp->lun, device?"slave":"master");
524 outb(scp->ioaddr + ATA_DRIVE, ATA_D_IBM | device);
525 DELAY(1);
526 status = inb(scp->ioaddr + ATA_STATUS);
527 }
528 if (status == 0xff)
529 return -1;
530 scp->status = status;
531 if (!(status & ATA_S_BSY)) {
532 if (status & ATA_S_ERROR)
533 scp->error = inb(scp->ioaddr + ATA_ERROR);
534 if ((status & mask) == mask)
535 return (status & ATA_S_ERROR);
536 }
537 if (timeout > 1000)
538 DELAY(1000);
539 else
540 DELAY(10);
541 }
542 return -1;
543}
544
545int32_t
546ata_command(struct ata_softc *scp, int32_t device, u_int32_t command,
547 u_int32_t cylinder, u_int32_t head, u_int32_t sector,
548 u_int32_t count, u_int32_t feature, int32_t flags)
549{
550#ifdef ATA_DEBUG
551printf("ata_command: addr=%04x, device=%02x, cmd=%02x, c=%d, h=%d, s=%d, count=%d, flags=%02x\n", scp->ioaddr, device, command, cylinder, head, sector, count, flags);
552#endif
553
554 /* ready to issue command ? */
555 if (ata_wait(scp, device, 0) < 0) {
556 printf("ata%d: %s: timeout waiting to give command s=%02x e=%02x\n",
557 scp->lun, device?"slave":"master", scp->status, scp->error);
558 }
559 outb(scp->ioaddr + ATA_FEATURE, feature);
560 outb(scp->ioaddr + ATA_CYL_LSB, cylinder);
561 outb(scp->ioaddr + ATA_CYL_MSB, cylinder >> 8);
562 outb(scp->ioaddr + ATA_DRIVE, ATA_D_IBM | device | head);
563 outb(scp->ioaddr + ATA_SECTOR, sector);
564 outb(scp->ioaddr + ATA_COUNT, count);
565
566 if (scp->active != ATA_IDLE && flags != ATA_IMMEDIATE)
567 printf("DANGER active=%d\n", scp->active);
568
569 switch (flags) {
570 case ATA_WAIT_INTR:
571 scp->active = ATA_WAIT_INTR;
572 outb(scp->ioaddr + ATA_CMD, command);
573 if (tsleep((caddr_t)scp, PRIBIO, "atacmd", 500)) {
574 printf("ata_command: timeout waiting for interrupt");
575 scp->active = ATA_IDLE;
576 return -1;
577 }
578 break;
579
580 case ATA_IGNORE_INTR:
581 scp->active = ATA_IGNORE_INTR;
582 outb(scp->ioaddr + ATA_CMD, command);
583 break;
584
585 case ATA_IMMEDIATE:
586 default:
587 outb(scp->ioaddr + ATA_CMD, command);
588 break;
589 }
590#ifdef ATA_DEBUG
591printf("ata_command: leaving\n");
592#endif
593 return 0;
594}
595
596void
597bswap(int8_t *buf, int32_t len)
598{
599 u_int16_t *p = (u_int16_t*)(buf + len);
600
601 while (--p >= (u_int16_t*)buf)
602 *p = ntohs(*p);
603}
604
605void
606btrim(int8_t *buf, int32_t len)
607{
608 int8_t *p;
609
610 for (p = buf; p < buf+len; ++p)
611 if (!*p)
612 *p = ' ';
613 for (p = buf + len - 1; p >= buf && *p == ' '; --p)
614 *p = 0;
615}
616
617void
618bpack(int8_t *src, int8_t *dst, int32_t len)
619{
620 int32_t i, j, blank;
621
622 for (i = j = blank = 0 ; i < len-1; i++) {
623 if (blank && src[i] == ' ') continue;
624 if (blank && src[i] != ' ') {
625 dst[j++] = src[i];
626 blank = 0;
627 continue;
628 }
629 if (src[i] == ' ')
630 blank = 1;
631 dst[j++] = src[i];
632 }
633 dst[j] = 0x00;
634}
635#endif /* NATA > 0 */