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

Cache object: d630aaf9d29c0197947f9df3c4df9cad


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