The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/ata/ata-lowlevel.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * Copyright (c) 1998 - 2004 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 
   29 #include <sys/cdefs.h>
   30 __FBSDID("$FreeBSD$");
   31 
   32 #include "opt_ata.h"
   33 #include <sys/param.h>
   34 #include <sys/systm.h>
   35 #include <sys/ata.h>
   36 #include <sys/kernel.h>
   37 #include <sys/conf.h>
   38 #include <sys/bus.h>
   39 #include <sys/sema.h>
   40 #include <sys/taskqueue.h>
   41 #include <vm/uma.h>
   42 #include <machine/bus.h>
   43 #include <sys/rman.h>
   44 #include <dev/ata/ata-all.h>
   45 
   46 /* prototypes */
   47 static int ata_begin_transaction(struct ata_request *);
   48 static int ata_end_transaction(struct ata_request *);
   49 static void ata_generic_reset(struct ata_channel *);
   50 static int ata_wait(struct ata_device *, u_int8_t);
   51 static void ata_pio_read(struct ata_request *, int);
   52 static void ata_pio_write(struct ata_request *, int);
   53 
   54 /* local vars */
   55 static int atadebug = 0;
   56 
   57 /*
   58  * low level ATA functions 
   59  */
   60 void
   61 ata_generic_hw(struct ata_channel *ch)
   62 {
   63     ch->hw.begin_transaction = ata_begin_transaction;
   64     ch->hw.end_transaction = ata_end_transaction;
   65     ch->hw.reset = ata_generic_reset;
   66     ch->hw.command = ata_generic_command;
   67 }
   68 
   69 /* must be called with ATA channel locked */
   70 static int
   71 ata_begin_transaction(struct ata_request *request)
   72 {
   73     struct ata_channel *ch = request->device->channel;
   74 
   75     /* safetybelt for HW that went away */
   76     if (!request->device->param || request->device->channel->flags&ATA_HWGONE) {
   77         request->retries = 0;
   78         request->result = ENXIO;
   79         return ATA_OP_FINISHED;
   80     }
   81 
   82     ATA_DEBUG_RQ(request, "begin transaction");
   83 
   84     /* disable ATAPI DMA writes if HW doesn't support it */
   85     if ((ch->flags & ATA_ATAPI_DMA_RO) &&
   86         ((request->flags & (ATA_R_ATAPI | ATA_R_DMA | ATA_R_WRITE)) ==
   87          (ATA_R_ATAPI | ATA_R_DMA | ATA_R_WRITE)))
   88         request->flags &= ~ATA_R_DMA;
   89 
   90     switch (request->flags & (ATA_R_ATAPI | ATA_R_DMA)) {
   91 
   92     /* ATA PIO data transfer and control commands */
   93     default:
   94         {
   95         /* record command direction here as our request might be gone later */
   96         int write = (request->flags & ATA_R_WRITE);
   97 
   98             /* issue command */
   99             if (ch->hw.command(request->device, request->u.ata.command,
  100                                request->u.ata.lba, request->u.ata.count,
  101                                request->u.ata.feature)) {
  102                 ata_prtdev(request->device, "error issuing %s command\n",
  103                            ata_cmd2str(request));
  104                 request->result = EIO;
  105                 break;
  106             }
  107 
  108             /* device reset doesn't interrupt */
  109             if (request->u.ata.command == ATA_ATAPI_RESET) {
  110                 int timeout = 1000000;
  111                 do {
  112                     DELAY(10);
  113                     request->status = ATA_IDX_INB(ch, ATA_STATUS);
  114                 } while (request->status & ATA_S_BUSY && timeout--);
  115                 if (request->status & ATA_S_ERROR)
  116                     request->error = ATA_IDX_INB(ch, ATA_ERROR);
  117                 break;
  118             }
  119 
  120             /* if write command output the data */
  121             if (write) {
  122                 if (ata_wait(request->device,
  123                              (ATA_S_READY | ATA_S_DSC | ATA_S_DRQ)) < 0) {
  124                     ata_prtdev(request->device,"timeout waiting for write DRQ");
  125                     request->result = EIO;
  126                     break;
  127                 }
  128                 ata_pio_write(request, request->transfersize);
  129             }
  130         }
  131         return ATA_OP_CONTINUES;
  132 
  133     /* ATA DMA data transfer commands */
  134     case ATA_R_DMA:
  135         /* check sanity, setup SG list and DMA engine */
  136         if (ch->dma->load(request->device, request->data, request->bytecount,
  137                           request->flags & ATA_R_READ)) {
  138             ata_prtdev(request->device, "setting up DMA failed\n");
  139             request->result = EIO;
  140             break;
  141         }
  142 
  143         /* issue command */
  144         if (ch->hw.command(request->device, request->u.ata.command,
  145                            request->u.ata.lba, request->u.ata.count,
  146                            request->u.ata.feature)) {
  147             ata_prtdev(request->device, "error issuing %s command\n",
  148                        ata_cmd2str(request));
  149             request->result = EIO;
  150             break;
  151         }
  152 
  153         /* start DMA engine */
  154         if (ch->dma->start(ch)) {
  155             ata_prtdev(request->device, "error starting DMA\n");
  156             request->result = EIO;
  157             break;
  158         }
  159         return ATA_OP_CONTINUES;
  160 
  161     /* ATAPI PIO commands */
  162     case ATA_R_ATAPI:
  163         /* is this just a POLL DSC command ? */
  164         if (request->u.atapi.ccb[0] == ATAPI_POLL_DSC) {
  165             ATA_IDX_OUTB(ch, ATA_DRIVE,
  166                          ATA_D_IBM | request->device->unit);
  167             DELAY(10);
  168             if (!(ATA_IDX_INB(ch, ATA_ALTSTAT)&ATA_S_DSC))
  169                 request->result = EBUSY;
  170             break;
  171         }
  172 
  173         /* start ATAPI operation */
  174         if (ch->hw.command(request->device, ATA_PACKET_CMD,
  175                            request->transfersize << 8, 0, 0)) {
  176             ata_prtdev(request->device, "error issuing ATA PACKET command\n");
  177             request->result = EIO;
  178             break;
  179         }
  180 
  181         /* command interrupt device ? just return and wait for interrupt */
  182         if ((request->device->param->config & ATA_DRQ_MASK) == ATA_DRQ_INTR)
  183             return ATA_OP_CONTINUES;
  184 
  185         /* wait for ready to write ATAPI command block */
  186         {
  187             int timeout = 5000; /* might be less for fast devices */
  188             while (timeout--) {
  189                 int reason = ATA_IDX_INB(ch, ATA_IREASON);
  190                 int status = ATA_IDX_INB(ch, ATA_STATUS);
  191 
  192                 if (((reason & (ATA_I_CMD | ATA_I_IN)) |
  193                      (status & (ATA_S_DRQ | ATA_S_BUSY))) == ATAPI_P_CMDOUT)
  194                     break;
  195                 DELAY(20);
  196             }
  197             if (timeout <= 0) {
  198                 ata_prtdev(request->device,
  199                            "timeout waiting for ATAPI ready\n");
  200                 request->result = EIO;
  201                 break;
  202             }
  203         }
  204 
  205         /* this seems to be needed for some (slow) devices */
  206         DELAY(10);
  207 
  208         /* output actual command block */
  209         ATA_IDX_OUTSW_STRM(ch, ATA_DATA, 
  210                            (int16_t *)request->u.atapi.ccb,
  211                            (request->device->param->config & ATA_PROTO_MASK) ==
  212                            ATA_PROTO_ATAPI_12 ? 6 : 8);
  213         return ATA_OP_CONTINUES;
  214 
  215     case ATA_R_ATAPI|ATA_R_DMA:
  216         /* is this just a POLL DSC command ? */
  217         if (request->u.atapi.ccb[0] == ATAPI_POLL_DSC) {
  218             ATA_IDX_OUTB(ch, ATA_DRIVE,
  219                          ATA_D_IBM | request->device->unit);
  220             DELAY(10);
  221             if (!(ATA_IDX_INB(ch, ATA_ALTSTAT)&ATA_S_DSC))
  222                 request->result = EBUSY;
  223             break;
  224         }
  225 
  226         /* check sanity, setup SG list and DMA engine */
  227         if (ch->dma->load(request->device,
  228                                                 request->data,
  229                                                 request->bytecount,
  230                                                 request->flags & ATA_R_READ)) {
  231             ata_prtdev(request->device, "setting up DMA failed\n");
  232             request->result = EIO;
  233             break;
  234         }
  235 
  236         /* start ATAPI operation */
  237         if (ch->hw.command(request->device, ATA_PACKET_CMD, 0, 0, ATA_F_DMA)) {
  238             ata_prtdev(request->device, "error issuing ATAPI packet command\n");
  239             request->result = EIO;
  240             break;
  241         }
  242 
  243         /* wait for ready to write ATAPI command block */
  244         {
  245             int timeout = 5000; /* might be less for fast devices */
  246             while (timeout--) {
  247                 int reason = ATA_IDX_INB(ch, ATA_IREASON);
  248                 int status = ATA_IDX_INB(ch, ATA_STATUS);
  249 
  250                 if (((reason & (ATA_I_CMD | ATA_I_IN)) |
  251                      (status & (ATA_S_DRQ | ATA_S_BUSY))) == ATAPI_P_CMDOUT)
  252                     break;
  253                 DELAY(20);
  254             }
  255             if (timeout <= 0) {
  256                 ata_prtdev(request->device,"timeout waiting for ATAPI ready\n");
  257                 request->result = EIO;
  258                 break;
  259             }
  260         }
  261 
  262         /* this seems to be needed for some (slow) devices */
  263         DELAY(10);
  264 
  265         /* output actual command block */
  266         ATA_IDX_OUTSW_STRM(ch, ATA_DATA, 
  267                            (int16_t *)request->u.atapi.ccb,
  268                            (request->device->param->config & ATA_PROTO_MASK) ==
  269                            ATA_PROTO_ATAPI_12 ? 6 : 8);
  270 
  271         /* start DMA engine */
  272         if (ch->dma->start(ch)) {
  273             request->result = EIO;
  274             break;
  275         }
  276         return ATA_OP_CONTINUES;
  277     }
  278 
  279     /* request finish here */
  280     if (ch->dma && ch->dma->flags & ATA_DMA_LOADED)
  281         ch->dma->unload(ch);
  282     return ATA_OP_FINISHED;
  283 }
  284 
  285 static int
  286 ata_end_transaction(struct ata_request *request)
  287 {
  288     struct ata_channel *ch = request->device->channel;
  289     int length;
  290 
  291     ATA_DEBUG_RQ(request, "end transaction");
  292 
  293     /* clear interrupt and get status */
  294     request->status = ATA_IDX_INB(ch, ATA_STATUS);
  295 
  296     switch (request->flags & (ATA_R_ATAPI | ATA_R_DMA | ATA_R_CONTROL)) {
  297 
  298     /* ATA PIO data transfer and control commands */
  299     default:
  300         /* XXX Doesn't handle the non-PIO case. */
  301         if (request->flags & ATA_R_TIMEOUT)
  302             return ATA_OP_FINISHED;
  303 
  304         /* on control commands read back registers to the request struct */
  305         if (request->flags & ATA_R_CONTROL) {
  306             request->u.ata.count = ATA_IDX_INB(ch, ATA_COUNT);
  307             request->u.ata.lba = ATA_IDX_INB(ch, ATA_SECTOR) |
  308                                  (ATA_IDX_INB(ch, ATA_CYL_LSB) << 8) |
  309                                  (ATA_IDX_INB(ch, ATA_CYL_MSB) << 16) |
  310                                  ((ATA_IDX_INB(ch, ATA_DRIVE) & 0x0f) << 24);
  311         }
  312 
  313         /* if we got an error we are done with the HW */
  314         if (request->status & ATA_S_ERROR) {
  315             request->error = ATA_IDX_INB(ch, ATA_ERROR);
  316             return ATA_OP_FINISHED;
  317         }
  318         
  319         /* are we moving data ? */
  320         if (request->flags & (ATA_R_READ | ATA_R_WRITE)) {
  321 
  322             /* if read data get it */
  323             if (request->flags & ATA_R_READ)
  324                 ata_pio_read(request, request->transfersize);
  325 
  326             /* update how far we've gotten */
  327             request->donecount += request->transfersize;
  328 
  329             /* do we need a scoop more ? */
  330             if (request->bytecount > request->donecount) {
  331 
  332                 /* set this transfer size according to HW capabilities */
  333                 request->transfersize = 
  334                     min((request->bytecount - request->donecount),
  335                         request->transfersize);
  336 
  337                 /* clear interrupt seen flag as we need to wait again */
  338                 request->flags &= ~ATA_R_INTR_SEEN;
  339 
  340                 /* if data write command, output the data */
  341                 if (request->flags & ATA_R_WRITE) {
  342 
  343                     /* if we get an error here we are done with the HW */
  344                     if (ata_wait(request->device,
  345                                  (ATA_S_READY | ATA_S_DSC | ATA_S_DRQ)) < 0) {
  346                         ata_prtdev(request->device,
  347                                    "timeout waiting for write DRQ");
  348                         request->status = ATA_IDX_INB(ch, ATA_STATUS);
  349                         return ATA_OP_FINISHED;
  350                     }
  351 
  352                     /* output data and return waiting for new interrupt */
  353                     ata_pio_write(request, request->transfersize);
  354                     return ATA_OP_CONTINUES;
  355                 }
  356 
  357                 /* if data read command, return & wait for interrupt */
  358                 if (request->flags & ATA_R_READ)
  359                     return ATA_OP_CONTINUES;
  360             }
  361         }
  362         /* done with HW */
  363         return ATA_OP_FINISHED;
  364 
  365     /* ATA DMA data transfer commands */
  366     case ATA_R_DMA:
  367 
  368         /* stop DMA engine and get status */
  369         if (ch->dma->stop)
  370             request->dmastat = ch->dma->stop(ch);
  371 
  372         /* did we get error or data */
  373         if (request->status & ATA_S_ERROR)
  374             request->error = ATA_IDX_INB(ch, ATA_ERROR);
  375         else if (request->dmastat & ATA_BMSTAT_ERROR)
  376             request->status |= ATA_S_ERROR;
  377         else
  378             request->donecount = request->bytecount;
  379 
  380         /* release SG list etc */
  381         ch->dma->unload(ch);
  382 
  383         /* done with HW */
  384         return ATA_OP_FINISHED;
  385 
  386     /* ATAPI PIO commands */
  387     case ATA_R_ATAPI:
  388         length = ATA_IDX_INB(ch, ATA_CYL_LSB)|(ATA_IDX_INB(ch, ATA_CYL_MSB)<<8);
  389 
  390         switch ((ATA_IDX_INB(ch, ATA_IREASON) & (ATA_I_CMD | ATA_I_IN)) |
  391                 (request->status & ATA_S_DRQ)) {
  392 
  393         case ATAPI_P_CMDOUT:
  394             /* this seems to be needed for some (slow) devices */
  395             DELAY(10);
  396 
  397             if (!(request->status & ATA_S_DRQ)) {
  398                 ata_prtdev(request->device, "command interrupt without DRQ\n");
  399                 request->status = ATA_S_ERROR;
  400                 return ATA_OP_FINISHED;
  401             }
  402             ATA_IDX_OUTSW_STRM(ch, ATA_DATA, (int16_t *)request->u.atapi.ccb,
  403                                (request->device->param->config &
  404                                 ATA_PROTO_MASK)== ATA_PROTO_ATAPI_12 ? 6 : 8);
  405             /* return wait for interrupt */
  406             return ATA_OP_CONTINUES;
  407 
  408         case ATAPI_P_WRITE:
  409             if (request->flags & ATA_R_READ) {
  410                 request->status = ATA_S_ERROR;
  411                 ata_prtdev(request->device,
  412                            "%s trying to write on read buffer\n",
  413                            ata_cmd2str(request));
  414                 return ATA_OP_FINISHED;
  415             }
  416             ata_pio_write(request, length);
  417             request->donecount += length;
  418 
  419             /* set next transfer size according to HW capabilities */
  420             request->transfersize = min((request->bytecount-request->donecount),
  421                                         request->transfersize);
  422             /* return wait for interrupt */
  423             return ATA_OP_CONTINUES;
  424 
  425         case ATAPI_P_READ:
  426             if (request->flags & ATA_R_WRITE) {
  427                 request->status = ATA_S_ERROR;
  428                 ata_prtdev(request->device,
  429                            "%s trying to read on write buffer\n",
  430                            ata_cmd2str(request));
  431                 return ATA_OP_FINISHED;
  432             }
  433             ata_pio_read(request, length);
  434             request->donecount += length;
  435 
  436             /* set next transfer size according to HW capabilities */
  437             request->transfersize = min((request->bytecount-request->donecount),
  438                                         request->transfersize);
  439             /* return wait for interrupt */
  440             return ATA_OP_CONTINUES;
  441 
  442         case ATAPI_P_DONEDRQ:
  443             ata_prtdev(request->device,
  444                        "WARNING - %s DONEDRQ non conformant device\n",
  445                        ata_cmd2str(request));
  446             if (request->flags & ATA_R_READ) {
  447                 ata_pio_read(request, length);
  448                 request->donecount += length;
  449             }
  450             else if (request->flags & ATA_R_WRITE) {
  451                 ata_pio_write(request, length);
  452                 request->donecount += length;
  453             }
  454             else
  455                 request->status = ATA_S_ERROR;
  456             /* FALLTHROUGH */
  457 
  458         case ATAPI_P_ABORT:
  459         case ATAPI_P_DONE:
  460             if (request->status & (ATA_S_ERROR | ATA_S_DWF))
  461                 request->error = ATA_IDX_INB(ch, ATA_ERROR);
  462             return ATA_OP_FINISHED;
  463 
  464         default:
  465             ata_prtdev(request->device, "unknown transfer phase\n");
  466             request->status = ATA_S_ERROR;
  467         }
  468 
  469         /* done with HW */
  470         return ATA_OP_FINISHED;
  471 
  472     /* ATAPI DMA commands */
  473     case ATA_R_ATAPI|ATA_R_DMA:
  474 
  475         /* stop the engine and get engine status */
  476         if (ch->dma->stop)
  477             request->dmastat = ch->dma->stop(ch);
  478 
  479         /* did we get error or data */
  480         if (request->status & (ATA_S_ERROR | ATA_S_DWF))
  481             request->error = ATA_IDX_INB(ch, ATA_ERROR);
  482         else if (request->dmastat & ATA_BMSTAT_ERROR)
  483             request->status |= ATA_S_ERROR;
  484         else
  485             request->donecount = request->bytecount;
  486  
  487         /* release SG list etc */
  488         ch->dma->unload(ch);
  489 
  490         /* done with HW */
  491         return ATA_OP_FINISHED;
  492     }
  493 }
  494 
  495 /* must be called with ATA channel locked */
  496 static void
  497 ata_generic_reset(struct ata_channel *ch)
  498 {
  499     u_int8_t err = 0, lsb = 0, msb = 0, ostat0, ostat1;
  500     u_int8_t stat0 = 0, stat1 = 0;
  501     int mask = 0, timeout;
  502 
  503     /* if DMA functionality present stop it  */
  504     if (ch->dma) {
  505         if (ch->dma->stop)
  506             ch->dma->stop(ch);
  507         if (ch->dma->flags & ATA_DMA_LOADED)
  508             ch->dma->unload(ch);
  509     }
  510 
  511     /* reset host end of channel (if supported) */
  512     if (ch->reset)
  513         ch->reset(ch);
  514 
  515     /* do we have any signs of ATA/ATAPI HW being present ? */
  516     ATA_IDX_OUTB(ch, ATA_DRIVE, ATA_D_IBM | ATA_MASTER);
  517     DELAY(10);
  518     ostat0 = ATA_IDX_INB(ch, ATA_STATUS);
  519     if ((ostat0 & 0xf8) != 0xf8 && ostat0 != 0xa5) {
  520         stat0 = ATA_S_BUSY;
  521         mask |= 0x01;
  522     }
  523 
  524     ATA_IDX_OUTB(ch, ATA_DRIVE, ATA_D_IBM | ATA_SLAVE);
  525     DELAY(10);  
  526     ostat1 = ATA_IDX_INB(ch, ATA_STATUS);
  527 
  528     /* in some setups we dont want to test for a slave */
  529     if (!(ch->flags & ATA_NO_SLAVE)) {
  530         if ((ostat1 & 0xf8) != 0xf8 && ostat1 != 0xa5) {
  531             stat1 = ATA_S_BUSY;
  532             mask |= 0x02;
  533         }
  534     }
  535 
  536     if (bootverbose)
  537         ata_printf(ch, -1, "reset tp1 mask=%02x ostat0=%02x ostat1=%02x\n",
  538                    mask, ostat0, ostat1);
  539 
  540     /* if nothing showed up there is no need to get any further */
  541     /* SOS is that too strong?, we just might loose devices here XXX */
  542     ch->devices = 0;
  543     if (!mask)
  544         return;
  545 
  546     /* reset (both) devices on this channel */
  547     ATA_IDX_OUTB(ch, ATA_DRIVE, ATA_D_IBM | ATA_MASTER);
  548     DELAY(10);
  549     ATA_IDX_OUTB(ch, ATA_ALTSTAT, ATA_A_IDS | ATA_A_RESET);
  550     ata_udelay(10000); 
  551     ATA_IDX_OUTB(ch, ATA_ALTSTAT, ATA_A_IDS);
  552     ata_udelay(100000);
  553     ATA_IDX_INB(ch, ATA_ERROR);
  554 
  555     /* wait for BUSY to go inactive */
  556     for (timeout = 0; timeout < 310; timeout++) {
  557         if (stat0 & ATA_S_BUSY) {
  558             ATA_IDX_OUTB(ch, ATA_DRIVE, ATA_D_IBM | ATA_MASTER);
  559             DELAY(10);
  560             err = ATA_IDX_INB(ch, ATA_ERROR);
  561             lsb = ATA_IDX_INB(ch, ATA_CYL_LSB);
  562             msb = ATA_IDX_INB(ch, ATA_CYL_MSB);
  563             stat0 = ATA_IDX_INB(ch, ATA_STATUS);
  564             if (bootverbose)
  565                 ata_printf(ch, ATA_MASTER,
  566                            "stat=0x%02x err=0x%02x lsb=0x%02x msb=0x%02x\n",
  567                            stat0, err, lsb, msb);
  568             if (!(stat0 & ATA_S_BUSY)) {
  569                 if ((err & 0x7f) == ATA_E_ILI) {
  570                     if (lsb == ATAPI_MAGIC_LSB && msb == ATAPI_MAGIC_MSB) {
  571                         ch->devices |= ATA_ATAPI_MASTER;
  572                     }
  573                     else if (stat0 & ATA_S_READY) {
  574                         ch->devices |= ATA_ATA_MASTER;
  575                     }
  576                 }
  577                 else if ((stat0 & 0x4f) && err == lsb && err == msb) {
  578                     stat0 |= ATA_S_BUSY;
  579                 }
  580             }
  581         }
  582         if (!((mask == 0x03) && (stat0 & ATA_S_BUSY)) && (stat1 & ATA_S_BUSY)) {
  583             ATA_IDX_OUTB(ch, ATA_DRIVE, ATA_D_IBM | ATA_SLAVE);
  584             DELAY(10);
  585             err = ATA_IDX_INB(ch, ATA_ERROR);
  586             lsb = ATA_IDX_INB(ch, ATA_CYL_LSB);
  587             msb = ATA_IDX_INB(ch, ATA_CYL_MSB);
  588             stat1 = ATA_IDX_INB(ch, ATA_STATUS);
  589             if (bootverbose)
  590                 ata_printf(ch, ATA_SLAVE,
  591                            " stat=0x%02x err=0x%02x lsb=0x%02x msb=0x%02x\n",
  592                            stat1, err, lsb, msb);
  593             if (!(stat1 & ATA_S_BUSY)) {
  594                 if ((err & 0x7f) == ATA_E_ILI) {
  595                     if (lsb == ATAPI_MAGIC_LSB && msb == ATAPI_MAGIC_MSB) {
  596                         ch->devices |= ATA_ATAPI_SLAVE;
  597                     }
  598                     else if (stat1 & ATA_S_READY) {
  599                         ch->devices |= ATA_ATA_SLAVE;
  600                     }
  601                 }
  602                 else if ((stat1 & 0x4f) && err == lsb && err == msb) {
  603                     stat1 |= ATA_S_BUSY;
  604                 }
  605             }
  606         }
  607         if (mask == 0x01)       /* wait for master only */
  608             if (!(stat0 & ATA_S_BUSY) || (stat0 == 0xff && timeout > 5) ||
  609                 (stat0 == err && lsb == err && msb == err && timeout > 5))
  610                 break;
  611         if (mask == 0x02)       /* wait for slave only */
  612             if (!(stat1 & ATA_S_BUSY) || (stat1 == 0xff && timeout > 5) ||
  613                 (stat1 == err && lsb == err && msb == err && timeout > 5))
  614                 break;
  615         if (mask == 0x03) {     /* wait for both master & slave */
  616             if (!(stat0 & ATA_S_BUSY) && !(stat1 & ATA_S_BUSY))
  617                 break;
  618             if ((stat0 == 0xff && timeout > 5) ||
  619                 (stat0 == err && lsb == err && msb == err && timeout > 5))
  620                 mask &= ~0x01;
  621             if ((stat1 == 0xff && timeout > 5) ||
  622                 (stat1 == err && lsb == err && msb == err && timeout > 5))
  623                 mask &= ~0x02;
  624         }
  625         if (mask == 0 && !(stat0 & ATA_S_BUSY) && !(stat1 & ATA_S_BUSY))
  626             break;
  627 
  628         ata_udelay(100000);
  629     }
  630 
  631     if (bootverbose)
  632         ata_printf(ch, -1,
  633                    "reset tp2 stat0=%02x stat1=%02x devices=0x%b\n",
  634                    stat0, stat1, ch->devices,
  635                    "\2\4ATAPI_SLAVE\3ATAPI_MASTER\2ATA_SLAVE\1ATA_MASTER");
  636 }
  637 
  638 static int
  639 ata_wait(struct ata_device *atadev, u_int8_t mask)
  640 {
  641     u_int8_t status;
  642     int timeout = 0;
  643     
  644     DELAY(1);
  645 
  646     /* wait 5 seconds for device to get !BUSY */
  647     while (timeout < 5000000) {
  648         status = ATA_IDX_INB(atadev->channel, ATA_STATUS);
  649 
  650         /* if drive fails status, reselect the drive just to be sure */
  651         if (status == 0xff) {
  652             ata_prtdev(atadev, "WARNING no status, reselecting device\n");
  653             ATA_IDX_OUTB(atadev->channel, ATA_DRIVE, ATA_D_IBM | atadev->unit);
  654             DELAY(10);
  655             status = ATA_IDX_INB(atadev->channel, ATA_STATUS);
  656             if (status == 0xff)
  657                 return -1;
  658         }
  659 
  660         /* are we done ? */
  661         if (!(status & ATA_S_BUSY))
  662             break;            
  663 
  664         if (timeout > 1000) {
  665             timeout += 1000;
  666             DELAY(1000);
  667         }
  668         else {
  669             timeout += 10;
  670             DELAY(10);
  671         }
  672     }    
  673     if (timeout >= 5000000)      
  674         return -1;          
  675     if (!mask)     
  676         return (status & ATA_S_ERROR);   
  677 
  678     DELAY(1);
  679     
  680     /* wait 50 msec for bits wanted */     
  681     timeout = 5000;
  682     while (timeout--) {   
  683         status = ATA_IDX_INB(atadev->channel, ATA_STATUS);
  684         if ((status & mask) == mask) 
  685             return (status & ATA_S_ERROR);            
  686         DELAY (10);        
  687     }     
  688     return -1;      
  689 }   
  690 
  691 int
  692 ata_generic_command(struct ata_device *atadev, u_int8_t command,
  693                     u_int64_t lba, u_int16_t count, u_int16_t feature)
  694 {
  695     if (atadebug)
  696         ata_prtdev(atadev, "ata_command: addr=%04lx, command=%02x, "
  697                    "lba=%jd, count=%d, feature=%d\n",
  698                    rman_get_start(atadev->channel->r_io[ATA_DATA].res), 
  699                    command, (intmax_t)lba, count, feature);
  700 
  701     /* select device */
  702     ATA_IDX_OUTB(atadev->channel, ATA_DRIVE, ATA_D_IBM | atadev->unit);
  703 
  704     /* ready to issue command ? */
  705     if (ata_wait(atadev, 0) < 0) { 
  706         ata_prtdev(atadev, "timeout sending command=%02x\n", command);
  707         return -1;
  708     }
  709 
  710     /* enable interrupt */
  711     ATA_IDX_OUTB(atadev->channel, ATA_ALTSTAT, ATA_A_4BIT);
  712 
  713     /* only use 48bit addressing if needed (avoid bugs and overhead) */
  714     if ((lba >= ATA_MAX_28BIT_LBA || count > 256) && atadev->param && 
  715         atadev->param->support.command2 & ATA_SUPPORT_ADDRESS48) {
  716 
  717         /* translate command into 48bit version */
  718         switch (command) {
  719         case ATA_READ:
  720             command = ATA_READ48; break;
  721         case ATA_READ_MUL:
  722             command = ATA_READ_MUL48; break;
  723         case ATA_READ_DMA:
  724             command = ATA_READ_DMA48; break;
  725         case ATA_READ_DMA_QUEUED:
  726             command = ATA_READ_DMA_QUEUED48; break;
  727         case ATA_WRITE:
  728             command = ATA_WRITE48; break;
  729         case ATA_WRITE_MUL:
  730             command = ATA_WRITE_MUL48; break;
  731         case ATA_WRITE_DMA:
  732             command = ATA_WRITE_DMA48; break;
  733         case ATA_WRITE_DMA_QUEUED:
  734             command = ATA_WRITE_DMA_QUEUED48; break;
  735         case ATA_FLUSHCACHE:
  736             command = ATA_FLUSHCACHE48; break;
  737         default:
  738             ata_prtdev(atadev, "can't translate cmd to 48bit version\n");
  739             return -1;
  740         }
  741         ATA_IDX_OUTB(atadev->channel, ATA_FEATURE, (feature>>8) & 0xff);
  742         ATA_IDX_OUTB(atadev->channel, ATA_FEATURE, feature & 0xff);
  743         ATA_IDX_OUTB(atadev->channel, ATA_COUNT, (count>>8) & 0xff);
  744         ATA_IDX_OUTB(atadev->channel, ATA_COUNT, count & 0xff);
  745         ATA_IDX_OUTB(atadev->channel, ATA_SECTOR, (lba>>24) & 0xff);
  746         ATA_IDX_OUTB(atadev->channel, ATA_SECTOR, lba & 0xff);
  747         ATA_IDX_OUTB(atadev->channel, ATA_CYL_LSB, (lba>>32) & 0xff);
  748         ATA_IDX_OUTB(atadev->channel, ATA_CYL_LSB, (lba>>8) & 0xff);
  749         ATA_IDX_OUTB(atadev->channel, ATA_CYL_MSB, (lba>>40) & 0xff);
  750         ATA_IDX_OUTB(atadev->channel, ATA_CYL_MSB, (lba>>16) & 0xff);
  751         ATA_IDX_OUTB(atadev->channel, ATA_DRIVE, ATA_D_LBA | atadev->unit);
  752         atadev->channel->flags |= ATA_48BIT_ACTIVE;
  753     }
  754     else {
  755         ATA_IDX_OUTB(atadev->channel, ATA_FEATURE, feature);
  756         ATA_IDX_OUTB(atadev->channel, ATA_COUNT, count);
  757         ATA_IDX_OUTB(atadev->channel, ATA_SECTOR, lba & 0xff);
  758         ATA_IDX_OUTB(atadev->channel, ATA_CYL_LSB, (lba>>8) & 0xff);
  759         ATA_IDX_OUTB(atadev->channel, ATA_CYL_MSB, (lba>>16) & 0xff);
  760         if (atadev->flags & ATA_D_USE_CHS)
  761             ATA_IDX_OUTB(atadev->channel, ATA_DRIVE,
  762                          ATA_D_IBM | atadev->unit | ((lba>>24) & 0xf));
  763         else
  764             ATA_IDX_OUTB(atadev->channel, ATA_DRIVE,
  765                          ATA_D_IBM | ATA_D_LBA | atadev->unit|((lba>>24)&0xf));
  766         atadev->channel->flags &= ~ATA_48BIT_ACTIVE;
  767     }
  768 
  769     /* issue command to controller */
  770     ATA_IDX_OUTB(atadev->channel, ATA_CMD, command);
  771 
  772     return 0;
  773 }
  774 
  775 static void
  776 ata_pio_read(struct ata_request *request, int length)
  777 {
  778     int size = min(request->transfersize, length);
  779     struct ata_channel *ch = request->device->channel;
  780     int resid;
  781 
  782     if (ch->flags & ATA_USE_16BIT || (size % sizeof(int32_t)))
  783         ATA_IDX_INSW_STRM(ch, ATA_DATA,
  784                           (void*)((uintptr_t)request->data+request->donecount),
  785                           size / sizeof(int16_t));
  786     else
  787         ATA_IDX_INSL_STRM(ch, ATA_DATA,
  788                           (void*)((uintptr_t)request->data+request->donecount),
  789                           size / sizeof(int32_t));
  790 
  791     if (request->transfersize < length) {
  792         ata_prtdev(request->device, "WARNING - %s read data overrun %d>%d\n",
  793                    ata_cmd2str(request), length, request->transfersize);
  794         for (resid = request->transfersize; resid < length;
  795              resid += sizeof(int16_t))
  796             ATA_IDX_INW(ch, ATA_DATA);
  797     }
  798 }
  799 
  800 static void
  801 ata_pio_write(struct ata_request *request, int length)
  802 {
  803     int size = min(request->transfersize, length);
  804     struct ata_channel *ch = request->device->channel;
  805     int resid;
  806 
  807     if (ch->flags & ATA_USE_16BIT || (size % sizeof(int32_t)))
  808         ATA_IDX_OUTSW_STRM(ch, ATA_DATA,
  809                            (void*)((uintptr_t)request->data+request->donecount),
  810                            size / sizeof(int16_t));
  811     else
  812         ATA_IDX_OUTSL_STRM(ch, ATA_DATA,
  813                            (void*)((uintptr_t)request->data+request->donecount),
  814                            size / sizeof(int32_t));
  815 
  816     if (request->transfersize < length) {
  817         ata_prtdev(request->device, "WARNING - %s write data underrun %d>%d\n",
  818                    ata_cmd2str(request), length, request->transfersize);
  819         for (resid = request->transfersize; resid < length;
  820              resid += sizeof(int16_t))
  821             ATA_IDX_OUTW(ch, ATA_DATA, 0);
  822     }
  823 }

Cache object: f804323c6f5a2ae88096d84edbafd8ae


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.