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/sqtsec/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  * Mach Operating System
    3  * Copyright (c) 1991 Carnegie Mellon University
    4  * Copyright (c) 1991 Sequent Computer Systems
    5  * All Rights Reserved.
    6  * 
    7  * Permission to use, copy, modify and distribute this software and its
    8  * documentation is hereby granted, provided that both the copyright
    9  * notice and this permission notice appear in all copies of the
   10  * software, derivative works or modified versions, and any portions
   11  * thereof, and that both notices appear in supporting documentation.
   12  * 
   13  * CARNEGIE MELLON AND SEQUENT COMPUTER SYSTEMS ALLOW FREE USE OF
   14  * THIS SOFTWARE IN ITS "AS IS" CONDITION.  CARNEGIE MELLON AND
   15  * SEQUENT COMPUTER SYSTEMS DISCLAIM ANY LIABILITY OF ANY KIND FOR
   16  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
   17  * 
   18  * Carnegie Mellon requests users of this software to return to
   19  * 
   20  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
   21  *  School of Computer Science
   22  *  Carnegie Mellon University
   23  *  Pittsburgh PA 15213-3890
   24  * 
   25  * any improvements or extensions that they make and grant Carnegie Mellon 
   26  * the rights to redistribute these changes.
   27  */
   28 
   29 /*
   30  * HISTORY
   31  * $Log:        sd.c,v $
   32  * Revision 2.6  93/05/18  11:42:10  rvb
   33  *      Lint
   34  * 
   35  * Revision 2.5  93/03/10  11:30:45  danner
   36  *      u_long -> u_int
   37  *      [93/03/10            danner]
   38  * 
   39  * Revision 2.4  92/02/23  22:45:14  elf
   40  *      Added sdgetstat().
   41  *      [92/02/22  19:53:28  af]
   42  * 
   43  * Revision 2.3  91/07/31  18:07:12  dbg
   44  *      Changed copyright.
   45  *      [91/07/31            dbg]
   46  * 
   47  * Revision 2.2  91/05/08  13:06:36  dbg
   48  *      Added volatile declarations.
   49  *      [91/03/25            dbg]
   50  * 
   51  *      Adapted for pure kernel.  No conditionals.
   52  *      [90/09/24            dbg]
   53  * 
   54  */
   55 /* $Copyright:  $
   56  * Copyright (c) 1984, 1985, 1986, 1987 Sequent Computer Systems, Inc.
   57  * All rights reserved
   58  *  
   59  * This software is furnished under a license and may be used
   60  * only in accordance with the terms of that license and with the
   61  * inclusion of the above copyright notice.   This software may not
   62  * be provided or otherwise made available to, or used by, any
   63  * other person.  No title to or ownership of the software is
   64  * hereby transferred.
   65  */
   66 
   67 #ifndef lint
   68 static  char    rcsid[] = "$Header: sd.c,v 2.6 93/05/18 11:42:10 rvb Exp $";
   69 #endif
   70 
   71 /*
   72  * sd.c 
   73  *      SCSI disk device driver
   74  */
   75 
   76 /*
   77  * Revision 1.3  89/08/03  12:30:11  kak
   78  * balance -> sqt
   79  * 
   80  * Revision 1.2  89/07/25  11:21:07  kak
   81  * fixed p_sema_v_lock define
   82  * 
   83  * Revision 1.1  89/07/05  13:20:13  kak
   84  * Initial revision
   85  * 
   86  * Revision 2.15  88/03/11  18:00:19  davest
   87  * sdboot deconfigures drives if mem > 128M
   88  * 
   89  * Revision 2.14  88/03/11  15:25:17  davest
   90  * changed the data buffer which sd_docmd() uses for its SCSI data transfers
   91  * into an IAT
   92  * 
   93  */
   94 
   95 #include <sys/types.h>
   96 #include <device/buf.h>
   97 #include <device/errno.h>
   98 #include <device/param.h>
   99 
  100 #include <sqt/macros.h>
  101 
  102 #include <sqt/vm_defs.h>
  103 #include <sqt/mutex.h>
  104 #include <sqt/slic.h>
  105 #include <sqt/ioconf.h>
  106 #include <sqt/intctl.h>
  107 
  108 #include <sqtsec/sec.h>                 /* SCSI common data structures */
  109 #include <sqtsec/sec_ctl.h>             /* SCSI drivers' common stuff */
  110 #include <sqtsec/sd.h>                  /* driver local structures */
  111 #include <sqtsec/scsi.h>
  112 
  113 /*
  114  * Externs and global data structures.
  115  */
  116 extern  gate_t  sdgate;                 /* Gate number for locks... */
  117 extern  struct  sd_bconf sdbconf[];     /* Binary configuration info (bc)*/
  118 struct  sd_info **sdifd;                /* Unit interrupt mapping base ptr */
  119 extern  u_char *SEC_rqinit();
  120 extern  struct timeval  time;
  121 extern  caddr_t topmem;                 /* highest addressable location */
  122 extern  u_char sddevtype;               /* byte 0 of INQUIRY return data */
  123 extern  u_char sdinq_targformat;        /* byte 3 of above on target adaptors */
  124 extern  u_char sdinq_ccsformat;         /* byte 3 of above on embedded SCSI */
  125 extern  boolean_t CCS_present;          /* is there an embedded SCSI drive */
  126 
  127 extern int      sdsensebuf_sz;          /* Sense buffer info - bc */
  128 extern int      sdmaxminor;             /* Device numbering info - bc */
  129 extern int      sdretrys;               /* Number of retrys before giving up */
  130 
  131 #ifdef SDDEBUG
  132 #define SCSIFIRMWARE_SANITY 
  133 #endif SDDEBUG
  134 
  135 int     sd_baselevel;                   /* Base interrupt lvl for all devices*/
  136 
  137 
  138 int     sdstrat(), sdiatsz();           /* Forward references */
  139 int     sdprobe(), sdboot(), sdintr();
  140 daddr_t sdreadc();
  141 
  142 struct sec_driver sd_driver = {
  143 /*      name base       flags                    probe    boot    intr */
  144         "sd", 0x20,     SED_TYPICAL|SED_IS_SCSI, sdprobe, sdboot, sdintr
  145 };
  146 
  147 
  148 /*
  149  * Driver development helpers.
  150  */
  151 #ifdef SDDEBUG
  152 int     sd_debug = 4;   /* 0=off 1=little 2=more 3=lots >3=all */
  153 #endif SDDEBUG
  154 
  155 /*
  156  * The following data structures are only used for probing
  157  */
  158 struct sec_dev_prog sd_devprog; /* one device program */
  159 u_char *sd_datap = 0;
  160 u_char *sd_data_queue;
  161 
  162 /* Mach pure kernel has full locking */
  163 
  164 #include <kern/assert.h>
  165 #define ASSERT(C,S)     assert(C)       /* convert to mach style assert */
  166 
  167 /*
  168  * sdprobe(sd) - probe procedure 
  169  *      struct sec_dev *sd;
  170  *
  171  * This procedure polls a device with the test unit ready command
  172  * to determine if the device is present.
  173  *
  174  * Note: This procedure tracks the header file sec.h
  175  * which must track the firmware for queue size information.
  176  * Also the status address MUST be below 4 Meg because the h/w
  177  * dma can not address above 4 Meg.
  178  */
  179 sdprobe(sed)
  180         struct sec_probe *sed;
  181 {
  182         int resp;
  183         struct sdreqsense *sense;
  184         struct sdinq *sdinq;
  185 
  186         if (! sd_datap) {
  187                 sd_datap = (u_char *) calloc(SDMAXDATASZ);
  188                 sd_data_queue = SEC_rqinit(sd_datap, SDMAXDATASZ);
  189         }
  190 
  191         if ((resp = sd_docmd_pr(SDC_TEST, sed)) == 2) {
  192 
  193                 /*
  194                  * could be a CCS disk - if so, we need to clear out
  195                  * the unit attention error condition.
  196                  */
  197 
  198                 if (sd_docmd_pr(SDC_REQUEST_SENSE, sed) != 0)
  199                         return(SECP_NOTFOUND);
  200 
  201                 sense = (struct sdreqsense *) sd_datap;
  202                 if ((sense->sdr_sensekey & SD_SENSEKEYMASK) != SD_UNIT_ATTN)
  203                         return(SECP_NOTFOUND);
  204 
  205         /*
  206          * timeout occurred - no target present
  207          */
  208 
  209         } else if (resp == 1) {
  210                 return(SECP_NOTFOUND|SECP_NOTARGET);
  211 
  212         } else if (resp != 0) {
  213                 return(SECP_NOTFOUND);
  214         }
  215 
  216         /*
  217          * discover the type of target adaptor
  218          */
  219 
  220         if (sd_docmd_pr(SDC_INQUIRY, sed) != 0)
  221                 return(SECP_NOTFOUND);
  222         sdinq = (struct sdinq *) sd_datap;
  223 
  224         /*
  225          * confirm that this is a disk.  This keeps the sd driver
  226          * from responding to a SCSI tape.
  227          */
  228 
  229         if (sdinq->sdq_devtype != sddevtype)
  230                 return(SECP_NOTFOUND);
  231 
  232         /*
  233          * non-CCS format disk
  234          */
  235 
  236         if (sdinq->sdq_format == sdinq_targformat)
  237                 return(SECP_FOUND);
  238 
  239         if (sdinq->sdq_format != sdinq_ccsformat) {
  240                 printf("sd: not a supported embedded SCSI drive, target %d, unit %d\n",
  241                         sed->secp_target, sed->secp_unit);
  242                 return(SECP_NOTFOUND|SECP_ONELUN);
  243         }
  244 
  245         /*
  246          * we have found a CCS drive.
  247          */
  248 
  249         CCS_present = 1;
  250         return(SECP_FOUND|SECP_ONELUN);
  251 }
  252 
  253 
  254 /*
  255  * sdboot - initialize all channels of this device driver.
  256  *
  257  * Called once after all probing has been done.
  258  *
  259  * This procedure initializes and allocates all device driver data
  260  * structures based off of the configuration information passed in from
  261  * autoconfig() and from the device drivers binary configuration tables.
  262  * The boot procedure also maps interrupt levels to unit number by
  263  * placing the channels communications structure pointer into a
  264  * major/minor number mapped dynamically allocated array (sdifd[]).
  265  */
  266 sdboot(ndevs, sed_array)
  267         int ndevs;
  268         struct sec_dev sed_array[];
  269 {
  270         register struct sec_dev *sed;
  271         register struct sd_info *ifd;
  272         register struct seddc *dc;
  273         struct  sd_bconf    *bconf;     /* Binary configuration info */
  274         int dev;
  275         daddr_t capacity;
  276 
  277         sdifd = (struct sd_info **)calloc(((sdmaxminor+1) * (sizeof(struct sd_info *))));
  278         sd_baselevel = sed_array[0].sd_vector;
  279         
  280         /*
  281          * for each configured device
  282          */
  283         for (dev = 0; dev < ndevs; ++dev) {
  284                 sed = &sed_array[dev];
  285 #ifdef SDDEBUG
  286                 if(sd_debug) {
  287                         printf("sdboot: info=0x%x cib=0x%x ta=%d un=%d bin=%d slic=%d vec=%d, alive is %s\n",
  288                                 sdifd,
  289                                 sed->sd_cib,
  290                                 sed->sd_target,
  291                                 sed->sd_unit,
  292                                 sed->sd_bin,
  293                                 sed->sd_desc->sec_slicaddr,
  294                                 sed->sd_vector,
  295                                 (sed->sd_alive ? "Found" : "Not Found")
  296                         );
  297                 }
  298 #endif SDDEBUG
  299                 if(!sed->sd_alive)
  300                         continue;
  301 
  302                 /*
  303                  * Verify that this device has been included into
  304                  * the devices binary configuration table. 
  305                  */
  306                 if(dev >= sdmaxminor) {
  307                         printf("sd%d: non-binary configured device found in config table ... deconfiguring.\n", dev);
  308                         sed->sd_alive = 0;      /* force deconfigure */
  309                         continue;
  310                 }
  311 
  312                 if (topmem > (caddr_t) MAX_SCED_ADDR_MEM) {
  313                         printf("sd%d: Unsupported memory configuration with SCSI disks ... deconfiguring.\n", dev);
  314                         sed->sd_alive = 0;
  315                         continue;
  316                 }
  317 
  318                 /*
  319                  * determine the disk's usable size by doing a
  320                  * READ CAPACITY scsi command and shaving off the
  321                  * last three cylinders, (used by diagnostics)
  322                  */
  323 
  324                 if ((capacity = sdreadc(sed)) <= 0) {
  325                         printf("sd%d: problem doing READ CAPACITY %s\n",
  326                         dev, "... deconfiguring");
  327                         sed->sd_alive = 0;
  328                         continue;
  329                 }
  330 
  331                 /*
  332                  * Initialize the device structure and
  333                  * copy pertenent info into it for faster/easier access.
  334                  */
  335 
  336                 bconf = &sdbconf[dev];
  337 
  338                 /*
  339                  * round number of iat's up to minimum boundary
  340                  */
  341                 bconf->bc_num_iat = MAX(4, bconf->bc_num_iat);
  342 
  343                 /*
  344                  * Info structure.
  345                  */
  346                 sdifd[dev] = ifd = (struct sd_info *)calloc(sizeof(struct sd_info));
  347 #ifdef SDDEBUG
  348                 if(sd_debug)
  349                         printf("ifd=0x%x, info=0x%x\n", ifd, sdifd[dev]);
  350 #endif SDDEBUG
  351                 ifd->sd_desc = sed;
  352                 ifd->sd_lun = sed->sd_unit<<5;
  353                 ifd->sd_size = capacity;
  354                 ifd->sd_part = bconf->bc_part;
  355                 ifd->sd_retrys = sdretrys;
  356                 ifd->sd_thresh = MIN(bconf->bc_thresh, sed->sd_doneq_size);
  357                 ifd->sd_low = MIN(bconf->bc_low, sed->sd_doneq_size);
  358                 if(ifd->sd_thresh <= 0)
  359                         printf("sd%d: Warning queueing disabled\n", dev);
  360 
  361                 /*
  362                  * Ioctl raw buffer.
  363                  */
  364                 ifd->sd_rawbuf = (caddr_t)calloc(bconf->bc_rawbuf_sz * sizeof(unsigned char)); /* next free mem */
  365 
  366                 /*
  367                  * Init locks, semas ...
  368                  */
  369                 init_lock(&ifd->sd_lock, sdgate);
  370                 init_sema(&ifd->sd_sema, 0, 0, sdgate);
  371 #ifndef MACH
  372                 bufinit(&ifd->sd_rbufh, sdgate);
  373 #endif  MACH
  374 
  375                 /*
  376                  * Init channel structure.
  377                  */
  378                 ifd->sd_dc = dc = (struct seddc *)calloc(sizeof(struct seddc));         /* next free mem */
  379 
  380                 /* 
  381                  * Device program for a request sense operation
  382                  * (separate to avoid fussing diq ptrs too much)
  383                  */
  384                 dc->dc_sense = (struct sec_dev_prog *)calloc(sizeof(struct sec_dev_prog)); /* sense info */
  385 
  386                 /*
  387                  * Set up the iat table area
  388                  */
  389                 dc->dc_iat = (struct sec_iat *) calloc(sizeof(struct sec_iat) * bconf->bc_num_iat); /* next free mem */
  390                 dc->dc_isz = bconf->bc_num_iat;
  391                 dc->dc_ifree = dc->dc_isz;
  392 
  393                 /*
  394                  * Device input queue.
  395                  */
  396                 dc->dc_diq = sed->sd_requestq;
  397                 SEC_fill_progq(dc->dc_diq, sed->sd_req_size, sizeof(struct sec_dev_prog));
  398                 dc->dc_devp = PHYSTOKV(dc->dc_diq->pq_un.pq_progs[0],
  399                                         struct sec_dev_prog *);
  400                 dc->dc_dsz = sed->sd_req_size;
  401                 dc->dc_dfree = dc->dc_dsz;
  402                 ASSERT(dc->dc_dsz > 0, "sdboot: no device programs");
  403 
  404                 /*
  405                  * Device Output queue.
  406                  */
  407                 dc->dc_doq = sed->sd_doneq;
  408 
  409                 /*
  410                  * Request sense information buffer,
  411                  * one per channel.
  412                  * Note: Assumes channel can only generate one fault
  413                  * at a time.
  414                  */
  415                 ifd->sd_sensebuf = (u_char *)calloc(sizeof(u_char) * sdsensebuf_sz);
  416                 ifd->sd_sensebufptr = SEC_rqinit(ifd->sd_sensebuf, sdsensebuf_sz);
  417 
  418 #ifdef SDDEBUG
  419                 if(sd_debug>1) {
  420                         printf("diq0x%x,doq0x%x,cib0x%x,bin%d,device%d,vector%d, all at 0x%x\n",dc->dc_diq,
  421                         dc->dc_doq, sed->sd_cib, sed->sd_bin, dev, sed->sd_vector);
  422                         printf("info=0x%x, ifd=0x%x\n",ifd,sdifd[dev]);
  423                 }
  424 #endif SDDEBUG
  425 #ifndef MACH
  426                 /*
  427                  * Initialize the statistics 
  428                  *
  429                  * Note: No seek statistics are
  430                  * recorded because of the logical SCSI interface.
  431                  */
  432                 if(dk_nxdrive < dk_ndrives) {
  433                         ifd->sd_stat_unit = dk_nxdrive;
  434                         ifd->sd_dk = &dk[dk_nxdrive++];
  435                         bcopy("sdX", ifd->sd_dk->dk_name , 4);
  436                         ifd->sd_dk->dk_name[2] = '' + dev;
  437                         ifd->sd_dk->dk_bps = bconf->bc_blks_per_sec;
  438                 }else
  439                         ifd->sd_stat_unit = SD_NO_UNIT;
  440 #endif  MACH
  441         }
  442 
  443 #ifdef SDDEBUG
  444         printf("sd_debug@0x%x, set to %d\n", &sd_debug, sd_debug);
  445 #endif SDDEBUG
  446 
  447 }
  448 
  449 /*
  450  *      sdopen - open a channel
  451  *
  452  *      Check for validity of device and partition.
  453  *
  454  *      Tmp assumptions: No mods needed for TMP because sdopen doesn't
  455  *      *modify* any concurrently accessed common data structures.
  456  *
  457  *      This assumes that the device is formated in DEV_BSIZE size blocks
  458  *      and won't work other wise.
  459  */
  460 
  461 sdopen(dev)
  462         dev_t   dev;
  463 {
  464         register int unit;
  465         register int part;
  466         register struct sd_partition *pt;
  467         register struct sd_info *ifd;
  468 
  469 #ifdef SDDEBUG
  470         if(sd_debug)
  471                 printf("O");
  472 #endif SDDEBUG
  473         unit = SD_UNIT(dev);
  474         part = SD_PART(dev);
  475 
  476         ifd = sdifd[unit];
  477         if(ifd == NULL || ifd->sd_part == NULL) /* Configured properly? */
  478                 return(ENXIO);
  479 
  480         pt = &(ifd->sd_part)[part];
  481 
  482         if( unit >= sdmaxminor                  /* Valid channel number? */
  483         || pt->p_length <= 0                    /* Valid partition table? */
  484         || (!ifd->sd_desc->sd_alive))                   /* Passed probing? */
  485                 return(ENXIO);
  486         
  487         return(0);                              /* Good status */
  488 }
  489 
  490 /*
  491  * sdminphys - correct for too large a request.
  492  *
  493  * Note: IATSIZE should reflect typical iat table entry size (currently 1k)
  494  */
  495 sdminphys(bp)
  496         register struct buf *bp;
  497 {
  498         struct sd_info *ifd;
  499         struct seddc    *dc;
  500 
  501         ifd = sdifd[SD_UNIT(bp->b_dev)];
  502         dc = ifd->sd_dc;
  503 
  504 #ifdef SDDEBUG
  505         if(bp->b_bcount<=0) {
  506                 printf("sdminphys: bad bp detected, bcount=%d\n", bp->b_bcount);
  507                 bp->b_bcount = 0;
  508         }
  509 #endif SDDEBUG
  510         
  511 #ifdef SCSIFIRMWARE_SANITY 
  512 
  513         /*
  514          * The iat size is enough except for the use of an extra
  515          * iat used for debug in sdiatsz() for driver fault firmware
  516          * tests.
  517          *
  518          * Added space for an iat entry so that #define SCSIFIRWARE_SANITY
  519          * doesn't deadlock on iat allocation in sdstart call.
  520          *
  521          * buf_iat(bp)+2        1 for scsifirmwaresanity 1 for deadlock
  522          * dc_isz-IATVARIANCE-4 (above adds total of 4) plus 1 so that
  523          *                      non-aligned xfers don't get rounded up.
  524          */
  525         if(buf_iatsz(bp)+2 >= dc->dc_isz)               
  526                 bp->b_bcount = (dc->dc_isz-IATVARIANCE-4)*IATBYTES;
  527 #else
  528 
  529         /*
  530          * Waste an extra couple of iat's to insure driver doesn't
  531          * deadlock if a request tries to allocate the entire iat
  532          * list to a single request.
  533          */
  534         if(buf_iatsz(bp)+1 >= dc->dc_isz)               
  535                 bp->b_bcount = (dc->dc_isz-IATVARIANCE-3)*IATBYTES;
  536 #endif SCSIFIRMWARE_SANITY
  537 
  538 #ifdef SDDEBUG
  539         if(sd_debug>1) 
  540                 printf("sdminphys: cnt=%d, ni=%d\n", bp->b_bcount, buf_iatsz(bp));
  541         else if(sd_debug)
  542                 printf("M");
  543 #endif SDDEBUG
  544 
  545         /*
  546          * Limit the xfer (because of SCSI command spec)
  547          * to no more that 255 blocks
  548          * at a time (note: 256 blocks are possible).
  549          * 255 limit is based on paranoia. A zero count
  550          * in the command structure results in xfer of 256 blocks.
  551          */
  552         if(bp->b_bcount > 255*DEV_BSIZE)
  553                 bp->b_bcount = 255*DEV_BSIZE;   
  554 }
  555 
  556 
  557 /*
  558  * sdwrite      -       Standard raw write procedure.
  559  */
  560 sdwrite(dev, uio)
  561         dev_t   dev;
  562         struct uio *uio;
  563 {
  564         int err, diff;
  565         off_t lim;
  566 
  567 #ifdef SDDEBUG
  568         ASSERT(SD_UNIT(dev) <sdmaxminor, "sdwrite dev");
  569         if(sd_debug>1)
  570                 printf("Dev=0x%x\n", dev);
  571 #endif SDDEBUG
  572 
  573 #ifndef MACH
  574         lim = (sdifd[SD_UNIT(dev)])->sd_part[SD_PART(dev)].p_length;
  575         lim <<= DEV_BSHIFT;
  576         err = physck(lim, uio, B_WRITE, &diff);
  577         if (err != 0) {
  578                 if (err == -1)  /* not an error, but request of 0 bytes */
  579                         err = 0;
  580                 return(err);
  581         }
  582         err = physio(sdstrat, (struct buf *)0, dev, B_WRITE, sdminphys, uio);
  583         uio->uio_resid += diff;
  584 #else   MACH
  585         err = physio(sdstrat, &sdbuf, dev, B_WRITE, sdminphys, uio);
  586 #endif  MACH
  587         return(err);
  588 }
  589 
  590 
  591 /*
  592  * sdread       -       Standard raw read procedure.
  593  */
  594 sdread(dev, uio)
  595         dev_t   dev;
  596         struct uio *uio;
  597 {
  598         int err, diff;
  599         off_t lim;
  600 
  601 #ifdef SDDEBUG
  602         ASSERT(SD_UNIT(dev) < sdmaxminor, "sdread dev");
  603         if(sd_debug>1)
  604                 printf("Dev=0x%x\n", dev);
  605 #endif SDDEBUG
  606 
  607 #ifndef MACH
  608         lim = (sdifd[SD_UNIT(dev)])->sd_part[SD_PART(dev)].p_length;
  609         lim <<= DEV_BSHIFT;
  610         err = physck(lim, uio, B_READ, &diff);
  611         if (err != 0) {
  612                 if (err == -1)  /* not an error, but request of 0 bytes */
  613                         err = 0;
  614                 return(err);
  615         }
  616         err = physio(sdstrat, (struct buf *)0, dev, B_READ, sdminphys, uio);
  617         uio->uio_resid += diff;
  618 #else   MACH
  619         err = physio(sdstrat, &sdbuf, dev, B_READ, sdminphys, uio);
  620 #endif  MACH
  621         return(err);
  622 }
  623 
  624 
  625 /*
  626  * sdstrat - SCSI strategy routine.
  627  *      check the block sizes and limits.
  628  *
  629  * TMP assumptions:
  630  *      Only one processor can access the sd_info structure for the
  631  *      state variable on each devices channel. Interrupts will block
  632  *      and spin on this lock for each channel. 
  633  *
  634  *      Concurrent interrupts on different channels is assumed possible.
  635  */
  636 sdstrat(bp)
  637         register struct buf     *bp;
  638 {
  639         register struct sd_partition *pt;
  640         register struct sd_info *ifd;
  641         register struct buf *bufh;
  642         int     length;
  643         int     x;
  644 
  645         
  646         ifd = sdifd[SD_UNIT(bp->b_dev)];
  647         pt = &(ifd->sd_part)[SD_PART(bp->b_dev)];
  648 
  649         /* 
  650          * length of the partition is computed as the size of the disk minus
  651          * partition start if the length is specified as SD_END.
  652          */
  653 
  654         if (pt->p_length == SD_END)
  655                 length = ifd->sd_size - pt->p_start;
  656         else
  657                 length = pt->p_length;
  658 
  659 #ifdef SDDEBUG
  660         if(sd_debug >1) {
  661                 printf("ifd=0x%x, pt=0x%x un=%d p=%d ", ifd, pt, SD_UNIT(bp->b_dev), SD_PART(bp->b_dev));
  662                 printf("start=%d, len=%d,\n", pt->p_start, length);
  663                 printf("sdstrat(%s) bp=0x%x, dev=0x%x, cnt=%d, blk=0x%x, vaddr=0x%x\n",
  664                         (bp->b_flags & B_READ) ? "READ" : "WRITE",
  665                         bp, bp->b_dev, bp->b_bcount, bp->b_blkno,
  666                         bp->b_un.b_addr);
  667                 ASSERT(ifd!=0,"sdstrat: ifd ptr zero");
  668                 ASSERT(ifd->sd_part!=0,"sdstrat: partition ptr zero");
  669         } else if(sd_debug)
  670                 printf("%s", (bp->b_flags & B_READ) ? "r" : "w");
  671 #endif SDDEBUG
  672 
  673         bufh = &ifd->sd_bufh;
  674 
  675         /*
  676          * Size and partitioning check.
  677          *
  678          * Fail request if bogus byte count, if address not aligned to
  679          * SD_ADDRALIGN boundary, or if transfer is not entirely within a
  680          * disk partition.
  681          */
  682         if ((bp->b_bcount <= 0)
  683         ||  (((int)bp->b_un.b_addr & (SD_ADDRALIGN - 1)) != 0)
  684         ||  (bp->b_blkno >= length)
  685         ||  ((bp->b_blkno + howmany(bp->b_bcount, DEV_BSIZE)) > length)) {
  686                 bp->b_resid = 0;                /* must be 0 when done! */
  687                 bp->b_flags |= B_ERROR;
  688                 bp->b_error = EINVAL;
  689                 iodone(bp);
  690                 return;
  691         }
  692 
  693         bp->b_resid = bp->b_blkno + pt->p_start;        /* for disksort */
  694 
  695         /*
  696          * Note: To this point in the procedure only static data
  697          * has been accessed.
  698          */
  699          
  700         x = p_lock(&ifd->sd_lock, SDSPL);
  701         disksort(bufh, bp);
  702         if(bufh->b_active == SDS_IDLE) {
  703                 bufh->b_active = SDS_BUSY;
  704                 sdstart(bufh, ifd);
  705         }
  706         v_lock(&ifd->sd_lock, x);
  707 }
  708 
  709 /*
  710  * sdstart - start a request to a channel.
  711  *
  712  * TMP concerns - bufh access mutexed above.
  713  * Assumptions:
  714  *      device program pointers are filled in at boot time
  715  *      iat table pointers in ifd->sd_dc->dc_iat are filled in at boot time.
  716  *
  717  */
  718 
  719 sdstart(bufh, ifd)
  720         register struct buf *bufh;
  721         register struct sd_info *ifd;
  722 {
  723         register struct seddc   *dc;            /* Device control block */
  724         register struct sec_dev_prog *devp;     /* Device program pointer */
  725         register struct buf     *bp;            /* First request from system */
  726         struct  buf             *qbp;           /* Last request made to device*/
  727         struct  sec_iat         *iat;           /* Base iat pointer */
  728         struct  sec_progq       *diq;           /* Device input queue */
  729         unsigned char           head;           /* Diq head value */
  730         int     numiat;                         /* Number of iats needed */
  731         int     numqueue;                       /* Number taken off each start */
  732         int     dstart;                         /* Begining of empty slots */
  733 
  734 
  735         if(bufh->b_actf == NULL)                /* Check for requests */
  736                 return;
  737         
  738         numqueue = ifd->sd_thresh;
  739 
  740         qbp = &ifd->sd_bp;
  741         dc = ifd->sd_dc;
  742         dstart = dc->dc_dfree;
  743         
  744         /*
  745          * We have at least one request to the disk so start it up.
  746          * Does not assume there is space for a request in the input queue.
  747          */
  748         for(;;) {                                       /* ever */
  749                 /*
  750                  * All completed?
  751                  */
  752                 if((bp=bufh->b_actf) == NULL)           /* No more to queue */
  753                         break;
  754 
  755 #ifdef SDDEBUG
  756         if(sd_debug>1) 
  757                 printf("bp=0x%x,ifd=0x%x,bufh=0x%x,bp=0x%x\n",bufh->b_actf, ifd ,bufh, bp);
  758 #endif SDDEBUG
  759 
  760                 /*
  761                  * See if there is room on the devices input queue
  762                  * and allocate the number of iat's needed for this
  763                  * request.
  764                  */
  765                 if(dc->dc_dfree<=2) {
  766                         ASSERT(qbp->b_actf != NULL, "sd: deadlock, no room & no requests");
  767                         ASSERT(dc->dc_dfree>=0, "sd: dfree < zero");
  768 
  769                         /*
  770                          * Check to see if the device has plenty of devp's 
  771                          * in the queue and if the queue is full wait till 
  772                          * it drains down so that disksorting is even more 
  773                          * affective.
  774                          */
  775                         ifd->sd_flags |= SDF_NOSTART;
  776 #ifdef SDDEBUG
  777                         if(sd_debug)
  778                                 printf("F");
  779 #endif SDDEBUG
  780                         break;
  781                 }
  782                 
  783                 /* 
  784                  * Allocate the iat's and handle wrap around.
  785                  */
  786                 numiat = sdiatsz(bp, dc);
  787                 if(numiat==0) {
  788 #ifdef SDDEBUG
  789                         if(sd_debug)
  790                                 printf("i");
  791 #endif SDDEBUG
  792                         break;                          /* Not enough for this one */
  793                 }
  794                 
  795 #ifndef MACH
  796                 /*
  797                  * Mark the idle to non idle time stamp on all units.
  798                  */
  799                 if(dc->dc_dfree != dc->dc_dsz)          /* all device programs free */
  800                         ifd->sd_starttime = time;
  801 #endif  MACH                    
  802                 dc->dc_dfree--;                         /* Allocate a device program */
  803 #ifdef SDDEBUG
  804                 if((dc->dc_dfree+1) == dc->dc_dsz)      
  805                         ASSERT(qbp->b_actf == NULL, "sdstart: qbp Non NULL");
  806 #endif SDDEBUG
  807 
  808                 /*
  809                  * Seems there is room on the input queue, so do this request.
  810                  */
  811                 diq = dc->dc_diq;
  812                 iat = dc->dc_istart;
  813                 head = diq->pq_head;
  814                 devp = PHYSTOKV((diq->pq_un.pq_progs)[head],
  815                                 struct sec_dev_prog *);
  816 #ifdef SDDEBUG
  817         if(sd_debug>2)
  818                 printf("devp=0x%x diq=0x%x head=%d numiat=%d\n", devp, diq, head, numiat);
  819 #endif SDDEBUG
  820                 
  821 
  822 
  823                 /*
  824                  * fill out the iat and the device program to be loaded
  825                  */
  826                 buf_iat(bp, iat, numiat);
  827                 devp->dp_un.dp_iat = (struct sec_iat *)
  828                         (KVTOPHYS(iat, int) | SEC_IAT_FLAG);
  829                 devp->dp_data_len = roundup(bp->b_bcount, DEV_BSIZE);
  830 #ifdef  MACH
  831                 devp->dp_cmd_len = SD_CMD6SZ;
  832 #else
  833                 devp->dp_cmd_len = (bp->b_flags&B_IOCTL) ? SD_IOCTL(bp) : SD_CMD6SZ;
  834 #endif  MACH
  835                 devp->dp_status1 = '';
  836                 devp->dp_status2 = '';
  837 
  838                 ASSERT(devp->dp_next==NULL,"sd: next_com ");
  839                 ASSERT(bp->b_bcount>0, "sd: bcount");
  840                 ASSERT(devp->dp_cmd_len==6, "sd:SCSI length");
  841 
  842                 /*
  843                  * The SCSI command itself.
  844                  */
  845 #ifdef  MACH
  846                 {
  847 #else   MACH
  848                 if(bp->b_flags & B_IOCTL) {             /* SCSI command */
  849                         panic("sd: no support in start for cmd type\n");
  850                         /* Should be just a bcopy and a check on the lun */
  851                 }else{
  852 #endif  MACH
  853                         devp->dp_cmd[0]  =  (bp->b_flags&B_READ) ? SDC_READ : SDC_WRITE;        /* install cmd */
  854                         devp->dp_cmd[1] = ifd->sd_lun | (u_char)((int)bp->b_resid >> 16);       /* msb blk number */
  855                         devp->dp_cmd[2] = (u_char)((int)bp->b_resid >> 8);
  856                         devp->dp_cmd[3] = (u_char)(bp->b_resid);                                /* lsb blk number */
  857                         devp->dp_cmd[4] = (u_char)howmany(bp->b_bcount,DEV_BSIZE);                      /* number of blks */
  858                         devp->dp_cmd[5] = 0;                                                    /* status, always 0 */
  859                 }
  860 
  861                 /*
  862                  * Increment the device input queue.
  863                  */
  864                 diq->pq_head = (head+1) % dc->dc_dsz;
  865 
  866                 /* 
  867                  * dequeue this request from the main buffer queue
  868                  */
  869 #ifdef SDDEBUG
  870         if(sd_debug>3)
  871                 printf("qbp=0x%x, b_actf=0x%x, b_actl=0x%x, bp=0x%x, f=0x%x, l=0x%x\n",
  872                         qbp, qbp->b_actf, qbp->b_actl, bp, bp->b_actf, bp->b_actl);
  873         else if(sd_debug)
  874                 printf("s");
  875 #endif SDDEBUG
  876                 if(qbp->b_actf == NULL)
  877                         qbp->b_actf = bp;
  878                 else
  879                         qbp->b_actl->b_actf = bp;
  880                 qbp->b_actl = bp;
  881                 bufh->b_actf = bp->b_actf;
  882                 bp->b_actf = NULL;                      /* Interrupt sanity */
  883 #ifdef SDDEBUG
  884                 if(bufh->b_actf == NULL)                /* XXX */
  885                         ASSERT(qbp->b_actf != NULL, "sdstart:qbp NULL bufh NULL");
  886 #endif SDDEBUG
  887 
  888                 if(--numqueue <= 0)                     /* Only take sd_thresh at a time, and at least one! */
  889                         break;
  890         }
  891         
  892         /*
  893          * To kick or not to kick, that is the question...
  894          *
  895          * Here we decide if there is a need to interrupt
  896          * the board. Here send an interrupt on the first
  897          * two queued request then none until it drains off.
  898          */
  899         if(dstart+1 >=dc->dc_dsz) {
  900 
  901                 ifd->sd_stat = 0;                       /* zap return status */
  902 
  903                 /*
  904                  * Start the requests out.
  905                  */
  906                 sec_startio(    SINST_STARTIO,          /* command */
  907                                 &ifd->sd_stat,          /* return status loc */
  908                                 ifd->sd_desc
  909                         );
  910 
  911                 if(ifd->sd_stat != SINST_INSDONE) {
  912                         printf("sd: Device Status Error 0x%x SCED dev#=0x%x\n",
  913                                 ifd->sd_stat,   ifd->sd_desc->sd_chan
  914                         );
  915                         panic("sd: SCED hard error status");
  916                 }
  917         }
  918 }
  919 
  920 /*
  921  * sdiatsz(bp, dc) -    get the number of iats needed for this request
  922  *                      and adjust the iat queue.
  923  * returns the number of iat's used.
  924  */
  925 int
  926 sdiatsz(bp, dc)
  927         register struct buf *bp;
  928         register struct seddc *dc;
  929 {
  930         register int tail;
  931         register int needed;
  932         int     head;
  933 
  934         needed = buf_iatsz(bp);         /* How many needed for this request */
  935 #ifdef SCSIFIRMWARE_SANITY
  936         needed++;
  937 #endif SCSIFIRMWARE_SANITY
  938         /* 
  939          * check for wraparound.
  940          */
  941         head = dc->dc_ihead;
  942         tail = dc->dc_itail;
  943 
  944         /*
  945          * If the head and tail pointers are equal then
  946          * start over at the beginning to handle the largest
  947          * size request generated by minphys. This allows
  948          * the device to block waiting for iats to freeup
  949          * because they aren't contiguous.
  950          */
  951         if(head==tail) 
  952                 head = tail = dc->dc_ihead = dc->dc_itail = 0;
  953 #ifdef SDDEBUG
  954         if(head==tail)
  955                 ASSERT(dc->dc_ifree==dc->dc_isz, "head says free");
  956 #endif SDDEBUG
  957         
  958 
  959         /*
  960          * See if there is enough room.
  961          * Note: It is possible to have a case
  962          * where the number of iat's goes off the
  963          * end and even though there are enough iats
  964          * for the request the iat's aren't contiguous,
  965          * the second test handles this.
  966          */
  967         if( dc->dc_ifree<=needed
  968         || ((tail + needed > dc->dc_isz)
  969         && (needed >= head))) {
  970 #ifdef SDDEBUG
  971                 if(sd_debug>1)
  972                         printf("ifree %d<%d needed\n", dc->dc_ifree, needed);
  973 #endif SDDEBUG
  974                 return(0);              /* Not enough */
  975         }
  976         
  977         if(tail+needed > dc->dc_isz) {
  978                 dc->dc_ifree -= (dc->dc_isz - tail + needed);
  979                 tail = needed;          /* Wrap it around */
  980                 dc->dc_istart = (struct sec_iat *)&(dc->dc_iat)[0];
  981         }else{
  982                 tail = (dc->dc_itail+needed) % dc->dc_isz;
  983                 dc->dc_istart = (struct sec_iat *)&(dc->dc_iat)[dc->dc_itail];/* tell the start */
  984                 dc->dc_ifree -= needed;
  985         }
  986         dc->dc_itail = tail;                    /* reflect the allocation */
  987 
  988 #ifdef SCSIFIRMWARE_SANITY
  989         /*
  990          * zero all iat's before filling them in to insure that the last one
  991          * contains a count of zero for the firmware sanity to be enabled.
  992          */
  993         bzero((char *) dc->dc_istart, (u_int) needed*sizeof(struct sec_iat));
  994 #endif SCSIFIRMWARE_SANITY
  995 
  996 #ifdef SDDEBUG
  997         if(sd_debug>1)
  998                 printf("Need %d iat's starting at 0x%x\n", needed, dc->dc_istart);
  999         ASSERT(dc->dc_itail<dc->dc_isz, "sdiat: iat overflow");
 1000 #endif SDDEBUG
 1001 
 1002         return(needed);
 1003 }
 1004 
 1005 /*
 1006  * sdiatfree(bp, dc) -  free the number of iats needed for this request
 1007  *                      and adjust the iat queue.
 1008  * Assumes that this is in sync with sdiatsz above for wrap around.
 1009  */
 1010 sdiatfree(bp, dc)
 1011         register struct buf *bp;
 1012         register struct seddc *dc;
 1013 {
 1014         register int free;
 1015         register int head;
 1016 
 1017         free = buf_iatsz(bp);           /* How many needed for this request */
 1018 #ifdef SCSIFIRMWARE_SANITY
 1019         free++;
 1020 #endif SCSIFIRMWARE_SANITY
 1021         /* 
 1022          * check for wraparound.
 1023          */
 1024         head = dc->dc_ihead;
 1025         
 1026         if(head+free > dc->dc_isz) {
 1027                 dc->dc_ifree += (dc->dc_isz - head + free);
 1028                 head = free;            /* Wrap it around */
 1029         }else{
 1030                 head = (head+free) % dc->dc_isz;
 1031                 dc->dc_ifree += free;
 1032         }
 1033         dc->dc_ihead = head;                    /* reflect the allocation */
 1034 
 1035 #ifdef SDDEBUG
 1036         if(sd_debug>1)
 1037                 printf("freed %d iat's\n", free);
 1038         ASSERT(dc->dc_ihead<dc->dc_isz, "sdiatfree: iat underflow");
 1039         ASSERT(dc->dc_ifree<=dc->dc_isz,"sdintr: ring overrun");
 1040         ASSERT(dc->dc_ifree>=0,"sdintr: ring underflow");
 1041 #endif SDDEBUG
 1042 }
 1043 
 1044 #undef SCSIFIRMWARE_SANITY
 1045 
 1046 /*
 1047  * sdintr(level) - interrupt routine.
 1048  *
 1049  * While there are outstanding requests that have completed
 1050  * service and complete them.
 1051  */
 1052 
 1053 sdintr(level)
 1054         int     level;
 1055 {
 1056         register struct sd_info *ifd = sdifd[level-sd_baselevel];
 1057         register struct seddc *dc;
 1058         register struct buf *bp;
 1059         register struct sec_progq *doq;
 1060         register struct sec_dev_prog *devp;
 1061         struct  buf *qbp;
 1062         struct  buf *bufh;
 1063         int     tail;
 1064         spl_t   x;
 1065 
 1066 #ifdef SDDEBUG
 1067         int     dfreexxx;               /* XXXX */
 1068 
 1069         ASSERT(level-sd_baselevel>=0, "sdintr: config bad, level negative check baselevel");
 1070         ASSERT(level-sd_baselevel<sdmaxminor, "sdintr: config bad, vec maps no-device");
 1071         if(sd_debug>2)
 1072                 printf("sdintr: ifd=0x%x, level %d\n",ifd, level-sd_baselevel);
 1073         else if(sd_debug)
 1074                 printf("I");
 1075 #endif SDDEBUG
 1076 
 1077 
 1078         ASSERT(ifd!=0,"sdintr: interrupt to non-configured device");
 1079 
 1080         qbp = &ifd->sd_bp;
 1081         dc = ifd->sd_dc;
 1082         doq = dc->dc_doq;
 1083         bufh = &ifd->sd_bufh;
 1084 
 1085         x = p_lock(&ifd->sd_lock, SDSPL);
 1086 
 1087 #ifdef SDDEBUG
 1088         for(dfreexxx=dc->dc_dfree, bp=qbp->b_actf; dfreexxx<dc->dc_dsz; bp=bp->b_actf,dfreexxx++)                                               /* XXXX */
 1089                 ASSERT(bp != NULL, "sdintr:Lost a bp");         /* XXXX */
 1090         ASSERT(bp==NULL,"sdintr:Extra bps");                    /* XXXX */
 1091 #endif SDDEBUG
 1092 
 1093 
 1094         for(;;) {               /* ever */
 1095                 
 1096                 if((bp = qbp->b_actf) == NULL)  /* current request */
 1097                         break;                          /* all done... */
 1098 
 1099                 if(doq->pq_tail == doq->pq_head)        /* All done */
 1100                         break;
 1101 
 1102                 tail = doq->pq_tail;
 1103                 devp = PHYSTOKV((doq->pq_un.pq_progs)[tail],
 1104                                 struct sec_dev_prog *);
 1105                 doq->pq_tail = (tail+1) % dc->dc_dsz;   /* tail ptr */
 1106                 /*
 1107                  * Check for command completion
 1108                  */
 1109                 if(devp->dp_status1 != SEC_ERR_NONE) {
 1110                         printf("sdintr: status1=%d\n", devp->dp_status1);
 1111                         /*
 1112                          * Insert a rezero unit command iff it is known that
 1113                          * this command will not hard error the device and the
 1114                          * command is not a rezero command!
 1115                          */
 1116                         if(ifd->sd_retrys > 0 && devp->dp_cmd[0] != SCSI_REZERO)
 1117                                 sd_rezero_insert(dc->dc_diq, devp->dp_cmd[1]&SDLUNMSK, dc->dc_dsz);
 1118                         ifd->sd_savedp = devp;          /* save it to print it later */
 1119                         ifd->sd_flags |= SDF_SENSE;     /* DO request sense */
 1120                         devp->dp_status1 = 0;           /* remove error condition */
 1121                         /*
 1122                          * fill in request sense dp and issue
 1123                          * a request sense command.
 1124                          *
 1125                          * Todo: move next 9 lines to sdboot()
 1126                          * because it's static (get it working first!)
 1127                          */
 1128                         ifd->sd_statb.rs_dev_prog.dp_un.dp_data =
 1129                             ifd->sd_sensebufptr;
 1130                         ifd->sd_statb.rs_dev_prog.dp_next = 0;
 1131                         ifd->sd_statb.rs_dev_prog.dp_count = 0;
 1132                         ifd->sd_statb.rs_dev_prog.dp_data_len = sdsensebuf_sz;
 1133                         ifd->sd_statb.rs_dev_prog.dp_cmd_len = 6;
 1134                         ifd->sd_statb.rs_dev_prog.dp_status1 = 0;
 1135                         ifd->sd_statb.rs_dev_prog.dp_status2 = 0;
 1136                         ifd->sd_statb.rs_dev_prog.dp_cmd[0] = SDC_REQUEST_SENSE; 
 1137                         ifd->sd_statb.rs_dev_prog.dp_cmd[4] = (u_char)sdsensebuf_sz;
 1138                         ifd->sd_statb.rs_dev_prog.dp_cmd[1] = devp->dp_cmd[1] & SDLUNMSK; /* Masked lun in */
 1139                         ifd->sd_statb.rs_status = 0;
 1140 
 1141                         sec_startio( SINST_REQUESTSENSE,
 1142                                 (volatile int *)&ifd->sd_statb,
 1143                                 ifd->sd_desc
 1144                         );
 1145                         v_lock(&ifd->sd_lock, x);
 1146                         return;
 1147                 }
 1148 
 1149                 if(ifd->sd_flags & SDF_SENSE) {
 1150                         ifd->sd_flags &= ~SDF_SENSE;
 1151 #ifdef SDDEBUG
 1152                         if(sd_debug) {
 1153                                 int     i;
 1154 
 1155                                 printf("Request sense bytes: ");
 1156                                 for(i=0; i<sdsensebuf_sz; i++)
 1157                                         printf("0x%x ", ifd->sd_sensebuf[i]);
 1158                                 printf("\n");
 1159                                 printf("Device prog: ");
 1160                                 for(i=0; i<6; i++)
 1161                                         printf("0x%x ", devp->dp_cmd[i]);
 1162                                 printf("\n");
 1163                         }
 1164 #endif SDDEBUG
 1165                         devp->dp_status1 = (u_char)(((ifd->sd_sensebuf[0]&SDKEY) == SDKEY) ? ifd->sd_sensebuf[2]:ifd->sd_sensebuf[0]);
 1166 
 1167 #ifdef notdef
 1168                         if (((ifd->sd_sensebuf[0] & SDKEY) == SDKEY) &&
 1169                           ((ifd->sd_sensebuf[2] & SD_SENSEKEYMASK) == SD_RECOVERED)) {
 1170 
 1171                                 /*
 1172                                  * recovered error on CCS disks.  Means the
 1173                                  * drive discovered an error, but corrected it,
 1174                                  * and we need not try it again.
 1175                                  */
 1176                                 printf("Soft error dev <0x%x,0x%x>, blk=0x%x, cnt=%d err=0x%x\n",
 1177                                         major(bp->b_dev), minor(bp->b_dev),
 1178                                         bp->b_blkno, bp->b_bcount,
 1179                                         devp->dp_status1
 1180                                 );
 1181                                 printf("(Drive recovered)\n");
 1182 
 1183                                 /*
 1184                                  * Print out all information about
 1185                                  * the error as possible.
 1186                                  */
 1187                                 {
 1188                                         int     i, j;
 1189                                         
 1190                                         i = sdsensebuf_sz;
 1191                                         printf("LBA: %d\n",
 1192                                                 XgetLBA(ifd->sd_sensebuf));
 1193                                         printf("Request sense bytes: ");
 1194                                         for(j=0; j<i; j++)
 1195                                                 printf("0x%x ", ifd->sd_sensebuf[j]);
 1196                                         printf("\n");
 1197                                         /*
 1198                                          * print out the error'ing device program
 1199                                          */
 1200                                         printf("Device prog: ");
 1201                                         for(i=0; i<6; i++)
 1202                                                 printf("0x%x ", ifd->sd_savedp->dp_cmd[i]);
 1203                                         printf("\n");
 1204                                 }
 1205 
 1206                                 devp->dp_status1 = SEC_ERR_NONE; /* fake it */
 1207 
 1208                                 sec_startio( SINST_RESTARTIO,
 1209                                         &ifd->sd_stat,
 1210                                         ifd->sd_desc
 1211                                 );
 1212                         } else
 1213 #endif notdef
 1214                         if(ifd->sd_retrys--) {          /* retry it */
 1215 
 1216                                 printf("Soft error dev <0x%x,0x%x>, blk=0x%x, cnt=%d err=0x%x\n",
 1217                                         major(bp->b_dev), minor(bp->b_dev),
 1218                                         bp->b_blkno, bp->b_bcount,
 1219                                         devp->dp_status1
 1220                                 );
 1221 
 1222                                 /*
 1223                                  * Print out all information about
 1224                                  * the error as possible.
 1225                                  */
 1226                                 {
 1227                                         int     i, j;
 1228                                         
 1229                                         if((ifd->sd_sensebuf[0]&SDKEY) == SDKEY){
 1230                                                 i = sdsensebuf_sz;
 1231                                                 printf("LBA: %d\n",
 1232                                                         XgetLBA(ifd->sd_sensebuf));
 1233                                         }else{
 1234                                                 i = 4;
 1235                                                 printf("LBA: %d\n",
 1236                                                         getLBA(ifd->sd_sensebuf));
 1237                                         }
 1238                                         printf("Request sense bytes: ");
 1239                                         for(j=0; j<i; j++)
 1240                                                 printf("0x%x ", ifd->sd_sensebuf[j]);
 1241                                         printf("\n");
 1242                                         /*
 1243                                          * print out the error'ing device program
 1244                                          */
 1245                                         printf("Device prog: ");
 1246                                         for(i=0; i<6; i++)
 1247                                                 printf("0x%x ", ifd->sd_savedp->dp_cmd[i]);
 1248                                         printf("\n");
 1249                                 }
 1250 
 1251                                 devp->dp_status1 = SEC_ERR_NONE; /* fake it */
 1252                                 sec_startio( SINST_RESTARTCURRENTIO,
 1253                                         &ifd->sd_stat,
 1254                                         ifd->sd_desc
 1255                                 );
 1256 
 1257                                 v_lock(&ifd->sd_lock, x);
 1258                                 return;
 1259                         }else{
 1260                                 printf("Hard error dev <0x%x,0x%x>, blk=0x%x, cnt=%d err=0x%x\n",
 1261                                         major(bp->b_dev), minor(bp->b_dev),
 1262                                         bp->b_blkno, bp->b_bcount,
 1263                                         devp->dp_status1
 1264                                 );
 1265 
 1266                                 /*
 1267                                  * Print out all information about
 1268                                  * the error as possible.
 1269                                  */
 1270                                 {
 1271                                         int     i, j;
 1272                                         
 1273                                         if((ifd->sd_sensebuf[0]&SDKEY) == SDKEY){
 1274                                                 i = sdsensebuf_sz;
 1275                                                 printf("LBA: %d\n",
 1276                                                         XgetLBA(ifd->sd_sensebuf));
 1277                                         }else{
 1278                                                 i = 4;
 1279                                                 printf("LBA: %d\n",
 1280                                                         getLBA(ifd->sd_sensebuf));
 1281                                         }
 1282                                         printf("Request sense bytes: ");
 1283                                         for(j=0; j<i; j++)
 1284                                                 printf("0x%x ", ifd->sd_sensebuf[j]);
 1285                                         printf("\n");
 1286                                         /*
 1287                                          * print out the error'ing device program
 1288                                          */
 1289                                         printf("Device prog: ");
 1290                                         for(i=0; i<6; i++)
 1291                                                 printf("0x%x ", ifd->sd_savedp->dp_cmd[i]);
 1292                                         printf("\n");
 1293                                 }
 1294 
 1295                                 devp->dp_status1 = SEC_ERR_NONE; /* fake it */
 1296 
 1297                                 /* 
 1298                                  * Uncorrectable error occured.
 1299                                  */
 1300                                 bp->b_flags |= B_ERROR;
 1301                                 sec_startio( SINST_RESTARTIO,
 1302                                         &ifd->sd_stat,
 1303                                         ifd->sd_desc
 1304                                 );
 1305                         }
 1306                 }
 1307 
 1308                 devp->dp_status1 = SEC_ERR_NONE;                /* Paranoid */
 1309 
 1310                 /*
 1311                  * Avoid looping forever on retries.
 1312                  */
 1313                 if(devp->dp_cmd[0] == SCSI_REZERO)
 1314                         continue;
 1315 
 1316                 ifd->sd_retrys = sdretrys;
 1317                 /*
 1318                  * Adjust queues
 1319                  */
 1320                 qbp->b_actf = bp->b_actf;
 1321                 bp->b_actf = 0;
 1322                 dc->dc_dfree++;
 1323 
 1324 #ifndef MACH
 1325                 /*
 1326                  * Update stats for xfers and blks and
 1327                  * mark do time stamp magic if all device programs
 1328                  * are free. Note: sd_dk may not be a valid ptr on all units.
 1329                  */
 1330                 if(ifd->sd_stat_unit != SD_NO_UNIT) {
 1331                         ifd->sd_dk->dk_xfer++;
 1332                         ifd->sd_dk->dk_blks += howmany(bp->b_bcount, DEV_BSIZE);
 1333                         
 1334                         if(dc->dc_dfree == dc->dc_dsz) {
 1335                                 struct  timeval elapsed;
 1336                                 
 1337                                 elapsed = time;
 1338                                 timevalsub(&elapsed, &ifd->sd_starttime);
 1339                                 timevaladd(&ifd->sd_dk->dk_time, &elapsed);
 1340 
 1341                                 ASSERT(qbp->b_actf == NULL,"sdintr: free nonNULL qbp");
 1342                         }
 1343                 }
 1344 #endif  MACH
 1345                 
 1346                 sdiatfree(bp, dc);              /* free used iats */
 1347 
 1348                 bp->b_resid = 0;
 1349                 iodone(bp);
 1350 
 1351         }       /* end forever loop */
 1352         
 1353         /*
 1354          * If non-startable check to see if its time to start again
 1355          * else Start any out standing requests
 1356          */
 1357         if(ifd->sd_flags & SDF_NOSTART) {
 1358                 if((dc->dc_dsz - dc->dc_dfree) <= ifd->sd_low) {
 1359                         ifd->sd_flags &= ~SDF_NOSTART;
 1360                         sdstart(bufh, ifd);
 1361                 }
 1362         }else{
 1363                 sdstart(bufh, ifd);
 1364         }
 1365 
 1366         /*
 1367          * Device will remain busy until bufhq is sucked dry
 1368          */
 1369         if(qbp->b_actf == NULL)
 1370                 bufh->b_active = SDS_IDLE;
 1371 
 1372         v_lock(&ifd->sd_lock, x);
 1373 }
 1374 
 1375 /*
 1376  * sdioctl
 1377  */
 1378 /* ARGSUSED */
 1379 sdioctl(dev, cmd, addr)
 1380         int     cmd;
 1381         dev_t   dev;
 1382         caddr_t addr;
 1383 {
 1384         return(ENXIO);                          /* not supported yet */
 1385 }
 1386         
 1387 /*
 1388  * sdsize()
 1389  *      Used for swap-space partition calculation.
 1390  *
 1391  * Doesn't assume that the device is open or alive at all
 1392  * Hence there is more parameter checks than really needed.
 1393  * Partitions can be designated as going out to the end of the
 1394  * drive by specifying the length as SD_END.  When this is done,
 1395  * the actual drive capacity is used.
 1396  */
 1397  
 1398 sdsize(dev)
 1399         dev_t   dev;
 1400 {
 1401         int     part, unit;
 1402         register struct sd_partition *pt;
 1403         register struct sd_info *ifd;
 1404 
 1405         unit = SD_UNIT(dev);
 1406         part = SD_PART(dev);
 1407         ifd = sdifd[unit];
 1408         pt = &(ifd->sd_part)[part];
 1409 
 1410         if(ifd == NULL                          /* set in boot? */
 1411         || ifd->sd_part == NULL                 /* table present? */
 1412         || unit >= sdmaxminor                   /* Binary conf'd? */
 1413         || pt->p_length == 0                    /* valid partition? */
 1414         || !ifd->sd_desc->sd_alive)             /* Passed probing? */
 1415                 return(-1);
 1416         if (pt->p_length == SD_END)
 1417                 return(ifd->sd_size - pt->p_start);
 1418         else
 1419                 return(pt->p_length);
 1420 }
 1421 
 1422 /*
 1423  * Rezero insert 
 1424  *
 1425  * Insert a device program into the device input queue
 1426  * ahead of the current request to recalibrate the device
 1427  * (rezero unit) before a retry operation. The insertion
 1428  * must be done before the request sense command is issued
 1429  * to the device so that when the device restarts the 
 1430  * recalibration is automatic and requires no further fuss.
 1431  *
 1432  * Note: Because of this 'recommended' condition the device
 1433  * input queue may never be allowed to get empty below two
 1434  * open positions, 1 for a rezero and one for wrap testing
 1435  * for the firmware.
 1436  */
 1437 
 1438 sd_rezero_insert(diq, lun, size)
 1439         register        struct sec_progq *diq;
 1440         u_char          lun;
 1441         int             size;
 1442 {
 1443         register        struct sec_dev_prog *idevp;
 1444         register        tail;
 1445 
 1446         tail = diq->pq_tail;
 1447         if(tail==0)             /* handle wrap around */
 1448                 tail = size-1;
 1449         else 
 1450                 tail--;
 1451         /*
 1452          * get previous now unused device program pointer and use
 1453          * it for the rezero command that is being inserted.
 1454          */
 1455         idevp = KVTOPHYS((diq->pq_un.pq_progs)[tail],
 1456                         struct sec_dev_prog *);
 1457         idevp->dp_cmd[0] = SCSI_REZERO;
 1458         idevp->dp_cmd[1] = lun;
 1459         bzero((char *)&idevp->dp_cmd[2], 4);
 1460         idevp->dp_un.dp_iat = 0;
 1461         idevp->dp_data_len = 0;
 1462         idevp->dp_cmd_len = 6;
 1463         idevp->dp_status1 = '';
 1464         idevp->dp_status2 = '';
 1465 
 1466         /*
 1467          * adjust diq ptrs to reflect new device program inserted.
 1468          */
 1469         diq->pq_tail = tail;
 1470 }
 1471 
 1472 daddr_t
 1473 sdreadc(sed)
 1474         struct sec_dev *sed;
 1475 {
 1476         struct sdcap *sdcap;
 1477         u_int   nblocks = 0;            /* number of blocks on disk */
 1478         daddr_t capacity;               /* usable disk capacity */
 1479 
 1480         if (sd_docmd(SDC_READ_CAPACITY, sed) != 0)
 1481                 return((daddr_t) -1);
 1482 
 1483         sdcap = (struct sdcap *)sd_datap;
 1484 
 1485         /*
 1486          * Reverse the byte order
 1487          */
 1488 
 1489         nblocks = (sdcap->sdc_nblocks0 << 24) |
 1490                   (sdcap->sdc_nblocks1 << 16) |
 1491                   (sdcap->sdc_nblocks2 << 8)  |
 1492                   (sdcap->sdc_nblocks3) ;
 1493 
 1494         /*
 1495          * decide which kind of disk we have based on which range of
 1496          * capacities the size falls into.  This allows us to reserve the
 1497          * right ammount for the diag tracks.
 1498          */
 1499 
 1500         if      (nblocks <= 140997 && nblocks >= 140869)
 1501                 capacity = 140436;                      /* fujitsu 2243 */
 1502         else if (nblocks <= 117452 && nblocks >= 117324)
 1503                 capacity = 117096;                      /* vertex 170 */
 1504         else if (nblocks <= 234089 && nblocks >= 233961)
 1505                 capacity = 233324;                      /* maxtor 1140 */
 1506         else if (nblocks == 285039)
 1507                 capacity = 284480;                      /* microp 1375 */
 1508         else if (nblocks == 304604)
 1509                 capacity = 303975;                      /* CDC wren 3 */
 1510         else if (nblocks == 270929)
 1511                 capacity = 270270;                      /* fujitsu m2246sa */
 1512         else
 1513                 capacity = nblocks;                     /* all others */
 1514 
 1515 #ifdef SDDEBUG
 1516         if (sd_debug > 3)
 1517                 printf("sdreadc: size=%d, capacity = %d\n", nblocks, capacity);
 1518 #endif SDDEBUG
 1519 
 1520         return(capacity);
 1521 }
 1522 
 1523 
 1524 /*
 1525  * Do an sd_docmd from sdprobe().  There is not a sec_dev structure availble
 1526  * for the device at this point, so we must transmogrify the sec_probe
 1527  * struct into a sec_dev struct for sd_docmd().
 1528  */
 1529 
 1530 sd_docmd_pr(cmd,sed)
 1531         u_char cmd;
 1532         struct sec_probe *sed;
 1533 {
 1534         struct sec_dev sdev;
 1535 
 1536         sdev.sd_desc    = sed->secp_desc;
 1537         sdev.sd_target  = sed->secp_target;
 1538         sdev.sd_unit    = sed->secp_unit;
 1539         sdev.sd_chan    = sed->secp_chan;
 1540         sdev.sd_flags   = sed->secp_flags;
 1541         sdev.sd_bin     = SD_ANYBIN;
 1542 
 1543         return(sd_docmd(cmd, &sdev));
 1544 }
 1545 
 1546 /*
 1547  * Do a general SCSI command on the target adaptor.
 1548  */
 1549 
 1550 sd_docmd(cmd, sed)
 1551         u_char cmd;
 1552         struct sec_dev *sed;
 1553 {
 1554         register struct sec_powerup *iq = sed->sd_desc->sec_powerup;
 1555         register int    i;
 1556         u_char          data_length;
 1557         u_char          cmd_length;
 1558         volatile int    stat = 0;
 1559 
 1560 #ifdef SDDEBUG
 1561         if(sd_debug>3) {
 1562                 printf("sd_docmd: init_q 0x%x, slicid 0x%x stat=0x%x,",
 1563                         (int)iq, sed->sd_desc->sec_slicaddr, &stat);
 1564 
 1565                 printf(" device=%d\n", sed->sd_chan);
 1566         }
 1567         printf("sd_docmd: cmd=0x%x\n", cmd);
 1568 #endif SDDEBUG 
 1569 
 1570         bzero((caddr_t)&sd_devprog, sizeof(struct sec_dev_prog));
 1571 
 1572         switch (cmd) {
 1573 
 1574         case SDC_READ_CAPACITY:
 1575                 data_length = SDD_READC;
 1576                 cmd_length  = SD_CMD10SZ;
 1577                 break;
 1578 
 1579         case SDC_TEST:
 1580                 data_length = SDD_TEST;
 1581                 cmd_length  = SD_CMD6SZ;
 1582                 break;
 1583 
 1584         case SDC_REQUEST_SENSE:
 1585                 data_length = SDD_REQSEN;
 1586                 cmd_length  = SD_CMD6SZ;
 1587                 break;
 1588 
 1589         case SDC_MODE_SENSE:
 1590                 sd_devprog.dp_cmd[2] = SDM_ERROR;
 1591                 data_length = SDD_MODE;
 1592                 cmd_length  = SD_CMD6SZ;
 1593                 break;
 1594 
 1595         case SDC_MODE_SELECT:
 1596                 sd_devprog.dp_cmd[1] = SDM_PF;
 1597                 data_length = SDD_MODE;
 1598                 cmd_length  = SD_CMD6SZ;
 1599                 break;
 1600 
 1601         case SDC_INQUIRY:
 1602                 data_length = SDD_INQ;
 1603                 cmd_length  = SD_CMD6SZ;
 1604                 break;
 1605         }
 1606 
 1607         /*
 1608          * Fill out the device program for a single command.
 1609          */
 1610 
 1611         sd_devprog.dp_un.dp_data = sd_data_queue;
 1612         sd_devprog.dp_data_len = data_length;
 1613         sd_devprog.dp_cmd_len = cmd_length;
 1614 
 1615         /*
 1616          * fill out the CDB - command goes in byte 0 and the logical unit
 1617          * number in byte 1
 1618          */
 1619 
 1620         sd_devprog.dp_cmd[0] = cmd;
 1621         sd_devprog.dp_cmd[1] |= (unsigned char)(sed->sd_unit<<5);
 1622 
 1623         /*
 1624          * Some commands take an allocation length in byte 4 of the CDB.
 1625          */
 1626 
 1627         switch (cmd) {
 1628         case SDC_REQUEST_SENSE:
 1629         case SDC_MODE_SELECT:
 1630         case SDC_MODE_SENSE:
 1631         case SDC_INQUIRY:
 1632                 sd_devprog.dp_cmd[4] = data_length;
 1633         }
 1634 
 1635         /*
 1636          * Insert device program into SCED queue and mark I/O in progress.
 1637          */
 1638 
 1639         i = iq->pu_requestq.pq_head;
 1640         iq->pu_requestq.pq_un.pq_progs[i] =
 1641                 KVTOPHYS(&sd_devprog, struct sec_dev_prog *);
 1642         iq->pu_requestq.pq_head = (i+1) % SEC_POWERUP_QUEUE_SIZE;
 1643 
 1644         SEC_startio(SINST_STARTIO,                      /* command */
 1645                     &stat,                              /* return status loc */
 1646                     sed->sd_bin,                        /* bin number on SEC */
 1647                     sed->sd_chan,                       /* Disk channel # */
 1648                     &iq->pu_cib,                        /* device input q loc */
 1649                     (u_char)sed->sd_desc->sec_slicaddr  /* SEC slic id number */
 1650                 );
 1651 
 1652         /*
 1653          * SCSI command in progress
 1654          */
 1655 
 1656         if(stat == SINST_INSDONE) {
 1657                 
 1658                 /*
 1659                  * spin, waiting for command to complete
 1660                  */
 1661 
 1662                 while(iq->pu_doneq.pq_tail == iq->pu_doneq.pq_head)
 1663                         ;
 1664 
 1665                 /*
 1666                  * Inform the SCED that the I/O is done by updating the
 1667                  * tail of the device queue.
 1668                  */
 1669 
 1670                 iq->pu_doneq.pq_tail = 
 1671                         (iq->pu_doneq.pq_tail + 1) % SEC_POWERUP_QUEUE_SIZE;
 1672 
 1673         } else {
 1674 
 1675                 iq->pu_requestq.pq_tail = iq->pu_requestq.pq_head = 0;
 1676                 printf("sd: probe issued a totally bad command (params)\n");
 1677                 printf("sd: stat = 0x%x\n", stat);
 1678                 return(stat);
 1679         }
 1680 
 1681         if(sd_devprog.dp_status1 != SEC_ERR_NONE) {
 1682                 int cmdret;
 1683 
 1684 #ifdef SDDEBUG
 1685                 printf("sd: err status=0x%x\n", sd_devprog.dp_status1);
 1686 #endif SDDEBUG
 1687                 cmdret = sd_devprog.dp_status1 ;
 1688                 sd_devprog.dp_status1 = 0;
 1689 
 1690                 /*
 1691                  * After an error, we need to tell the SCED to keep going
 1692                  * with a RESTARTIO.
 1693                  */
 1694 
 1695                 SEC_startio(SINST_RESTARTIO, &stat, sed->sd_bin, sed->sd_chan,
 1696                         &iq->pu_cib, (u_char)sed->sd_desc->sec_slicaddr);
 1697 
 1698                 return(cmdret);
 1699         }
 1700         return(0);
 1701 }
 1702 
 1703 /*
 1704  * Get status routine
 1705  */
 1706 sdgetstat(dev, flavor, status, count)
 1707         dev_t   dev;
 1708         int     *status, *count;
 1709 {
 1710         register struct sd_partition *pt;
 1711         register struct sd_info *ifd;
 1712 
 1713         ifd = sdifd[SD_UNIT(dev)];
 1714         pt = &(ifd->sd_part)[SD_PART(dev)];
 1715 
 1716         if (flavor == DEV_GET_SIZE) {
 1717                 unsigned int length;
 1718 
 1719                 if (pt->p_length == SD_END)
 1720                         length = ifd->sd_size - pt->p_start;
 1721                 else
 1722                         length = pt->p_length;
 1723 
 1724                 status[DEV_GET_SIZE_DEVICE_SIZE] = length * DEV_BSIZE;
 1725                 status[DEV_GET_SIZE_RECORD_SIZE] = DEV_BSIZE;
 1726                 *count = DEV_GET_SIZE_COUNT;
 1727                 
 1728                 return D_SUCCESS;
 1729         } else return D_INVALID_OPERATION;
 1730 }
 1731 

Cache object: c4af50e5b9b074cb7ba9173986773e03


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