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/ida/ida_disk.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * Copyright (c) 1999,2000 Jonathan Lemon
    3  * All rights reserved.
    4  *
    5  * Redistribution and use in source and binary forms, with or without
    6  * modification, are permitted provided that the following conditions
    7  * are met:
    8  * 1. Redistributions of source code must retain the above copyright
    9  *    notice, this list of conditions and the following disclaimer.
   10  * 2. Redistributions in binary form must reproduce the above copyright
   11  *    notice, this list of conditions and the following disclaimer in the
   12  *    documentation and/or other materials provided with the distribution.
   13  *
   14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   24  * SUCH DAMAGE.
   25  *
   26  * $FreeBSD: releng/8.3/sys/dev/ida/ida_disk.c 146734 2005-05-29 04:42:30Z nyan $
   27  */
   28 
   29 /*
   30  * Disk driver for Compaq SMART RAID adapters.
   31  */
   32 
   33 #include <sys/param.h>
   34 #include <sys/systm.h>
   35 #include <sys/kernel.h>
   36 #include <sys/module.h>
   37 
   38 #include <sys/bio.h>
   39 #include <sys/bus.h>
   40 #include <sys/conf.h>
   41 #include <sys/cons.h>
   42 
   43 #include <machine/bus.h>
   44 #include <sys/rman.h>
   45 
   46 #include <vm/vm.h>
   47 #include <vm/pmap.h>
   48 #include <machine/md_var.h>
   49 
   50 #include <geom/geom_disk.h>
   51 
   52 #include <dev/ida/idareg.h>
   53 #include <dev/ida/idavar.h>
   54 
   55 /* prototypes */
   56 static int idad_probe(device_t dev);
   57 static int idad_attach(device_t dev);
   58 static int idad_detach(device_t dev);
   59 
   60 static  d_strategy_t    idad_strategy;
   61 static  dumper_t        idad_dump;
   62 
   63 static devclass_t       idad_devclass;
   64 
   65 static device_method_t idad_methods[] = {
   66         DEVMETHOD(device_probe,         idad_probe),
   67         DEVMETHOD(device_attach,        idad_attach),
   68         DEVMETHOD(device_detach,        idad_detach),
   69         { 0, 0 }
   70 };
   71 
   72 static driver_t idad_driver = {
   73         "idad",
   74         idad_methods,
   75         sizeof(struct idad_softc)
   76 };
   77 
   78 DRIVER_MODULE(idad, ida, idad_driver, idad_devclass, 0, 0);
   79 
   80 /*
   81  * Read/write routine for a buffer.  Finds the proper unit, range checks
   82  * arguments, and schedules the transfer.  Does not wait for the transfer
   83  * to complete.  Multi-page transfers are supported.  All I/O requests must
   84  * be a multiple of a sector in length.
   85  */
   86 static void
   87 idad_strategy(struct bio *bp)
   88 {
   89         struct idad_softc *drv;
   90         int s;
   91 
   92         drv = bp->bio_disk->d_drv1;
   93         if (drv == NULL) {
   94                 bp->bio_error = EINVAL;
   95                 goto bad;
   96         }
   97 
   98         /*
   99          * software write protect check
  100          */
  101         if (drv->flags & DRV_WRITEPROT && (bp->bio_cmd == BIO_WRITE)) {
  102                 bp->bio_error = EROFS;
  103                 goto bad;
  104         }
  105 
  106         bp->bio_driver1 = drv;
  107         s = splbio();
  108         ida_submit_buf(drv->controller, bp);
  109         splx(s);
  110         return;
  111 
  112 bad:
  113         bp->bio_flags |= BIO_ERROR;
  114 
  115         /*
  116          * Correctly set the buf to indicate a completed transfer
  117          */
  118         bp->bio_resid = bp->bio_bcount;
  119         biodone(bp);
  120         return;
  121 }
  122 
  123 static int
  124 idad_dump(void *arg, void *virtual, vm_offset_t physical, off_t offset, size_t length)
  125 {
  126 
  127         struct idad_softc *drv;
  128         int error = 0;
  129         struct disk *dp;
  130 
  131         dp = arg;
  132         drv = dp->d_drv1;
  133         if (drv == NULL)
  134                 return (ENXIO);
  135 
  136         drv->controller->flags &= ~IDA_INTERRUPTS;
  137 
  138         if (length > 0) {
  139                 error = ida_command(drv->controller, CMD_WRITE, virtual,
  140                     length, drv->drive, offset / DEV_BSIZE, DMA_DATA_OUT);
  141         }
  142         drv->controller->flags |= IDA_INTERRUPTS;
  143         return (error);
  144 }
  145 
  146 void
  147 idad_intr(struct bio *bp)
  148 {
  149         struct idad_softc *drv;
  150 
  151         drv = bp->bio_disk->d_drv1;
  152 
  153         if (bp->bio_flags & BIO_ERROR)
  154                 bp->bio_error = EIO;
  155         else
  156                 bp->bio_resid = 0;
  157 
  158         biodone(bp);
  159 }
  160 
  161 static int
  162 idad_probe(device_t dev)
  163 {
  164 
  165         device_set_desc(dev, "Compaq Logical Drive");
  166         return (0);
  167 }
  168 
  169 static int
  170 idad_attach(device_t dev)
  171 {
  172         struct ida_drive_info dinfo;
  173         struct idad_softc *drv;
  174         device_t parent;
  175         int error;
  176 
  177         drv = (struct idad_softc *)device_get_softc(dev);
  178         parent = device_get_parent(dev);
  179         drv->dev = dev;
  180         drv->controller = (struct ida_softc *)device_get_softc(parent);
  181         drv->unit = device_get_unit(dev);
  182         drv->drive = drv->controller->num_drives;
  183         drv->controller->num_drives++;
  184 
  185         error = ida_command(drv->controller, CMD_GET_LOG_DRV_INFO,
  186             &dinfo, sizeof(dinfo), drv->drive, 0, DMA_DATA_IN);
  187         if (error) {
  188                 device_printf(dev, "CMD_GET_LOG_DRV_INFO failed\n");
  189                 return (ENXIO);
  190         }
  191 
  192         drv->cylinders = dinfo.dp.ncylinders;
  193         drv->heads = dinfo.dp.nheads;
  194         drv->sectors = dinfo.dp.nsectors;
  195         drv->secsize = dinfo.secsize == 0 ? 512 : dinfo.secsize;
  196         drv->secperunit = dinfo.secperunit;
  197 
  198         /* XXX
  199          * other initialization
  200          */
  201         device_printf(dev, "%uMB (%u sectors), blocksize=%d\n",
  202             drv->secperunit / ((1024 * 1024) / drv->secsize),
  203             drv->secperunit, drv->secsize);
  204 
  205         drv->disk = disk_alloc();
  206         drv->disk->d_strategy = idad_strategy;
  207         drv->disk->d_name = "idad";
  208         drv->disk->d_dump = idad_dump;
  209         drv->disk->d_sectorsize = drv->secsize;
  210         drv->disk->d_mediasize = (off_t)drv->secperunit * drv->secsize;
  211         drv->disk->d_fwsectors = drv->sectors;
  212         drv->disk->d_fwheads = drv->heads;
  213         drv->disk->d_drv1 = drv;
  214         drv->disk->d_maxsize = DFLTPHYS;                /* XXX guess? */
  215         drv->disk->d_unit = drv->unit;
  216         drv->disk->d_flags = DISKFLAG_NEEDSGIANT;
  217         disk_create(drv->disk, DISK_VERSION);
  218 
  219         return (0);
  220 }
  221 
  222 static int
  223 idad_detach(device_t dev)
  224 {
  225         struct idad_softc *drv;
  226 
  227         drv = (struct idad_softc *)device_get_softc(dev);
  228         disk_destroy(drv->disk);
  229         return (0);
  230 }

Cache object: 59c1e333c4d31c466b3d7a41ec82d2cb


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