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

Cache object: ca42360b1e8e7dd9fbcc8826d21f0e6c


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