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/scsi/sd.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  * Written by Julian Elischer (julian@dialix.oz.au)
    3  * for TRW Financial Systems for use under the MACH(2.5) operating system.
    4  *
    5  * TRW Financial Systems, in accordance with their agreement with Carnegie
    6  * Mellon University, makes this software available to CMU to distribute
    7  * or use in any manner that they see fit as long as this message is kept with
    8  * the software. For this reason TFS also grants any other persons or
    9  * organisations permission to use or modify this software.
   10  *
   11  * TFS supplies this software to be publicly redistributed
   12  * on the understanding that TFS is not responsible for the correct
   13  * functioning of this software in any circumstances.
   14  *
   15  * Ported to run under 386BSD by Julian Elischer (julian@dialix.oz.au) Sept 1992
   16  *
   17  * $FreeBSD: src/sys/scsi/sd.c,v 1.95.2.11 1999/09/05 08:21:49 peter Exp $
   18  */
   19 
   20 #include "opt_bounce.h"
   21 #include "opt_scsi.h"
   22 
   23 #define SPLSD splbio
   24 #include <sys/param.h>
   25 #include <sys/kernel.h>
   26 #include <sys/dkbad.h>
   27 #include <sys/systm.h>
   28 #include <sys/ioctl.h>
   29 #include <sys/buf.h>
   30 #include <sys/disklabel.h>
   31 #include <sys/diskslice.h>
   32 #include <sys/dkstat.h>
   33 #include <sys/errno.h>
   34 #include <sys/malloc.h>
   35 #include <sys/conf.h>
   36 #ifdef DEVFS
   37 #include <sys/devfsext.h>
   38 #endif /*DEVFS*/
   39 
   40 #include <scsi/scsi_all.h>
   41 #include <scsi/scsi_disk.h>
   42 #include <scsi/scsiconf.h>
   43 
   44 #include <vm/vm.h>
   45 #include <vm/vm_param.h>
   46 #include <vm/vm_prot.h>
   47 #include <vm/pmap.h>
   48 #include <machine/md_var.h>
   49 #include <i386/i386/cons.h>             /* XXX *//* for aborting dump */
   50 #ifdef PC98
   51 #include <pc98/pc98/pc98_machdep.h>
   52 #endif
   53 
   54 static u_int32_t sdstrats, sdqueues;
   55 
   56 #define SECSIZE 512
   57 #ifdef PC98
   58 #define SDOUTSTANDING   2
   59 #else
   60 #define SDOUTSTANDING   4
   61 #endif
   62 #define SD_RETRIES      4
   63 #define MAXTRANSFER     8               /* 1 page at a time */
   64 
   65 #define PARTITION(dev)  dkpart(dev)
   66 #define SDUNIT(dev)     dkunit(dev)
   67 
   68 /* XXX introduce a dkmodunit() macro for this. */
   69 #define SDSETUNIT(DEV, U) \
   70  makedev(major(DEV), dkmakeminor((U), dkslice(DEV), dkpart(DEV)))
   71 
   72 static errval   sd_get_parms __P((int unit, int flags));
   73 static errval   sd_reassign_blocks __P((int unit, int block));
   74 static u_int32_t        sd_size __P((int unit, int flags, int *secsize));
   75 static  void    sdstrategy1 __P((struct buf *));
   76 
   77 static int              sd_sense_handler __P((struct scsi_xfer *));
   78 static void    sdstart __P((u_int32_t, u_int32_t));
   79 
   80 struct scsi_data {
   81         u_int32_t flags;
   82 #define SDINIT          0x04    /* device has been init'd */
   83         struct disk_parms {
   84                 u_char  heads;  /* Number of heads */
   85                 u_int16_t cyls; /* Number of cylinders */
   86                 u_char  sectors;        /*dubious *//* Number of sectors/track */
   87                 u_int16_t secsiz;       /* Number of bytes/sector */
   88                 u_int32_t disksize;     /* total number sectors */
   89         } params;
   90         struct diskslices *dk_slices;   /* virtual drives */
   91         struct buf_queue_head buf_queue;
   92         int dkunit;             /* disk stats unit number */
   93 #ifdef  DEVFS
   94         void    *b_devfs_token;
   95         void    *c_devfs_token;
   96         void    *ctl_devfs_token;
   97 #endif
   98 };
   99 
  100 static int sdunit(dev_t dev) { return SDUNIT(dev); }
  101 static dev_t sdsetunit(dev_t dev, int unit) { return SDSETUNIT(dev, unit); }
  102 
  103 static errval sd_open __P((dev_t dev, int mode, int fmt, struct proc *p,
  104                     struct scsi_link *sc_link));
  105 static errval sd_ioctl(dev_t dev, int cmd, caddr_t addr, int flag,
  106                 struct proc *p, struct scsi_link *sc_link);
  107 static errval sd_close __P((dev_t dev, int fflag, int fmt, struct proc *p,
  108                      struct scsi_link *sc_link));
  109 static void sd_strategy(struct buf *bp, struct scsi_link *sc_link);
  110 
  111 static  d_open_t        sdopen;
  112 static  d_close_t       sdclose;
  113 static  d_ioctl_t       sdioctl;
  114 static  d_dump_t        sddump;
  115 static  d_psize_t       sdsize;
  116 static  d_strategy_t    sdstrategy;
  117 
  118 #define CDEV_MAJOR 13
  119 #define BDEV_MAJOR 4
  120 static struct cdevsw sd_cdevsw;
  121 static struct bdevsw sd_bdevsw = 
  122         { sdopen,       sdclose,        sdstrategy,     sdioctl,        /*4*/
  123           sddump,       sdsize,         0,      "sd",   &sd_cdevsw,     -1 };
  124 
  125 
  126 
  127 SCSI_DEVICE_ENTRIES(sd)
  128 
  129 static struct scsi_device sd_switch =
  130 {
  131         sd_sense_handler,
  132         sdstart,                        /* have a queue, served by this */
  133         NULL,                   /* have no async handler */
  134         NULL,                   /* Use default 'done' routine */
  135         "sd",
  136         0,
  137         {0, 0},
  138         0,                              /* Link flags */
  139         sdattach,
  140         "Direct-Access",
  141         sdopen,
  142         sizeof(struct scsi_data),
  143         T_DIRECT,
  144         sdunit,
  145         sdsetunit,
  146         sd_open,
  147         sd_ioctl,
  148         sd_close,
  149         sd_strategy,
  150 };
  151 
  152 static struct scsi_xfer sx;
  153 
  154 
  155 static __inline void
  156 sd_registerdev(int unit)
  157 {
  158         if(dk_ndrive < DK_NDRIVE) {
  159                 sprintf(dk_names[dk_ndrive], "sd%d", unit);
  160                 dk_wpms[dk_ndrive] = (8*1024*1024/2);
  161                 SCSI_DATA(&sd_switch, unit)->dkunit = dk_ndrive++;
  162         } else {
  163                 SCSI_DATA(&sd_switch, unit)->dkunit = -1;
  164         }
  165 }
  166 
  167 
  168 /*
  169  * The routine called by the low level scsi routine when it discovers
  170  * a device suitable for this driver.
  171  */
  172 static errval
  173 sdattach(struct scsi_link *sc_link)
  174 {
  175         u_int32_t unit;
  176         struct disk_parms *dp;
  177 #ifdef DEVFS
  178         int     mynor;
  179 #endif
  180 
  181         struct scsi_data *sd = sc_link->sd;
  182 
  183         unit = sc_link->dev_unit;
  184 
  185         dp = &(sd->params);
  186 
  187         if (sc_link->opennings > SDOUTSTANDING)
  188                 sc_link->opennings = SDOUTSTANDING;
  189 
  190         bufq_init(&sd->buf_queue);
  191         /*
  192          * In case it is a funny one, tell it to start
  193          * not needed for  most hard drives (ignore failure)
  194          */
  195         scsi_start_unit(sc_link,
  196                         SCSI_ERR_OK | SCSI_SILENT | SCSI_NOSLEEP | SCSI_NOMASK);
  197         /*
  198          * Use the subdriver to request information regarding
  199          * the drive. We cannot use interrupts yet, so the
  200          * request must specify this.
  201          */
  202         sd_get_parms(unit, SCSI_NOSLEEP | SCSI_NOMASK);
  203         /*
  204          * if we don't have actual parameters, assume 512 bytes/sec
  205          * (could happen on removable media - MOD)
  206          * -- this avoids the division below from falling over
  207          */
  208         if(dp->secsiz == 0) dp->secsiz = SECSIZE;
  209         printf("%ldMB (%ld %d byte sectors)",
  210             dp->disksize / ((1024L * 1024L) / dp->secsiz),
  211             dp->disksize,
  212             dp->secsiz);
  213 
  214 #ifndef SCSI_REPORT_GEOMETRY
  215         if ( (sc_link->flags & SDEV_BOOTVERBOSE) )
  216 #endif
  217         {
  218                 sc_print_addr(sc_link);
  219                 printf("with %d cyls, %d heads, and an average %d sectors/track",
  220                 dp->cyls, dp->heads, dp->sectors);
  221         }
  222 
  223         sd->flags |= SDINIT;
  224         sd_registerdev(unit);
  225 
  226 #ifdef DEVFS
  227         mynor = dkmakeminor(unit, WHOLE_DISK_SLICE, RAW_PART);
  228         sd->b_devfs_token = devfs_add_devswf(&sd_bdevsw, mynor, DV_BLK,
  229                                              UID_ROOT, GID_OPERATOR, 0640,
  230                                              "sd%d", unit);
  231         sd->c_devfs_token = devfs_add_devswf(&sd_cdevsw, mynor, DV_CHR,
  232                                              UID_ROOT, GID_OPERATOR, 0640,
  233                                              "rsd%d", unit);
  234         mynor = dkmakeminor(unit, 0, 0);        /* XXX */
  235         sd->ctl_devfs_token = devfs_add_devswf(&sd_cdevsw,
  236                                                mynor | SCSI_CONTROL_MASK,
  237                                                DV_CHR,
  238                                                UID_ROOT, GID_WHEEL, 0600,
  239                                                "rsd%d.ctl", unit);
  240 #endif
  241 
  242         return 0;
  243 }
  244 
  245 /*
  246  * open the device. Make sure the partition info is a up-to-date as can be.
  247  */
  248 static errval
  249 sd_open(dev, mode, fmt, p, sc_link)
  250         dev_t   dev;
  251         int     mode;
  252         int     fmt;
  253         struct proc *p;
  254         struct scsi_link *sc_link;
  255 {
  256         errval  errcode = 0;
  257         u_int32_t unit;
  258         struct disklabel label;
  259         struct scsi_data *sd;
  260 
  261         unit = SDUNIT(dev);
  262         sd = sc_link->sd;
  263 
  264         /*
  265          * Make sure the disk has been initialised
  266          * At some point in the future, get the scsi driver
  267          * to look for a new device if we are not initted
  268          */
  269         if ((!sd) || (!(sd->flags & SDINIT))) {
  270                 return (ENXIO);
  271         }
  272 
  273         SC_DEBUG(sc_link, SDEV_DB1,
  274             ("sd_open: dev=0x%lx (unit %ld, partition %d)\n",
  275                 dev, unit, PARTITION(dev)));
  276 
  277         /*
  278          * "unit attention" errors should occur here if the
  279          * drive has been restarted or the pack changed.
  280          * just ingnore the result, it's a decoy instruction
  281          * The error handlers will act on the error though
  282          * and invalidate any media information we had.
  283          */
  284         scsi_test_unit_ready(sc_link, 0);
  285 
  286         /*
  287          * If it's been invalidated, then forget the label
  288          */
  289         sc_link->flags |= SDEV_OPEN;    /* unit attn becomes an err now */
  290         if (!(sc_link->flags & SDEV_MEDIA_LOADED) && sd->dk_slices != NULL) {
  291                 /*
  292                  * If somebody still has it open, then forbid re-entry.
  293                  */
  294                 if (dsisopen(sd->dk_slices)) {
  295                         errcode = ENXIO;
  296                         goto bad;
  297                 }
  298 
  299                 dsgone(&sd->dk_slices);
  300         }
  301 
  302         /*
  303          * Check that it is still responding and ok.
  304          */
  305         if (scsi_test_unit_ready(sc_link, 0)) {
  306                 SC_DEBUG(sc_link, SDEV_DB3, ("device not reponding\n"));
  307                 errcode = ENXIO;
  308                 goto bad;
  309         }
  310         SC_DEBUG(sc_link, SDEV_DB3, ("device ok\n"));
  311 
  312         /*
  313          * Load the physical device parameters
  314          */
  315         sd_get_parms(unit, 0);  /* sets SDEV_MEDIA_LOADED */
  316         /* Hack for some special disk in disk arrays */
  317         if ( sd->params.secsiz == 528 ){
  318           printf("sd%ld:  Forcing sector size to %d\n", unit, SECSIZE);
  319           sd->params.secsiz = SECSIZE;
  320         }
  321 
  322         if (sd->params.secsiz != SECSIZE) {     /* XXX One day... */
  323                 printf("sd%ld: Can't deal with %d bytes logical blocks\n",
  324                     unit, sd->params.secsiz);
  325                 Debugger("sd");
  326                 errcode = ENXIO;
  327                 goto bad;
  328         }
  329         SC_DEBUG(sc_link, SDEV_DB3, ("Params loaded "));
  330 
  331         /* Lock the pack in. */
  332         scsi_prevent(sc_link, PR_PREVENT, SCSI_ERR_OK | SCSI_SILENT);
  333 
  334         /* Build label for whole disk. */
  335         bzero(&label, sizeof label);
  336         label.d_secsize = sd->params.secsiz;
  337         label.d_nsectors = sd->params.sectors;
  338         label.d_ntracks = sd->params.heads;
  339         label.d_ncylinders = sd->params.cyls;
  340         label.d_secpercyl = sd->params.heads * sd->params.sectors;
  341         if (label.d_secpercyl == 0)
  342                 label.d_secpercyl = 100;
  343                 /* XXX as long as it's not 0 - readdisklabel divides by it (?) */
  344         label.d_secperunit = sd->params.disksize;
  345 
  346         /* Initialize slice tables. */
  347         errcode = dsopen("sd", dev, fmt, &sd->dk_slices, &label, sdstrategy1,
  348                          (ds_setgeom_t *)NULL, &sd_bdevsw, &sd_cdevsw);
  349         if (errcode != 0)
  350                 goto bad;
  351         SC_DEBUG(sc_link, SDEV_DB3, ("Slice tables initialized "));
  352 
  353         SC_DEBUG(sc_link, SDEV_DB3, ("open %ld %ld\n", sdstrats, sdqueues));
  354 
  355         return 0;
  356 
  357 bad:
  358         if (!dsisopen(sd->dk_slices)) {
  359                 scsi_prevent(sc_link, PR_ALLOW, SCSI_ERR_OK | SCSI_SILENT);
  360                 sc_link->flags &= ~SDEV_OPEN;
  361         }
  362         return errcode;
  363 }
  364 
  365 /*
  366  * close the device.. only called if we are the LAST occurence of an open
  367  * device.  Convenient now but usually a pain.
  368  */
  369 static errval
  370 sd_close(dev, fflag, fmt, p, sc_link)
  371         dev_t   dev;
  372         int     fflag;
  373         int     fmt;
  374         struct proc *p;
  375         struct scsi_link *sc_link;
  376 {
  377         struct scsi_data *sd;
  378 
  379         sd = sc_link->sd;
  380         dsclose(dev, fmt, sd->dk_slices);
  381         if (!dsisopen(sd->dk_slices)) {
  382                 scsi_prevent(sc_link, PR_ALLOW, SCSI_SILENT | SCSI_ERR_OK);
  383                 sc_link->flags &= ~SDEV_OPEN;
  384         }
  385         return (0);
  386 }
  387 
  388 /*
  389  * Actually translate the requested transfer into one the physical driver
  390  * can understand.  The transfer is described by a buf and will include
  391  * only one physical transfer.
  392  */
  393 static void
  394 sd_strategy(struct buf *bp, struct scsi_link *sc_link)
  395 {
  396         u_int32_t opri;
  397         struct scsi_data *sd;
  398         u_int32_t unit;
  399 
  400         sdstrats++;
  401         unit = SDUNIT((bp->b_dev));
  402         sd = sc_link->sd;
  403         /*
  404          * If the device has been made invalid, error out
  405          */
  406         if (!(sc_link->flags & SDEV_MEDIA_LOADED)) {
  407                 bp->b_error = EIO;
  408                 goto bad;
  409         }
  410 
  411         /*
  412          * check it's not too big a transfer for our adapter
  413          */
  414         scsi_minphys(bp,&sd_switch);
  415 
  416         /*
  417          * Odd number of bytes or negative offset
  418          */
  419         if (bp->b_blkno < 0 || bp->b_bcount % DEV_BSIZE != 0) {
  420                 bp->b_error = EINVAL;
  421                 goto bad;
  422         }
  423         /*
  424          * Do bounds checking, adjust transfer, set b_cylin and b_pbklno.
  425          */
  426         if (dscheck(bp, sd->dk_slices) <= 0)
  427                 goto done;      /* XXX check b_resid */
  428 
  429         opri = SPLSD();
  430         /*
  431          * Use a bounce buffer if necessary
  432          */
  433 #ifdef BOUNCE_BUFFERS
  434         if (sc_link->flags & SDEV_BOUNCE)
  435                 vm_bounce_alloc(bp);
  436 #endif
  437 
  438         /*
  439          * Place it in the queue of disk activities for this disk
  440          */
  441 #ifdef SDDISKSORT
  442         bufq_disksort(&sd->buf_queue, bp);
  443 #else
  444         bufq_insert_tail(&sd->buf_queue, bp);
  445 #endif
  446 
  447         /*
  448          * Tell the device to get going on the transfer if it's
  449          * not doing anything, otherwise just wait for completion
  450          */
  451         sdstart(unit, 0);
  452 
  453         splx(opri);
  454         return /**/;
  455 bad:
  456         bp->b_flags |= B_ERROR;
  457 done:
  458 
  459         /*
  460          * Correctly set the buf to indicate a completed xfer
  461          */
  462         bp->b_resid = bp->b_bcount;
  463         biodone(bp);
  464         return /**/;
  465 }
  466 
  467 static void
  468 sdstrategy1(struct buf *bp)
  469 {
  470         /*
  471          * XXX - do something to make sdstrategy() but not this block while
  472          * we're doing dsinit() and dsioctl().
  473          */
  474         sdstrategy(bp);
  475 }
  476 
  477 /*
  478  * sdstart looks to see if there is a buf waiting for the device
  479  * and that the device is not already busy. If both are true,
  480  * It dequeues the buf and creates a scsi command to perform the
  481  * transfer in the buf. The transfer request will call scsi_done
  482  * on completion, which will in turn call this routine again
  483  * so that the next queued transfer is performed.
  484  * The bufs are queued by the strategy routine (sdstrategy)
  485  *
  486  * This routine is also called after other non-queued requests
  487  * have been made of the scsi driver, to ensure that the queue
  488  * continues to be drained.
  489  *
  490  * must be called at the correct (highish) spl level
  491  * sdstart() is called at SPLSD  from sdstrategy and scsi_done
  492  */
  493 static void
  494 sdstart(u_int32_t unit, u_int32_t flags)
  495 {
  496         register struct scsi_link *sc_link = SCSI_LINK(&sd_switch, unit);
  497         register struct scsi_data *sd = sc_link->sd;
  498         struct buf *bp = NULL;
  499         struct scsi_rw_big cmd;
  500         u_int32_t blkno, nblk;
  501 
  502         SC_DEBUG(sc_link, SDEV_DB2, ("sdstart "));
  503         /*
  504          * Check if the device has room for another command
  505          */
  506         while (sc_link->opennings) {
  507 
  508                 /*
  509                  * there is excess capacity, but a special waits
  510                  * It'll need the adapter as soon as we clear out of the
  511                  * way and let it run (user level wait).
  512                  */
  513                 if (sc_link->flags & SDEV_WAITING) {
  514                         return;
  515                 }
  516                 /*
  517                  * See if there is a buf with work for us to do..
  518                  */
  519                 bp = bufq_first(&sd->buf_queue);
  520                 if (bp == NULL) {       /* yes, an assign */
  521                         return;
  522                 }
  523                 bufq_remove(&sd->buf_queue, bp);
  524 
  525                 /*
  526                  *  If the device has become invalid, abort all the
  527                  * reads and writes until all files have been closed and
  528                  * re-openned
  529                  */
  530                 if (!(sc_link->flags & SDEV_MEDIA_LOADED)) {
  531                         goto bad;
  532                 }
  533                 /*
  534                  * We have a buf, now we know we are going to go through
  535                  * With this thing..
  536                  */
  537                 blkno = bp->b_pblkno;
  538                 if (bp->b_bcount & (SECSIZE - 1))
  539                 {
  540                     goto bad;
  541                 }
  542                 nblk = bp->b_bcount >> 9;
  543 
  544                 /*
  545                  *  Fill out the scsi command
  546                  */
  547                 cmd.op_code = (bp->b_flags & B_READ)
  548                     ? READ_BIG : WRITE_BIG;
  549                 cmd.addr_3 = (blkno & 0xff000000UL) >> 24;
  550                 cmd.addr_2 = (blkno & 0xff0000) >> 16;
  551                 cmd.addr_1 = (blkno & 0xff00) >> 8;
  552                 cmd.addr_0 = blkno & 0xff;
  553                 cmd.length2 = (nblk & 0xff00) >> 8;
  554                 cmd.length1 = (nblk & 0xff);
  555                 cmd.byte2 = cmd.reserved = cmd.control = 0;
  556                 /*
  557                  * Call the routine that chats with the adapter.
  558                  * Note: we cannot sleep as we may be an interrupt
  559                  */
  560                 if (scsi_scsi_cmd(sc_link,
  561                         (struct scsi_generic *) &cmd,
  562                         sizeof(cmd),
  563                         (u_char *) bp->b_un.b_addr,
  564                         bp->b_bcount,
  565                         SD_RETRIES,
  566                         10000,
  567                         bp,
  568                         flags | ((bp->b_flags & B_READ) ?
  569                             SCSI_DATA_IN : SCSI_DATA_OUT))
  570                     == SUCCESSFULLY_QUEUED) {
  571                         sdqueues++;
  572                         if(sd->dkunit >= 0) {
  573                                 dk_xfer[sd->dkunit]++;
  574                                 dk_seek[sd->dkunit]++; /* don't know */
  575                                 dk_wds[sd->dkunit] += bp->b_bcount >> 6;
  576                         }
  577                 } else {
  578 bad:
  579                         printf("sd%ld: oops not queued\n", unit);
  580                         bp->b_error = EIO;
  581                         bp->b_flags |= B_ERROR;
  582                         biodone(bp);
  583                 }
  584         }
  585 }
  586 
  587 /*
  588  * Perform special action on behalf of the user
  589  * Knows about the internals of this device
  590  */
  591 static errval
  592 sd_ioctl(dev_t dev, int cmd, caddr_t addr, int flag, struct proc *p,
  593          struct scsi_link *sc_link)
  594 {
  595         /* struct sd_cmd_buf *args; */
  596         errval  error;
  597         struct scsi_data *sd;
  598 
  599         /*
  600          * Find the device that the user is talking about
  601          */
  602         sd = sc_link->sd;
  603         SC_DEBUG(sc_link, SDEV_DB1, ("sdioctl (0x%x)", cmd));
  604 
  605 #if 0
  606         /* Wait until we have exclusive access to the device. */
  607         /* XXX this is how wd does it.  How did we work without this? */
  608         wdsleep(du->dk_ctrlr, "wdioct");
  609 #endif
  610 
  611         /*
  612          * If the device is not valid.. abandon ship
  613          */
  614         if (!(sc_link->flags & SDEV_MEDIA_LOADED))
  615                 return (EIO);
  616 
  617         if (cmd == DIOCSBAD)
  618                 return (EINVAL);        /* XXX */
  619         error = dsioctl("sd", dev, cmd, addr, flag, &sd->dk_slices,
  620                         sdstrategy1, (ds_setgeom_t *)NULL);
  621         if (error != -1)
  622                 return (error);
  623         if (PARTITION(dev) != RAW_PART)
  624                 return (ENOTTY);
  625         return (scsi_do_ioctl(dev, cmd, addr, flag, p, sc_link));
  626 }
  627 
  628 /*
  629  * Find out from the device what it's capacity is
  630  */
  631 static u_int32_t
  632 sd_size(unit, flags, secsize)
  633         int     unit, flags;
  634         int     *secsize;
  635 {
  636         struct scsi_read_cap_data rdcap;
  637         struct scsi_read_capacity scsi_cmd;
  638         u_int32_t size;
  639         struct scsi_link *sc_link = SCSI_LINK(&sd_switch, unit);
  640 
  641         /*
  642          * make up a scsi command and ask the scsi driver to do
  643          * it for you.
  644          */
  645         bzero(&scsi_cmd, sizeof(scsi_cmd));
  646         scsi_cmd.op_code = READ_CAPACITY;
  647 
  648         /*
  649          * If the command works, interpret the result as a 4 byte
  650          * number of blocks
  651          */
  652         if (scsi_scsi_cmd(sc_link,
  653                 (struct scsi_generic *) &scsi_cmd,
  654                 sizeof(scsi_cmd),
  655                 (u_char *) & rdcap,
  656                 sizeof(rdcap),
  657                 SD_RETRIES,
  658                 2000,
  659                 NULL,
  660                 flags | SCSI_DATA_IN) != 0) {
  661                 printf("sd%d: could not get size\n", unit);
  662                 *secsize = 0;
  663                 size = 0;
  664         } else {
  665                 *secsize = scsi_4btou(&rdcap.length_3);
  666                 size = scsi_4btou(&rdcap.addr_3) + 1;
  667         }
  668         return (size);
  669 }
  670 
  671 /*
  672  * Tell the device to map out a defective block
  673  */
  674 static errval
  675 sd_reassign_blocks(unit, block)
  676         int     unit, block;
  677 {
  678         struct scsi_reassign_blocks scsi_cmd;
  679         struct scsi_reassign_blocks_data rbdata;
  680         struct scsi_link *sc_link = SCSI_LINK(&sd_switch, unit);
  681 
  682         bzero(&scsi_cmd, sizeof(scsi_cmd));
  683         bzero(&rbdata, sizeof(rbdata));
  684         scsi_cmd.op_code = REASSIGN_BLOCKS;
  685 
  686         rbdata.length_msb = 0;
  687         rbdata.length_lsb = sizeof(rbdata.defect_descriptor[0]);
  688         rbdata.defect_descriptor[0].dlbaddr_3 = ((block >> 24) & 0xff);
  689         rbdata.defect_descriptor[0].dlbaddr_2 = ((block >> 16) & 0xff);
  690         rbdata.defect_descriptor[0].dlbaddr_1 = ((block >> 8) & 0xff);
  691         rbdata.defect_descriptor[0].dlbaddr_0 = ((block) & 0xff);
  692 
  693         return (scsi_scsi_cmd(sc_link,
  694                 (struct scsi_generic *) &scsi_cmd,
  695                 sizeof(scsi_cmd),
  696                 (u_char *) & rbdata,
  697                 sizeof(rbdata),
  698                 SD_RETRIES,
  699                 5000,
  700                 NULL,
  701                 SCSI_DATA_OUT));
  702 }
  703 #define b2tol(a)        (((unsigned)(a##_1) << 8) + (unsigned)a##_0 )
  704 
  705 /*
  706  * Get the scsi driver to send a full inquiry to the
  707  * device and use the results to fill out the disk
  708  * parameter structure.
  709  */
  710 static errval
  711 sd_get_parms(unit, flags)
  712         int     unit, flags;
  713 {
  714         struct scsi_link *sc_link = SCSI_LINK(&sd_switch, unit);
  715         struct scsi_data *sd = sc_link->sd;
  716         struct disk_parms *disk_parms = &sd->params;
  717         struct scsi_mode_sense scsi_cmd;
  718         struct scsi_mode_sense_data {
  719                 struct scsi_mode_header header;
  720                 struct blk_desc blk_desc;
  721                 union disk_pages pages;
  722         } scsi_sense;
  723         u_int32_t sectors;
  724         u_int32_t secsize;
  725 
  726         /*
  727          * First check if we have it all loaded
  728          */
  729         if (sc_link->flags & SDEV_MEDIA_LOADED)
  730                 return 0;
  731 
  732         sectors = sd_size(unit, flags, &secsize);
  733 
  734         /*
  735          * do a "mode sense page 4"
  736          */
  737         bzero(&scsi_cmd, sizeof(scsi_cmd));
  738         scsi_cmd.op_code = MODE_SENSE;
  739         scsi_cmd.page = 4;
  740         scsi_cmd.length = 0x20;
  741 #ifdef PC98
  742         if (sd_bios_parms(disk_parms, sc_link)) {
  743         } else
  744 #endif
  745         /*
  746          * If the command worked, use the results to fill out
  747          * the parameter structure
  748          */
  749         if (scsi_scsi_cmd(sc_link,
  750                 (struct scsi_generic *) &scsi_cmd,
  751                 sizeof(scsi_cmd),
  752                 (u_char *) & scsi_sense,
  753                 sizeof(scsi_sense),
  754                 SD_RETRIES,
  755                 4000,
  756                 NULL,
  757                 flags | SCSI_DATA_IN) != 0) {
  758 
  759                 printf("sd%d could not mode sense (4).", unit);
  760                 printf(" Using fictitious geometry\n");
  761                 /*
  762                  * use adaptec standard fictitious geometry
  763                  * this depends on which controller (e.g. 1542C is
  764                  * different. but we have to put SOMETHING here..)
  765                  */
  766                 disk_parms->heads = 64;
  767                 disk_parms->sectors = 32;
  768                 disk_parms->cyls = sectors / (64 * 32);
  769                 disk_parms->secsiz = secsize;
  770                 disk_parms->disksize = sectors;
  771         } else {
  772 
  773                 SC_DEBUG(sc_link, SDEV_DB3,
  774                     ("%ld cyls, %d heads, %d precomp, %d red_write, %d land_zone\n",
  775                         scsi_3btou(&scsi_sense.pages.rigid_geometry.ncyl_2),
  776                         scsi_sense.pages.rigid_geometry.nheads,
  777                         b2tol(scsi_sense.pages.rigid_geometry.st_cyl_wp),
  778                         b2tol(scsi_sense.pages.rigid_geometry.st_cyl_rwc),
  779                         b2tol(scsi_sense.pages.rigid_geometry.land_zone)));
  780 
  781                 /*
  782                  * KLUDGE!!(for zone recorded disks)
  783                  * give a number of sectors so that sec * trks * cyls
  784                  * is <= disk_size
  785                  * can lead to wasted space! THINK ABOUT THIS !
  786                  */
  787                 disk_parms->heads = scsi_sense.pages.rigid_geometry.nheads;
  788                 disk_parms->cyls = scsi_3btou(&scsi_sense.pages.rigid_geometry.ncyl_2);
  789                 disk_parms->secsiz = scsi_3btou(scsi_sense.blk_desc.blklen);
  790 
  791                 sectors = sd_size(unit, flags, &secsize);
  792                 disk_parms->disksize = sectors;
  793                 /* Check if none of these values are zero */
  794                 if(disk_parms->heads && disk_parms->cyls) {
  795                         sectors /= (disk_parms->heads * disk_parms->cyls);
  796                 }
  797                 else {
  798                         /* set it to something reasonable */
  799                         disk_parms->heads = 64;
  800                         disk_parms->cyls = sectors / (64 * 32);
  801                         sectors = 32;
  802                 }
  803                 /* keep secsiz sane too - we may divide by it later */
  804                 if(disk_parms->secsiz == 0)
  805                         disk_parms->secsiz = SECSIZE;
  806                 disk_parms->sectors = sectors;  /* dubious on SCSI *//*XXX */
  807         }
  808         sc_link->flags |= SDEV_MEDIA_LOADED;
  809         return 0;
  810 }
  811 
  812 static int
  813 sdsize(dev_t dev)
  814 {
  815         struct scsi_data *sd;
  816 
  817         sd = SCSI_DATA(&sd_switch, (u_int32_t) SDUNIT(dev));
  818         if (sd == NULL)
  819                 return (-1);
  820         return (dssize(dev, &sd->dk_slices, sdopen, sdclose));
  821 }
  822 
  823 /*
  824  * sense handler: Called to determine what to do when the
  825  * device returns a CHECK CONDITION.
  826  *
  827  * This will issue a retry when the device returns a
  828  * non-media hardware failure.  The CDC-WREN IV does this
  829  * when you access it during thermal calibrarion, so the drive
  830  * is pretty useless without this.
  831  *
  832  * In general, you probably almost always would like to issue a retry
  833  * for your disk I/O.  It can't hurt too much (the caller only retries
  834  * so many times) and it may save your butt.
  835  */
  836 
  837 static int
  838 sd_sense_handler(struct scsi_xfer *xs)
  839 {
  840         struct scsi_sense_data *sense;
  841         struct scsi_inquiry_data *inqbuf;
  842 
  843         sense = &(xs->sense);
  844 
  845         /* I don't know what the heck to do with a deferred error,
  846          * so I'll just kick it back to the caller.
  847          */
  848         if ((sense->error_code & SSD_ERRCODE) == 0x71)
  849                 return SCSIRET_CONTINUE;
  850 
  851         if (((sense->error_code & SSD_ERRCODE) == 0x70) &&
  852                 ((sense->ext.extended.flags & SSD_KEY) == 0x05))
  853                 /* No point in retrying Illegal Requests */
  854                         return SCSIRET_CONTINUE;
  855 
  856         inqbuf = &(xs->sc_link->inqbuf);
  857 
  858         /* It is dangerous to retry on removable drives without
  859          * looking carefully at the additional sense code
  860          * and sense code qualifier and ensuring the disk hasn't changed:
  861          */
  862         if (inqbuf->dev_qual2 & SID_REMOVABLE)
  863                 return SCSIRET_CONTINUE;
  864 
  865         /* Retry all disk errors.
  866          */
  867         scsi_sense_print(xs);
  868         if (xs->retries)
  869                 printf(", retries:%d\n", xs->retries);
  870         else
  871                 printf(", FAILURE\n");
  872 
  873         return SCSIRET_DO_RETRY;
  874 }
  875 
  876 /*
  877  * dump all of physical memory into the partition specified, starting
  878  * at offset 'dumplo' into the partition.
  879  */
  880 static errval
  881 sddump(dev_t dev)
  882 {                               /* dump core after a system crash */
  883         struct disklabel *lp;
  884         register struct scsi_data *sd;  /* disk unit to do the IO */
  885         struct scsi_link *sc_link;
  886         int32_t num;            /* number of sectors to write */
  887         u_int32_t       unit, part;
  888         int32_t blkoff, blknum, blkcnt = MAXTRANSFER;
  889         int32_t nblocks;
  890         char    *addr;
  891         struct  scsi_rw_big cmd;
  892         static  int sddoingadump = 0;
  893         struct  scsi_xfer *xs = &sx;
  894         errval  retval;
  895 
  896         addr = (char *) 0;      /* starting address */
  897 
  898         /* toss any characters present prior to dump */
  899         while (cncheckc() != -1)
  900                 ;
  901 
  902         /* size of memory to dump */
  903         num = Maxmem;
  904         unit = SDUNIT(dev);     /* eventually support floppies? */
  905         part = PARTITION(dev);  /* file system */
  906 
  907         sc_link = SCSI_LINK(&sd_switch, unit);
  908 
  909         if (!sc_link)
  910                 return ENXIO;
  911 
  912         sd = sc_link->sd;
  913 
  914         /* was it ever initialized etc. ? */
  915         if (!(sd->flags & SDINIT))
  916                 return (ENXIO);
  917         if ((sc_link->flags & SDEV_MEDIA_LOADED) != SDEV_MEDIA_LOADED)
  918                 return (ENXIO);
  919         if (sd->dk_slices == NULL)
  920                 Debugger("sddump: no slices");
  921         if ((lp = dsgetlabel(dev, sd->dk_slices)) == NULL)
  922                 return (ENXIO);
  923 
  924         /* Convert to disk sectors */
  925         num = (u_int32_t) num * PAGE_SIZE / sd->params.secsiz;  /* XXX it must be 512 */
  926 
  927         /* check if controller active */
  928         if (sddoingadump)
  929                 return (EFAULT);
  930 
  931         nblocks = lp->d_partitions[part].p_size;
  932         blkoff = lp->d_partitions[part].p_offset;
  933         /* XXX */
  934         blkoff += sd->dk_slices->dss_slices[dkslice(dev)].ds_offset;
  935 
  936         /* check transfer bounds against partition size */
  937         if ((dumplo < 0) || ((dumplo + num) > nblocks))
  938                 return (EINVAL);
  939 
  940         sddoingadump = 1;
  941 
  942         blknum = dumplo + blkoff;
  943         while (num > 0) {
  944                 if (is_physical_memory((vm_offset_t)addr))
  945                     pmap_enter(kernel_pmap, (vm_offset_t)CADDR1,
  946                                trunc_page(addr), VM_PROT_READ, TRUE);
  947                 else
  948                     pmap_enter(kernel_pmap, (vm_offset_t)CADDR1,
  949                                trunc_page(0), VM_PROT_READ, TRUE);
  950                 /*
  951                  *  Fill out the scsi command
  952                  */
  953                 bzero(&cmd, sizeof(cmd));
  954                 cmd.op_code = WRITE_BIG;
  955                 cmd.addr_3 = (blknum & 0xff000000) >> 24;
  956                 cmd.addr_2 = (blknum & 0xff0000) >> 16;
  957                 cmd.addr_1 = (blknum & 0xff00) >> 8;
  958                 cmd.addr_0 = blknum & 0xff;
  959                 cmd.length2 = (blkcnt & 0xff00) >> 8;
  960                 cmd.length1 = (blkcnt & 0xff);
  961                 /*
  962                  * Fill out the scsi_xfer structure
  963                  *    Note: we cannot sleep as we may be an interrupt
  964                  * don't use scsi_scsi_cmd() as it may want
  965                  * to wait for an xs.
  966                  */
  967                 bzero(xs, sizeof(sx));
  968                 xs->flags |= SCSI_NOMASK | SCSI_NOSLEEP | INUSE | SCSI_DATA_OUT;
  969                 xs->sc_link = sc_link;
  970                 xs->retries = SD_RETRIES;
  971                 xs->timeout = 10000;    /* 10000 millisecs for a disk ! */
  972                 xs->cmd = (struct scsi_generic *) &cmd;
  973                 xs->cmdlen = sizeof(cmd);
  974                 xs->resid = 0;
  975                 xs->error = XS_NOERROR;
  976                 xs->bp = 0;
  977                 xs->data = (u_char *) CADDR1;   /* XXX use pmap_enter() */
  978                 xs->datalen = blkcnt * SECSIZE;
  979 
  980                 /*
  981                  * Pass all this info to the scsi driver.
  982                  */
  983                 retval = (*(sc_link->adapter->scsi_cmd)) (xs);
  984                 switch (retval) {
  985                 case SUCCESSFULLY_QUEUED:
  986                 case HAD_ERROR:
  987                         return (ENXIO);         /* we said not to sleep! */
  988                 case COMPLETE:
  989                         break;
  990                 default:
  991                         return (ENXIO);         /* we said not to sleep! */
  992                 }
  993 
  994                 /*
  995                  * If we are dumping core, it may take a while.
  996                  * So reassure the user and hold off any watchdogs.
  997                  */
  998                 if ((unsigned)addr % (1024 * 1024) == 0) {
  999 #ifdef  HW_WDOG
 1000                         if (wdog_tickler)
 1001                                 (*wdog_tickler)();
 1002 #endif /* HW_WDOG */
 1003                         printf("%ld ", num / 2048);
 1004                 }
 1005                 /* update block count */
 1006                 num -= blkcnt;
 1007                 blknum += blkcnt;
 1008                 (int) addr += SECSIZE * blkcnt;
 1009 
 1010                 /* operator aborting dump? */
 1011                 if (cncheckc() != -1)
 1012                         return (EINTR);
 1013         }
 1014         return (0);
 1015 }
 1016 
 1017 static sd_devsw_installed = 0;
 1018 
 1019 static void     sd_drvinit(void *unused)
 1020 {
 1021 
 1022         if( ! sd_devsw_installed ) {
 1023                 bdevsw_add_generic(BDEV_MAJOR, CDEV_MAJOR, &sd_bdevsw);
 1024                 sd_devsw_installed = 1;
 1025         }
 1026 }
 1027 
 1028 SYSINIT(sddev,SI_SUB_DRIVERS,SI_ORDER_MIDDLE+CDEV_MAJOR,sd_drvinit,NULL)
 1029 

Cache object: 5ad06b2dd84f2313b12a221293265b0d


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