]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/pc98/pc98/atapi.c
unfinished sblive driver, playback/mixer only for now - not enabled in
[FreeBSD/FreeBSD.git] / sys / pc98 / pc98 / atapi.c
1 /*
2  * Device-independent level for ATAPI drivers.
3  *
4  * Copyright (C) 1995 Cronyx Ltd.
5  * Author Serge Vakulenko, <vak@cronyx.ru>
6  *
7  * This software is distributed with NO WARRANTIES, not even the implied
8  * warranties for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
9  *
10  * Authors grant any other persons or organisations permission to use
11  * or modify this software as long as this message is kept with the software,
12  * all derivative works or modified versions.
13  *
14  * Version 1.9, Mon Oct  9 22:34:47 MSK 1995
15  *
16  * $FreeBSD$
17  */
18
19 /*
20  * The ATAPI level is implemented as a machine-dependent layer
21  * between the device driver and the IDE controller.
22  * All the machine- and controller dependency is isolated inside
23  * the ATAPI level, while all the device dependency is located
24  * in the device subdriver.
25  *
26  * It seems that an ATAPI bus will became popular for medium-speed
27  * storage devices such as CD-ROMs, magneto-optical disks, tape streamers etc.
28  *
29  * To ease the development of new ATAPI drivers, the subdriver
30  * interface was designed to be as simple as possible.
31  *
32  * Three routines are available for the subdriver to access the device:
33  *
34  *      struct atapires atapi_request_wait (ata, unit, cmd, a1, a2, a3, a4, a5,
35  *              a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, addr, count);
36  *      struct atapi *ata;  -- atapi controller descriptor
37  *      int unit;           -- device unit number on the IDE bus
38  *      u_char cmd;         -- ATAPI command code
39  *      u_char a1..a15;     -- ATAPI command arguments
40  *      char *addr;         -- address of the data buffer for i/o
41  *      int count;          -- data length, >0 for read ops, <0 for write ops
42  *
43  * The atapi_request_wait() function puts the op in the queue of ATAPI
44  * commands for the IDE controller, starts the controller, the waits for
45  * operation to be completed (using tsleep).
46  * The function should be called from the user phase only (open(), close(),
47  * ioctl() etc).
48  * Ata and unit args are the values which the subdriver gets from the ATAPI
49  * level via attach() call.
50  * Buffer pointed to by *addr should be placed in core memory, static
51  * or dynamic, but not in stack.
52  * The function returns the error code structure, which consists of:
53  * - atapi driver code value
54  * - controller status port value
55  * - controller error port value
56  *
57  *      struct atapires atapi_request_immediate (ata, unit, cmd, a1, a2, a3,
58  *              a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15,
59  *              addr, count);
60  *
61  * The atapi_request_immediate() function is similar to atapi_request_wait(),
62  * but it does not use interrupts for performing the request.
63  * It should be used during an attach phase to get parameters from the device.
64  *
65  *      void atapi_request_callback (ata, unit, cmd, a1, a2, a3, a4, a5,
66  *              a6, a7, a8, a9, a10, a11, a12, a13, a14, a15,
67  *              addr, count, done, x, y);
68  *      struct atapi *ata;  -- atapi controller descriptor
69  *      int unit;           -- device unit number on the IDE bus
70  *      u_char cmd;         -- ATAPI command code
71  *      u_char a1..a15;     -- ATAPI command arguments
72  *      char *addr;         -- address of the data buffer for i/o
73  *      int count;          -- data length, >0 for read ops, <0 for write ops
74  *      void (*done)();     -- function to call when op finished
75  *      void *x, *y;        -- arguments for done() function
76  *
77  * The atapi_request_callback() function puts the op in the queue of ATAPI
78  * commands for the IDE controller, starts the controller, then returns.
79  * When the operation finishes, then the callback function done()
80  * will be called on the interrupt level.
81  * The function is designed to be callable from the interrupt phase.
82  * The done() functions is called with the following arguments:
83  *      (void) (*done) (x, y, count, errcode)
84  *      void *x, *y;             -- arguments from the atapi_request_callback()
85  *      int count;               -- the data residual count
86  *      struct atapires errcode; -- error code structure, see above
87  *
88  * The new driver could be added in three steps:
89  * 1. Add entries for the new driver to bdevsw and cdevsw tables in conf.c.
90  *    You will need to make at least three routines: open(), close(),
91  *    strategy() and possibly ioctl().
92  * 2. Make attach() routine, which should allocate all the needed data
93  *    structures and print the device description string (see xxxattach()).
94  * 3. Add an appropriate case to the switch in atapi_attach() routine,
95  *    call attach() routine of the new driver here.  Add the appropriate
96  *    #include line at the top of attach.c.
97  * That's all!
98  *
99  * Use #define DEBUG in atapi.c to enable tracing of all i/o operations
100  * on the IDE bus.
101  */
102 #undef DEBUG
103
104 #include "wdc.h"
105
106 #include "wcd.h"
107 #include "wfd.h"
108 #include "wst.h"
109 /* #include "wmd.h" -- add your driver here */
110
111 #if NWDC > 0
112
113 #include <sys/param.h>
114 #include <sys/systm.h>
115 #include <sys/malloc.h>
116
117 #include <machine/clock.h>
118
119 #include <pc98/pc98/atapi.h>
120
121 /* this code is compiled part of the module */
122
123 #ifdef DEBUG
124 #   define print(s)     printf s
125 #else
126 #   define print(s)     {/*void*/}
127 #endif
128
129 /*
130  * ATAPI packet command phase.
131  */
132 #define PHASE_CMDOUT    (ARS_DRQ | ARI_CMD)
133 #define PHASE_DATAIN    (ARS_DRQ | ARI_IN)
134 #define PHASE_DATAOUT   ARS_DRQ
135 #define PHASE_COMPLETED (ARI_IN | ARI_CMD)
136 #define PHASE_ABORTED   0                       /* nonstandard - for NEC 260 */
137
138 static struct atapi atapitab[NWDC];
139
140 static struct atapi_params *atapi_probe (int port, int unit);
141 static int atapi_wait (int port, u_char bits_wanted);
142 static void atapi_send_cmd (struct atapi *ata, struct atapicmd *ac);
143 static int atapi_io (struct atapi *ata, struct atapicmd *ac);
144 static int atapi_start_cmd (struct atapi *ata, struct atapicmd *ac);
145 static int atapi_wait_cmd (struct atapi *ata, struct atapicmd *ac);
146
147 extern void wdstart (int ctrlr);
148 extern int acdattach(struct atapi*, int, struct atapi_params*, int);
149 extern int wfdattach(struct atapi*, int, struct atapi_params*, int);
150 extern int wstattach(struct atapi*, int, struct atapi_params*, int);
151
152 /*
153  * Probe the ATAPI device at IDE controller `ctlr', drive `unit'.
154  * Called at splbio().
155  */
156 int atapi_attach (int ctlr, int unit, int port)
157 {
158         struct atapi *ata = atapitab + ctlr;
159         struct atapi_params *ap;
160         char buf [sizeof(ap->model) + 1];
161         char revbuf [sizeof(ap->revision) + 1];
162         struct atapicmd *ac;
163
164         print (("atapi%d.%d at 0x%x: attach called\n", ctlr, unit, port));
165         ap = atapi_probe (port, unit);
166         if (! ap)
167                 return (0);
168
169         bcopy (ap->model, buf, sizeof(buf)-1);
170         buf[sizeof(buf)-1] = 0;
171
172         bcopy (ap->revision, revbuf, sizeof(revbuf)-1);
173         revbuf[sizeof(revbuf)-1] = 0;
174
175         printf ("wdc%d: unit %d (atapi): <%s/%s>", ctlr, unit, buf, revbuf);
176
177         /* device is removable */
178         if (ap->removable)
179                 printf (", removable");
180
181         /* packet command size */
182         switch (ap->cmdsz) {
183         case AT_PSIZE_12: break;
184         case AT_PSIZE_16: printf (", cmd16"); ata->cmd16 = 1; break;
185         default:          printf (", cmd%d", ap->cmdsz);
186         }
187
188         /* DRQ type */
189         switch (ap->drqtype) {
190         case AT_DRQT_MPROC: ata->slow = 1; break;
191         case AT_DRQT_INTR:  printf (", intr"); ata->intrcmd = 1; break;
192         case AT_DRQT_ACCEL: printf (", accel"); ata->accel = 1; break;
193         default:            printf (", drq%d", ap->drqtype);
194         }
195         if (ata->slow)
196                 ata->intrcmd = 0;
197
198         /* 
199          * If we have two devices, one supporting INTR and one ACCEL, we
200          * have to pessimise - clear INTR and set slow.
201          */
202         if (ata->accel && ata->intrcmd) {
203         ata->intrcmd = 0;
204         ata->slow = 1;
205         }
206
207         /* overlap operation supported */
208         if (ap->ovlapflag)
209                 printf (", ovlap");
210
211         /* interleaved DMA supported */
212         if (ap->idmaflag)
213                 printf (", idma");
214         /* DMA supported */
215         else if (ap->dmaflag)
216                 printf (", dma");
217
218         /* IORDY can be disabled */
219         if (ap->iordydis)
220                 printf (", iordis");
221         /* IORDY supported */
222         else if (ap->iordyflag)
223                 printf (", iordy");
224
225         printf ("\n");
226
227         ata->port = port;
228         ata->ctrlr = ctlr;
229         ata->attached[unit] = 0;
230 #ifdef DEBUG
231         ata->debug = 1;
232 #else
233         ata->debug = 0;
234 #endif
235         /* Initialize free queue. */
236         ata->cmdrq[15].next = 0;
237         for (ac = ata->cmdrq+14; ac >= ata->cmdrq; --ac)
238                 ac->next = ac+1;
239         ata->free = ata->cmdrq;
240
241         if (ap->proto != AT_PROTO_ATAPI) {
242                 printf ("wdc%d: unit %d: unknown ATAPI protocol=%d\n",
243                         ctlr, unit, ap->proto);
244                 free (ap, M_TEMP);
245                 return (0);
246         }
247         switch (ap->devtype) {
248         default:
249                 /* unknown ATAPI device */
250                 printf ("wdc%d: unit %d: unknown ATAPI type=%d\n",
251                         ctlr, unit, ap->devtype);
252                 break;
253
254         case AT_TYPE_DIRECT:            /* direct-access */
255 #if NWFD > 0
256                 /* ATAPI Floppy(LS-120) */
257                 if (wfdattach (ata, unit, ap, ata->debug) < 0)
258                         break;
259                         /* Device attached successfully. */
260                 ata->attached[unit] = 1;
261                 return (1);
262 #else
263                 printf ("wdc%d: ATAPI Floppies not configured\n", ctlr);
264                 break;
265 #endif
266         case AT_TYPE_CDROM:             /* CD-ROM device */
267 #if NWCD > 0
268                 /* ATAPI CD-ROM & CD-R/RW drives */
269                 if (acdattach (ata, unit, ap, ata->debug) < 0)
270                         break;
271                 ata->attached[unit] = 1;
272                 return (1);
273 #else
274                 printf ("wdc%d: ATAPI CD-ROMs not configured\n", ctlr);
275                 break;
276 #endif
277
278         case AT_TYPE_TAPE:              /* streaming tape */
279 #if NWST > 0
280                 /* ATAPI Streaming Tape */
281                 if (wstattach (ata, unit, ap, ata->debug) < 0)
282                         break;
283                 /* Device attached successfully. */
284                 ata->attached[unit] = 1;
285                 return (1);
286 #else
287                 printf ("wdc%d: ATAPI streaming tapes not configured\n", ctlr);
288 #endif
289                 break;
290
291         case AT_TYPE_OPTICAL:           /* optical disk */
292 #if NWMD > 0
293                 /* Add your driver here */
294 #else
295                 printf ("wdc%d: ATAPI optical disks not supported yet\n", ctlr);
296 #endif
297                 break;
298         }
299         /* Attach failed. */
300         free (ap, M_TEMP);
301         return (0);
302 }
303
304 static char *cmdname (u_char cmd)
305 {
306         static char buf[8];
307
308         switch (cmd) {
309         case 0x00: return ("TEST_UNIT_READY");
310         case 0x01: return ("REZERO_UNIT");
311         case 0x03: return ("REQUEST_SENSE");
312         case 0x04: return ("FORMAT_UNIT");
313         case 0x1b: return ("START_STOP");
314         case 0x1e: return ("PREVENT_ALLOW");
315         case 0x25: return ("READ_CAPACITY");
316         case 0x28: return ("READ_BIG");
317         case 0x2a: return ("WRITE_BIG");
318         case 0x35: return ("SYNCHRONIZE_CACHE");
319         case 0x42: return ("READ_SUBCHANNEL");
320         case 0x43: return ("READ_TOC");
321         case 0x51: return ("READ_DISC_INFO");
322         case 0x52: return ("READ_TRACK_INFO");
323         case 0x53: return ("RESERVE_TRACK");
324         case 0x54: return ("SEND_OPC_INFO");
325         case 0x55: return ("MODE_SELECT");
326         case 0x58: return ("REPAIR_TRACK");
327         case 0x59: return ("READ_MASTER_CUE");
328         case 0x5a: return ("MODE_SENSE");
329         case 0x5b: return ("CLOSE_TRACK/SESSION");
330         case 0x5c: return ("READ_BUFFER_CAPACITY");
331         case 0x5d: return ("SEND_CUE_SHEET");
332         case 0x47: return ("PLAY_MSF");
333         case 0x4b: return ("PAUSE");
334         case 0x48: return ("PLAY_TRACK");
335         case 0xa1: return ("BLANK_CMD");
336         case 0xa5: return ("PLAY_BIG");
337         case 0xb4: return ("PLAY_CD");
338         case 0xbd: return ("ATAPI_MECH_STATUS"); 
339         case 0xbe: return ("READ_CD");
340         }
341         snprintf (buf, sizeof(buf), "[0x%x]", cmd);
342         return (buf);
343 }
344
345 static void bswap (char *buf, int len)
346 {
347         u_short *p = (u_short*) (buf + len);
348         while (--p >= (u_short*) buf)
349                 *p = ntohs (*p);
350 }
351
352 static void btrim (char *buf, int len)
353 {
354         char *p;
355
356         /* Remove the trailing spaces. */
357         for (p=buf; p<buf+len; ++p)
358                 if (! *p)
359                         *p = ' ';
360         for (p=buf+len-1; p>=buf && *p==' '; --p)
361                 *p = 0;
362 }
363
364 /*
365  * Issue IDENTIFY command to ATAPI drive to ask it what it is.
366  */
367 static struct atapi_params *atapi_probe (int port, int unit)
368 {
369         struct atapi_params *ap;
370         char tb [DEV_BSIZE];
371 #ifdef PC98
372         int cnt;
373
374         outb(0x432,unit%2); 
375         print(("unit = %d,select %d\n",unit,unit%2)); 
376 #endif
377         /* Wait for controller not busy. */
378 #ifdef PC98
379         outb (port + AR_DRIVE, unit / 2 ? ARD_DRIVE1 : ARD_DRIVE0);
380 #else
381         outb (port + AR_DRIVE, unit ? ARD_DRIVE1 : ARD_DRIVE0);
382 #endif
383         if (atapi_wait (port, 0) < 0) {
384                 print (("atapiX.%d at 0x%x: controller busy, status=%b\n",
385                         unit, port, inb (port + AR_STATUS), ARS_BITS));
386                 return (0);
387         }
388
389         /* Issue ATAPI IDENTIFY command. */
390 #ifdef PC98
391         outb (port + AR_DRIVE, unit/2 ? ARD_DRIVE1 : ARD_DRIVE0);
392
393         /* Wait for DRQ deassert. */
394         for (cnt=2000; cnt>0; --cnt)
395           if (! (inb (port + AR_STATUS) & ARS_DRQ))
396             break;
397
398         outb (port + AR_COMMAND, ATAPIC_IDENTIFY);
399         DELAY(500);
400 #else
401         outb (port + AR_DRIVE, unit ? ARD_DRIVE1 : ARD_DRIVE0);
402         outb (port + AR_COMMAND, ATAPIC_IDENTIFY);
403 #endif
404
405         /* Check that device is present. */
406         if (inb (port + AR_STATUS) == 0xff) {
407                 print (("atapiX.%d at 0x%x: no device\n", unit, port));
408 #ifdef PC98
409                 if (unit / 2)
410 #else
411                 if (unit == 1)
412 #endif
413                         /* Select unit 0. */
414                         outb (port + AR_DRIVE, ARD_DRIVE0);
415                 return (0);
416         }
417
418         /* Wait for data ready. */
419         if (atapi_wait (port, ARS_DRQ) != 0) {
420                 print (("atapiX.%d at 0x%x: identify not ready, status=%b\n",
421                         unit, port, inb (port + AR_STATUS), ARS_BITS));
422 #ifdef PC98
423                 if (unit / 2)
424 #else
425                 if (unit == 1)
426 #endif
427                         /* Select unit 0. */
428                         outb (port + AR_DRIVE, ARD_DRIVE0);
429                 return (0);
430         }
431
432         /* check that DRQ isn't a fake */
433         if (inb (port + AR_STATUS) == 0xff) {
434                 print (("atapiX.%d at 0x%x: no device\n", unit, port));
435 #ifdef PC98
436                 if (unit / 2)
437 #else
438                 if (unit == 1)
439 #endif
440                         /* Select unit 0. */
441                         outb (port + AR_DRIVE, ARD_DRIVE0);
442                 return (0);
443         }
444
445         /* Obtain parameters. */
446         insw (port + AR_DATA, tb, sizeof(tb) / sizeof(short));
447
448         ap = malloc (sizeof *ap, M_TEMP, M_NOWAIT);
449         if (! ap)
450                 return (0);
451         bcopy (tb, ap, sizeof *ap);
452
453 #ifdef PC98
454         /*
455          * Check model string.
456          * If all of it makes unprintable characters, ignore this device.
457          */
458         for (cnt = 0; cnt < sizeof(ap->model)-1; cnt++) {
459                 if (ap->model[cnt] >= ' ')
460                         break;
461         }
462         if (cnt >= sizeof(ap->model)-1) {
463                 free (ap, M_TEMP);
464                 return (0);
465         }
466 #endif
467
468         /*
469          * Shuffle string byte order.
470          * Mitsumi and NEC drives don't need this.
471          */
472         if (! ((ap->model[0] == 'N' && ap->model[1] == 'E') ||
473             (ap->model[0] == 'F' && ap->model[1] == 'X')))
474                 bswap (ap->model, sizeof(ap->model));
475         bswap (ap->serial, sizeof(ap->serial));
476         bswap (ap->revision, sizeof(ap->revision));
477
478         /* Clean up the model name, serial and revision numbers. */
479         btrim (ap->model, sizeof(ap->model));
480         btrim (ap->serial, sizeof(ap->serial));
481         btrim (ap->revision, sizeof(ap->revision));
482         return (ap);
483 }
484
485 /*
486  * Wait uninterruptibly until controller is not busy and certain
487  * status bits are set.
488  * The wait is usually short unless it is for the controller to process
489  * an entire critical command.
490  * Return 1 for (possibly stale) controller errors, -1 for timeout errors,
491  * or 0 for no errors.
492  */
493 static int atapi_wait (int port, u_char bits_wanted)
494 {
495         int cnt;
496         u_char s;
497
498         /* Wait 5 sec for BUSY deassert. */
499         for (cnt=500000; cnt>0; --cnt) {
500                 s = inb (port + AR_STATUS);
501                 if (! (s & ARS_BSY))
502                         break;
503                 DELAY (10);
504         }
505         if (cnt <= 0)
506                 return (-1);
507         if (! bits_wanted)
508                 return (s & ARS_CHECK);
509
510         /* Wait 50 msec for bits wanted. */
511         for (cnt=5000; cnt>0; --cnt) {
512                 s = inb (port + AR_STATUS);
513                 if ((s & bits_wanted) == bits_wanted)
514                         return (s & ARS_CHECK);
515                 DELAY (10);
516         }
517         return (-1);
518 }
519
520 void atapi_debug (struct atapi *ata, int on)
521 {
522         ata->debug = on;
523 }
524
525 static struct atapicmd *atapi_alloc (struct atapi *ata)
526 {
527         struct atapicmd *ac;
528
529         while (! ata->free)
530                 tsleep ((caddr_t)ata, PRIBIO, "atacmd", 100);
531         ac = ata->free;
532         ata->free = ac->next;
533         ac->busy = 1;
534         return (ac);
535 }
536
537 static void atapi_free (struct atapi *ata, struct atapicmd *ac)
538 {
539         if (! ata->free)
540                 wakeup ((caddr_t)ata);
541         ac->busy = 0;
542         ac->next = ata->free;
543         ata->free = ac;
544 }
545
546 /*
547  * Add new command request to the end of the queue.
548  */
549 static void atapi_enqueue (struct atapi *ata, struct atapicmd *ac)
550 {
551         ac->next = 0;
552         if (ata->tail)
553                 ata->tail->next = ac;
554         else
555                 ata->queue = ac;
556         ata->tail = ac;
557 }
558
559 static void atapi_done (struct atapi *ata)
560 {
561         struct atapicmd *ac = ata->queue;
562
563         if (! ac)
564                 return; /* cannot happen */
565
566         ata->queue = ac->next;
567         if (! ata->queue)
568                 ata->tail = 0;
569
570         if (ac->callback) {
571                 (*ac->callback) (ac->cbarg1, ac->cbarg2, ac->count, ac->result);
572                 atapi_free (ata, ac);
573         } else
574                 wakeup ((caddr_t)ac);
575 }
576
577 /*
578  * Start new packet op.  Called from wdstart().
579  * Return 1 if op started, and we are waiting for interrupt.
580  * Return 0 when idle.
581  */
582 int atapi_start (int ctrlr)
583 {
584         struct atapi *ata = atapitab + ctrlr;
585         struct atapicmd *ac;
586 again:
587         ac = ata->queue;
588         if (! ac)
589                 return (0);
590
591         /* Start packet command. */
592         if (atapi_start_cmd (ata, ac) < 0) {
593                 atapi_done (ata);
594                 goto again;
595         }
596
597         if (ata->intrcmd)
598                 /* Wait for interrupt before sending packet command */
599                 return (1);
600
601         /* Wait for DRQ. */
602         if (atapi_wait_cmd (ata, ac) < 0) {
603                 atapi_done (ata);
604                 goto again;
605         }
606
607         /* Send packet command. */
608         atapi_send_cmd (ata, ac);
609         return (1);
610 }
611
612 /*
613  * Start new packet op. Returns -1 on errors.
614  */
615 int atapi_start_cmd (struct atapi *ata, struct atapicmd *ac)
616 {
617         ac->result.error = 0;
618         ac->result.status = 0;
619
620 #ifdef PC98
621         outb(0x432,(ac->unit)%2); 
622         print(("(ac->unit) = %d,select %d (2) \n",(ac->unit),(ac->unit)%2)); 
623         outb (ata->port + AR_DRIVE, (ac->unit)/2 ? ARD_DRIVE1 : ARD_DRIVE0);
624 #else
625         outb (ata->port + AR_DRIVE, ac->unit ? ARD_DRIVE1 : ARD_DRIVE0);
626 #endif
627         if (atapi_wait (ata->port, 0) < 0) {
628                 printf ("atapi%d.%d: controller not ready for cmd\n",
629                         ata->ctrlr, ac->unit);
630                 ac->result.code = RES_NOTRDY;
631                 return (-1);
632         }
633
634         /* Set up the controller registers. */
635         outb (ata->port + AR_FEATURES, 0);
636         outb (ata->port + AR_IREASON, 0);
637         outb (ata->port + AR_TAG, 0);
638         outb (ata->port + AR_CNTLO, ac->count & 0xff);
639         outb (ata->port + AR_CNTHI, ac->count >> 8);
640         outb (ata->port + AR_COMMAND, ATAPIC_PACKET);
641
642         if (ata->debug)
643                 printf ("atapi%d.%d: start\n", ata->ctrlr, ac->unit);
644         return (0);
645 }
646
647 /*
648  * Wait for DRQ before sending packet cmd. Returns -1 on errors.
649  */
650 int atapi_wait_cmd (struct atapi *ata, struct atapicmd *ac)
651 {
652         /* Wait for DRQ from 100 usec to 3 msec for slow devices */
653         int cnt = ata->intrcmd ? 10000 : ata->slow ? 3000 : 100;
654         int ireason = 0, phase = 0;
655
656         /* Wait for command phase. */
657         for (; cnt>0; cnt-=10) {
658                 ireason = inb (ata->port + AR_IREASON);
659                 ac->result.status = inb (ata->port + AR_STATUS);
660                 phase = (ireason & (ARI_CMD | ARI_IN)) |
661                         (ac->result.status & (ARS_DRQ | ARS_BSY));
662                 if (phase == PHASE_CMDOUT)
663                         break;
664                 DELAY (10);
665         }
666
667         if (phase != PHASE_CMDOUT) {
668                 ac->result.code = RES_NODRQ;
669                 ac->result.error = inb (ata->port + AR_ERROR);
670                 printf ("atapi%d.%d: invalid command phase, ireason=0x%x, status=%b, error=%b\n",
671                         ata->ctrlr, ac->unit, ireason,
672                         ac->result.status, ARS_BITS,
673                         ac->result.error, AER_BITS);
674                 return (-1);
675         }
676         return (0);
677 }
678
679 /*
680  * Send packet cmd.
681  */
682 void atapi_send_cmd (struct atapi *ata, struct atapicmd *ac)
683 {
684         outsw (ata->port + AR_DATA, ac->cmd, ata->cmd16 ? 8 : 6);
685         if (ata->debug)
686                 printf ("atapi%d.%d: send cmd %s %x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x\n",
687                         ata->ctrlr, ac->unit, cmdname (ac->cmd[0]), ac->cmd[0],
688                         ac->cmd[1], ac->cmd[2], ac->cmd[3], ac->cmd[4],
689                         ac->cmd[5], ac->cmd[6], ac->cmd[7], ac->cmd[8],
690                         ac->cmd[9], ac->cmd[10], ac->cmd[11], ac->cmd[12],
691                         ac->cmd[13], ac->cmd[14], ac->cmd[15]);
692 }
693
694 /*
695  * Interrupt routine for the controller.  Called from wdintr().
696  * Finish the started op, wakeup wait-type commands,
697  * run callbacks for callback-type commands, then return.
698  * Do not start new op here, it will be done by wdstart,
699  * which is called just after us.
700  * Return 1 if op continues, and we are waiting for new interrupt.
701  * Return 0 when idle.
702  */
703 int atapi_intr (int ctrlr)
704 {
705         struct atapi *ata = atapitab + ctrlr;
706         struct atapicmd *ac = ata->queue;
707
708 #ifdef PC98
709         outb(0x432,(ac->unit)%2);
710         print(("atapi_intr:(ac->unit)= %d,select %d\n",ac->unit,(ac->unit)%2));
711 #endif
712
713         if (! ac) {
714                 printf ("atapi%d: stray interrupt\n", ata->ctrlr);
715                 return (0);
716         }
717         if (atapi_io (ata, ac) > 0)
718                 return (1);
719         atapi_done (ata);
720         return (0);
721 }
722
723 /*
724  * Process the i/o phase, transferring the command/data to/from the device.
725  * Return 1 if op continues, and we are waiting for new interrupt.
726  * Return 0 when idle.
727  */
728 int atapi_io (struct atapi *ata, struct atapicmd *ac)
729 {
730         u_char ireason;
731         u_short len, i;
732
733         if (atapi_wait (ata->port, 0) < 0) {
734                 ac->result.status = inb (ata->port + AR_STATUS);
735                 ac->result.error = inb (ata->port + AR_ERROR);
736                 ac->result.code = RES_NOTRDY;
737                 printf ("atapi%d.%d: controller not ready, status=%b, error=%b\n",
738                         ata->ctrlr, ac->unit, ac->result.status, ARS_BITS,
739                         ac->result.error, AER_BITS);
740                 return (0);
741         }
742
743         ac->result.status = inb (ata->port + AR_STATUS);
744         ac->result.error = inb (ata->port + AR_ERROR);
745         len = inb (ata->port + AR_CNTLO);
746         len |= inb (ata->port + AR_CNTHI) << 8;
747         ireason = inb (ata->port + AR_IREASON);
748
749         if (ata->debug) {
750                 printf ("atapi%d.%d: intr ireason=0x%x, len=%d, status=%b, error=%b\n",
751                         ata->ctrlr, ac->unit, ireason, len,
752                         ac->result.status, ARS_BITS,
753                         ac->result.error, AER_BITS);
754         }
755         switch ((ireason & (ARI_CMD | ARI_IN)) | (ac->result.status & ARS_DRQ)) {
756         default:
757                 printf ("atapi%d.%d: unknown phase\n", ata->ctrlr, ac->unit);
758                 ac->result.code = RES_ERR;
759                 break;
760
761         case PHASE_CMDOUT:
762                 /* Send packet command. */
763                 if (! (ac->result.status & ARS_DRQ)) {
764                         printf ("atapi%d.%d: no cmd drq\n",
765                                 ata->ctrlr, ac->unit);
766                         ac->result.code = RES_NODRQ;
767                         break;
768                 }
769                 atapi_send_cmd (ata, ac);
770                 return (1);
771
772         case PHASE_DATAOUT:
773                 /* Write data */
774                 if (ac->count > 0) {
775                         printf ("atapi%d.%d: invalid data direction\n",
776                                 ata->ctrlr, ac->unit);
777                         ac->result.code = RES_INVDIR;
778                         break;
779                 }
780                 if (-ac->count < len) {
781                         print (("atapi%d.%d: send data underrun, %d bytes left\n",
782                                 ata->ctrlr, ac->unit, -ac->count));
783                         ac->result.code = RES_UNDERRUN;
784                         outsw (ata->port + AR_DATA, ac->addr,
785                                 -ac->count / sizeof(short));
786                         for (i= -ac->count; i<len; i+=sizeof(short))
787                                 outw (ata->port + AR_DATA, 0);
788                 } else
789                         outsw (ata->port + AR_DATA, ac->addr,
790                                 len / sizeof(short));
791                 ac->addr += len;
792                 ac->count += len;
793                 return (1);
794
795         case PHASE_DATAIN:
796                 /* Read data */
797                 if (ac->count < 0) {
798                         printf ("atapi%d.%d: invalid data direction\n",
799                                 ata->ctrlr, ac->unit);
800                         ac->result.code = RES_INVDIR;
801                         break;
802                 }
803                 if (ac->count < len) {
804                         print (("atapi%d.%d: recv data overrun, %d bytes left\n",
805                                 ata->ctrlr, ac->unit, ac->count));
806                         ac->result.code = RES_OVERRUN;
807                         insw (ata->port + AR_DATA, ac->addr,
808                                 ac->count / sizeof(short));
809                         for (i=ac->count; i<len; i+=sizeof(short))
810                                 inw (ata->port + AR_DATA);
811                 } else
812                         insw (ata->port + AR_DATA, ac->addr,
813                                 len / sizeof(short));
814                 ac->addr += len;
815                 ac->count -= len;
816                 return (1);
817
818         case PHASE_ABORTED:
819         case PHASE_COMPLETED:
820                 if (ac->result.status & (ARS_CHECK | ARS_DF))
821                         ac->result.code = RES_ERR;
822                 else if (ac->count < 0) {
823                         print (("atapi%d.%d: send data overrun, %d bytes left\n",
824                                 ata->ctrlr, ac->unit, -ac->count));
825                         ac->result.code = RES_OVERRUN;
826                 } else if (ac->count > 0) {
827                         print (("atapi%d.%d: recv data underrun, %d bytes left\n",
828                                 ata->ctrlr, ac->unit, ac->count));
829                         ac->result.code = RES_UNDERRUN;
830                         bzero (ac->addr, ac->count);
831                 } else
832                         ac->result.code = RES_OK;
833                 break;
834         }
835         return (0);
836 }
837
838 /*
839  * Queue new packet request, then call wdstart().
840  * Called on splbio().
841  */
842 void atapi_request_callback (struct atapi *ata, int unit,
843         u_char cmd, u_char a1, u_char a2, u_char a3, u_char a4,
844         u_char a5, u_char a6, u_char a7, u_char a8, u_char a9,
845         u_char a10, u_char a11, u_char a12, u_char a13, u_char a14, u_char a15,
846         char *addr, int count, atapi_callback_t *done, void *x, void *y)
847 {
848         struct atapicmd *ac;
849
850         ac = atapi_alloc (ata);
851         ac->cmd[0] = cmd;       ac->cmd[1] = a1;
852         ac->cmd[2] = a2;        ac->cmd[3] = a3;
853         ac->cmd[4] = a4;        ac->cmd[5] = a5;
854         ac->cmd[6] = a6;        ac->cmd[7] = a7;
855         ac->cmd[8] = a8;        ac->cmd[9] = a9;
856         ac->cmd[10] = a10;      ac->cmd[11] = a11;
857         ac->cmd[12] = a12;      ac->cmd[13] = a13;
858         ac->cmd[14] = a14;      ac->cmd[15] = a15;
859         ac->unit = unit;
860         ac->addr = addr;
861         ac->count = count;
862         ac->callback = done;
863         ac->cbarg1 = x;
864         ac->cbarg2 = y;
865
866         if (ata->debug)
867                 printf ("atapi%d.%d: req cb %x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x len=%d\n",
868                         ata->ctrlr, ac->unit, ac->cmd[0], ac->cmd[1],
869                         ac->cmd[2], ac->cmd[3], ac->cmd[4], ac->cmd[5],
870                         ac->cmd[6], ac->cmd[7], ac->cmd[8], ac->cmd[9],
871                         ac->cmd[10], ac->cmd[11], ac->cmd[12],
872                         ac->cmd[13], ac->cmd[14], ac->cmd[15], count);
873         atapi_enqueue (ata, ac);
874         wdstart (ata->ctrlr);
875 }
876
877 /*
878  * Queue new packet request, then call wdstart().
879  * Wait until the request is finished.
880  * Called on spl0().
881  * Return atapi error.
882  * Buffer pointed to by *addr should be placed in core memory, not in stack!
883  */
884 struct atapires atapi_request_wait (struct atapi *ata, int unit,
885         u_char cmd, u_char a1, u_char a2, u_char a3, u_char a4,
886         u_char a5, u_char a6, u_char a7, u_char a8, u_char a9,
887         u_char a10, u_char a11, u_char a12, u_char a13, u_char a14, u_char a15,
888         char *addr, int count)
889 {
890         struct atapicmd *ac;
891         int x = splbio ();
892         struct atapires result;
893
894         ac = atapi_alloc (ata);
895         ac->cmd[0] = cmd;       ac->cmd[1] = a1;
896         ac->cmd[2] = a2;        ac->cmd[3] = a3;
897         ac->cmd[4] = a4;        ac->cmd[5] = a5;
898         ac->cmd[6] = a6;        ac->cmd[7] = a7;
899         ac->cmd[8] = a8;        ac->cmd[9] = a9;
900         ac->cmd[10] = a10;      ac->cmd[11] = a11;
901         ac->cmd[12] = a12;      ac->cmd[13] = a13;
902         ac->cmd[14] = a14;      ac->cmd[15] = a15;
903         ac->unit = unit;
904         ac->addr = addr;
905         ac->count = count;
906         ac->callback = 0;
907         ac->cbarg1 = 0;
908         ac->cbarg2 = 0;
909
910         if (ata->debug)
911                 printf ("atapi%d.%d: req w %x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x len=%d\n",
912                         ata->ctrlr, ac->unit, ac->cmd[0], ac->cmd[1],
913                         ac->cmd[2], ac->cmd[3], ac->cmd[4], ac->cmd[5],
914                         ac->cmd[6], ac->cmd[7], ac->cmd[8], ac->cmd[9],
915                         ac->cmd[10], ac->cmd[11], ac->cmd[12],
916                         ac->cmd[13], ac->cmd[14], ac->cmd[15], count);
917         atapi_enqueue (ata, ac);
918         wdstart (ata->ctrlr);
919         if (ata->tail == ac)
920                 tsleep ((caddr_t)ac, PRIBIO, "atareq", 0);
921
922         result = ac->result;
923         atapi_free (ata, ac);
924         splx (x);
925         return (result);
926 }
927
928 /*
929  * Perform a packet command on the device.
930  * Should be called on splbio().
931  * Return atapi error.
932  */
933 struct atapires atapi_request_immediate (struct atapi *ata, int unit,
934         u_char cmd, u_char a1, u_char a2, u_char a3, u_char a4,
935         u_char a5, u_char a6, u_char a7, u_char a8, u_char a9,
936         u_char a10, u_char a11, u_char a12, u_char a13, u_char a14, u_char a15,
937         char *addr, int count)
938 {
939         struct atapicmd cmdbuf, *ac = &cmdbuf;
940         int cnt;
941
942         ac->cmd[0] = cmd;       ac->cmd[1] = a1;
943         ac->cmd[2] = a2;        ac->cmd[3] = a3;
944         ac->cmd[4] = a4;        ac->cmd[5] = a5;
945         ac->cmd[6] = a6;        ac->cmd[7] = a7;
946         ac->cmd[8] = a8;        ac->cmd[9] = a9;
947         ac->cmd[10] = a10;      ac->cmd[11] = a11;
948         ac->cmd[12] = a12;      ac->cmd[13] = a13;
949         ac->cmd[14] = a14;      ac->cmd[15] = a15;
950         ac->unit = unit;
951         ac->addr = addr;
952         ac->count = count;
953         ac->callback = 0;
954         ac->cbarg1 = 0;
955         ac->cbarg2 = 0;
956
957         if (ata->debug)
958                 printf ("atapi%d.%d: req im %x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x len=%d\n",
959                         ata->ctrlr, ac->unit, ac->cmd[0], ac->cmd[1],
960                         ac->cmd[2], ac->cmd[3], ac->cmd[4], ac->cmd[5],
961                         ac->cmd[6], ac->cmd[7], ac->cmd[8], ac->cmd[9],
962                         ac->cmd[10], ac->cmd[11], ac->cmd[12],
963                         ac->cmd[13], ac->cmd[14], ac->cmd[15], count);
964
965         /* Start packet command, wait for DRQ. */
966         if (atapi_start_cmd (ata, ac) >= 0 && atapi_wait_cmd (ata, ac) >= 0) {
967                 /* Send packet command. */
968                 atapi_send_cmd (ata, ac);
969
970                 /* Wait for data i/o phase. */
971                 for (cnt=20000; cnt>0; --cnt)
972                         if (((inb (ata->port + AR_IREASON) & (ARI_CMD | ARI_IN)) |
973                             (inb (ata->port + AR_STATUS) & ARS_DRQ)) != PHASE_CMDOUT)
974                                 break;
975
976                 /* Do all needed i/o. */
977                 while (atapi_io (ata, ac))
978                         /* Wait for DRQ deassert. */
979                         for (cnt=2000; cnt>0; --cnt) {
980                                 if (! (inb (ata->port + AR_STATUS) & ARS_DRQ))
981                                         break;
982                                 DELAY(10);
983                         }
984         }
985         return (ac->result);
986 }
987
988 #endif /* NWDC */