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

Cache object: a26296751d67e463516f2c4e1027e7f1


[ 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.