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

Cache object: 843cb29d07427432fd19b4a396d9a9ed


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