]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/dev/ata/atapi-all.c
Fill in missing parts of the ATAPI/CAM XPT: implement XPT_RESET_BUS
[FreeBSD/FreeBSD.git] / sys / dev / ata / atapi-all.c
1 /*-
2  * Copyright (c) 1998,1999,2000,2001,2002 Søren Schmidt <sos@FreeBSD.org>
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  * $FreeBSD$
29  */
30
31 #include "opt_ata.h"
32 #include <sys/param.h>
33 #include <sys/systm.h>
34 #include <sys/ata.h>
35 #include <sys/kernel.h>
36 #include <sys/bus.h>
37 #include <sys/malloc.h>
38 #include <sys/bio.h>
39 #include <sys/sysctl.h>
40 #include <machine/bus.h>
41 #include <sys/rman.h>
42 #include <dev/ata/ata-all.h>
43 #include <dev/ata/atapi-all.h>
44
45 /* prototypes */
46 static void atapi_read(struct atapi_request *, int);
47 static void atapi_write(struct atapi_request *, int);
48 static void atapi_finish(struct atapi_request *);
49 static void atapi_timeout(struct atapi_request *);
50 static char *atapi_cmd2str(u_int8_t);
51 static char *atapi_skey2str(u_int8_t);
52
53 /* misc defines */
54 #define ATAPI_MAX_RETRIES       3
55
56 /* internal vars */
57 static int atapi_dma = 0;
58 TUNABLE_INT("hw.ata.atapi_dma", &atapi_dma);
59 static MALLOC_DEFINE(M_ATAPI, "ATAPI generic", "ATAPI driver generic layer");
60
61 /* systcl vars */
62 SYSCTL_DECL(_hw_ata);
63 SYSCTL_INT(_hw_ata, OID_AUTO, atapi_dma, CTLFLAG_RD, &atapi_dma, 0,
64            "ATAPI device DMA mode control");
65
66 void
67 atapi_attach(struct ata_device *atadev)
68 {
69     if (bootverbose) 
70         ata_prtdev(atadev, "piomode=%d dmamode=%d udmamode=%d dmaflag=%d\n",
71                    ata_pmode(atadev->param), ata_wmode(atadev->param),
72                    ata_umode(atadev->param), atadev->param->support_dma);
73
74     ATA_SLEEPLOCK_CH(atadev->channel, ATA_CONTROL);
75     if (atapi_dma && !(atadev->param->drq_type == ATAPI_DRQT_INTR)) {
76         ata_dmainit(atadev,
77                     (ata_pmode(atadev->param) < 0) ? 
78                     (atadev->param->support_dma ? 4:0):ata_pmode(atadev->param),
79                     (ata_wmode(atadev->param) < 0) ? 
80                     (atadev->param->support_dma ? 2:0):ata_wmode(atadev->param),
81                     ata_umode(atadev->param));
82     }
83     else
84         ata_dmainit(atadev,
85                     ata_pmode(atadev->param) < 0 ? 0 : ata_pmode(atadev->param),
86                     -1, -1);
87     ATA_UNLOCK_CH(atadev->channel);
88
89     if (!(atadev->result = malloc(sizeof(struct atapi_reqsense), M_ATAPI,
90                                   M_NOWAIT | M_ZERO)))
91         ata_prtdev(atadev, "no memory for sense data\n");
92
93     switch (atadev->param->type) {
94 #ifdef DEV_ATAPICD
95     case ATAPI_TYPE_CDROM:
96         if (acdattach(atadev))
97             return;
98         break; 
99 #endif
100 #ifdef DEV_ATAPIFD
101     case ATAPI_TYPE_DIRECT:
102         if (afdattach(atadev))
103             return; 
104         break;
105 #endif
106 #ifdef DEV_ATAPIST
107     case ATAPI_TYPE_TAPE:
108         if (astattach(atadev))
109             return; 
110         break;
111 #endif
112     }
113 #ifndef DEV_ATAPICAM
114     ata_prtdev(atadev, "<%.40s/%.8s> - NO DRIVER!\n",
115                atadev->param->model, atadev->param->revision);
116     free(atadev->result, M_ATAPI);
117     atadev->driver = NULL;
118 #endif
119 }
120
121 void
122 atapi_detach(struct ata_device *atadev)
123 {
124     struct atapi_request *request;
125
126     atadev->flags |= ATA_D_DETACHING;
127     ata_prtdev(atadev, "removed from configuration\n");
128     switch (atadev->param->type) {
129 #ifdef DEV_ATAPICD
130     case ATAPI_TYPE_CDROM:
131         acddetach(atadev);
132         break; 
133 #endif
134 #ifdef DEV_ATAPIFD
135     case ATAPI_TYPE_DIRECT:
136         afddetach(atadev);
137         break; 
138 #endif
139 #ifdef DEV_ATAPIST
140     case ATAPI_TYPE_TAPE:
141         astdetach(atadev);
142         break; 
143 #endif
144     default:
145         return;
146     }
147     TAILQ_FOREACH(request, &atadev->channel->atapi_queue, chain) {
148         if (request->device != atadev)
149             continue;
150         TAILQ_REMOVE(&atadev->channel->atapi_queue, request, chain);
151         if (request->driver) {
152             struct bio *bp = (struct bio *) request->driver;
153             biofinish(bp, NULL, ENXIO);
154         }
155         free(request, M_ATAPI);
156     }
157     ata_dmafree(atadev);
158     free(atadev->result, M_ATAPI);
159     atadev->driver = NULL;
160     atadev->flags = 0;
161
162 }
163
164 int       
165 atapi_queue_cmd(struct ata_device *atadev, int8_t *ccb, caddr_t data, 
166                 int count, int flags, int timeout,
167                 atapi_callback_t callback, void *driver)
168 {
169     struct atapi_request *request;
170     int error, s;
171  
172     if (!(request = malloc(sizeof(struct atapi_request), M_ATAPI,
173                            M_NOWAIT | M_ZERO)))
174         return ENOMEM;
175
176     request->device = atadev;
177     request->data = data;
178     request->bytecount = count;
179     request->flags = flags;
180     request->error = EINPROGRESS;
181     request->timeout = timeout * hz;
182     request->ccbsize = atadev->param->packet_size ? 16 : 12;
183     bcopy(ccb, request->ccb, request->ccbsize);
184     if (callback) {
185         request->callback = callback;
186         request->driver = driver;
187     }
188     if (atadev->mode >= ATA_DMA) {
189         if (ata_dmaalloc(atadev))
190             atadev->mode = ATA_PIO;
191     }
192
193 #ifdef ATAPI_DEBUG
194     ata_prtdev(atadev, "queueing %s ", atapi_cmd2str(request->ccb[0]));
195     atapi_dump("ccb = ", &request->ccb[0], sizeof(request->ccb));
196 #endif
197     /* append onto controller queue and try to start controller */
198     s = splbio();
199     if (flags & ATPR_F_AT_HEAD)
200         TAILQ_INSERT_HEAD(&atadev->channel->atapi_queue, request, chain);
201     else
202         TAILQ_INSERT_TAIL(&atadev->channel->atapi_queue, request, chain);
203     ata_start(atadev->channel);
204
205     /* if callback used, then just return, gets called from interrupt context */
206     if (callback) {
207         splx(s);
208         return 0;
209     }
210
211     /* only sleep when command is in progress */
212     if (request->error == EINPROGRESS)
213         tsleep((caddr_t)request, PRIBIO, "atprq", 0);
214     splx(s);
215     error = request->error;
216     if (error)
217          bcopy(&request->sense, atadev->result, sizeof(struct atapi_reqsense));
218     free(request, M_ATAPI);
219     return error;
220 }
221     
222 void
223 atapi_start(struct ata_device *atadev)
224 {
225     switch (atadev->param->type) {
226 #ifdef DEV_ATAPICD
227     case ATAPI_TYPE_CDROM:
228         acd_start(atadev);
229         break; 
230 #endif
231 #ifdef DEV_ATAPIFD
232     case ATAPI_TYPE_DIRECT:
233         afd_start(atadev);
234         break; 
235 #endif
236 #ifdef DEV_ATAPIST
237     case ATAPI_TYPE_TAPE:
238         ast_start(atadev);
239         break; 
240 #endif
241     default:
242         return;
243     }
244 }
245
246 int
247 atapi_transfer(struct atapi_request *request)
248 {
249     struct ata_device *atadev = request->device;
250     int timout;
251     u_int8_t reason;
252
253 #ifdef ATAPI_DEBUG
254     ata_prtdev(atadev, "starting %s ", atapi_cmd2str(request->ccb[0]));
255     atapi_dump("ccb = ", &request->ccb[0], sizeof(request->ccb));
256 #endif
257     /* is this just a POLL DSC command ? */
258     if (request->ccb[0] == ATAPI_POLL_DSC) {
259         ATA_OUTB(atadev->channel->r_io, ATA_DRIVE, ATA_D_IBM | atadev->unit);
260         DELAY(10);
261         if (ATA_INB(atadev->channel->r_altio, ATA_ALTSTAT) & ATA_S_DSC)
262             request->error = 0;
263         else
264             request->error = EBUSY;
265         atapi_finish(request);
266         return ATA_OP_FINISHED;
267     }
268
269     /* start timeout for this command */
270     request->timeout_handle = timeout((timeout_t *)atapi_timeout, 
271                                       request, request->timeout);
272
273     if (!(request->flags & ATPR_F_INTERNAL))
274         atadev->cmd = request->ccb[0];
275
276     /* if DMA enabled setup DMA hardware */
277     request->flags &= ~ATPR_F_DMA_USED; 
278     if ((atadev->mode >= ATA_DMA) &&
279         (request->ccb[0] == ATAPI_READ || 
280          request->ccb[0] == ATAPI_READ_BIG ||
281          request->ccb[0] == ATAPI_READ_CD ||
282          ((request->ccb[0] == ATAPI_WRITE ||
283            request->ccb[0] == ATAPI_WRITE_BIG) &&
284           !(atadev->channel->flags & ATA_ATAPI_DMA_RO))) &&
285         !ata_dmasetup(atadev, (void *)request->data, request->bytecount)) {
286         request->flags |= ATPR_F_DMA_USED;
287     }
288
289     /* start ATAPI operation */
290     if (ata_command(atadev, ATA_C_PACKET_CMD, 
291                     min(request->bytecount, 65534) << 8, 0,
292                     (request->flags & ATPR_F_DMA_USED) ? ATA_F_DMA : 0,
293                     ATA_IMMEDIATE))
294         ata_prtdev(atadev, "failure to send ATAPI packet command\n");
295
296     if (request->flags & ATPR_F_DMA_USED)
297         ata_dmastart(atadev, request->data, request->bytecount,
298                      request->flags & ATPR_F_READ);
299
300     /* command interrupt device ? just return */
301     if (atadev->param->drq_type == ATAPI_DRQT_INTR)
302         return ATA_OP_CONTINUES;
303
304     /* ready to write ATAPI command */
305     timout = 5000; /* might be less for fast devices */
306     while (timout--) {
307         reason = ATA_INB(atadev->channel->r_io, ATA_IREASON);
308         atadev->channel->status = ATA_INB(atadev->channel->r_io, ATA_STATUS);
309         if (((reason & (ATA_I_CMD | ATA_I_IN)) |
310              (atadev->channel->status&(ATA_S_DRQ|ATA_S_BUSY)))==ATAPI_P_CMDOUT)
311             break;
312         DELAY(20);
313     }
314     if (timout <= 0) {
315         ata_prtdev(atadev, "failure to execute ATAPI packet command\n");
316         untimeout((timeout_t *)atapi_timeout, request, request->timeout_handle);
317         request->error = EIO;
318         atapi_finish(request);  
319         return ATA_OP_FINISHED;
320     }
321
322     /* this seems to be needed for some (slow) devices */
323     DELAY(10);
324
325     /* send actual command */
326     ATA_OUTSW_STRM(atadev->channel->r_io, ATA_DATA, (int16_t *)request->ccb,
327                    request->ccbsize / sizeof(int16_t));
328     return ATA_OP_CONTINUES;
329 }
330
331 int
332 atapi_interrupt(struct atapi_request *request)
333 {
334     struct ata_device *atadev = request->device;
335     int reason, dma_stat = 0;
336
337     reason = (ATA_INB(atadev->channel->r_io, ATA_IREASON)&(ATA_I_CMD|ATA_I_IN))|
338              (atadev->channel->status & ATA_S_DRQ);
339
340     if (reason == ATAPI_P_CMDOUT) {
341         if (!(atadev->channel->status & ATA_S_DRQ)) {
342             ata_prtdev(atadev, "command interrupt without DRQ\n");
343             untimeout((timeout_t *)atapi_timeout,
344                       request, request->timeout_handle);
345             request->error = EIO;
346             atapi_finish(request);      
347             return ATA_OP_FINISHED;
348         }
349         ATA_OUTSW_STRM(atadev->channel->r_io, ATA_DATA, (int16_t *)request->ccb,
350                        request->ccbsize / sizeof(int16_t));
351         return ATA_OP_CONTINUES;
352     }
353
354     if (request->flags & ATPR_F_DMA_USED) {
355         dma_stat = ata_dmadone(atadev);
356         if ((atadev->channel->status & (ATA_S_ERROR | ATA_S_DWF)) ||
357             dma_stat & ATA_BMSTAT_ERROR) {
358             request->result = ATA_INB(atadev->channel->r_io, ATA_ERROR);
359         }
360         else {
361             request->result = 0;
362             request->donecount = request->bytecount;
363             request->bytecount = 0;
364         }
365     }
366     else {
367         int length = ATA_INB(atadev->channel->r_io, ATA_CYL_LSB) |
368                      ATA_INB(atadev->channel->r_io, ATA_CYL_MSB) << 8;
369
370         switch (reason) {
371         case ATAPI_P_WRITE:
372             if (request->flags & ATPR_F_READ) {
373                 request->result = ATA_INB(atadev->channel->r_io, ATA_ERROR);
374                 ata_prtdev(atadev, "%s trying to write on read buffer\n",
375                            atapi_cmd2str(atadev->cmd));
376                 break;
377             }
378             atapi_write(request, length);
379             return ATA_OP_CONTINUES;
380         
381         case ATAPI_P_READ:
382             if (!(request->flags & ATPR_F_READ)) {
383                 request->result = ATA_INB(atadev->channel->r_io, ATA_ERROR);
384                 ata_prtdev(atadev, "%s trying to read on write buffer\n",
385                            atapi_cmd2str(atadev->cmd));
386                 break;
387             }
388             atapi_read(request, length);
389             return ATA_OP_CONTINUES;
390
391         case ATAPI_P_DONEDRQ:
392             ata_prtdev(atadev, "%s DONEDRQ\n", atapi_cmd2str(atadev->cmd));
393             if (request->flags & ATPR_F_READ)
394                 atapi_read(request, length);
395             else
396                 atapi_write(request, length);
397             /* FALLTHROUGH */
398
399         case ATAPI_P_ABORT:
400         case ATAPI_P_DONE:
401             if (atadev->channel->status & (ATA_S_ERROR | ATA_S_DWF))
402                 request->result = ATA_INB(atadev->channel->r_io, ATA_ERROR);
403             else 
404                 if (!(request->flags & ATPR_F_INTERNAL))
405                     request->result = 0;
406             break;
407
408         default:
409             ata_prtdev(atadev, "unknown transfer phase %d\n", reason);
410         }
411     }
412     untimeout((timeout_t *)atapi_timeout, request, request->timeout_handle);
413
414     /* check for error, if valid sense key, queue a request sense cmd */
415     if ((request->result & ATAPI_SK_MASK) && 
416         request->ccb[0] != ATAPI_REQUEST_SENSE) {
417         bzero(request->ccb, request->ccbsize);
418         request->ccb[0] = ATAPI_REQUEST_SENSE;
419         request->ccb[4] = sizeof(struct atapi_reqsense);
420         request->bytecount = sizeof(struct atapi_reqsense);
421         request->flags &= ATPR_F_QUIET;
422         request->flags |= ATPR_F_READ | ATPR_F_INTERNAL;
423         TAILQ_INSERT_HEAD(&atadev->channel->atapi_queue, request, chain);
424     }
425     else {
426         if (request->result) {
427             switch ((request->result & ATAPI_SK_MASK)) {
428             case ATAPI_SK_NO_SENSE:
429                 request->error = 0;
430                 break;
431
432             case ATAPI_SK_RECOVERED_ERROR:
433                 ata_prtdev(atadev, "%s - recovered error\n",
434                            atapi_cmd2str(atadev->cmd));
435                 request->error = 0;
436                 break;
437
438             case ATAPI_SK_NOT_READY:
439                 request->error = EBUSY;
440                 break;
441
442             case ATAPI_SK_UNIT_ATTENTION:
443                 atadev->flags |= ATA_D_MEDIA_CHANGED;
444                 request->error = EIO;
445                 break;
446
447             default: 
448                 request->error = EIO;
449
450                 if (request->flags & ATPR_F_QUIET)
451                     break;
452
453                 ata_prtdev(atadev, "%s - %s asc=0x%02x ascq=0x%02x ",
454                            atapi_cmd2str(atadev->cmd), 
455                            atapi_skey2str(request->sense.sense_key), 
456                            request->sense.asc, request->sense.ascq);
457                 if (request->sense.sksv)
458                     printf("sks=0x%02x 0x%02x 0x%02x ",
459                            request->sense.sk_specific,
460                            request->sense.sk_specific1,
461                            request->sense.sk_specific2);
462                 printf("error=0x%02x\n", request->result & ATAPI_E_MASK);
463             }
464         }
465         else
466             request->error = 0;
467         atapi_finish(request);  
468     }
469     return ATA_OP_FINISHED;
470 }
471
472 void
473 atapi_reinit(struct ata_device *atadev)
474 {
475     /* reinit device parameters */
476     if (atadev->mode >= ATA_DMA)
477         ata_dmainit(atadev,
478                     (ata_pmode(atadev->param) < 0) ?
479                     (atadev->param->support_dma ? 4:0):ata_pmode(atadev->param),
480                     (ata_wmode(atadev->param) < 0) ? 
481                     (atadev->param->support_dma ? 2:0):ata_wmode(atadev->param),
482                     ata_umode(atadev->param));
483     else
484         ata_dmainit(atadev,
485                     ata_pmode(atadev->param)<0 ? 0 : ata_pmode(atadev->param),
486                     -1, -1);
487 }
488
489 int
490 atapi_test_ready(struct ata_device *atadev)
491 {
492     int8_t ccb[16] = { ATAPI_TEST_UNIT_READY, 0, 0, 0, 0,
493                        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
494         
495     return atapi_queue_cmd(atadev, ccb, NULL, 0, 0, 30, NULL, NULL);
496 }
497         
498 int
499 atapi_wait_dsc(struct ata_device *atadev, int timeout)
500 {
501     int error = 0;
502     int8_t ccb[16] = { ATAPI_POLL_DSC, 0, 0, 0, 0,
503                        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
504
505     timeout *= hz;
506     while (timeout > 0) {
507         error = atapi_queue_cmd(atadev, ccb, NULL, 0, 0, 0, NULL, NULL);
508         if (error != EBUSY)
509             break;
510         tsleep((caddr_t)&error, PRIBIO, "atpwt", hz / 2);
511         timeout -= (hz / 2);
512     }
513     return error;
514 }
515
516 void
517 atapi_dump(char *label, void *data, int len)
518 {
519     u_int8_t *p = data;
520
521     printf("%s %02x", label, *p++);
522     while (--len > 0) 
523         printf ("-%02x", *p++);
524     printf("\n");
525 }
526
527 static void
528 atapi_read(struct atapi_request *request, int length)
529 {
530     int8_t **buffer = (int8_t **)&request->data;
531     int size = min(request->bytecount, length);
532     struct ata_channel *ch = request->device->channel;
533     int resid;
534
535     if (request->flags & ATPR_F_INTERNAL)
536         *buffer = (int8_t *)&request->sense;
537
538     if (ch->flags & ATA_USE_16BIT || (size % sizeof(int32_t)))
539         ATA_INSW_STRM(ch->r_io, ATA_DATA, (void *)((uintptr_t)*buffer), 
540                       size / sizeof(int16_t));
541     else
542         ATA_INSL_STRM(ch->r_io, ATA_DATA, (void *)((uintptr_t)*buffer),
543                       size / sizeof(int32_t));
544
545     if (request->bytecount < length) {
546         ata_prtdev(request->device, "read data overrun %d/%d\n",
547                    length, request->bytecount);
548         for (resid=request->bytecount; resid<length; resid+=sizeof(int16_t))
549              ATA_INW(ch->r_io, ATA_DATA);
550     }
551     *buffer += size;
552     request->bytecount -= size;
553     request->donecount += size;
554 }
555
556 static void
557 atapi_write(struct atapi_request *request, int length)
558 {
559     int8_t **buffer = (int8_t **)&request->data;
560     int size = min(request->bytecount, length);
561     struct ata_channel *ch = request->device->channel;
562     int resid;
563
564     if (request->flags & ATPR_F_INTERNAL)
565         *buffer = (int8_t *)&request->sense;
566
567     if (ch->flags & ATA_USE_16BIT || (size % sizeof(int32_t)))
568         ATA_OUTSW_STRM(ch->r_io, ATA_DATA, (void *)((uintptr_t)*buffer),
569                        size / sizeof(int16_t));
570     else
571         ATA_OUTSL_STRM(ch->r_io, ATA_DATA, (void *)((uintptr_t)*buffer),
572                        size / sizeof(int32_t));
573
574     if (request->bytecount < length) {
575         ata_prtdev(request->device, "write data underrun %d/%d\n",
576                    length, request->bytecount);
577         for (resid=request->bytecount; resid<length; resid+=sizeof(int16_t))
578             ATA_OUTW(ch->r_io, ATA_DATA, 0);
579     }
580     *buffer += size;
581     request->bytecount -= size;
582     request->donecount += size;
583 }
584
585 static void
586 atapi_finish(struct atapi_request *request)
587 {
588 #ifdef ATAPI_DEBUG
589     ata_prtdev(request->device, "finished %s%s\n",
590                request->callback ? "callback " : "",
591                atapi_cmd2str(request->ccb[0]));
592 #endif
593     if (request->callback) {
594         if (!((request->callback)(request)))
595             free(request, M_ATAPI);
596     }
597     else 
598         wakeup((caddr_t)request);       
599 }
600
601 static void 
602 atapi_timeout(struct atapi_request *request)
603 {
604     struct ata_device *atadev = request->device;
605
606     atadev->channel->running = NULL;
607     ata_prtdev(atadev, "%s command timeout - resetting\n", 
608                atapi_cmd2str(request->ccb[0]));
609
610     if (request->flags & ATPR_F_DMA_USED) {
611         ata_dmadone(atadev);
612         if (request->retries == ATAPI_MAX_RETRIES) {
613             ata_dmainit(atadev,
614                         (ata_pmode(atadev->param) < 0) ? 0 :
615                          ata_pmode(atadev->param), -1, -1);
616             ata_prtdev(atadev, "trying fallback to PIO mode\n");
617             request->retries = 0;
618         }
619     }
620
621     /* if retries still permit, reinject this request */
622     if (request->retries++ < ATAPI_MAX_RETRIES) {
623         int s = splbio();
624
625         TAILQ_INSERT_HEAD(&atadev->channel->atapi_queue, request, chain);
626         splx(s);
627     }
628     else {
629         /* retries all used up, return error */
630         request->error = EIO;
631         wakeup((caddr_t)request);
632     } 
633     ata_reinit(atadev->channel);
634 }
635
636 static char *
637 atapi_cmd2str(u_int8_t cmd)
638 {
639     switch (cmd) {
640     case 0x00: return ("TEST_UNIT_READY");
641     case 0x01: return ("REZERO");
642     case 0x03: return ("REQUEST_SENSE");
643     case 0x04: return ("FORMAT_UNIT");
644     case 0x08: return ("READ");
645     case 0x0a: return ("WRITE");
646     case 0x10: return ("WEOF");
647     case 0x11: return ("SPACE");
648     case 0x15: return ("MODE_SELECT");
649     case 0x19: return ("ERASE");
650     case 0x1a: return ("MODE_SENSE");
651     case 0x1b: return ("START_STOP");
652     case 0x1e: return ("PREVENT_ALLOW");
653     case 0x23: return ("ATAPI_READ_FORMAT_CAPACITIES");
654     case 0x25: return ("READ_CAPACITY");
655     case 0x28: return ("READ_BIG");
656     case 0x2a: return ("WRITE_BIG");
657     case 0x2b: return ("LOCATE");
658     case 0x34: return ("READ_POSITION");
659     case 0x35: return ("SYNCHRONIZE_CACHE");
660     case 0x3b: return ("WRITE_BUFFER");
661     case 0x3c: return ("READ_BUFFER");
662     case 0x42: return ("READ_SUBCHANNEL");
663     case 0x43: return ("READ_TOC");
664     case 0x45: return ("PLAY_10");
665     case 0x47: return ("PLAY_MSF");
666     case 0x48: return ("PLAY_TRACK");
667     case 0x4b: return ("PAUSE");
668     case 0x51: return ("READ_DISK_INFO");
669     case 0x52: return ("READ_TRACK_INFO");
670     case 0x53: return ("RESERVE_TRACK");
671     case 0x54: return ("SEND_OPC_INFO");
672     case 0x55: return ("MODE_SELECT_BIG");
673     case 0x58: return ("REPAIR_TRACK");
674     case 0x59: return ("READ_MASTER_CUE");
675     case 0x5a: return ("MODE_SENSE_BIG");
676     case 0x5b: return ("CLOSE_TRACK/SESSION");
677     case 0x5c: return ("READ_BUFFER_CAPACITY");
678     case 0x5d: return ("SEND_CUE_SHEET");
679     case 0xa1: return ("BLANK_CMD");
680     case 0xa3: return ("SEND_KEY");
681     case 0xa4: return ("REPORT_KEY");
682     case 0xa5: return ("PLAY_12");
683     case 0xa6: return ("LOAD_UNLOAD");
684     case 0xad: return ("READ_DVD_STRUCTURE");
685     case 0xb4: return ("PLAY_CD");
686     case 0xbb: return ("SET_SPEED");
687     case 0xbd: return ("MECH_STATUS");
688     case 0xbe: return ("READ_CD");
689     case 0xff: return ("POLL_DSC");
690     default: {
691         static char buffer[20];
692         sprintf(buffer, "unknown CMD (0x%02x)", cmd);
693         return buffer;
694         }
695     }
696 }
697
698 static char *
699 atapi_skey2str(u_int8_t skey)
700 {
701     switch (skey) {
702     case 0x00: return ("NO SENSE");
703     case 0x01: return ("RECOVERED ERROR");
704     case 0x02: return ("NOT READY");
705     case 0x03: return ("MEDIUM ERROR");
706     case 0x04: return ("HARDWARE ERROR");
707     case 0x05: return ("ILLEGAL REQUEST");
708     case 0x06: return ("UNIT ATTENTION");
709     case 0x07: return ("DATA PROTECT");
710     case 0x08: return ("BLANK CHECK");
711     case 0x09: return ("VENDOR SPECIFIC");
712     case 0x0a: return ("COPY ABORTED");
713     case 0x0b: return ("ABORTED COMMAND");
714     case 0x0c: return ("EQUAL");
715     case 0x0d: return ("VOLUME OVERFLOW");
716     case 0x0e: return ("MISCOMPARE");
717     case 0x0f: return ("RESERVED");
718     default: return("UNKNOWN");
719     }
720 }