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