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


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

FreeBSD/Linux Kernel Cross Reference
sys/dev/qbus/rf.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 /*      $NetBSD: rf.c,v 1.5 2004/02/24 15:12:52 wiz Exp $       */
    2 /*
    3  * Copyright (c) 2002 Jochen Kunz.
    4  * All rights reserved.
    5  *
    6  * Redistribution and use in source and binary forms, with or without
    7  * modification, are permitted provided that the following conditions
    8  * are met:
    9  * 1. Redistributions of source code must retain the above copyright
   10  *    notice, this list of conditions and the following disclaimer.
   11  * 2. Redistributions in binary form must reproduce the above copyright
   12  *    notice, this list of conditions and the following disclaimer in the
   13  *    documentation and/or other materials provided with the distribution.
   14  * 3. The name of Jochen Kunz may not be used to endorse or promote
   15  *    products derived from this software without specific prior
   16  *    written permission.
   17  *
   18  * THIS SOFTWARE IS PROVIDED BY JOCHEN KUNZ
   19  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
   20  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   21  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL JOCHEN KUNZ
   22  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   23  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   24  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   25  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   26  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   27  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   28  * POSSIBILITY OF SUCH DAMAGE.
   29  */
   30 
   31 /*
   32 TODO:
   33 - Better LBN bound checking, block padding for SD disks.
   34 - Formating / "Set Density"
   35 - Better error handling / detaild error reason reportnig.
   36 */
   37 
   38 #include <sys/cdefs.h>
   39 __KERNEL_RCSID(0, "$NetBSD: rf.c,v 1.5 2004/02/24 15:12:52 wiz Exp $");
   40 
   41 /* autoconfig stuff */
   42 #include <sys/param.h>
   43 #include <sys/device.h>
   44 #include <sys/conf.h>
   45 #include "locators.h"
   46 #include "ioconf.h"
   47 
   48 /* bus_space / bus_dma */
   49 #include <machine/bus.h>
   50 
   51 /* UniBus / QBus specific stuff */
   52 #include <dev/qbus/ubavar.h>
   53 
   54 /* disk interface */
   55 #include <sys/types.h>
   56 #include <sys/disklabel.h>
   57 #include <sys/disk.h>
   58 
   59 /* general system data and functions */
   60 #include <sys/systm.h>
   61 #include <sys/ioctl.h>
   62 #include <sys/ioccom.h>
   63 
   64 /* physio / buffer handling */
   65 #include <sys/buf.h>
   66 
   67 /* tsleep / sleep / wakeup */
   68 #include <sys/proc.h>
   69 /* hz for above */
   70 #include <sys/kernel.h>
   71 
   72 /* bitdefinitions for RX211 */
   73 #include <dev/qbus/rfreg.h>
   74 
   75 
   76 #define RFS_DENS        0x0001          /* single or double density */
   77 #define RFS_AD          0x0002          /* density auto detect */
   78 #define RFS_NOTINIT     0x0000          /* not initialized */
   79 #define RFS_PROBING     0x0010          /* density detect / verify started */
   80 #define RFS_FBUF        0x0020          /* Fill Buffer */
   81 #define RFS_EBUF        0x0030          /* Empty Buffer */
   82 #define RFS_WSEC        0x0040          /* Write Sector */
   83 #define RFS_RSEC        0x0050          /* Read Sector */
   84 #define RFS_SMD         0x0060          /* Set Media Density */
   85 #define RFS_RSTAT       0x0070          /* Read Status */
   86 #define RFS_WDDS        0x0080          /* Write Deleted Data Sector */
   87 #define RFS_REC         0x0090          /* Read Error Code */
   88 #define RFS_IDLE        0x00a0          /* controller is idle */
   89 #define RFS_CMDS        0x00f0          /* command mask */
   90 #define RFS_OPEN_A      0x0100          /* partition a open */
   91 #define RFS_OPEN_B      0x0200          /* partition b open */
   92 #define RFS_OPEN_C      0x0400          /* partition c open */
   93 #define RFS_OPEN_MASK   0x0f00          /* mask for open partitions */
   94 #define RFS_OPEN_SHIFT  8               /* to shift 1 to get RFS_OPEN_A */
   95 #define RFS_SETCMD(rf, state)   ((rf) = ((rf) & ~RFS_CMDS) | (state))
   96 
   97 
   98 
   99 /* autoconfig stuff */
  100 static int rfc_match(struct device *, struct cfdata *, void *);
  101 static void rfc_attach(struct device *, struct device *, void *);
  102 static int rf_match(struct device *, struct cfdata *, void *);
  103 static void rf_attach(struct device *, struct device *, void *);
  104 static int rf_print(void *, const char *);
  105 
  106 /* device interfce functions / interface to disk(9) */
  107 dev_type_open(rfopen);
  108 dev_type_close(rfclose);
  109 dev_type_read(rfread);
  110 dev_type_write(rfwrite);
  111 dev_type_ioctl(rfioctl);
  112 dev_type_strategy(rfstrategy);
  113 dev_type_dump(rfdump);
  114 dev_type_size(rfsize);
  115 
  116 
  117 /* Entries in block and character major device number switch table. */
  118 const struct bdevsw rf_bdevsw = {
  119         rfopen,
  120         rfclose,
  121         rfstrategy,
  122         rfioctl,
  123         rfdump,
  124         rfsize,
  125         D_DISK
  126 };
  127 
  128 const struct cdevsw rf_cdevsw = {
  129         rfopen,
  130         rfclose,
  131         rfread,
  132         rfwrite,
  133         rfioctl,
  134         nostop,
  135         notty,
  136         nopoll,
  137         nommap,
  138         nokqfilter,
  139         D_DISK
  140 };
  141 
  142 
  143 
  144 struct rfc_softc {
  145         struct device sc_dev;           /* common device data */
  146         struct device *sc_childs[2];    /* child devices */
  147         struct evcnt sc_intr_count;     /* Interrupt counter for statistics */
  148         struct buf *sc_curbuf;          /* buf that is currently in work */
  149         bus_space_tag_t sc_iot;         /* bus_space IO tag */
  150         bus_space_handle_t sc_ioh;      /* bus_space IO handle */
  151         bus_dma_tag_t sc_dmat;          /* bus_dma DMA tag */
  152         bus_dmamap_t sc_dmam;           /* bus_dma DMA map */
  153         caddr_t sc_bufidx;              /* current position in buffer data */
  154         int sc_curchild;                /* child whos bufq is in work */
  155         int sc_bytesleft;               /* bytes left to transfer */
  156         u_int8_t type;                  /* controller type, 1 or 2 */
  157 };
  158 
  159 
  160 
  161 CFATTACH_DECL(
  162         rfc,
  163         sizeof(struct rfc_softc),
  164         rfc_match,
  165         rfc_attach,
  166         NULL,
  167         NULL
  168 );
  169 
  170 
  171 
  172 struct rf_softc {
  173         struct device sc_dev;           /* common device data */
  174         struct disk sc_disk;            /* common disk device data */
  175         struct bufq_state sc_bufq;      /* queue of pending transfers */
  176         int sc_state;                   /* state of drive */
  177         u_int8_t sc_dnum;               /* drive number, 0 or 1 */
  178 };
  179 
  180 
  181 
  182 CFATTACH_DECL(
  183         rf,
  184         sizeof(struct rf_softc),
  185         rf_match,
  186         rf_attach,
  187         NULL,
  188         NULL
  189 );
  190 
  191 
  192 
  193 struct rfc_attach_args {
  194         u_int8_t type;          /* controller type, 1 or 2 */
  195         u_int8_t dnum;          /* drive number, 0 or 1 */
  196 };
  197 
  198 
  199 
  200 struct dkdriver rfdkdriver = {
  201         rfstrategy
  202 };
  203 
  204 
  205 
  206 /* helper functions */
  207 int rfc_sendcmd(struct rfc_softc *, int, int, int);
  208 struct rf_softc* get_new_buf( struct rfc_softc *);
  209 static void rfc_intr(void *);
  210 
  211 
  212 
  213 /*
  214  * Issue a reset command to the controller and look for the bits in
  215  * RX2CS and RX2ES.
  216  * RX2CS_RX02 and / or RX2CS_DD can be set,
  217  * RX2ES has to be set, all other bits must be 0
  218  */
  219 int
  220 rfc_match(struct device *parent, struct cfdata *match, void *aux)
  221 {
  222         struct uba_attach_args *ua = aux;
  223         int i;
  224 
  225         /* Issue reset command. */
  226         bus_space_write_2(ua->ua_iot, ua->ua_ioh, RX2CS, RX2CS_INIT);
  227         /* Wait for the controller to become ready, that is when
  228          * RX2CS_DONE, RX2ES_RDY and RX2ES_ID are set. */
  229         for (i = 0 ; i < 20 ; i++) {
  230                 if ((bus_space_read_2(ua->ua_iot, ua->ua_ioh, RX2CS)
  231                     & RX2CS_DONE) != 0
  232                     && (bus_space_read_2(ua->ua_iot, ua->ua_ioh, RX2ES)
  233                     & (RX2ES_RDY | RX2ES_ID)) != 0)
  234                         break;
  235                 DELAY(100000);  /* wait 100ms */
  236         }
  237         /*
  238          * Give up if the timeout has elapsed
  239          * and the controller is not ready.
  240          */
  241         if (i >= 20)
  242                 return(0);
  243         /*
  244          * Issue a Read Status command with interrupt enabled.
  245          * The uba(4) driver wants to catch the interrupt to get the
  246          * interrupt vector and level of the device
  247          */
  248         bus_space_write_2(ua->ua_iot, ua->ua_ioh, RX2CS,
  249             RX2CS_RSTAT | RX2CS_IE);
  250         /*
  251          * Wait for command to finish, ignore errors and
  252          * abort if the controller does not respond within the timeout
  253          */
  254         for (i = 0 ; i < 20 ; i++) {
  255                 if ((bus_space_read_2(ua->ua_iot, ua->ua_ioh, RX2CS)
  256                     & (RX2CS_DONE | RX2CS_IE)) != 0
  257                     && (bus_space_read_2(ua->ua_iot, ua->ua_ioh, RX2ES)
  258                     & RX2ES_RDY) != 0 )
  259                         return(1);
  260                 DELAY(100000);  /* wait 100ms */
  261         }
  262         return(0);
  263 }
  264 
  265 
  266 
  267 /* #define RX02_PROBE 1 */
  268 #ifdef RX02_PROBE
  269 /*
  270  * Probe the density of an inserted floppy disk.
  271  * This is done by reading a sector from disk.
  272  * Return -1 on error, 0 on SD and 1 on DD.
  273  */
  274 int rfcprobedens(struct rfc_softc *, int);
  275 int
  276 rfcprobedens(struct rfc_softc *rfc_sc, int dnum)
  277 {
  278         int dens_flag;
  279         int i;
  280 
  281         dens_flag = 0;
  282         do {
  283                 bus_space_write_2(rfc_sc->sc_iot, rfc_sc->sc_ioh, RX2CS,
  284                     RX2CS_RSEC | (dens_flag == 0 ? 0 : RX2CS_DD)
  285                     | (dnum == 0 ? 0 : RX2CS_US));
  286                 /*
  287                  * Transfer request set?
  288                  * Wait 50us, the controller needs this time to setle
  289                  */
  290                 DELAY(50);
  291                 if ((bus_space_read_2(rfc_sc->sc_iot, rfc_sc->sc_ioh, RX2CS)
  292                     & RX2CS_TR) == 0) {
  293                         printf("%s: did not respond to Read Sector CMD(1)\n",
  294                             rfc_sc->sc_dev.dv_xname);
  295                         return(-1);
  296                 }
  297                 bus_space_write_2(rfc_sc->sc_iot, rfc_sc->sc_ioh, RX2SA, 1);
  298                 /* Wait 50us, the controller needs this time to setle */
  299                 DELAY(50);
  300                 if ((bus_space_read_2(rfc_sc->sc_iot, rfc_sc->sc_ioh, RX2CS)
  301                     & RX2CS_TR) == 0) {
  302                         printf("%s: did not respond to Read Sector CMD(2)\n",
  303                             rfc_sc->sc_dev.dv_xname);
  304                         return(-1);
  305                 }
  306                 bus_space_write_2(rfc_sc->sc_iot, rfc_sc->sc_ioh, RX2TA, 1);
  307                 /* Wait for the command to finish */
  308                 for (i = 0 ; i < 200 ; i++) {
  309                         if ((bus_space_read_2(rfc_sc->sc_iot, rfc_sc->sc_ioh,
  310                             RX2CS) & RX2CS_DONE) != 0)
  311                                 break;
  312                         DELAY(10000);   /* wait 10ms */
  313                 }
  314                 if (i >= 200) {
  315                         printf("%s: did not respond to Read Sector CMD(3)\n",
  316                             rfc_sc->sc_dev.dv_xname);
  317                         return(-1);
  318                 }
  319                 if ((bus_space_read_2(rfc_sc->sc_iot, rfc_sc->sc_ioh, RX2CS)
  320                     & RX2CS_ERR) == 0)
  321                         return(dens_flag);
  322         } while (rfc_sc->type == 2 && dens_flag++ == 0);
  323         return(-1);
  324 }
  325 #endif /* RX02_PROBE */
  326 
  327 
  328 
  329 void
  330 rfc_attach(struct device *parent, struct device *self, void *aux)
  331 {
  332         struct rfc_softc *rfc_sc = (struct rfc_softc *)self;
  333         struct uba_attach_args *ua = aux;
  334         struct rfc_attach_args rfc_aa;
  335         int i;
  336 
  337         rfc_sc->sc_iot = ua->ua_iot;
  338         rfc_sc->sc_ioh = ua->ua_ioh;
  339         rfc_sc->sc_dmat = ua->ua_dmat;
  340         rfc_sc->sc_curbuf = NULL;
  341         /* Tell the QBus busdriver about our interrupt handler. */
  342         uba_intr_establish(ua->ua_icookie, ua->ua_cvec, rfc_intr, rfc_sc,
  343             &rfc_sc->sc_intr_count);
  344         /* Attach to the interrupt counter, see evcnt(9) */
  345         evcnt_attach_dynamic(&rfc_sc->sc_intr_count, EVCNT_TYPE_INTR,
  346             ua->ua_evcnt, rfc_sc->sc_dev.dv_xname, "intr");
  347         /* get a bus_dma(9) handle */
  348         i = bus_dmamap_create(rfc_sc->sc_dmat, RX2_BYTE_DD, 1, RX2_BYTE_DD, 0,
  349             BUS_DMA_ALLOCNOW, &rfc_sc->sc_dmam);
  350         if (i != 0) {
  351                 printf("rfc_attach: Error creating bus dma map: %d\n", i);
  352                 return;
  353         }
  354 
  355         /* Issue reset command. */
  356         bus_space_write_2(rfc_sc->sc_iot, rfc_sc->sc_ioh, RX2CS, RX2CS_INIT);
  357         /*
  358          * Wait for the controller to become ready, that is when
  359          * RX2CS_DONE, RX2ES_RDY and RX2ES_ID are set.
  360          */
  361         for (i = 0 ; i < 20 ; i++) {
  362                 if ((bus_space_read_2(rfc_sc->sc_iot, rfc_sc->sc_ioh, RX2CS)
  363                     & RX2CS_DONE) != 0
  364                     && (bus_space_read_2(rfc_sc->sc_iot, rfc_sc->sc_ioh, RX2ES)
  365                     & (RX2ES_RDY | RX2ES_ID)) != 0)
  366                         break;
  367                 DELAY(100000);  /* wait 100ms */
  368         }
  369         /*
  370          * Give up if the timeout has elapsed
  371          * and the controller is not ready.
  372          */
  373         if (i >= 20) {
  374                 printf(": did not respond to INIT CMD\n");
  375                 return;
  376         }
  377         /* Is ths a RX01 or a RX02? */
  378         if ((bus_space_read_2(rfc_sc->sc_iot, rfc_sc->sc_ioh, RX2CS)
  379             & RX2CS_RX02) != 0) {
  380                 rfc_sc->type = 2;
  381                 rfc_aa.type = 2;
  382         } else {
  383                 rfc_sc->type = 1;
  384                 rfc_aa.type = 1;
  385         }
  386         printf(": RX0%d\n", rfc_sc->type);
  387 
  388 #ifndef RX02_PROBE
  389         /*
  390          * Bouth disk drievs and the controller are one physical unit.
  391          * If we found the controller, there will be bouth disk drievs.
  392          * So attach them.
  393          */
  394         rfc_aa.dnum = 0;
  395         rfc_sc->sc_childs[0] = config_found(&rfc_sc->sc_dev, &rfc_aa,rf_print);
  396         rfc_aa.dnum = 1;
  397         rfc_sc->sc_childs[1] = config_found(&rfc_sc->sc_dev, &rfc_aa,rf_print);
  398 #else /* RX02_PROBE */
  399         /*
  400          * There are clones of the DEC RX system with standard shugart
  401          * interface. In this case we can not be sure that there are
  402          * bouth disk drievs. So we want to do a detection of attached
  403          * drives. This is done by reading a sector from disk. This means
  404          * that there must be a formated disk in the drive at boot time.
  405          * This is bad, but I did not find an other way to detect the
  406          * (non)existence of a floppy drive.
  407          */
  408         if (rfcprobedens(rfc_sc, 0) >= 0) {
  409                 rfc_aa.dnum = 0;
  410                 rfc_sc->sc_childs[0] = config_found(&rfc_sc->sc_dev, &rfc_aa,
  411                     rf_print);
  412         } else
  413                 rfc_sc->sc_childs[0] = NULL;
  414         if (rfcprobedens(rfc_sc, 1) >= 0) {
  415                 rfc_aa.dnum = 1;
  416                 rfc_sc->sc_childs[1] = config_found(&rfc_sc->sc_dev, &rfc_aa,
  417                     rf_print);
  418         } else
  419                 rfc_sc->sc_childs[1] = NULL;
  420 #endif /* RX02_PROBE */
  421         return;
  422 }
  423 
  424 
  425 
  426 int
  427 rf_match(struct device *parent, struct cfdata *match, void *aux)
  428 {
  429         struct rfc_attach_args *rfc_aa = aux;
  430 
  431         /*
  432          * Only attach if the locator is wildcarded or
  433          * if the specified locator addresses the current device.
  434          */
  435         if (match->cf_loc[RFCCF_DRIVE] == RFCCF_DRIVE_DEFAULT ||
  436             match->cf_loc[RFCCF_DRIVE] == rfc_aa->dnum)
  437                 return(1);
  438         return(0);
  439 }
  440 
  441 
  442 
  443 void
  444 rf_attach(struct device *parent, struct device *self, void *aux)
  445 {
  446         struct rf_softc *rf_sc = (struct rf_softc *)self;
  447         struct rfc_attach_args *rfc_aa = (struct rfc_attach_args *)aux;
  448         struct rfc_softc *rfc_sc;
  449         struct disklabel *dl;
  450 
  451         rfc_sc = (struct rfc_softc *)rf_sc->sc_dev.dv_parent;
  452         rf_sc->sc_dnum = rfc_aa->dnum;
  453         rf_sc->sc_state = 0;
  454         rf_sc->sc_disk.dk_name = rf_sc->sc_dev.dv_xname;
  455         rf_sc->sc_disk.dk_driver = &rfdkdriver;
  456         disk_attach(&rf_sc->sc_disk);
  457         dl = rf_sc->sc_disk.dk_label;
  458         dl->d_type = DTYPE_FLOPPY;              /* drive type */
  459         dl->d_magic = DISKMAGIC;                /* the magic number */
  460         dl->d_magic2 = DISKMAGIC;
  461         dl->d_typename[0] = 'R';
  462         dl->d_typename[1] = 'X';
  463         dl->d_typename[2] = '';
  464         dl->d_typename[3] = rfc_sc->type == 1 ? '1' : '2';      /* type name */
  465         dl->d_typename[4] = '\0';
  466         dl->d_secsize = DEV_BSIZE;              /* bytes per sector */
  467         /*
  468          * Fill in some values to have a initialized data structure. Some
  469          * values will be reset by rfopen() depending on the actual density.
  470          */
  471         dl->d_nsectors = RX2_SECTORS;           /* sectors per track */
  472         dl->d_ntracks = 1;                                                              /* tracks per cylinder */
  473         dl->d_ncylinders = RX2_TRACKS;          /* cylinders per unit */
  474         dl->d_secpercyl = RX2_SECTORS;          /* sectors per cylinder */
  475         dl->d_secperunit = RX2_SECTORS * RX2_TRACKS;    /* sectors per unit */   
  476         dl->d_rpm = 360;                        /* rotational speed */
  477         dl->d_interleave = 1;                   /* hardware sector interleave */
  478         /* number of partitions in following */
  479         dl->d_npartitions = MAXPARTITIONS;
  480         dl->d_bbsize = 0;               /* size of boot area at sn0, bytes */
  481         dl->d_sbsize = 0;               /* max size of fs superblock, bytes */
  482         /* number of sectors in partition */
  483         dl->d_partitions[0].p_size = 501;
  484         dl->d_partitions[0].p_offset = 0;       /* starting sector */
  485         dl->d_partitions[0].p_fsize = 0;        /* fs basic fragment size */
  486         dl->d_partitions[0].p_fstype = 0;       /* fs type */
  487         dl->d_partitions[0].p_frag = 0;         /* fs fragments per block */
  488         dl->d_partitions[1].p_size = RX2_SECTORS * RX2_TRACKS / 2;
  489         dl->d_partitions[1].p_offset = 0;       /* starting sector */
  490         dl->d_partitions[1].p_fsize = 0;        /* fs basic fragment size */
  491         dl->d_partitions[1].p_fstype = 0;       /* fs type */
  492         dl->d_partitions[1].p_frag = 0;         /* fs fragments per block */
  493         dl->d_partitions[2].p_size = RX2_SECTORS * RX2_TRACKS;
  494         dl->d_partitions[2].p_offset = 0;       /* starting sector */
  495         dl->d_partitions[2].p_fsize = 0;        /* fs basic fragment size */
  496         dl->d_partitions[2].p_fstype = 0;       /* fs type */
  497         dl->d_partitions[2].p_frag = 0;         /* fs fragments per block */
  498         bufq_alloc(&rf_sc->sc_bufq, BUFQ_DISKSORT | BUFQ_SORT_CYLINDER);
  499         printf("\n");
  500         return;
  501 }
  502 
  503 
  504 
  505 int
  506 rf_print(void *aux, const char *name)
  507 {
  508         struct rfc_attach_args *rfc_aa = aux;
  509 
  510         if (name != NULL)
  511                 aprint_normal("RX0%d at %s", rfc_aa->type, name);
  512         aprint_normal(" drive %d", rfc_aa->dnum);
  513         return(UNCONF);
  514 }
  515 
  516 
  517 
  518 /* Send a command to the controller */
  519 int
  520 rfc_sendcmd(struct rfc_softc *rfc_sc, int cmd, int data1, int data2)
  521 {
  522 
  523         /* Write command to CSR. */
  524         bus_space_write_2(rfc_sc->sc_iot, rfc_sc->sc_ioh, RX2CS, cmd);
  525         /* Wait 50us, the controller needs this time to setle. */
  526         DELAY(50);
  527         /* Write parameter 1 to DBR */
  528         if ((cmd & RX2CS_FC) != RX2CS_RSTAT) {
  529                 /* Transfer request set? */
  530                 if ((bus_space_read_2(rfc_sc->sc_iot, rfc_sc->sc_ioh, RX2CS)
  531                     & RX2CS_TR) == 0) {
  532                         printf("%s: did not respond to CMD %x (1)\n",
  533                             rfc_sc->sc_dev.dv_xname, cmd);
  534                         return(-1);
  535                 }
  536                 bus_space_write_2(rfc_sc->sc_iot, rfc_sc->sc_ioh, RX2DB,
  537                     data1);
  538         }
  539         /* Write parameter 2 to DBR */
  540         if ((cmd & RX2CS_FC) <= RX2CS_RSEC || (cmd & RX2CS_FC) == RX2CS_WDDS) {
  541                 /* Wait 50us, the controller needs this time to setle. */
  542                 DELAY(50);
  543                 /* Transfer request set? */
  544                 if ((bus_space_read_2(rfc_sc->sc_iot, rfc_sc->sc_ioh, RX2CS)
  545                     & RX2CS_TR) == 0) {
  546                         printf("%s: did not respond to CMD %x (2)\n",
  547                             rfc_sc->sc_dev.dv_xname, cmd);
  548                         return(-1);
  549                 }
  550                 bus_space_write_2(rfc_sc->sc_iot, rfc_sc->sc_ioh, RX2DB,
  551                     data2);
  552         }
  553         return(1);
  554 }
  555 
  556 
  557 
  558 void
  559 rfstrategy(struct buf *buf)
  560 {
  561         struct rf_softc *rf_sc;
  562         struct rfc_softc *rfc_sc;
  563         int i;
  564 
  565         i = DISKUNIT(buf->b_dev);
  566         if (i >= rf_cd.cd_ndevs || (rf_sc = rf_cd.cd_devs[i]) == NULL) {
  567                 buf->b_flags |= B_ERROR;
  568                 buf->b_error = ENXIO;
  569                 biodone(buf);
  570                 return;
  571         }
  572         rfc_sc = (struct rfc_softc *)rf_sc->sc_dev.dv_parent;
  573         /* We are going to operate on a non open dev? PANIC! */
  574         if ((rf_sc->sc_state & 1 << (DISKPART(buf->b_dev) + RFS_OPEN_SHIFT)) 
  575             == 0)
  576                 panic("rfstrategy: can not operate on non-open drive %s "
  577                     "partition %d", rf_sc->sc_dev.dv_xname, 
  578                     DISKPART(buf->b_dev));
  579         if (buf->b_bcount == 0) {
  580                 biodone(buf);
  581                 return;
  582         }
  583         /*
  584          * BUFQ_PUT() operates on b_rawblkno. rfstrategy() gets
  585          * only b_blkno that is partition relative. As a floppy does not
  586          * have partitions b_rawblkno == b_blkno.
  587          */
  588         buf->b_rawblkno = buf->b_blkno;
  589         /*
  590          * from sys/kern/subr_disk.c:
  591          * Seek sort for disks.  We depend on the driver which calls us using
  592          * b_resid as the current cylinder number.
  593          */
  594         i = splbio();
  595         if (rfc_sc->sc_curbuf == NULL) {
  596                 rfc_sc->sc_curchild = rf_sc->sc_dnum;
  597                 rfc_sc->sc_curbuf = buf;
  598                 rfc_sc->sc_bufidx = buf->b_un.b_addr;
  599                 rfc_sc->sc_bytesleft = buf->b_bcount;
  600                 rfc_intr(rfc_sc);
  601         } else {
  602                 buf->b_resid = buf->b_blkno / RX2_SECTORS;
  603                 BUFQ_PUT(&rf_sc->sc_bufq, buf);
  604                 buf->b_resid = 0;
  605         }
  606         splx(i);
  607         return;
  608 }
  609 
  610 
  611 
  612 /*
  613  * Look if there is an other buffer in the bufferqueue of this drive
  614  * and start to process it if there is one.
  615  * If the bufferqueue is empty, look at the bufferqueue of the other drive
  616  * that is attached to this controller. 
  617  * Start procesing the bufferqueue of the other drive if it isn't empty. 
  618  * Return a pointer to the softc structure of the drive that is now 
  619  * ready to process a buffer or NULL if there is no buffer in either queues.
  620  */
  621 struct rf_softc*
  622 get_new_buf( struct rfc_softc *rfc_sc) 
  623 {
  624         struct rf_softc *rf_sc;
  625         struct rf_softc *other_drive;
  626 
  627         rf_sc = (struct rf_softc *)rfc_sc->sc_childs[rfc_sc->sc_curchild];
  628         rfc_sc->sc_curbuf = BUFQ_GET(&rf_sc->sc_bufq);
  629         if (rfc_sc->sc_curbuf != NULL) {
  630                 rfc_sc->sc_bufidx = rfc_sc->sc_curbuf->b_un.b_addr;
  631                 rfc_sc->sc_bytesleft = rfc_sc->sc_curbuf->b_bcount;
  632         } else {
  633                 RFS_SETCMD(rf_sc->sc_state, RFS_IDLE);
  634                 other_drive = (struct rf_softc *)
  635                     rfc_sc->sc_childs[ rfc_sc->sc_curchild == 0 ? 1 : 0];
  636                 if (other_drive != NULL 
  637                     && BUFQ_PEEK(&other_drive->sc_bufq) != NULL) {
  638                         rfc_sc->sc_curchild = rfc_sc->sc_curchild == 0 ? 1 : 0;
  639                         rf_sc = other_drive;
  640                         rfc_sc->sc_curbuf = BUFQ_GET(&rf_sc->sc_bufq);
  641                         rfc_sc->sc_bufidx = rfc_sc->sc_curbuf->b_un.b_addr;
  642                         rfc_sc->sc_bytesleft = rfc_sc->sc_curbuf->b_bcount;
  643                 } else
  644                         return(NULL);
  645         }
  646         return(rf_sc);
  647 }
  648 
  649 
  650 
  651 void
  652 rfc_intr(void *intarg)
  653 {
  654         struct rfc_softc *rfc_sc = intarg;
  655         struct rf_softc *rf_sc;
  656         int i;
  657 
  658         rf_sc = (struct rf_softc *)rfc_sc->sc_childs[rfc_sc->sc_curchild];
  659         do {
  660                 /*
  661                  * First clean up from previous command...
  662                  */
  663                 switch (rf_sc->sc_state & RFS_CMDS) {
  664                 case RFS_PROBING:       /* density detect / verify started */
  665                         disk_unbusy(&rf_sc->sc_disk, 0, 1);
  666                         if ((bus_space_read_2(rfc_sc->sc_iot, rfc_sc->sc_ioh,
  667                             RX2CS) & RX2CS_ERR) == 0) {
  668                                 RFS_SETCMD(rf_sc->sc_state, RFS_IDLE);
  669                                 wakeup(rf_sc);
  670                         } else {
  671                                 if (rfc_sc->type == 2
  672                                     && (rf_sc->sc_state & RFS_DENS) == 0
  673                                     && (rf_sc->sc_state & RFS_AD) != 0) {
  674                                         /* retry at DD */
  675                                         rf_sc->sc_state |= RFS_DENS;
  676                                         disk_busy(&rf_sc->sc_disk);
  677                                         if (rfc_sendcmd(rfc_sc, RX2CS_RSEC 
  678                                             | RX2CS_IE | RX2CS_DD | 
  679                                             (rf_sc->sc_dnum == 0 ? 0 : 
  680                                             RX2CS_US), 1, 1) < 0) {
  681                                                 disk_unbusy(&rf_sc->sc_disk, 
  682                                                     0, 1);
  683                                                 RFS_SETCMD(rf_sc->sc_state,
  684                                                     RFS_NOTINIT);
  685                                                 wakeup(rf_sc);
  686                                         }
  687                                 } else {
  688                                         printf("%s: density error.\n",
  689                                             rf_sc->sc_dev.dv_xname);
  690                                         RFS_SETCMD(rf_sc->sc_state,RFS_NOTINIT);
  691                                         wakeup(rf_sc);
  692                                 }
  693                         }
  694                         return;
  695                 case RFS_IDLE:  /* controller is idle */
  696                         if (rfc_sc->sc_curbuf->b_bcount
  697                             % ((rf_sc->sc_state & RFS_DENS) == 0
  698                             ? RX2_BYTE_SD : RX2_BYTE_DD) != 0) {
  699                                 /*
  700                                  * can only handle blocks that are a multiple 
  701                                  * of the physical block size
  702                                  */
  703                                 rfc_sc->sc_curbuf->b_flags |= B_ERROR;
  704                         }
  705                         RFS_SETCMD(rf_sc->sc_state, (rfc_sc->sc_curbuf->b_flags
  706                             & B_READ) != 0 ? RFS_RSEC : RFS_FBUF);
  707                         break;
  708                 case RFS_RSEC:  /* Read Sector */
  709                         disk_unbusy(&rf_sc->sc_disk, 0, 1);
  710                         /* check for errors */
  711                         if ((bus_space_read_2(rfc_sc->sc_iot, rfc_sc->sc_ioh, 
  712                             RX2CS) & RX2CS_ERR) != 0) {
  713                                 /* should do more verbose error reporting */
  714                                 printf("rfc_intr: Error reading secotr: %x\n", 
  715                                     bus_space_read_2(rfc_sc->sc_iot,
  716                                     rfc_sc->sc_ioh, RX2ES) );
  717                                 rfc_sc->sc_curbuf->b_flags |= B_ERROR;
  718                         }
  719                         RFS_SETCMD(rf_sc->sc_state, RFS_EBUF);
  720                         break;
  721                 case RFS_WSEC:  /* Write Sector */
  722                         i = (rf_sc->sc_state & RFS_DENS) == 0
  723                                 ? RX2_BYTE_SD : RX2_BYTE_DD;
  724                         disk_unbusy(&rf_sc->sc_disk, i, 0);
  725                         /* check for errors */
  726                         if ((bus_space_read_2(rfc_sc->sc_iot, rfc_sc->sc_ioh, 
  727                             RX2CS) & RX2CS_ERR) != 0) {
  728                                 /* should do more verbose error reporting */
  729                                 printf("rfc_intr: Error writing secotr: %x\n",
  730                                     bus_space_read_2(rfc_sc->sc_iot,
  731                                     rfc_sc->sc_ioh, RX2ES) );
  732                                 rfc_sc->sc_curbuf->b_flags |= B_ERROR;
  733                                 break;
  734                         }
  735                         if (rfc_sc->sc_bytesleft > i) {
  736                                 rfc_sc->sc_bytesleft -= i;
  737                                 rfc_sc->sc_bufidx += i;
  738                         } else {
  739                                 biodone(rfc_sc->sc_curbuf);
  740                                 rf_sc = get_new_buf( rfc_sc);
  741                                 if (rf_sc == NULL)
  742                                         return;
  743                         }
  744                         RFS_SETCMD(rf_sc->sc_state,
  745                             (rfc_sc->sc_curbuf->b_flags & B_READ) != 0
  746                             ? RFS_RSEC : RFS_FBUF);
  747                         break;
  748                 case RFS_FBUF:  /* Fill Buffer */
  749                         disk_unbusy(&rf_sc->sc_disk, 0, 0);
  750                         bus_dmamap_unload(rfc_sc->sc_dmat, rfc_sc->sc_dmam);
  751                         /* check for errors */
  752                         if ((bus_space_read_2(rfc_sc->sc_iot, rfc_sc->sc_ioh, 
  753                             RX2CS) & RX2CS_ERR) != 0) {
  754                                 /* should do more verbose error reporting */
  755                                 printf("rfc_intr: Error while DMA: %x\n",
  756                                     bus_space_read_2(rfc_sc->sc_iot,
  757                                     rfc_sc->sc_ioh, RX2ES));
  758                                 rfc_sc->sc_curbuf->b_flags |= B_ERROR;
  759                         }
  760                         RFS_SETCMD(rf_sc->sc_state, RFS_WSEC);
  761                         break;
  762                 case RFS_EBUF:  /* Empty Buffer */
  763                         i = (rf_sc->sc_state & RFS_DENS) == 0
  764                             ? RX2_BYTE_SD : RX2_BYTE_DD;
  765                         disk_unbusy(&rf_sc->sc_disk, i, 1);
  766                         bus_dmamap_unload(rfc_sc->sc_dmat, rfc_sc->sc_dmam);
  767                         /* check for errors */
  768                         if ((bus_space_read_2(rfc_sc->sc_iot, rfc_sc->sc_ioh, 
  769                             RX2CS) & RX2CS_ERR) != 0) {
  770                                 /* should do more verbose error reporting */
  771                                 printf("rfc_intr: Error while DMA: %x\n",
  772                                     bus_space_read_2(rfc_sc->sc_iot,
  773                                     rfc_sc->sc_ioh, RX2ES));
  774                                 rfc_sc->sc_curbuf->b_flags |= B_ERROR;
  775                                 break;
  776                         }
  777                         if (rfc_sc->sc_bytesleft > i) {
  778                                 rfc_sc->sc_bytesleft -= i;
  779                                 rfc_sc->sc_bufidx += i;
  780                         } else {
  781                                 biodone(rfc_sc->sc_curbuf);
  782                                 rf_sc = get_new_buf( rfc_sc);
  783                                 if (rf_sc == NULL)
  784                                         return;
  785                         }
  786                         RFS_SETCMD(rf_sc->sc_state,
  787                             (rfc_sc->sc_curbuf->b_flags & B_READ) != 0
  788                             ? RFS_RSEC : RFS_FBUF);
  789                         break;
  790                 case RFS_NOTINIT: /* Device is not open */
  791                 case RFS_SMD:   /* Set Media Density */
  792                 case RFS_RSTAT: /* Read Status */
  793                 case RFS_WDDS:  /* Write Deleted Data Sector */
  794                 case RFS_REC:   /* Read Error Code */
  795                 default:
  796                         panic("Impossible state in rfc_intr(1).\n");    
  797                 }
  798 
  799                 if ((rfc_sc->sc_curbuf->b_flags & B_ERROR) != 0) {
  800                         /* 
  801                          * An error occurred while processing this buffer. 
  802                          * Finish it and try to get a new buffer to process.
  803                          * Return if there are no buffers in the queues.
  804                          * This loops until the queues are empty or a new
  805                          * action was successfully scheduled.
  806                          */
  807                         rfc_sc->sc_curbuf->b_resid = rfc_sc->sc_bytesleft;
  808                         rfc_sc->sc_curbuf->b_error = EIO;
  809                         biodone(rfc_sc->sc_curbuf);
  810                         rf_sc = get_new_buf( rfc_sc);
  811                         if (rf_sc == NULL)
  812                                 return;
  813                         continue;
  814                 }
  815 
  816                 /*
  817                  * ... then initiate next command.
  818                  */
  819                 switch (rf_sc->sc_state & RFS_CMDS) {
  820                 case RFS_EBUF:  /* Empty Buffer */
  821                         i = bus_dmamap_load(rfc_sc->sc_dmat, rfc_sc->sc_dmam,
  822                             rfc_sc->sc_bufidx, (rf_sc->sc_state & RFS_DENS) == 0
  823                             ? RX2_BYTE_SD : RX2_BYTE_DD, 
  824                             rfc_sc->sc_curbuf->b_proc, BUS_DMA_NOWAIT);
  825                         if (i != 0) {
  826                                 printf("rfc_intr: Error loading dmamap: %d\n",
  827                                 i);
  828                                 rfc_sc->sc_curbuf->b_flags |= B_ERROR;
  829                                 break;
  830                         }
  831                         disk_busy(&rf_sc->sc_disk);
  832                         if (rfc_sendcmd(rfc_sc, RX2CS_EBUF | RX2CS_IE
  833                             | ((rf_sc->sc_state & RFS_DENS) == 0 ? 0 : RX2CS_DD)
  834                             | (rf_sc->sc_dnum == 0 ? 0 : RX2CS_US)
  835                             | ((rfc_sc->sc_dmam->dm_segs[0].ds_addr 
  836                             & 0x30000) >>4), ((rf_sc->sc_state & RFS_DENS) == 0
  837                             ? RX2_BYTE_SD : RX2_BYTE_DD) / 2,
  838                             rfc_sc->sc_dmam->dm_segs[0].ds_addr & 0xffff) < 0) {
  839                                 disk_unbusy(&rf_sc->sc_disk, 0, 1);
  840                                 rfc_sc->sc_curbuf->b_flags |= B_ERROR;
  841                                 bus_dmamap_unload(rfc_sc->sc_dmat, 
  842                                 rfc_sc->sc_dmam);
  843                         }
  844                         break;
  845                 case RFS_FBUF:  /* Fill Buffer */
  846                         i = bus_dmamap_load(rfc_sc->sc_dmat, rfc_sc->sc_dmam,
  847                             rfc_sc->sc_bufidx, (rf_sc->sc_state & RFS_DENS) == 0
  848                             ? RX2_BYTE_SD : RX2_BYTE_DD,
  849                             rfc_sc->sc_curbuf->b_proc, BUS_DMA_NOWAIT);
  850                         if (i != 0) {
  851                                 printf("rfc_intr: Error loading dmamap: %d\n", 
  852                                     i);
  853                                 rfc_sc->sc_curbuf->b_flags |= B_ERROR;
  854                                 break;
  855                         }
  856                         disk_busy(&rf_sc->sc_disk);
  857                         if (rfc_sendcmd(rfc_sc, RX2CS_FBUF | RX2CS_IE
  858                             | ((rf_sc->sc_state & RFS_DENS) == 0 ? 0 : RX2CS_DD)
  859                             | (rf_sc->sc_dnum == 0 ? 0 : RX2CS_US)
  860                             | ((rfc_sc->sc_dmam->dm_segs[0].ds_addr 
  861                             & 0x30000)>>4), ((rf_sc->sc_state & RFS_DENS) == 0
  862                             ? RX2_BYTE_SD : RX2_BYTE_DD) / 2,
  863                             rfc_sc->sc_dmam->dm_segs[0].ds_addr & 0xffff) < 0) {
  864                                 disk_unbusy(&rf_sc->sc_disk, 0, 0);
  865                                 rfc_sc->sc_curbuf->b_flags |= B_ERROR;
  866                                 bus_dmamap_unload(rfc_sc->sc_dmat, 
  867                                     rfc_sc->sc_dmam);
  868                         }
  869                         break;
  870                 case RFS_WSEC:  /* Write Sector */
  871                         i = (rfc_sc->sc_curbuf->b_bcount - rfc_sc->sc_bytesleft
  872                             + rfc_sc->sc_curbuf->b_blkno * DEV_BSIZE) /
  873                             ((rf_sc->sc_state & RFS_DENS) == 0
  874                             ? RX2_BYTE_SD : RX2_BYTE_DD);
  875                         if (i > RX2_TRACKS * RX2_SECTORS) {
  876                                 rfc_sc->sc_curbuf->b_flags |= B_ERROR;
  877                                 break;
  878                         }
  879                         disk_busy(&rf_sc->sc_disk);
  880                         if (rfc_sendcmd(rfc_sc, RX2CS_WSEC | RX2CS_IE
  881                             | (rf_sc->sc_dnum == 0 ? 0 : RX2CS_US)
  882                             | ((rf_sc->sc_state& RFS_DENS) == 0 ? 0 : RX2CS_DD),
  883                             i % RX2_SECTORS + 1, i / RX2_SECTORS) < 0) {
  884                                 disk_unbusy(&rf_sc->sc_disk, 0, 0);
  885                                 rfc_sc->sc_curbuf->b_flags |= B_ERROR;
  886                         }
  887                         break;
  888                 case RFS_RSEC:  /* Read Sector */
  889                         i = (rfc_sc->sc_curbuf->b_bcount - rfc_sc->sc_bytesleft
  890                             + rfc_sc->sc_curbuf->b_blkno * DEV_BSIZE) /
  891                             ((rf_sc->sc_state & RFS_DENS) == 0
  892                             ? RX2_BYTE_SD : RX2_BYTE_DD);
  893                         if (i > RX2_TRACKS * RX2_SECTORS) {
  894                                 rfc_sc->sc_curbuf->b_flags |= B_ERROR;
  895                                 break;
  896                         }
  897                         disk_busy(&rf_sc->sc_disk);
  898                         if (rfc_sendcmd(rfc_sc, RX2CS_RSEC | RX2CS_IE
  899                             | (rf_sc->sc_dnum == 0 ? 0 : RX2CS_US)
  900                             | ((rf_sc->sc_state& RFS_DENS) == 0 ? 0 : RX2CS_DD),
  901                             i % RX2_SECTORS + 1, i / RX2_SECTORS) < 0) {
  902                                 disk_unbusy(&rf_sc->sc_disk, 0, 1);
  903                                 rfc_sc->sc_curbuf->b_flags |= B_ERROR;
  904                         }
  905                         break;
  906                 case RFS_NOTINIT: /* Device is not open */
  907                 case RFS_PROBING: /* density detect / verify started */
  908                 case RFS_IDLE:  /* controller is idle */
  909                 case RFS_SMD:   /* Set Media Density */
  910                 case RFS_RSTAT: /* Read Status */
  911                 case RFS_WDDS:  /* Write Deleted Data Sector */
  912                 case RFS_REC:   /* Read Error Code */
  913                 default:
  914                         panic("Impossible state in rfc_intr(2).\n");    
  915                 }
  916 
  917                 if ((rfc_sc->sc_curbuf->b_flags & B_ERROR) != 0) {
  918                         /* 
  919                          * An error occurred while processing this buffer. 
  920                          * Finish it and try to get a new buffer to process.
  921                          * Return if there are no buffers in the queues.
  922                          * This loops until the queues are empty or a new
  923                          * action was successfully scheduled.
  924                          */
  925                         rfc_sc->sc_curbuf->b_resid = rfc_sc->sc_bytesleft;
  926                         rfc_sc->sc_curbuf->b_error = EIO;
  927                         biodone(rfc_sc->sc_curbuf);
  928                         rf_sc = get_new_buf( rfc_sc);
  929                         if (rf_sc == NULL)
  930                                 return;
  931                         continue;
  932                 }
  933         } while ( 1 == 0 /* CONSTCOND */ );
  934         return;
  935 }
  936 
  937 
  938 
  939 int
  940 rfdump(dev_t dev, daddr_t blkno, caddr_t va, size_t size)
  941 {
  942 
  943         /* A 0.5MB floppy is much to small to take a system dump... */
  944         return(ENXIO);
  945 }
  946 
  947 
  948 
  949 int
  950 rfsize(dev_t dev)
  951 {
  952 
  953         return(-1);
  954 }
  955 
  956 
  957 
  958 int
  959 rfopen(dev_t dev, int oflags, int devtype, struct proc *p)
  960 {
  961         struct rf_softc *rf_sc;
  962         struct rfc_softc *rfc_sc;
  963         struct disklabel *dl;
  964         int unit;
  965 
  966         unit = DISKUNIT(dev);
  967         if (unit >= rf_cd.cd_ndevs || (rf_sc = rf_cd.cd_devs[unit]) == NULL) {
  968                 return(ENXIO);
  969         }
  970         rfc_sc = (struct rfc_softc *)rf_sc->sc_dev.dv_parent;
  971         dl = rf_sc->sc_disk.dk_label;
  972         switch (DISKPART(dev)) {
  973                 case 0:                 /* Part. a is single density. */
  974                         /* opening in single and double density is sensless */
  975                         if ((rf_sc->sc_state & RFS_OPEN_B) != 0 ) 
  976                                 return(ENXIO);
  977                         rf_sc->sc_state &= ~RFS_DENS;
  978                         rf_sc->sc_state &= ~RFS_AD;
  979                         rf_sc->sc_state |= RFS_OPEN_A;
  980                 break;
  981                 case 1:                 /* Part. b is double density. */
  982                         /*
  983                          * Opening a singe density only drive in double 
  984                          * density or simultaneous opening in single and 
  985                          * double density is sensless.
  986                          */
  987                         if (rfc_sc->type == 1 
  988                             || (rf_sc->sc_state & RFS_OPEN_A) != 0 ) 
  989                                 return(ENXIO);  
  990                         rf_sc->sc_state |= RFS_DENS;
  991                         rf_sc->sc_state &= ~RFS_AD;
  992                         rf_sc->sc_state |= RFS_OPEN_B;
  993                 break;
  994                 case 2:                 /* Part. c is auto density. */
  995                         rf_sc->sc_state |= RFS_AD;
  996                         rf_sc->sc_state |= RFS_OPEN_C;
  997                 break;
  998                 default:
  999                         return(ENXIO);
 1000                 break;
 1001         }
 1002         if ((rf_sc->sc_state & RFS_CMDS) == RFS_NOTINIT) {
 1003                 rfc_sc->sc_curchild = rf_sc->sc_dnum;
 1004                 /*
 1005                  * Controller is idle and density is not detected.
 1006                  * Start a density probe by issuing a read sector command
 1007                  * and sleep until the density probe finished.
 1008                  * Due to this it is imposible to open unformated media.
 1009                  * As the RX02/02 is not able to format its own media,
 1010                  * media must be purchased preformated. fsck DEC makreting!
 1011                  */
 1012                 RFS_SETCMD(rf_sc->sc_state, RFS_PROBING);
 1013                 disk_busy(&rf_sc->sc_disk);
 1014                 if (rfc_sendcmd(rfc_sc, RX2CS_RSEC | RX2CS_IE
 1015                     | (rf_sc->sc_dnum == 0 ? 0 : RX2CS_US)
 1016                     | ((rf_sc->sc_state & RFS_DENS) == 0 ? 0 : RX2CS_DD),
 1017                     1, 1) < 0) {
 1018                         rf_sc->sc_state = 0;
 1019                         return(ENXIO);
 1020                 }
 1021                 /* wait max. 2 sec for density probe to finish */
 1022                 if (tsleep(rf_sc, PRIBIO | PCATCH, "density probe", 2 * hz)
 1023                     != 0 || (rf_sc->sc_state & RFS_CMDS) == RFS_NOTINIT) {
 1024                         /* timeout elapsed and / or somthing went wrong */
 1025                         rf_sc->sc_state = 0;
 1026                         return(ENXIO);
 1027                 }
 1028         }
 1029         /* disklabel. We use different fake geometries for SD and DD. */
 1030         if ((rf_sc->sc_state & RFS_DENS) == 0) {
 1031                 dl->d_nsectors = 10;            /* sectors per track */
 1032                 dl->d_secpercyl = 10;           /* sectors per cylinder */
 1033                 dl->d_ncylinders = 50;          /* cylinders per unit */
 1034                 dl->d_secperunit = 501; /* sectors per unit */
 1035                 /* number of sectors in partition */
 1036                 dl->d_partitions[2].p_size = 500;
 1037         } else {
 1038                 dl->d_nsectors = RX2_SECTORS / 2;  /* sectors per track */
 1039                 dl->d_secpercyl = RX2_SECTORS / 2; /* sectors per cylinder */
 1040                 dl->d_ncylinders = RX2_TRACKS;     /* cylinders per unit */
 1041                 /* sectors per unit */
 1042                 dl->d_secperunit = RX2_SECTORS * RX2_TRACKS / 2;
 1043                 /* number of sectors in partition */
 1044                 dl->d_partitions[2].p_size = RX2_SECTORS * RX2_TRACKS / 2;
 1045         }
 1046         return(0);
 1047 }
 1048 
 1049 
 1050 
 1051 int
 1052 rfclose(dev_t dev, int fflag, int devtype, struct proc *p)
 1053 {
 1054         struct rf_softc *rf_sc;
 1055         int unit;
 1056 
 1057         unit = DISKUNIT(dev);
 1058         if (unit >= rf_cd.cd_ndevs || (rf_sc = rf_cd.cd_devs[unit]) == NULL) {
 1059                 return(ENXIO);
 1060         }
 1061         if ((rf_sc->sc_state & 1 << (DISKPART(dev) + RFS_OPEN_SHIFT)) == 0)
 1062                 panic("rfclose: can not close on non-open drive %s "
 1063                     "partition %d", rf_sc->sc_dev.dv_xname, DISKPART(dev));
 1064         else 
 1065                 rf_sc->sc_state &= ~(1 << (DISKPART(dev) + RFS_OPEN_SHIFT));
 1066         if ((rf_sc->sc_state & RFS_OPEN_MASK) == 0)
 1067                 rf_sc->sc_state = 0;
 1068         return(0);
 1069 }
 1070 
 1071 
 1072 
 1073 int
 1074 rfread(dev_t dev, struct uio *uio, int ioflag)
 1075 {
 1076 
 1077         return(physio(rfstrategy, NULL, dev, B_READ, minphys, uio));
 1078 }
 1079 
 1080 
 1081 
 1082 int
 1083 rfwrite(dev_t dev, struct uio *uio, int ioflag)
 1084 {
 1085 
 1086         return(physio(rfstrategy, NULL, dev, B_WRITE, minphys, uio));
 1087 }
 1088 
 1089 
 1090 
 1091 int
 1092 rfioctl(dev_t dev, u_long cmd, caddr_t data, int fflag, struct proc *p)
 1093 {
 1094         struct rf_softc *rf_sc;
 1095         int unit;
 1096 
 1097         unit = DISKUNIT(dev);
 1098         if (unit >= rf_cd.cd_ndevs || (rf_sc = rf_cd.cd_devs[unit]) == NULL) {
 1099                 return(ENXIO);
 1100         }
 1101         /* We are going to operate on a non open dev? PANIC! */
 1102         if ((rf_sc->sc_state & 1 << (DISKPART(dev) + RFS_OPEN_SHIFT)) == 0)
 1103                 panic("rfioctl: can not operate on non-open drive %s "
 1104                     "partition %d", rf_sc->sc_dev.dv_xname, DISKPART(dev));
 1105         switch (cmd) {
 1106         /* get and set disklabel; DIOCGPART used internally */
 1107         case DIOCGDINFO: /* get */
 1108                 memcpy(data, rf_sc->sc_disk.dk_label,
 1109                     sizeof(struct disklabel));
 1110                 return(0);
 1111         case DIOCSDINFO: /* set */
 1112                 return(0);
 1113         case DIOCWDINFO: /* set, update disk */
 1114                 return(0);
 1115         case DIOCGPART:  /* get partition */
 1116                 ((struct partinfo *)data)->disklab = rf_sc->sc_disk.dk_label;
 1117                 ((struct partinfo *)data)->part =
 1118                     &rf_sc->sc_disk.dk_label->d_partitions[DISKPART(dev)];
 1119                 return(0);
 1120 
 1121         /* do format operation, read or write */
 1122         case DIOCRFORMAT:
 1123         break;
 1124         case DIOCWFORMAT:
 1125         break;
 1126 
 1127         case DIOCSSTEP: /* set step rate */
 1128         break;
 1129         case DIOCSRETRIES: /* set # of retries */
 1130         break;
 1131         case DIOCKLABEL: /* keep/drop label on close? */
 1132         break;
 1133         case DIOCWLABEL: /* write en/disable label */
 1134         break;
 1135 
 1136 /*      case DIOCSBAD: / * set kernel dkbad */
 1137         break; /* */
 1138         case DIOCEJECT: /* eject removable disk */
 1139         break;
 1140         case ODIOCEJECT: /* eject removable disk */
 1141         break;
 1142         case DIOCLOCK: /* lock/unlock pack */
 1143         break;
 1144 
 1145         /* get default label, clear label */
 1146         case DIOCGDEFLABEL:
 1147         break;
 1148         case DIOCCLRLABEL:
 1149         break;
 1150         default:
 1151                 return(ENOTTY);
 1152         }
 1153 
 1154         return(ENOTTY);
 1155 }
 1156 
 1157 

Cache object: 855bc7037ce3c08a4d09eef91a8600d7


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