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.21 2008/07/25 18:37:24 dsl 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.21 2008/07/25 18:37:24 dsl 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 <sys/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(device_t, cfdata_t, void *);
  102 static void rfc_attach(device_t, device_t, void *);
  103 static int rf_match(device_t, cfdata_t, void *);
  104 static void rf_attach(device_t, device_t, 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         device_t sc_dev;                /* common device data */
  147         device_t 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         void *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_NEW(
  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         device_t sc_dev;                /* common device data */
  175         struct disk sc_disk;            /* common disk device data */
  176         struct rfc_softc *sc_rfc;       /* our parent */
  177         struct bufq_state *sc_bufq;     /* queue of pending transfers */
  178         int sc_state;                   /* state of drive */
  179         u_int8_t sc_dnum;               /* drive number, 0 or 1 */
  180 };
  181 
  182 
  183 
  184 CFATTACH_DECL_NEW(
  185         rf,
  186         sizeof(struct rf_softc),
  187         rf_match,
  188         rf_attach,
  189         NULL,
  190         NULL
  191 );
  192 
  193 
  194 
  195 struct rfc_attach_args {
  196         u_int8_t type;          /* controller type, 1 or 2 */
  197         u_int8_t dnum;          /* drive number, 0 or 1 */
  198 };
  199 
  200 
  201 
  202 const struct dkdriver rfdkdriver = {
  203         rfstrategy
  204 };
  205 
  206 
  207 
  208 /* helper functions */
  209 int rfc_sendcmd(struct rfc_softc *, int, int, int);
  210 struct rf_softc* get_new_buf( struct rfc_softc *);
  211 static void rfc_intr(void *);
  212 
  213 
  214 
  215 /*
  216  * Issue a reset command to the controller and look for the bits in
  217  * RX2CS and RX2ES.
  218  * RX2CS_RX02 and / or RX2CS_DD can be set,
  219  * RX2ES has to be set, all other bits must be 0
  220  */
  221 int
  222 rfc_match(device_t parent, cfdata_t match, void *aux)
  223 {
  224         struct uba_attach_args *ua = aux;
  225         int i;
  226 
  227         /* Issue reset command. */
  228         bus_space_write_2(ua->ua_iot, ua->ua_ioh, RX2CS, RX2CS_INIT);
  229         /* Wait for the controller to become ready, that is when
  230          * RX2CS_DONE, RX2ES_RDY and RX2ES_ID are set. */
  231         for (i = 0 ; i < 20 ; i++) {
  232                 if ((bus_space_read_2(ua->ua_iot, ua->ua_ioh, RX2CS)
  233                     & RX2CS_DONE) != 0
  234                     && (bus_space_read_2(ua->ua_iot, ua->ua_ioh, RX2ES)
  235                     & (RX2ES_RDY | RX2ES_ID)) != 0)
  236                         break;
  237                 DELAY(100000);  /* wait 100ms */
  238         }
  239         /*
  240          * Give up if the timeout has elapsed
  241          * and the controller is not ready.
  242          */
  243         if (i >= 20)
  244                 return(0);
  245         /*
  246          * Issue a Read Status command with interrupt enabled.
  247          * The uba(4) driver wants to catch the interrupt to get the
  248          * interrupt vector and level of the device
  249          */
  250         bus_space_write_2(ua->ua_iot, ua->ua_ioh, RX2CS,
  251             RX2CS_RSTAT | RX2CS_IE);
  252         /*
  253          * Wait for command to finish, ignore errors and
  254          * abort if the controller does not respond within the timeout
  255          */
  256         for (i = 0 ; i < 20 ; i++) {
  257                 if ((bus_space_read_2(ua->ua_iot, ua->ua_ioh, RX2CS)
  258                     & (RX2CS_DONE | RX2CS_IE)) != 0
  259                     && (bus_space_read_2(ua->ua_iot, ua->ua_ioh, RX2ES)
  260                     & RX2ES_RDY) != 0 )
  261                         return(1);
  262                 DELAY(100000);  /* wait 100ms */
  263         }
  264         return(0);
  265 }
  266 
  267 
  268 
  269 /* #define RX02_PROBE 1 */
  270 #ifdef RX02_PROBE
  271 /*
  272  * Probe the density of an inserted floppy disk.
  273  * This is done by reading a sector from disk.
  274  * Return -1 on error, 0 on SD and 1 on DD.
  275  */
  276 int rfcprobedens(struct rfc_softc *, int);
  277 int
  278 rfcprobedens(struct rfc_softc *rfc_sc, int dnum)
  279 {
  280         int dens_flag;
  281         int i;
  282 
  283         dens_flag = 0;
  284         do {
  285                 bus_space_write_2(rfc_sc->sc_iot, rfc_sc->sc_ioh, RX2CS,
  286                     RX2CS_RSEC | (dens_flag == 0 ? 0 : RX2CS_DD)
  287                     | (dnum == 0 ? 0 : RX2CS_US));
  288                 /*
  289                  * Transfer request set?
  290                  * Wait 50us, the controller needs this time to setle
  291                  */
  292                 DELAY(50);
  293                 if ((bus_space_read_2(rfc_sc->sc_iot, rfc_sc->sc_ioh, RX2CS)
  294                     & RX2CS_TR) == 0) {
  295                         printf("%s: did not respond to Read Sector CMD(1)\n",
  296                             device_xname(rfc_sc->sc_dev));
  297                         return(-1);
  298                 }
  299                 bus_space_write_2(rfc_sc->sc_iot, rfc_sc->sc_ioh, RX2SA, 1);
  300                 /* Wait 50us, the controller needs this time to setle */
  301                 DELAY(50);
  302                 if ((bus_space_read_2(rfc_sc->sc_iot, rfc_sc->sc_ioh, RX2CS)
  303                     & RX2CS_TR) == 0) {
  304                         printf("%s: did not respond to Read Sector CMD(2)\n",
  305                             device_xname(rfc_sc->sc_dev));
  306                         return(-1);
  307                 }
  308                 bus_space_write_2(rfc_sc->sc_iot, rfc_sc->sc_ioh, RX2TA, 1);
  309                 /* Wait for the command to finish */
  310                 for (i = 0 ; i < 200 ; i++) {
  311                         if ((bus_space_read_2(rfc_sc->sc_iot, rfc_sc->sc_ioh,
  312                             RX2CS) & RX2CS_DONE) != 0)
  313                                 break;
  314                         DELAY(10000);   /* wait 10ms */
  315                 }
  316                 if (i >= 200) {
  317                         printf("%s: did not respond to Read Sector CMD(3)\n",
  318                             device_xname(rfc_sc->sc_dev));
  319                         return(-1);
  320                 }
  321                 if ((bus_space_read_2(rfc_sc->sc_iot, rfc_sc->sc_ioh, RX2CS)
  322                     & RX2CS_ERR) == 0)
  323                         return(dens_flag);
  324         } while (rfc_sc->type == 2 && dens_flag++ == 0);
  325         return(-1);
  326 }
  327 #endif /* RX02_PROBE */
  328 
  329 
  330 
  331 void
  332 rfc_attach(device_t parent, device_t self, void *aux)
  333 {
  334         struct rfc_softc *rfc_sc = device_private(self);
  335         struct uba_attach_args *ua = aux;
  336         struct rfc_attach_args rfc_aa;
  337         int i;
  338 
  339         rfc_sc->sc_dev = self;
  340         rfc_sc->sc_iot = ua->ua_iot;
  341         rfc_sc->sc_ioh = ua->ua_ioh;
  342         rfc_sc->sc_dmat = ua->ua_dmat;
  343         rfc_sc->sc_curbuf = NULL;
  344         /* Tell the QBus busdriver about our interrupt handler. */
  345         uba_intr_establish(ua->ua_icookie, ua->ua_cvec, rfc_intr, rfc_sc,
  346             &rfc_sc->sc_intr_count);
  347         /* Attach to the interrupt counter, see evcnt(9) */
  348         evcnt_attach_dynamic(&rfc_sc->sc_intr_count, EVCNT_TYPE_INTR,
  349             ua->ua_evcnt, device_xname(rfc_sc->sc_dev), "intr");
  350         /* get a bus_dma(9) handle */
  351         i = bus_dmamap_create(rfc_sc->sc_dmat, RX2_BYTE_DD, 1, RX2_BYTE_DD, 0,
  352             BUS_DMA_ALLOCNOW, &rfc_sc->sc_dmam);
  353         if (i != 0) {
  354                 printf("rfc_attach: Error creating bus dma map: %d\n", i);
  355                 return;
  356         }
  357 
  358         /* Issue reset command. */
  359         bus_space_write_2(rfc_sc->sc_iot, rfc_sc->sc_ioh, RX2CS, RX2CS_INIT);
  360         /*
  361          * Wait for the controller to become ready, that is when
  362          * RX2CS_DONE, RX2ES_RDY and RX2ES_ID are set.
  363          */
  364         for (i = 0 ; i < 20 ; i++) {
  365                 if ((bus_space_read_2(rfc_sc->sc_iot, rfc_sc->sc_ioh, RX2CS)
  366                     & RX2CS_DONE) != 0
  367                     && (bus_space_read_2(rfc_sc->sc_iot, rfc_sc->sc_ioh, RX2ES)
  368                     & (RX2ES_RDY | RX2ES_ID)) != 0)
  369                         break;
  370                 DELAY(100000);  /* wait 100ms */
  371         }
  372         /*
  373          * Give up if the timeout has elapsed
  374          * and the controller is not ready.
  375          */
  376         if (i >= 20) {
  377                 printf(": did not respond to INIT CMD\n");
  378                 return;
  379         }
  380         /* Is ths a RX01 or a RX02? */
  381         if ((bus_space_read_2(rfc_sc->sc_iot, rfc_sc->sc_ioh, RX2CS)
  382             & RX2CS_RX02) != 0) {
  383                 rfc_sc->type = 2;
  384                 rfc_aa.type = 2;
  385         } else {
  386                 rfc_sc->type = 1;
  387                 rfc_aa.type = 1;
  388         }
  389         printf(": RX0%d\n", rfc_sc->type);
  390 
  391 #ifndef RX02_PROBE
  392         /*
  393          * Bouth disk drievs and the controller are one physical unit.
  394          * If we found the controller, there will be bouth disk drievs.
  395          * So attach them.
  396          */
  397         rfc_aa.dnum = 0;
  398         rfc_sc->sc_childs[0] = config_found(rfc_sc->sc_dev, &rfc_aa, rf_print);
  399         rfc_aa.dnum = 1;
  400         rfc_sc->sc_childs[1] = config_found(rfc_sc->sc_dev, &rfc_aa, rf_print);
  401 #else /* RX02_PROBE */
  402         /*
  403          * There are clones of the DEC RX system with standard shugart
  404          * interface. In this case we can not be sure that there are
  405          * bouth disk drievs. So we want to do a detection of attached
  406          * drives. This is done by reading a sector from disk. This means
  407          * that there must be a formatted disk in the drive at boot time.
  408          * This is bad, but I did not find another way to detect the
  409          * (non)existence of a floppy drive.
  410          */
  411         if (rfcprobedens(rfc_sc, 0) >= 0) {
  412                 rfc_aa.dnum = 0;
  413                 rfc_sc->sc_childs[0] = config_found(&rfc_sc->sc_dev, &rfc_aa,
  414                     rf_print);
  415         } else
  416                 rfc_sc->sc_childs[0] = NULL;
  417         if (rfcprobedens(rfc_sc, 1) >= 0) {
  418                 rfc_aa.dnum = 1;
  419                 rfc_sc->sc_childs[1] = config_found(&rfc_sc->sc_dev, &rfc_aa,
  420                     rf_print);
  421         } else
  422                 rfc_sc->sc_childs[1] = NULL;
  423 #endif /* RX02_PROBE */
  424         return;
  425 }
  426 
  427 
  428 
  429 int
  430 rf_match(device_t parent, cfdata_t match, void *aux)
  431 {
  432         struct rfc_attach_args *rfc_aa = aux;
  433 
  434         /*
  435          * Only attach if the locator is wildcarded or
  436          * if the specified locator addresses the current device.
  437          */
  438         if (match->cf_loc[RFCCF_DRIVE] == RFCCF_DRIVE_DEFAULT ||
  439             match->cf_loc[RFCCF_DRIVE] == rfc_aa->dnum)
  440                 return(1);
  441         return(0);
  442 }
  443 
  444 
  445 
  446 void
  447 rf_attach(device_t parent, device_t self, void *aux)
  448 {
  449         struct rf_softc *rf_sc = device_private(self);
  450         struct rfc_softc *rfc_sc = device_private(parent);
  451         struct rfc_attach_args *rfc_aa = (struct rfc_attach_args *)aux;
  452         struct disklabel *dl;
  453 
  454         rf_sc->sc_dev = self;
  455         rf_sc->sc_rfc = rfc_sc;
  456         rf_sc->sc_dnum = rfc_aa->dnum;
  457         rf_sc->sc_state = 0;
  458         disk_init(&rf_sc->sc_disk, device_xname(rf_sc->sc_dev), &rfdkdriver);
  459         disk_attach(&rf_sc->sc_disk);
  460         dl = rf_sc->sc_disk.dk_label;
  461         dl->d_type = DTYPE_FLOPPY;              /* drive type */
  462         dl->d_magic = DISKMAGIC;                /* the magic number */
  463         dl->d_magic2 = DISKMAGIC;
  464         dl->d_typename[0] = 'R';
  465         dl->d_typename[1] = 'X';
  466         dl->d_typename[2] = '';
  467         dl->d_typename[3] = rfc_sc->type == 1 ? '1' : '2';      /* type name */
  468         dl->d_typename[4] = '\0';
  469         dl->d_secsize = DEV_BSIZE;              /* bytes per sector */
  470         /*
  471          * Fill in some values to have a initialized data structure. Some
  472          * values will be reset by rfopen() depending on the actual density.
  473          */
  474         dl->d_nsectors = RX2_SECTORS;           /* sectors per track */
  475         dl->d_ntracks = 1;                                                              /* tracks per cylinder */
  476         dl->d_ncylinders = RX2_TRACKS;          /* cylinders per unit */
  477         dl->d_secpercyl = RX2_SECTORS;          /* sectors per cylinder */
  478         dl->d_secperunit = RX2_SECTORS * RX2_TRACKS;    /* sectors per unit */
  479         dl->d_rpm = 360;                        /* rotational speed */
  480         dl->d_interleave = 1;                   /* hardware sector interleave */
  481         /* number of partitions in following */
  482         dl->d_npartitions = MAXPARTITIONS;
  483         dl->d_bbsize = 0;               /* size of boot area at sn0, bytes */
  484         dl->d_sbsize = 0;               /* max size of fs superblock, bytes */
  485         /* number of sectors in partition */
  486         dl->d_partitions[0].p_size = 501;
  487         dl->d_partitions[0].p_offset = 0;       /* starting sector */
  488         dl->d_partitions[0].p_fsize = 0;        /* fs basic fragment size */
  489         dl->d_partitions[0].p_fstype = 0;       /* fs type */
  490         dl->d_partitions[0].p_frag = 0;         /* fs fragments per block */
  491         dl->d_partitions[1].p_size = RX2_SECTORS * RX2_TRACKS / 2;
  492         dl->d_partitions[1].p_offset = 0;       /* starting sector */
  493         dl->d_partitions[1].p_fsize = 0;        /* fs basic fragment size */
  494         dl->d_partitions[1].p_fstype = 0;       /* fs type */
  495         dl->d_partitions[1].p_frag = 0;         /* fs fragments per block */
  496         dl->d_partitions[2].p_size = RX2_SECTORS * RX2_TRACKS;
  497         dl->d_partitions[2].p_offset = 0;       /* starting sector */
  498         dl->d_partitions[2].p_fsize = 0;        /* fs basic fragment size */
  499         dl->d_partitions[2].p_fstype = 0;       /* fs type */
  500         dl->d_partitions[2].p_frag = 0;         /* fs fragments per block */
  501         bufq_alloc(&rf_sc->sc_bufq, "disksort", BUFQ_SORT_CYLINDER);
  502         printf("\n");
  503         return;
  504 }
  505 
  506 
  507 
  508 int
  509 rf_print(void *aux, const char *name)
  510 {
  511         struct rfc_attach_args *rfc_aa = aux;
  512 
  513         if (name != NULL)
  514                 aprint_normal("RX0%d at %s", rfc_aa->type, name);
  515         aprint_normal(" drive %d", rfc_aa->dnum);
  516         return(UNCONF);
  517 }
  518 
  519 
  520 
  521 /* Send a command to the controller */
  522 int
  523 rfc_sendcmd(struct rfc_softc *rfc_sc, int cmd, int data1, int data2)
  524 {
  525 
  526         /* Write command to CSR. */
  527         bus_space_write_2(rfc_sc->sc_iot, rfc_sc->sc_ioh, RX2CS, cmd);
  528         /* Wait 50us, the controller needs this time to setle. */
  529         DELAY(50);
  530         /* Write parameter 1 to DBR */
  531         if ((cmd & RX2CS_FC) != RX2CS_RSTAT) {
  532                 /* Transfer request set? */
  533                 if ((bus_space_read_2(rfc_sc->sc_iot, rfc_sc->sc_ioh, RX2CS)
  534                     & RX2CS_TR) == 0) {
  535                         printf("%s: did not respond to CMD %x (1)\n",
  536                             device_xname(rfc_sc->sc_dev), cmd);
  537                         return(-1);
  538                 }
  539                 bus_space_write_2(rfc_sc->sc_iot, rfc_sc->sc_ioh, RX2DB,
  540                     data1);
  541         }
  542         /* Write parameter 2 to DBR */
  543         if ((cmd & RX2CS_FC) <= RX2CS_RSEC || (cmd & RX2CS_FC) == RX2CS_WDDS) {
  544                 /* Wait 50us, the controller needs this time to setle. */
  545                 DELAY(50);
  546                 /* Transfer request set? */
  547                 if ((bus_space_read_2(rfc_sc->sc_iot, rfc_sc->sc_ioh, RX2CS)
  548                     & RX2CS_TR) == 0) {
  549                         printf("%s: did not respond to CMD %x (2)\n",
  550                             device_xname(rfc_sc->sc_dev), cmd);
  551                         return(-1);
  552                 }
  553                 bus_space_write_2(rfc_sc->sc_iot, rfc_sc->sc_ioh, RX2DB,
  554                     data2);
  555         }
  556         return(1);
  557 }
  558 
  559 
  560 
  561 void
  562 rfstrategy(struct buf *buf)
  563 {
  564         struct rf_softc *rf_sc;
  565         struct rfc_softc *rfc_sc;
  566         int s;
  567 
  568         if ((rf_sc = device_lookup_private(&rf_cd, DISKUNIT(buf->b_dev))) == NULL) {
  569                 buf->b_error = ENXIO;
  570                 biodone(buf);
  571                 return;
  572         }
  573         rfc_sc = rf_sc->sc_rfc;
  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", device_xname(rf_sc->sc_dev),
  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         s = 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_data;
  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(s);
  608 }
  609 
  610 /*
  611  * Look if there is another buffer in the bufferqueue of this drive
  612  * and start to process it if there is one.
  613  * If the bufferqueue is empty, look at the bufferqueue of the other drive
  614  * that is attached to this controller.
  615  * Start procesing the bufferqueue of the other drive if it isn't empty.
  616  * Return a pointer to the softc structure of the drive that is now
  617  * ready to process a buffer or NULL if there is no buffer in either queues.
  618  */
  619 struct rf_softc*
  620 get_new_buf( struct rfc_softc *rfc_sc)
  621 {
  622         struct rf_softc *rf_sc;
  623         struct rf_softc *other_drive;
  624 
  625         rf_sc = device_private(rfc_sc->sc_childs[rfc_sc->sc_curchild]);
  626         rfc_sc->sc_curbuf = BUFQ_GET(rf_sc->sc_bufq);
  627         if (rfc_sc->sc_curbuf != NULL) {
  628                 rfc_sc->sc_bufidx = rfc_sc->sc_curbuf->b_data;
  629                 rfc_sc->sc_bytesleft = rfc_sc->sc_curbuf->b_bcount;
  630         } else {
  631                 RFS_SETCMD(rf_sc->sc_state, RFS_IDLE);
  632                 other_drive = device_private(
  633                     rfc_sc->sc_childs[ rfc_sc->sc_curchild == 0 ? 1 : 0]);
  634                 if (other_drive != NULL
  635                     && BUFQ_PEEK(other_drive->sc_bufq) != NULL) {
  636                         rfc_sc->sc_curchild = rfc_sc->sc_curchild == 0 ? 1 : 0;
  637                         rf_sc = other_drive;
  638                         rfc_sc->sc_curbuf = BUFQ_GET(rf_sc->sc_bufq);
  639                         rfc_sc->sc_bufidx = rfc_sc->sc_curbuf->b_data;
  640                         rfc_sc->sc_bytesleft = rfc_sc->sc_curbuf->b_bcount;
  641                 } else
  642                         return(NULL);
  643         }
  644         return(rf_sc);
  645 }
  646 
  647 
  648 
  649 void
  650 rfc_intr(void *intarg)
  651 {
  652         struct rfc_softc *rfc_sc = intarg;
  653         struct rf_softc *rf_sc;
  654         int i;
  655 
  656         rf_sc = device_private(rfc_sc->sc_childs[rfc_sc->sc_curchild]);
  657         for (;;) {
  658                 /*
  659                  * First clean up from previous command...
  660                  */
  661                 switch (rf_sc->sc_state & RFS_CMDS) {
  662                 case RFS_PROBING:       /* density detect / verify started */
  663                         disk_unbusy(&rf_sc->sc_disk, 0, 1);
  664                         if ((bus_space_read_2(rfc_sc->sc_iot, rfc_sc->sc_ioh,
  665                             RX2CS) & RX2CS_ERR) == 0) {
  666                                 RFS_SETCMD(rf_sc->sc_state, RFS_IDLE);
  667                                 wakeup(rf_sc);
  668                         } else {
  669                                 if (rfc_sc->type == 2
  670                                     && (rf_sc->sc_state & RFS_DENS) == 0
  671                                     && (rf_sc->sc_state & RFS_AD) != 0) {
  672                                         /* retry at DD */
  673                                         rf_sc->sc_state |= RFS_DENS;
  674                                         disk_busy(&rf_sc->sc_disk);
  675                                         if (rfc_sendcmd(rfc_sc, RX2CS_RSEC
  676                                             | RX2CS_IE | RX2CS_DD |
  677                                             (rf_sc->sc_dnum == 0 ? 0 :
  678                                             RX2CS_US), 1, 1) < 0) {
  679                                                 disk_unbusy(&rf_sc->sc_disk,
  680                                                     0, 1);
  681                                                 RFS_SETCMD(rf_sc->sc_state,
  682                                                     RFS_NOTINIT);
  683                                                 wakeup(rf_sc);
  684                                         }
  685                                 } else {
  686                                         printf("%s: density error.\n",
  687                                             device_xname(rf_sc->sc_dev));
  688                                         RFS_SETCMD(rf_sc->sc_state,RFS_NOTINIT);
  689                                         wakeup(rf_sc);
  690                                 }
  691                         }
  692                         return;
  693                 case RFS_IDLE:  /* controller is idle */
  694                         if (rfc_sc->sc_curbuf->b_bcount
  695                             % ((rf_sc->sc_state & RFS_DENS) == 0
  696                             ? RX2_BYTE_SD : RX2_BYTE_DD) != 0) {
  697                                 /*
  698                                  * can only handle blocks that are a multiple
  699                                  * of the physical block size
  700                                  */
  701                                 rfc_sc->sc_curbuf->b_error = EIO;
  702                         }
  703                         RFS_SETCMD(rf_sc->sc_state, (rfc_sc->sc_curbuf->b_flags
  704                             & B_READ) != 0 ? RFS_RSEC : RFS_FBUF);
  705                         break;
  706                 case RFS_RSEC:  /* Read Sector */
  707                         disk_unbusy(&rf_sc->sc_disk, 0, 1);
  708                         /* check for errors */
  709                         if ((bus_space_read_2(rfc_sc->sc_iot, rfc_sc->sc_ioh,
  710                             RX2CS) & RX2CS_ERR) != 0) {
  711                                 /* should do more verbose error reporting */
  712                                 printf("rfc_intr: Error reading secotr: %x\n",
  713                                     bus_space_read_2(rfc_sc->sc_iot,
  714                                     rfc_sc->sc_ioh, RX2ES) );
  715                                 rfc_sc->sc_curbuf->b_error = EIO;
  716                         }
  717                         RFS_SETCMD(rf_sc->sc_state, RFS_EBUF);
  718                         break;
  719                 case RFS_WSEC:  /* Write Sector */
  720                         i = (rf_sc->sc_state & RFS_DENS) == 0
  721                                 ? RX2_BYTE_SD : RX2_BYTE_DD;
  722                         disk_unbusy(&rf_sc->sc_disk, i, 0);
  723                         /* check for errors */
  724                         if ((bus_space_read_2(rfc_sc->sc_iot, rfc_sc->sc_ioh,
  725                             RX2CS) & RX2CS_ERR) != 0) {
  726                                 /* should do more verbose error reporting */
  727                                 printf("rfc_intr: Error writing secotr: %x\n",
  728                                     bus_space_read_2(rfc_sc->sc_iot,
  729                                     rfc_sc->sc_ioh, RX2ES) );
  730                                 rfc_sc->sc_curbuf->b_error = EIO;
  731                                 break;
  732                         }
  733                         if (rfc_sc->sc_bytesleft > i) {
  734                                 rfc_sc->sc_bytesleft -= i;
  735                                 rfc_sc->sc_bufidx =
  736                                     (char *)rfc_sc->sc_bufidx + i;
  737                         } else {
  738                                 biodone(rfc_sc->sc_curbuf);
  739                                 rf_sc = get_new_buf( rfc_sc);
  740                                 if (rf_sc == NULL)
  741                                         return;
  742                         }
  743                         RFS_SETCMD(rf_sc->sc_state,
  744                             (rfc_sc->sc_curbuf->b_flags & B_READ) != 0
  745                             ? RFS_RSEC : RFS_FBUF);
  746                         break;
  747                 case RFS_FBUF:  /* Fill Buffer */
  748                         disk_unbusy(&rf_sc->sc_disk, 0, 0);
  749                         bus_dmamap_unload(rfc_sc->sc_dmat, rfc_sc->sc_dmam);
  750                         /* check for errors */
  751                         if ((bus_space_read_2(rfc_sc->sc_iot, rfc_sc->sc_ioh,
  752                             RX2CS) & RX2CS_ERR) != 0) {
  753                                 /* should do more verbose error reporting */
  754                                 printf("rfc_intr: Error while DMA: %x\n",
  755                                     bus_space_read_2(rfc_sc->sc_iot,
  756                                     rfc_sc->sc_ioh, RX2ES));
  757                                 rfc_sc->sc_curbuf->b_error = EIO;
  758                         }
  759                         RFS_SETCMD(rf_sc->sc_state, RFS_WSEC);
  760                         break;
  761                 case RFS_EBUF:  /* Empty Buffer */
  762                         i = (rf_sc->sc_state & RFS_DENS) == 0
  763                             ? RX2_BYTE_SD : RX2_BYTE_DD;
  764                         disk_unbusy(&rf_sc->sc_disk, i, 1);
  765                         bus_dmamap_unload(rfc_sc->sc_dmat, rfc_sc->sc_dmam);
  766                         /* check for errors */
  767                         if ((bus_space_read_2(rfc_sc->sc_iot, rfc_sc->sc_ioh,
  768                             RX2CS) & RX2CS_ERR) != 0) {
  769                                 /* should do more verbose error reporting */
  770                                 printf("rfc_intr: Error while DMA: %x\n",
  771                                     bus_space_read_2(rfc_sc->sc_iot,
  772                                     rfc_sc->sc_ioh, RX2ES));
  773                                 rfc_sc->sc_curbuf->b_error = EIO;
  774                                 break;
  775                         }
  776                         if (rfc_sc->sc_bytesleft > i) {
  777                                 rfc_sc->sc_bytesleft -= i;
  778                                 rfc_sc->sc_bufidx =
  779                                     (char *)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): 0x%x\n",
  797                             rf_sc->sc_state & RFS_CMDS);
  798                 }
  799 
  800                 if (rfc_sc->sc_curbuf->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_error = EIO;
  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_error = EIO;
  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_error = EIO;
  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_error = EIO;
  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_error = EIO;
  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_error = EIO;
  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_error = EIO;
  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_error = EIO;
  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): 0x%x\n",
  916                             rf_sc->sc_state & RFS_CMDS);
  917                 }
  918 
  919                 if (rfc_sc->sc_curbuf->b_error != 0) {
  920                         /*
  921                          * An error occurred while processing this buffer.
  922                          * Finish it and try to get a new buffer to process.
  923                          * Return if there are no buffers in the queues.
  924                          * This loops until the queues are empty or a new
  925                          * action was successfully scheduled.
  926                          */
  927                         rfc_sc->sc_curbuf->b_resid = rfc_sc->sc_bytesleft;
  928                         rfc_sc->sc_curbuf->b_error = EIO;
  929                         biodone(rfc_sc->sc_curbuf);
  930                         rf_sc = get_new_buf( rfc_sc);
  931                         if (rf_sc == NULL)
  932                                 return;
  933                         continue;
  934                 }
  935                 break;
  936         }
  937         return;
  938 }
  939 
  940 
  941 
  942 int
  943 rfdump(dev_t dev, daddr_t blkno, void *va, size_t size)
  944 {
  945 
  946         /* A 0.5MB floppy is much to small to take a system dump... */
  947         return(ENXIO);
  948 }
  949 
  950 
  951 
  952 int
  953 rfsize(dev_t dev)
  954 {
  955 
  956         return(-1);
  957 }
  958 
  959 
  960 
  961 int
  962 rfopen(dev_t dev, int oflags, int devtype, struct lwp *l)
  963 {
  964         struct rf_softc *rf_sc;
  965         struct rfc_softc *rfc_sc;
  966         struct disklabel *dl;
  967 
  968         if ((rf_sc = device_lookup_private(&rf_cd, DISKUNIT(dev))) == NULL)
  969                 return ENXIO;
  970 
  971         rfc_sc = rf_sc->sc_rfc;
  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 lwp *l)
 1054 {
 1055         struct rf_softc *rf_sc = device_lookup_private(&rf_cd, DISKUNIT(dev));
 1056 
 1057         if ((rf_sc->sc_state & 1 << (DISKPART(dev) + RFS_OPEN_SHIFT)) == 0)
 1058                 panic("rfclose: can not close non-open drive %s "
 1059                     "partition %d", device_xname(rf_sc->sc_dev), DISKPART(dev));
 1060         else
 1061                 rf_sc->sc_state &= ~(1 << (DISKPART(dev) + RFS_OPEN_SHIFT));
 1062         if ((rf_sc->sc_state & RFS_OPEN_MASK) == 0)
 1063                 rf_sc->sc_state = 0;
 1064         return(0);
 1065 }
 1066 
 1067 
 1068 
 1069 int
 1070 rfread(dev_t dev, struct uio *uio, int ioflag)
 1071 {
 1072 
 1073         return(physio(rfstrategy, NULL, dev, B_READ, minphys, uio));
 1074 }
 1075 
 1076 
 1077 
 1078 int
 1079 rfwrite(dev_t dev, struct uio *uio, int ioflag)
 1080 {
 1081 
 1082         return(physio(rfstrategy, NULL, dev, B_WRITE, minphys, uio));
 1083 }
 1084 
 1085 
 1086 
 1087 int
 1088 rfioctl(dev_t dev, u_long cmd, void *data, int fflag, struct lwp *l)
 1089 {
 1090         struct rf_softc *rf_sc = device_lookup_private(&rf_cd, DISKUNIT(dev));
 1091 
 1092         /* We are going to operate on a non-open dev? PANIC! */
 1093         if ((rf_sc->sc_state & 1 << (DISKPART(dev) + RFS_OPEN_SHIFT)) == 0)
 1094                 panic("rfioctl: can not operate on non-open drive %s "
 1095                     "partition %d", device_xname(rf_sc->sc_dev), DISKPART(dev));
 1096         switch (cmd) {
 1097         /* get and set disklabel; DIOCGPART used internally */
 1098         case DIOCGDINFO: /* get */
 1099                 memcpy(data, rf_sc->sc_disk.dk_label,
 1100                     sizeof(struct disklabel));
 1101                 return(0);
 1102         case DIOCSDINFO: /* set */
 1103                 return(0);
 1104         case DIOCWDINFO: /* set, update disk */
 1105                 return(0);
 1106         case DIOCGPART:  /* get partition */
 1107                 ((struct partinfo *)data)->disklab = rf_sc->sc_disk.dk_label;
 1108                 ((struct partinfo *)data)->part =
 1109                     &rf_sc->sc_disk.dk_label->d_partitions[DISKPART(dev)];
 1110                 return(0);
 1111 
 1112         /* do format operation, read or write */
 1113         case DIOCRFORMAT:
 1114         break;
 1115         case DIOCWFORMAT:
 1116         break;
 1117 
 1118         case DIOCSSTEP: /* set step rate */
 1119         break;
 1120         case DIOCSRETRIES: /* set # of retries */
 1121         break;
 1122         case DIOCKLABEL: /* keep/drop label on close? */
 1123         break;
 1124         case DIOCWLABEL: /* write en/disable label */
 1125         break;
 1126 
 1127 /*      case DIOCSBAD: / * set kernel dkbad */
 1128         break; /* */
 1129         case DIOCEJECT: /* eject removable disk */
 1130         break;
 1131         case ODIOCEJECT: /* eject removable disk */
 1132         break;
 1133         case DIOCLOCK: /* lock/unlock pack */
 1134         break;
 1135 
 1136         /* get default label, clear label */
 1137         case DIOCGDEFLABEL:
 1138         break;
 1139         case DIOCCLRLABEL:
 1140         break;
 1141         default:
 1142                 return(ENOTTY);
 1143         }
 1144 
 1145         return(ENOTTY);
 1146 }
 1147 
 1148 

Cache object: 3dc9eb8aa935ff392916d1803635976b


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