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/scsi_tape.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,1990 Carnegie Mellon University
    4  * All Rights Reserved.
    5  * 
    6  * Permission to use, copy, modify and distribute this software and its
    7  * documentation is hereby granted, provided that both the copyright
    8  * notice and this permission notice appear in all copies of the
    9  * software, derivative works or modified versions, and any portions
   10  * thereof, and that both notices appear in supporting documentation.
   11  * 
   12  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
   13  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
   14  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
   15  * 
   16  * Carnegie Mellon requests users of this software to return to
   17  * 
   18  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
   19  *  School of Computer Science
   20  *  Carnegie Mellon University
   21  *  Pittsburgh PA 15213-3890
   22  * 
   23  * any improvements or extensions that they make and grant Carnegie Mellon
   24  * the rights to redistribute these changes.
   25  */
   26 /*
   27  * HISTORY
   28  * $Log:        scsi_tape.c,v $
   29  * Revision 2.15  93/05/10  21:23:17  rvb
   30  *      Always pass density code down. Fixed log.
   31  *      [93/04/09            af]
   32  * 
   33  * Revision 2.14  92/08/03  17:55:37  jfriedl
   34  *      removed silly prototypes
   35  *      [92/08/02            jfriedl]
   36  * 
   37  * Revision 2.13  92/05/21  17:24:52  jfriedl
   38  *      Cleanup to quiet gcc warnings.
   39  *      [92/05/16            jfriedl]
   40  * 
   41  * Revision 2.12  92/02/23  22:45:07  elf
   42  *      Changed the interface of a number of functions not to
   43  *      require the scsi_softc pointer any longer.  It was
   44  *      mostly unused, now it can be found via tgt->masterno.
   45  *      [92/02/22  19:29:10  af]
   46  * 
   47  * Revision 2.11  91/11/12  11:17:27  rvb
   48  *      Deal with fixed-size tapes more gracefully: fixed a bug in
   49  *      read (incorrectly called the go routine with the number of
   50  *      blocks rather than the number of bytes), in mode select
   51  *      set the block size too.
   52  *      We seem to be happy with DEC TZK10s now.
   53  *      [91/10/30  13:39:34  af]
   54  * 
   55  * Revision 2.10  91/08/24  12:29:16  af
   56  *      Support for fixed-size-tapes: careful about speed selections,
   57  *      round sizes properly, use fixed bit.
   58  *      [91/08/02  03:58:18  af]
   59  * 
   60  * Revision 2.9  91/06/19  11:58:13  rvb
   61  *      File moved here from mips/PMAX since it is now "MI" code, also
   62  *      used by Vax3100 and soon -- the omron luna88k.
   63  *      [91/06/04            rvb]
   64  * 
   65  * Revision 2.8  91/05/14  17:31:26  mrt
   66  *      Correcting copyright
   67  * 
   68  * Revision 2.7  91/05/13  06:35:55  af
   69  *      Cleaned up mode_select, vendor unique data can be passed
   70  *      in if necessary.  Density and speed are taken from target 
   71  *      structure.  Added rewind command and all th eothers that
   72  *      were missing (but what we do not use is disabled).
   73  * 
   74  * Revision 2.6  91/02/05  17:46:24  mrt
   75  *      Added author notices
   76  *      [91/02/04  11:20:18  mrt]
   77  * 
   78  *      Changed to use new Mach copyright
   79  *      [91/02/02  12:19:07  mrt]
   80  * 
   81  * Revision 2.5  90/12/05  23:35:49  af
   82  *      Mild attempt to get it working.  Actually wrote and read
   83  *      back a tape.
   84  *      [90/12/03  23:49:49  af]
   85  * 
   86  * Revision 2.3.1.1  90/11/01  03:40:30  af
   87  *      Created, from the SCSI specs:
   88  *      "Small Computer Systems Interface (SCSI)", ANSI Draft
   89  *      X3T9.2/82-2 - Rev 17B December 1985
   90  *      "Small Computer System Interface - 2 (SCSI-II)", ANSI Draft
   91  *      X3T9.2/86-109 -  Rev 10C March 1990
   92  *      [90/10/11            af]
   93  */
   94 /*
   95  *      File: scsi_tape.c
   96  *      Author: Alessandro Forin, Carnegie Mellon University
   97  *      Date:   10/90
   98  *
   99  *      Middle layer of the SCSI driver: SCSI protocol implementation
  100  *
  101  * This file contains code for SCSI commands for SEQUENTIAL ACCESS devices.
  102  */
  103 
  104 #include <mach/std_types.h>
  105 #include <scsi/compat_30.h>
  106 
  107 #include <scsi/scsi.h>
  108 #include <scsi/scsi_defs.h>
  109 
  110 
  111 
  112 
  113 
  114 char *sctape_name(internal)
  115         boolean_t       internal;
  116 {
  117         return internal ? "tz" : "tape";
  118 }
  119 
  120 void sctape_optimize(tgt)
  121         target_info_t           *tgt;
  122 {
  123         register int    i;
  124         char            result[6];
  125 
  126         /* Some (DEC) tapes want to send you the self-test results */
  127         for (i = 0; i < 10; i++) {
  128                 if (scsi_receive_diag( tgt, result, sizeof(result), 0)
  129                     == SCSI_RET_SUCCESS)
  130                         break;
  131         }
  132         if (scsi_debug)
  133                 printf("[tape_rcvdiag: after %d, x%x x%x x%x x%x x%x x%x]\n", i+1,
  134                 result[0], result[1], result[2], result[3], result[4], result[5]);
  135 }
  136 
  137 /*
  138  * SCSI commands specific to sequential access devices
  139  */
  140 int sctape_mode_select( tgt, vuque_data, vuque_data_len, newspeed, ior)
  141         register target_info_t  *tgt;
  142         unsigned char           *vuque_data;
  143         int                     vuque_data_len;
  144         int                     newspeed;
  145         io_req_t                ior;
  146 {
  147         scsi_cmd_mode_select_t  *cmd;
  148         scsi_mode_select_param_t        *parm;
  149 
  150         bzero(tgt->cmd_ptr, sizeof(*cmd) + 2 * sizeof(*parm));
  151         cmd = (scsi_cmd_mode_select_t*) (tgt->cmd_ptr);
  152         cmd->scsi_cmd_code = SCSI_CMD_MODE_SELECT;
  153         cmd->scsi_cmd_lun_and_lba1 = 0;
  154         cmd->scsi_cmd_xfer_len = sizeof(scsi_mode_select_param_t) + vuque_data_len;
  155 
  156         parm = (scsi_mode_select_param_t*) (cmd + 1);
  157         if (newspeed) {
  158                 parm->speed = tgt->dev_info.tape.speed;
  159         } else {
  160                 /* Standard sez 0 -> no change */
  161                 parm->speed = 0;
  162         }
  163         /* parm->medium_type = 0; reserved */
  164         parm->descs[0].density_code = tgt->dev_info.tape.density;
  165         parm->buffer_mode = 1;
  166         parm->desc_len = 8;
  167         if (tgt->dev_info.tape.fixed_size) {
  168                 register int reclen = tgt->block_size;
  169                 parm->descs[0].reclen1 = reclen >> 16;
  170                 parm->descs[0].reclen2 = reclen >>  8;
  171                 parm->descs[0].reclen3 = reclen;
  172         }
  173 
  174         if (vuque_data_len)
  175                 bcopy(vuque_data, (char*)(parm+1), vuque_data_len);
  176 
  177         tgt->cur_cmd = SCSI_CMD_MODE_SELECT;
  178 
  179         scsi_go_and_wait(tgt, sizeof(*cmd) + sizeof(*parm) + vuque_data_len, 0, ior);
  180 
  181         return tgt->done;
  182 }
  183 
  184 void sctape_read( tgt, ior)
  185         register target_info_t  *tgt;
  186         io_req_t                ior;
  187 {
  188         scsi_cmd_read_t         *cmd;
  189         register unsigned       len, max;
  190 #       define                  nbytes max
  191         boolean_t               fixed = FALSE;
  192 
  193         max = scsi_softc[(unsigned char)tgt->masterno]->max_dma_data;
  194 
  195         len = ior->io_count;
  196         if (tgt->dev_info.tape.fixed_size) {
  197                 unsigned int bs = tgt->block_size;
  198                 fixed = TRUE;
  199                 nbytes = len;
  200                 ior->io_residual += len % bs;
  201                 len = len / bs;
  202         } else {
  203                 if (max > tgt->dev_info.tape.maxreclen)
  204                         max = tgt->dev_info.tape.maxreclen;
  205                 if (len > max) {
  206                         ior->io_residual = len - max;
  207                         len = max;
  208                 }
  209                 if (len < tgt->block_size)
  210                         len = tgt->block_size;
  211                 nbytes = len;
  212         }
  213 
  214         cmd = (scsi_cmd_read_t*) (tgt->cmd_ptr);
  215         cmd->scsi_cmd_code = SCSI_CMD_READ;
  216         cmd->scsi_cmd_lun_and_lba1 = fixed ? SCSI_CMD_TP_FIXED : 0;
  217         cmd->scsi_cmd_lba2         = len >> 16;
  218         cmd->scsi_cmd_lba3         = len >>  8;
  219         cmd->scsi_cmd_xfer_len     = len;
  220         cmd->scsi_cmd_ctrl_byte = 0;    /* not linked */
  221         
  222         tgt->cur_cmd = SCSI_CMD_READ;
  223 
  224         scsi_go(tgt, sizeof(*cmd), nbytes, FALSE);
  225 #undef  nbytes
  226 }
  227 
  228 void sctape_write( tgt, ior)
  229         register target_info_t  *tgt;
  230         io_req_t                ior;
  231 {
  232         scsi_cmd_write_t        *cmd;
  233         register unsigned       len, max;
  234         boolean_t               fixed = FALSE;
  235 
  236         len = ior->io_count;
  237         max = scsi_softc[(unsigned char)tgt->masterno]->max_dma_data;
  238 
  239         if (tgt->dev_info.tape.fixed_size) {
  240                 unsigned int bs = tgt->block_size;
  241                 fixed = TRUE;
  242                 ior->io_residual += len % bs;
  243                 len = len / bs;
  244         } else {
  245                 if (max > tgt->dev_info.tape.maxreclen)
  246                         max = tgt->dev_info.tape.maxreclen;
  247                 if (len > max) {
  248                         ior->io_residual = len - max;
  249                         len = max;
  250                 }
  251                 if (len < tgt->block_size)
  252                         len = tgt->block_size;
  253         }
  254 
  255         cmd = (scsi_cmd_write_t*) (tgt->cmd_ptr);
  256         cmd->scsi_cmd_code = SCSI_CMD_WRITE;
  257         cmd->scsi_cmd_lun_and_lba1 = fixed ? SCSI_CMD_TP_FIXED : 0;
  258         cmd->scsi_cmd_lba2         = len >> 16;
  259         cmd->scsi_cmd_lba3         = len >>  8;
  260         cmd->scsi_cmd_xfer_len     = len;
  261         cmd->scsi_cmd_ctrl_byte = 0;    /* not linked */
  262         
  263         tgt->cur_cmd = SCSI_CMD_WRITE;
  264 
  265         scsi_go(tgt, sizeof(*cmd), 0, FALSE);
  266 }
  267 
  268 int scsi_rewind( tgt, ior, wait)
  269         register target_info_t  *tgt;
  270         io_req_t                ior;
  271         boolean_t               wait;
  272 {
  273         scsi_cmd_rewind_t       *cmd;
  274 
  275 
  276         cmd = (scsi_cmd_rewind_t*) (tgt->cmd_ptr);
  277         cmd->scsi_cmd_code = SCSI_CMD_REWIND;
  278         cmd->scsi_cmd_lun_and_lba1 = wait ? 0 : SCSI_CMD_REW_IMMED;
  279         cmd->scsi_cmd_lba2         = 0;
  280         cmd->scsi_cmd_lba3         = 0;
  281         cmd->scsi_cmd_xfer_len     = 0;
  282         cmd->scsi_cmd_ctrl_byte = 0;    /* not linked */
  283         
  284         tgt->cur_cmd = SCSI_CMD_REWIND;
  285 
  286         scsi_go( tgt, sizeof(*cmd), 0, FALSE);
  287         return SCSI_RET_SUCCESS;
  288 }
  289 
  290 int scsi_write_filemarks( tgt, count, ior)
  291         register target_info_t  *tgt;
  292         register unsigned int   count;
  293         io_req_t                ior;
  294 {
  295         scsi_cmd_write_fil_t    *cmd;
  296 
  297         cmd = (scsi_cmd_write_fil_t*) (tgt->cmd_ptr);
  298         cmd->scsi_cmd_code = SCSI_CMD_WRITE_FILEMARKS;
  299         cmd->scsi_cmd_lun_and_lba1 = 0;
  300         cmd->scsi_cmd_lba2         = count >> 16;
  301         cmd->scsi_cmd_lba3         = count >>  8;
  302         cmd->scsi_cmd_xfer_len     = count;
  303         cmd->scsi_cmd_ctrl_byte = 0;    /* not linked */
  304 
  305 
  306         tgt->cur_cmd = SCSI_CMD_WRITE_FILEMARKS;
  307 
  308         scsi_go_and_wait(tgt, sizeof(*cmd), 0, ior);
  309 
  310         return tgt->done;
  311 }
  312 
  313 int scsi_space( tgt, mode, count, ior)
  314         register target_info_t  *tgt;
  315         int mode;
  316         register int            count;
  317         io_req_t                ior;
  318 {
  319         scsi_cmd_space_t        *cmd;
  320 
  321         cmd = (scsi_cmd_space_t*) (tgt->cmd_ptr);
  322         cmd->scsi_cmd_code = SCSI_CMD_SPACE;
  323         cmd->scsi_cmd_lun_and_lba1 = mode & 0x3;
  324         cmd->scsi_cmd_lba2         = count >> 16;
  325         cmd->scsi_cmd_lba3         = count >>  8;
  326         cmd->scsi_cmd_xfer_len     = count;
  327         cmd->scsi_cmd_ctrl_byte = 0;    /* not linked */
  328 
  329 
  330         tgt->cur_cmd = SCSI_CMD_SPACE;
  331 
  332         scsi_go_and_wait(tgt, sizeof(*cmd), 0, ior);
  333 
  334         return tgt->done;
  335 }
  336 
  337 
  338 int scsi_read_block_limits( tgt, ior)
  339         register target_info_t  *tgt;
  340         io_req_t                ior;
  341 {
  342         scsi_cmd_block_limits_t *cmd;
  343 
  344         cmd = (scsi_cmd_block_limits_t*) (tgt->cmd_ptr);
  345         cmd->scsi_cmd_code = SCSI_CMD_READ_BLOCK_LIMITS;
  346         cmd->scsi_cmd_lun_and_lba1 = 0;
  347         cmd->scsi_cmd_lba2         = 0;
  348         cmd->scsi_cmd_lba3         = 0;
  349         cmd->scsi_cmd_xfer_len     = 0;
  350         cmd->scsi_cmd_ctrl_byte = 0;    /* not linked */
  351 
  352 
  353         tgt->cur_cmd = SCSI_CMD_READ_BLOCK_LIMITS;
  354 
  355         scsi_go_and_wait(tgt, sizeof(*cmd), sizeof(scsi_blimits_data_t), ior);
  356         return tgt->done;
  357 }
  358 
  359 #if 0 /* unused */
  360 
  361 void scsi_track_select( tgt, trackno, ior)
  362         register target_info_t  *tgt;
  363         register unsigned char  trackno;
  364         io_req_t                ior;
  365 {
  366         scsi_cmd_seek_t *cmd;
  367 
  368         cmd = (scsi_cmd_seek_t*) (tgt->cmd_ptr);
  369         cmd->scsi_cmd_code = SCSI_CMD_TRACK_SELECT;
  370         cmd->scsi_cmd_lun_and_lba1 = 0;
  371         cmd->scsi_cmd_lba2         = 0;
  372         cmd->scsi_cmd_lba3         = 0;
  373         cmd->scsi_cmd_tp_trackno   = trackno;
  374         cmd->scsi_cmd_ctrl_byte = 0;    /* not linked */
  375 
  376 
  377         tgt->cur_cmd = SCSI_CMD_TRACK_SELECT;
  378 
  379         scsi_go_and_wait(tgt, sizeof(*cmd), 0, ior);
  380 }
  381 
  382 void scsi_read_reverse( tgt, ior)
  383         register target_info_t  *tgt;
  384         io_req_t                ior;
  385 {
  386         scsi_cmd_rev_read_t     *cmd;
  387         register unsigned       len;
  388         unsigned int            max_dma_data;
  389 
  390         max_dma_data = scsi_softc[(unsigned char)tgt->masterno]->max_dma_data;
  391 
  392         len = ior->io_count;
  393         if (len > max_dma_data)
  394                 len = max_dma_data;
  395 
  396         cmd = (scsi_cmd_rev_read_t*) (tgt->cmd_ptr);
  397         cmd->scsi_cmd_code = SCSI_CMD_READ_REVERSE;
  398         cmd->scsi_cmd_lun_and_lba1 = 0;
  399         cmd->scsi_cmd_lba2         = len >> 16;
  400         cmd->scsi_cmd_lba3         = len >>  8;
  401         cmd->scsi_cmd_xfer_len     = len;
  402         cmd->scsi_cmd_ctrl_byte = 0;    /* not linked */
  403         
  404         tgt->cur_cmd = SCSI_CMD_READ_REVERSE;
  405 
  406         scsi_go(tgt, sizeof(*cmd), len, FALSE);
  407 }
  408 
  409 void sctape_verify( tgt, len, ior)
  410         register target_info_t  *tgt;
  411         register unsigned int   len;
  412         io_req_t                ior;
  413 {
  414         scsi_cmd_verify_t       *cmd;
  415 
  416         cmd = (scsi_cmd_verify_t*) (tgt->cmd_ptr);
  417         cmd->scsi_cmd_code = SCSI_CMD_VERIFY_0;
  418         cmd->scsi_cmd_lun_and_lba1 = 0;/* XXX */
  419         cmd->scsi_cmd_lba2         = len >> 16;
  420         cmd->scsi_cmd_lba3         = len >>  8;
  421         cmd->scsi_cmd_xfer_len     = len;
  422         cmd->scsi_cmd_ctrl_byte = 0;    /* not linked */
  423 
  424 
  425         tgt->cur_cmd = SCSI_CMD_VERIFY_0;
  426 
  427         scsi_go_and_wait(tgt, sizeof(*cmd), 0, ior);
  428 }
  429 
  430 
  431 void scsi_recover_buffered_data( tgt, ior)
  432         register target_info_t  *tgt;
  433         io_req_t                ior;
  434 {
  435         scsi_cmd_recover_buffer_t       *cmd;
  436         register unsigned               len;
  437         unsigned int            max_dma_data;
  438 
  439         max_dma_data = scsi_softc[(unsigned char)tgt->masterno]->max_dma_data;
  440 
  441         len = ior->io_count;
  442         if (len > max_dma_data)
  443                 len = max_dma_data;
  444 
  445         cmd = (scsi_cmd_recover_buffer_t*) (tgt->cmd_ptr);
  446         cmd->scsi_cmd_code = SCSI_CMD_RECOVER_BUFFERED_DATA;
  447         cmd->scsi_cmd_lun_and_lba1 = 0;
  448         cmd->scsi_cmd_lba2         = len >> 16;
  449         cmd->scsi_cmd_lba3         = len >>  8;
  450         cmd->scsi_cmd_xfer_len     = len;
  451         cmd->scsi_cmd_ctrl_byte = 0;    /* not linked */
  452         
  453         tgt->cur_cmd = SCSI_CMD_RECOVER_BUFFERED_DATA;
  454 
  455         scsi_go(tgt, sizeof(*cmd), len, FALSE);
  456 }
  457 
  458 void scsi_erase( tgt, mode, ior)
  459         register target_info_t  *tgt;
  460         io_req_t                ior;
  461 {
  462         scsi_cmd_erase_t        *cmd;
  463 
  464         cmd = (scsi_cmd_erase_t*) (tgt->cmd_ptr);
  465         cmd->scsi_cmd_code = SCSI_CMD_ERASE;
  466         cmd->scsi_cmd_lun_and_lba1 = mode & SCSI_CMD_ER_LONG;
  467         cmd->scsi_cmd_lba2         = 0;
  468         cmd->scsi_cmd_lba3         = 0;
  469         cmd->scsi_cmd_xfer_len     = 0;
  470         cmd->scsi_cmd_ctrl_byte = 0;    /* not linked */
  471 
  472 
  473         tgt->cur_cmd = SCSI_CMD_ERASE;
  474 
  475         scsi_go_and_wait(tgt, sizeof(*cmd), 0, ior);
  476 }
  477 
  478 #endif
  479 
  480 #ifdef  SCSI2
  481 scsi_locate
  482 scsi_read_position
  483 #endif  SCSI2

Cache object: 40479cb2ce415558155058cce3ce2253


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