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

Cache object: 3a434819375f13c47e1b743381c8a176


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