File:  [DragonFly] / src / sys / dev / disk / ata / atapi-all.c
Revision 1.7: download - view: text, annotated - select for diffs
Wed Feb 18 00:50:00 2004 UTC (10 years, 7 months ago) by dillon
Branches: MAIN
CVS tags: HEAD
ATAng stage 2: sync part of the ata_dma*() API.  No operational changes.

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