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/cam/ctl/ctl_util.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  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
    3  *
    4  * Copyright (c) 2003 Silicon Graphics International Corp.
    5  * All rights reserved.
    6  *
    7  * Redistribution and use in source and binary forms, with or without
    8  * modification, are permitted provided that the following conditions
    9  * are met:
   10  * 1. Redistributions of source code must retain the above copyright
   11  *    notice, this list of conditions, and the following disclaimer,
   12  *    without modification.
   13  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
   14  *    substantially similar to the "NO WARRANTY" disclaimer below
   15  *    ("Disclaimer") and any redistribution must be conditioned upon
   16  *    including a substantially similar Disclaimer requirement for further
   17  *    binary redistribution.
   18  *
   19  * NO WARRANTY
   20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
   21  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
   22  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
   23  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
   24  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   25  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   26  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   27  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
   28  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
   29  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   30  * POSSIBILITY OF SUCH DAMAGES.
   31  *
   32  * $Id: //depot/users/kenm/FreeBSD-test2/sys/cam/ctl/ctl_util.c#2 $
   33  */
   34 /*
   35  * CAM Target Layer SCSI library
   36  *
   37  * Author: Ken Merry <ken@FreeBSD.org>
   38  */
   39 
   40 #include <sys/cdefs.h>
   41 __FBSDID("$FreeBSD$");
   42 
   43 #ifdef _KERNEL
   44 #include <sys/param.h>
   45 #include <sys/systm.h>
   46 #include <sys/kernel.h>
   47 #include <sys/types.h>
   48 #include <sys/malloc.h>
   49 #else /* __KERNEL__ */
   50 #include <sys/types.h>
   51 #include <sys/time.h>
   52 #include <stdint.h>
   53 #include <stdio.h>
   54 #include <stdlib.h>
   55 #include <string.h>
   56 #endif /* __KERNEL__ */
   57 #include <sys/sbuf.h>
   58 #include <sys/queue.h>
   59 #include <sys/callout.h>
   60 #include <cam/scsi/scsi_all.h>
   61 #include <cam/ctl/ctl_io.h>
   62 #include <cam/ctl/ctl_scsi_all.h>
   63 #include <cam/ctl/ctl_util.h>
   64 
   65 struct ctl_status_desc {
   66         ctl_io_status status;
   67         const char *description;
   68 };
   69 
   70 struct ctl_task_desc {
   71         ctl_task_type   task_action;
   72         const char      *description;
   73 };
   74 static struct ctl_status_desc ctl_status_table[] = {
   75         {CTL_STATUS_NONE, "No Status"},
   76         {CTL_SUCCESS, "Command Completed Successfully"},
   77         {CTL_CMD_TIMEOUT, "Command Timed Out"},
   78         {CTL_SEL_TIMEOUT, "Selection Timeout"},
   79         {CTL_ERROR, "Command Failed"},
   80         {CTL_SCSI_ERROR, "SCSI Error"},
   81         {CTL_CMD_ABORTED, "Command Aborted"},
   82 };
   83 
   84 static struct ctl_task_desc ctl_task_table[] = {
   85         {CTL_TASK_ABORT_TASK, "Abort Task"},
   86         {CTL_TASK_ABORT_TASK_SET, "Abort Task Set"},
   87         {CTL_TASK_CLEAR_ACA, "Clear ACA"},
   88         {CTL_TASK_CLEAR_TASK_SET, "Clear Task Set"},
   89         {CTL_TASK_I_T_NEXUS_RESET, "I_T Nexus Reset"},
   90         {CTL_TASK_LUN_RESET, "LUN Reset"},
   91         {CTL_TASK_TARGET_RESET, "Target Reset"},
   92         {CTL_TASK_BUS_RESET, "Bus Reset"},
   93         {CTL_TASK_PORT_LOGIN, "Port Login"},
   94         {CTL_TASK_PORT_LOGOUT, "Port Logout"},
   95         {CTL_TASK_QUERY_TASK, "Query Task"},
   96         {CTL_TASK_QUERY_TASK_SET, "Query Task Set"},
   97         {CTL_TASK_QUERY_ASYNC_EVENT, "Query Async Event"}
   98 };
   99 
  100 void
  101 ctl_scsi_tur(union ctl_io *io, ctl_tag_type tag_type, uint8_t control)
  102 {
  103         struct ctl_scsiio *ctsio;
  104         struct scsi_test_unit_ready *cdb;
  105 
  106         ctl_scsi_zero_io(io);
  107 
  108         io->io_hdr.io_type = CTL_IO_SCSI;
  109         ctsio = &io->scsiio;
  110         cdb = (struct scsi_test_unit_ready *)ctsio->cdb;
  111 
  112         cdb->opcode = TEST_UNIT_READY;
  113         cdb->control = control;
  114         io->io_hdr.flags = CTL_FLAG_DATA_NONE;
  115         ctsio->tag_type = tag_type;
  116         ctsio->cdb_len = sizeof(*cdb);
  117         ctsio->ext_data_len = 0;
  118         ctsio->ext_data_ptr = NULL;
  119         ctsio->ext_sg_entries = 0;
  120         ctsio->ext_data_filled = 0;
  121         ctsio->sense_len = SSD_FULL_SIZE;
  122 }
  123 
  124 void
  125 ctl_scsi_inquiry(union ctl_io *io, uint8_t *data_ptr, int32_t data_len,
  126                  uint8_t byte2, uint8_t page_code, ctl_tag_type tag_type,
  127                  uint8_t control)
  128 {
  129         struct ctl_scsiio *ctsio;
  130         struct scsi_inquiry *cdb;
  131 
  132         ctl_scsi_zero_io(io);
  133 
  134         io->io_hdr.io_type = CTL_IO_SCSI;
  135         ctsio = &io->scsiio;
  136         cdb = (struct scsi_inquiry *)ctsio->cdb;
  137 
  138         cdb->opcode = INQUIRY;
  139         cdb->byte2 = byte2;
  140         cdb->page_code = page_code;
  141         cdb->control = control;
  142         scsi_ulto2b(data_len, cdb->length);
  143         io->io_hdr.io_type = CTL_IO_SCSI;
  144         io->io_hdr.flags = CTL_FLAG_DATA_IN;
  145         ctsio->tag_type = tag_type;
  146         ctsio->cdb_len = sizeof(*cdb);
  147         ctsio->ext_data_len = data_len;
  148         ctsio->ext_data_ptr = data_ptr;
  149         ctsio->ext_sg_entries = 0;
  150         ctsio->ext_data_filled = 0;
  151         ctsio->sense_len = SSD_FULL_SIZE;
  152 }
  153 
  154 void
  155 ctl_scsi_request_sense(union ctl_io *io, uint8_t *data_ptr,
  156                        int32_t data_len, uint8_t byte2, ctl_tag_type tag_type,
  157                        uint8_t control)
  158 {
  159         struct ctl_scsiio *ctsio;
  160         struct scsi_request_sense *cdb;
  161 
  162         ctl_scsi_zero_io(io);
  163 
  164         io->io_hdr.io_type = CTL_IO_SCSI;
  165         ctsio = &io->scsiio;
  166         cdb = (struct scsi_request_sense *)ctsio->cdb;
  167 
  168         cdb->opcode = REQUEST_SENSE;
  169         cdb->byte2 = byte2;
  170         cdb->control = control;
  171         cdb->length = data_len;
  172         io->io_hdr.io_type = CTL_IO_SCSI;
  173         io->io_hdr.flags = CTL_FLAG_DATA_IN;
  174         ctsio->tag_type = tag_type;
  175         ctsio->cdb_len = sizeof(*cdb);
  176         ctsio->ext_data_ptr = data_ptr;
  177         ctsio->ext_data_len = data_len;
  178         ctsio->ext_sg_entries = 0;
  179         ctsio->ext_data_filled = 0;
  180         ctsio->sense_len = SSD_FULL_SIZE;
  181 }
  182 
  183 void
  184 ctl_scsi_report_luns(union ctl_io *io, uint8_t *data_ptr, uint32_t data_len,
  185                      uint8_t select_report, ctl_tag_type tag_type,
  186                      uint8_t control)
  187 {
  188         struct ctl_scsiio *ctsio;
  189         struct scsi_report_luns *cdb;
  190 
  191         ctl_scsi_zero_io(io);
  192 
  193         io->io_hdr.io_type = CTL_IO_SCSI;
  194         ctsio = &io->scsiio;
  195         cdb = (struct scsi_report_luns *)ctsio->cdb;
  196 
  197         cdb->opcode = REPORT_LUNS;
  198         cdb->select_report = select_report;
  199         scsi_ulto4b(data_len, cdb->length);
  200         cdb->control = control;
  201         io->io_hdr.io_type = CTL_IO_SCSI;
  202         io->io_hdr.flags = CTL_FLAG_DATA_IN;
  203         ctsio->tag_type = tag_type;
  204         ctsio->cdb_len = sizeof(*cdb);
  205         ctsio->ext_data_ptr = data_ptr;
  206         ctsio->ext_data_len = data_len;
  207         ctsio->ext_sg_entries = 0;
  208         ctsio->ext_data_filled = 0;
  209         ctsio->sense_len = SSD_FULL_SIZE;
  210 }
  211 
  212 void
  213 ctl_scsi_read_write_buffer(union ctl_io *io, uint8_t *data_ptr,
  214                            uint32_t data_len, int read_buffer, uint8_t mode,
  215                            uint8_t buffer_id, uint32_t buffer_offset,
  216                            ctl_tag_type tag_type, uint8_t control)
  217 {
  218         struct ctl_scsiio *ctsio;
  219         struct scsi_write_buffer *cdb;
  220 
  221         ctl_scsi_zero_io(io);
  222 
  223         io->io_hdr.io_type = CTL_IO_SCSI;
  224         ctsio = &io->scsiio;
  225         cdb = (struct scsi_write_buffer *)ctsio->cdb;
  226 
  227         if (read_buffer != 0)
  228                 cdb->opcode = READ_BUFFER;
  229         else
  230                 cdb->opcode = WRITE_BUFFER;
  231 
  232         cdb->byte2 = mode & RWB_MODE;
  233         cdb->buffer_id = buffer_id;
  234         scsi_ulto3b(buffer_offset, cdb->offset);
  235         scsi_ulto3b(data_len, cdb->length);
  236         cdb->control = control;
  237         io->io_hdr.io_type = CTL_IO_SCSI;
  238         if (read_buffer != 0)
  239                 io->io_hdr.flags = CTL_FLAG_DATA_IN;
  240         else
  241                 io->io_hdr.flags = CTL_FLAG_DATA_OUT;
  242         ctsio->tag_type = tag_type;
  243         ctsio->cdb_len = sizeof(*cdb);
  244         ctsio->ext_data_ptr = data_ptr;
  245         ctsio->ext_data_len = data_len;
  246         ctsio->ext_sg_entries = 0;
  247         ctsio->ext_data_filled = 0;
  248         ctsio->sense_len = SSD_FULL_SIZE;
  249 }
  250 
  251 void
  252 ctl_scsi_read_write(union ctl_io *io, uint8_t *data_ptr, uint32_t data_len,
  253                     int read_op, uint8_t byte2, int minimum_cdb_size,
  254                     uint64_t lba, uint32_t num_blocks, ctl_tag_type tag_type,
  255                     uint8_t control)
  256 {
  257         struct ctl_scsiio *ctsio;
  258 
  259         ctl_scsi_zero_io(io);
  260 
  261         io->io_hdr.io_type = CTL_IO_SCSI;
  262         ctsio = &io->scsiio;
  263 
  264         /*
  265          * Pick out the smallest CDB that will hold the user's request.
  266          * minimum_cdb_size allows cranking the CDB size up, even for
  267          * requests that would not normally need a large CDB.  This can be
  268          * useful for testing (e.g. to make sure READ_16 support works without
  269          * having an array larger than 2TB) and for compatibility -- e.g.
  270          * if your device doesn't support READ_6.  (ATAPI drives don't.)
  271          */
  272         if ((minimum_cdb_size < 10)
  273          && ((lba & 0x1fffff) == lba)
  274          && ((num_blocks & 0xff) == num_blocks)
  275          && (byte2 == 0)) {
  276                 struct scsi_rw_6 *cdb;
  277 
  278                 /*
  279                  * Note that according to SBC-2, the target should return 256
  280                  * blocks if the transfer length in a READ(6) or WRITE(6) CDB
  281                  * is set to 0.  Since it's possible that some targets
  282                  * won't do the right thing, we only send a READ(6) or
  283                  * WRITE(6) for transfer sizes up to and including 255 blocks.
  284                  */
  285                 cdb = (struct scsi_rw_6 *)ctsio->cdb;
  286 
  287                 cdb->opcode = (read_op) ? READ_6 : WRITE_6;
  288                 scsi_ulto3b(lba, cdb->addr);
  289                 cdb->length = num_blocks & 0xff;
  290                 cdb->control = control;
  291 
  292                 ctsio->cdb_len = sizeof(*cdb);
  293 
  294         } else if ((minimum_cdb_size < 12)
  295                 && ((num_blocks & 0xffff) == num_blocks)
  296                 && ((lba & 0xffffffff) == lba)) {
  297                 struct scsi_rw_10 *cdb;
  298 
  299                 cdb = (struct scsi_rw_10 *)ctsio->cdb;
  300 
  301                 cdb->opcode = (read_op) ? READ_10 : WRITE_10;
  302                 cdb->byte2 = byte2;
  303                 scsi_ulto4b(lba, cdb->addr);
  304                 cdb->reserved = 0;
  305                 scsi_ulto2b(num_blocks, cdb->length);
  306                 cdb->control = control;
  307 
  308                 ctsio->cdb_len = sizeof(*cdb);
  309         } else if ((minimum_cdb_size < 16)
  310                 && ((num_blocks & 0xffffffff) == num_blocks)
  311                 && ((lba & 0xffffffff) == lba)) {
  312                 struct scsi_rw_12 *cdb;
  313 
  314                 cdb = (struct scsi_rw_12 *)ctsio->cdb;
  315 
  316                 cdb->opcode = (read_op) ? READ_12 : WRITE_12;
  317                 cdb->byte2 = byte2;
  318                 scsi_ulto4b(lba, cdb->addr);
  319                 scsi_ulto4b(num_blocks, cdb->length);
  320                 cdb->reserved = 0;
  321                 cdb->control = control;
  322 
  323                 ctsio->cdb_len = sizeof(*cdb);
  324         } else {
  325                 struct scsi_rw_16 *cdb;
  326 
  327                 cdb = (struct scsi_rw_16 *)ctsio->cdb;
  328 
  329                 cdb->opcode = (read_op) ? READ_16 : WRITE_16;
  330                 cdb->byte2 = byte2;
  331                 scsi_u64to8b(lba, cdb->addr);
  332                 scsi_ulto4b(num_blocks, cdb->length);
  333                 cdb->reserved = 0;
  334                 cdb->control = control;
  335 
  336                 ctsio->cdb_len = sizeof(*cdb);
  337         }
  338 
  339         io->io_hdr.io_type = CTL_IO_SCSI;
  340         if (read_op != 0)
  341                 io->io_hdr.flags = CTL_FLAG_DATA_IN;
  342         else
  343                 io->io_hdr.flags = CTL_FLAG_DATA_OUT;
  344         ctsio->tag_type = tag_type;
  345         ctsio->ext_data_ptr = data_ptr;
  346         ctsio->ext_data_len = data_len;
  347         ctsio->ext_sg_entries = 0;
  348         ctsio->ext_data_filled = 0;
  349         ctsio->sense_len = SSD_FULL_SIZE;
  350 }
  351 
  352 void
  353 ctl_scsi_write_same(union ctl_io *io, uint8_t *data_ptr, uint32_t data_len,
  354                     uint8_t byte2, uint64_t lba, uint32_t num_blocks,
  355                     ctl_tag_type tag_type, uint8_t control)
  356 {
  357         struct ctl_scsiio *ctsio;
  358         struct scsi_write_same_16 *cdb;
  359 
  360         ctl_scsi_zero_io(io);
  361 
  362         io->io_hdr.io_type = CTL_IO_SCSI;
  363         ctsio = &io->scsiio;
  364         ctsio->cdb_len = sizeof(*cdb);
  365         cdb = (struct scsi_write_same_16 *)ctsio->cdb;
  366         cdb->opcode = WRITE_SAME_16;
  367         cdb->byte2 = byte2;
  368         scsi_u64to8b(lba, cdb->addr);
  369         scsi_ulto4b(num_blocks, cdb->length);
  370         cdb->group = 0;
  371         cdb->control = control;
  372 
  373         io->io_hdr.io_type = CTL_IO_SCSI;
  374         io->io_hdr.flags = CTL_FLAG_DATA_OUT;
  375         ctsio->tag_type = tag_type;
  376         ctsio->ext_data_ptr = data_ptr;
  377         ctsio->ext_data_len = data_len;
  378         ctsio->ext_sg_entries = 0;
  379         ctsio->ext_data_filled = 0;
  380         ctsio->sense_len = SSD_FULL_SIZE;
  381 }
  382 
  383 void
  384 ctl_scsi_read_capacity(union ctl_io *io, uint8_t *data_ptr, uint32_t data_len,
  385                        uint32_t addr, int reladr, int pmi,
  386                        ctl_tag_type tag_type, uint8_t control)
  387 {
  388         struct scsi_read_capacity *cdb;
  389 
  390         ctl_scsi_zero_io(io);
  391 
  392         io->io_hdr.io_type = CTL_IO_SCSI;
  393         cdb = (struct scsi_read_capacity *)io->scsiio.cdb;
  394 
  395         cdb->opcode = READ_CAPACITY;
  396         if (reladr)
  397                 cdb->byte2 = SRC_RELADR;
  398         if (pmi)
  399                 cdb->pmi = SRC_PMI;
  400         scsi_ulto4b(addr, cdb->addr);
  401         cdb->control = control;
  402         io->io_hdr.io_type = CTL_IO_SCSI;
  403         io->io_hdr.flags = CTL_FLAG_DATA_IN;
  404         io->scsiio.tag_type = tag_type;
  405         io->scsiio.ext_data_ptr = data_ptr;
  406         io->scsiio.ext_data_len = data_len;
  407         io->scsiio.ext_sg_entries = 0;
  408         io->scsiio.ext_data_filled = 0;
  409         io->scsiio.sense_len = SSD_FULL_SIZE;
  410 }
  411 
  412 void
  413 ctl_scsi_read_capacity_16(union ctl_io *io, uint8_t *data_ptr,
  414                           uint32_t data_len, uint64_t addr, int reladr,
  415                           int pmi, ctl_tag_type tag_type, uint8_t control)
  416 {
  417         struct scsi_read_capacity_16 *cdb;
  418 
  419         ctl_scsi_zero_io(io);
  420 
  421         io->io_hdr.io_type = CTL_IO_SCSI;
  422         cdb = (struct scsi_read_capacity_16 *)io->scsiio.cdb;
  423 
  424         cdb->opcode = SERVICE_ACTION_IN;
  425         cdb->service_action = SRC16_SERVICE_ACTION;
  426         if (reladr)
  427                 cdb->reladr |= SRC16_RELADR;
  428         if (pmi)
  429                 cdb->reladr |= SRC16_PMI;
  430         scsi_u64to8b(addr, cdb->addr);
  431         scsi_ulto4b(data_len, cdb->alloc_len);
  432         cdb->control = control;
  433 
  434         io->io_hdr.io_type = CTL_IO_SCSI;
  435         io->io_hdr.flags = CTL_FLAG_DATA_IN;
  436         io->scsiio.tag_type = tag_type;
  437         io->scsiio.ext_data_ptr = data_ptr;
  438         io->scsiio.ext_data_len = data_len;
  439         io->scsiio.ext_sg_entries = 0;
  440         io->scsiio.ext_data_filled = 0;
  441         io->scsiio.sense_len = SSD_FULL_SIZE;
  442 }
  443 
  444 void
  445 ctl_scsi_mode_sense(union ctl_io *io, uint8_t *data_ptr, uint32_t data_len, 
  446                     int dbd, int llbaa, uint8_t page_code, uint8_t pc,
  447                     uint8_t subpage, int minimum_cdb_size,
  448                     ctl_tag_type tag_type, uint8_t control)
  449 {
  450         ctl_scsi_zero_io(io);
  451 
  452         if ((minimum_cdb_size < 10)
  453          && (llbaa == 0)
  454          && (data_len < 256)) {
  455                 struct scsi_mode_sense_6 *cdb;
  456 
  457                 cdb = (struct scsi_mode_sense_6 *)io->scsiio.cdb;
  458 
  459                 cdb->opcode = MODE_SENSE_6;
  460                 if (dbd)
  461                         cdb->byte2 |= SMS_DBD;
  462                 cdb->page = page_code | pc;
  463                 cdb->subpage = subpage;
  464                 cdb->length = data_len;
  465                 cdb->control = control;
  466         } else {
  467                 struct scsi_mode_sense_10 *cdb;
  468 
  469                 cdb = (struct scsi_mode_sense_10 *)io->scsiio.cdb;
  470 
  471                 cdb->opcode = MODE_SENSE_10;
  472                 if (dbd)
  473                         cdb->byte2 |= SMS_DBD;
  474                 if (llbaa)
  475                         cdb->byte2 |= SMS10_LLBAA;
  476                 cdb->page = page_code | pc;
  477                 cdb->subpage = subpage;
  478                 scsi_ulto2b(data_len, cdb->length);
  479                 cdb->control = control;
  480         }
  481 
  482         io->io_hdr.io_type = CTL_IO_SCSI;
  483         io->io_hdr.flags = CTL_FLAG_DATA_IN;
  484         io->scsiio.tag_type = tag_type;
  485         io->scsiio.ext_data_ptr = data_ptr;
  486         io->scsiio.ext_data_len = data_len;
  487         io->scsiio.ext_sg_entries = 0;
  488         io->scsiio.ext_data_filled = 0;
  489         io->scsiio.sense_len = SSD_FULL_SIZE;
  490 }
  491 
  492 void
  493 ctl_scsi_start_stop(union ctl_io *io, int start, int load_eject, int immediate,
  494     int power_conditions, ctl_tag_type tag_type, uint8_t control)
  495 {
  496         struct scsi_start_stop_unit *cdb;
  497 
  498         cdb = (struct scsi_start_stop_unit *)io->scsiio.cdb;
  499 
  500         ctl_scsi_zero_io(io);
  501 
  502         cdb->opcode = START_STOP_UNIT;
  503         if (immediate)
  504                 cdb->byte2 |= SSS_IMMED;
  505         cdb->how = power_conditions;
  506         if (load_eject)
  507                 cdb->how |= SSS_LOEJ;
  508         if (start)
  509                 cdb->how |= SSS_START;
  510         cdb->control = control;
  511         io->io_hdr.io_type = CTL_IO_SCSI;
  512         io->io_hdr.flags = CTL_FLAG_DATA_NONE;
  513         io->scsiio.tag_type = tag_type;
  514         io->scsiio.ext_data_ptr = NULL;
  515         io->scsiio.ext_data_len = 0;
  516         io->scsiio.ext_sg_entries = 0;
  517         io->scsiio.ext_data_filled = 0;
  518         io->scsiio.sense_len = SSD_FULL_SIZE;
  519 }
  520 
  521 void
  522 ctl_scsi_sync_cache(union ctl_io *io, int immed, int reladr,
  523                     int minimum_cdb_size, uint64_t starting_lba,
  524                     uint32_t block_count, ctl_tag_type tag_type,
  525                     uint8_t control)
  526 {
  527         ctl_scsi_zero_io(io);
  528 
  529         if ((minimum_cdb_size < 16)
  530          && ((block_count & 0xffff) == block_count)
  531          && ((starting_lba & 0xffffffff) == starting_lba)) {
  532                 struct scsi_sync_cache *cdb;
  533 
  534                 cdb = (struct scsi_sync_cache *)io->scsiio.cdb;
  535 
  536                 cdb->opcode = SYNCHRONIZE_CACHE;
  537                 if (reladr)
  538                         cdb->byte2 |= SSC_RELADR;
  539 
  540                 if (immed)
  541                         cdb->byte2 |= SSC_IMMED;
  542 
  543                 scsi_ulto4b(starting_lba, cdb->begin_lba);
  544                 scsi_ulto2b(block_count, cdb->lb_count);
  545                 cdb->control = control;
  546         } else {
  547                 struct scsi_sync_cache_16 *cdb;
  548 
  549                 cdb = (struct scsi_sync_cache_16 *)io->scsiio.cdb;
  550 
  551                 cdb->opcode = SYNCHRONIZE_CACHE_16;
  552                 if (reladr)
  553                         cdb->byte2 |= SSC_RELADR;
  554 
  555                 if (immed)
  556                         cdb->byte2 |= SSC_IMMED;
  557 
  558                 scsi_u64to8b(starting_lba, cdb->begin_lba);
  559                 scsi_ulto4b(block_count, cdb->lb_count);
  560                 cdb->control = control;
  561         }
  562         io->io_hdr.io_type = CTL_IO_SCSI;
  563         io->io_hdr.flags = CTL_FLAG_DATA_NONE;
  564         io->scsiio.tag_type = tag_type;
  565         io->scsiio.ext_data_ptr = NULL;
  566         io->scsiio.ext_data_len = 0;
  567         io->scsiio.ext_sg_entries = 0;
  568         io->scsiio.ext_data_filled = 0;
  569         io->scsiio.sense_len = SSD_FULL_SIZE;
  570 }
  571 
  572 void
  573 ctl_scsi_persistent_res_in(union ctl_io *io, uint8_t *data_ptr,
  574                            uint32_t data_len, int action,
  575                            ctl_tag_type tag_type, uint8_t control)
  576 {
  577 
  578         struct scsi_per_res_in *cdb;
  579 
  580         ctl_scsi_zero_io(io);
  581 
  582         cdb = (struct scsi_per_res_in *)io->scsiio.cdb;
  583         cdb->opcode = PERSISTENT_RES_IN;
  584         cdb->action = action;
  585         scsi_ulto2b(data_len, cdb->length);
  586         cdb->control = control;
  587 
  588         io->io_hdr.io_type = CTL_IO_SCSI;
  589         io->io_hdr.flags = CTL_FLAG_DATA_IN;
  590         io->scsiio.tag_type = tag_type;
  591         io->scsiio.ext_data_ptr = data_ptr;
  592         io->scsiio.ext_data_len = data_len;
  593         io->scsiio.ext_sg_entries = 0;
  594         io->scsiio.ext_data_filled = 0;
  595         io->scsiio.sense_len = SSD_FULL_SIZE;
  596 }
  597 
  598 void
  599 ctl_scsi_persistent_res_out(union ctl_io *io, uint8_t *data_ptr,
  600                             uint32_t data_len, int action, int type,
  601                             uint64_t key, uint64_t sa_key,
  602                             ctl_tag_type tag_type, uint8_t control)
  603 {
  604 
  605         struct scsi_per_res_out *cdb;
  606         struct scsi_per_res_out_parms *params;
  607 
  608         ctl_scsi_zero_io(io);
  609 
  610         cdb = (struct scsi_per_res_out *)io->scsiio.cdb;
  611         params = (struct scsi_per_res_out_parms *)data_ptr;
  612 
  613         cdb->opcode = PERSISTENT_RES_OUT;
  614         if (action == 5)
  615             cdb->action = 6;
  616         else
  617             cdb->action = action;
  618         switch(type)
  619         {
  620             case 0:
  621                     cdb->scope_type = 1;
  622                         break;
  623             case 1:
  624                     cdb->scope_type = 3;
  625                         break;
  626             case 2:
  627                     cdb->scope_type = 5;
  628                         break;
  629             case 3:
  630                     cdb->scope_type = 6;
  631                         break;
  632             case 4:
  633                     cdb->scope_type = 7;
  634                         break;
  635             case 5:
  636                     cdb->scope_type = 8;
  637                         break;
  638         }
  639         scsi_ulto4b(data_len, cdb->length);
  640         cdb->control = control;
  641 
  642         scsi_u64to8b(key, params->res_key.key);
  643         scsi_u64to8b(sa_key, params->serv_act_res_key);
  644 
  645         io->io_hdr.io_type = CTL_IO_SCSI;
  646         io->io_hdr.flags = CTL_FLAG_DATA_OUT;
  647         io->scsiio.tag_type = tag_type;
  648         io->scsiio.ext_data_ptr = data_ptr;
  649         io->scsiio.ext_data_len = data_len;
  650         io->scsiio.ext_sg_entries = 0;
  651         io->scsiio.ext_data_filled = 0;
  652         io->scsiio.sense_len = SSD_FULL_SIZE;
  653 
  654 }
  655 
  656 void
  657 ctl_scsi_maintenance_in(union ctl_io *io, uint8_t *data_ptr, uint32_t data_len, 
  658                         uint8_t action, ctl_tag_type tag_type, uint8_t control)
  659 {
  660         struct scsi_maintenance_in *cdb;
  661 
  662         ctl_scsi_zero_io(io);
  663 
  664         cdb = (struct scsi_maintenance_in *)io->scsiio.cdb;
  665         cdb->opcode = MAINTENANCE_IN;
  666         cdb->byte2 = action;
  667         scsi_ulto4b(data_len, cdb->length);
  668         cdb->control = control;
  669 
  670         io->io_hdr.io_type = CTL_IO_SCSI;
  671         io->io_hdr.flags = CTL_FLAG_DATA_IN;
  672         io->scsiio.tag_type = tag_type;
  673         io->scsiio.ext_data_ptr = data_ptr;
  674         io->scsiio.ext_data_len = data_len;
  675         io->scsiio.ext_sg_entries = 0;
  676         io->scsiio.ext_data_filled = 0;
  677         io->scsiio.sense_len = SSD_FULL_SIZE;
  678 }
  679 
  680 #ifndef _KERNEL
  681 union ctl_io *
  682 ctl_scsi_alloc_io(uint32_t initid)
  683 {
  684         union ctl_io *io;
  685 
  686         io = (union ctl_io *)malloc(sizeof(*io));
  687         if (io == NULL)
  688                 goto bailout;
  689 
  690         io->io_hdr.nexus.initid = initid;
  691 
  692 bailout:
  693         return (io);
  694 }
  695 
  696 void
  697 ctl_scsi_free_io(union ctl_io *io)
  698 {
  699         free(io);
  700 }
  701 
  702 void
  703 ctl_scsi_zero_io(union ctl_io *io)
  704 {
  705         void *pool_ref;
  706 
  707         if (io == NULL)
  708                 return;
  709 
  710         pool_ref = io->io_hdr.pool;
  711         memset(io, 0, sizeof(*io));
  712         io->io_hdr.pool = pool_ref;
  713 }
  714 #endif /* !_KERNEL */
  715 
  716 const char *
  717 ctl_scsi_task_string(struct ctl_taskio *taskio)
  718 {
  719         unsigned int i;
  720 
  721         for (i = 0; i < (sizeof(ctl_task_table)/sizeof(ctl_task_table[0]));
  722              i++) {
  723                 if (taskio->task_action == ctl_task_table[i].task_action) {
  724                         return (ctl_task_table[i].description);
  725                 }
  726         }
  727 
  728         return (NULL);
  729 }
  730 
  731 void
  732 ctl_io_sbuf(union ctl_io *io, struct sbuf *sb)
  733 {
  734         const char *task_desc;
  735         char path_str[64];
  736 
  737         ctl_scsi_path_string(io, path_str, sizeof(path_str));
  738 
  739         switch (io->io_hdr.io_type) {
  740         case CTL_IO_SCSI:
  741                 sbuf_cat(sb, path_str);
  742                 ctl_scsi_command_string(&io->scsiio, NULL, sb);
  743                 sbuf_printf(sb, " Tag: %#jx/%d, Prio: %d\n",
  744                             io->scsiio.tag_num, io->scsiio.tag_type,
  745                             io->scsiio.priority);
  746                 break;
  747         case CTL_IO_TASK:
  748                 sbuf_cat(sb, path_str);
  749                 task_desc = ctl_scsi_task_string(&io->taskio);
  750                 if (task_desc == NULL)
  751                         sbuf_printf(sb, "Unknown Task Action %d (%#x)",
  752                             io->taskio.task_action, io->taskio.task_action);
  753                 else
  754                         sbuf_printf(sb, "Task Action: %s", task_desc);
  755                 switch (io->taskio.task_action) {
  756                 case CTL_TASK_ABORT_TASK:
  757                         sbuf_printf(sb, " Tag: %#jx/%d\n",
  758                             io->taskio.tag_num, io->taskio.tag_type);
  759                         break;
  760                 default:
  761                         sbuf_printf(sb, "\n");
  762                         break;
  763                 }
  764                 break;
  765         default:
  766                 break;
  767         }
  768 }
  769 
  770 void
  771 ctl_io_error_sbuf(union ctl_io *io, struct scsi_inquiry_data *inq_data,
  772                   struct sbuf *sb)
  773 {
  774         struct ctl_status_desc *status_desc;
  775         char path_str[64];
  776         unsigned int i;
  777 
  778         ctl_io_sbuf(io, sb);
  779 
  780         status_desc = NULL;
  781         for (i = 0; i < (sizeof(ctl_status_table)/sizeof(ctl_status_table[0]));
  782              i++) {
  783                 if ((io->io_hdr.status & CTL_STATUS_MASK) ==
  784                      ctl_status_table[i].status) {
  785                         status_desc = &ctl_status_table[i];
  786                         break;
  787                 }
  788         }
  789 
  790         ctl_scsi_path_string(io, path_str, sizeof(path_str));
  791 
  792         sbuf_cat(sb, path_str);
  793         if (status_desc == NULL)
  794                 sbuf_printf(sb, "CTL Status: Unknown status %#x\n",
  795                             io->io_hdr.status);
  796         else
  797                 sbuf_printf(sb, "CTL Status: %s\n", status_desc->description);
  798 
  799         if ((io->io_hdr.io_type == CTL_IO_SCSI)
  800          && ((io->io_hdr.status & CTL_STATUS_MASK) == CTL_SCSI_ERROR)) {
  801                 sbuf_cat(sb, path_str);
  802                 sbuf_printf(sb, "SCSI Status: %s\n",
  803                             ctl_scsi_status_string(&io->scsiio));
  804 
  805                 if (io->scsiio.scsi_status == SCSI_STATUS_CHECK_COND)
  806                         ctl_scsi_sense_sbuf(&io->scsiio, inq_data,
  807                                             sb, SSS_FLAG_NONE);
  808         }
  809 }
  810 
  811 char *
  812 ctl_io_string(union ctl_io *io, char *str, int str_len)
  813 {
  814         struct sbuf sb;
  815 
  816         sbuf_new(&sb, str, str_len, SBUF_FIXEDLEN);
  817         ctl_io_sbuf(io, &sb);
  818         sbuf_finish(&sb);
  819         return (sbuf_data(&sb));
  820 }
  821 
  822 char *
  823 ctl_io_error_string(union ctl_io *io, struct scsi_inquiry_data *inq_data,
  824                     char *str, int str_len)
  825 {
  826         struct sbuf sb;
  827 
  828         sbuf_new(&sb, str, str_len, SBUF_FIXEDLEN);
  829         ctl_io_error_sbuf(io, inq_data, &sb);
  830         sbuf_finish(&sb);
  831         return (sbuf_data(&sb));
  832 }
  833 
  834 #ifdef _KERNEL
  835 
  836 void
  837 ctl_io_print(union ctl_io *io)
  838 {
  839         char str[512];
  840 
  841         printf("%s", ctl_io_string(io, str, sizeof(str)));
  842 }
  843 
  844 void
  845 ctl_io_error_print(union ctl_io *io, struct scsi_inquiry_data *inq_data)
  846 {
  847         char str[512];
  848 
  849         printf("%s", ctl_io_error_string(io, inq_data, str, sizeof(str)));
  850 
  851 }
  852 
  853 void
  854 ctl_data_print(union ctl_io *io)
  855 {
  856         char str[128];
  857         char path_str[64];
  858         struct sbuf sb;
  859         int i, j, len;
  860 
  861         if (io->io_hdr.io_type != CTL_IO_SCSI)
  862                 return;
  863         if (io->io_hdr.flags & CTL_FLAG_BUS_ADDR)
  864                 return;
  865         if (io->scsiio.kern_sg_entries > 0)     /* XXX: Implement */
  866                 return;
  867         ctl_scsi_path_string(io, path_str, sizeof(path_str));
  868         len = min(io->scsiio.kern_data_len, 4096);
  869         for (i = 0; i < len; ) {
  870                 sbuf_new(&sb, str, sizeof(str), SBUF_FIXEDLEN);
  871                 sbuf_cat(&sb, path_str);
  872                 sbuf_printf(&sb, " %#jx:%04x:", io->scsiio.tag_num, i);
  873                 for (j = 0; j < 16 && i < len; i++, j++) {
  874                         if (j == 8)
  875                                 sbuf_cat(&sb, " ");
  876                         sbuf_printf(&sb, " %02x", io->scsiio.kern_data_ptr[i]);
  877                 }
  878                 sbuf_cat(&sb, "\n");
  879                 sbuf_finish(&sb);
  880                 printf("%s", sbuf_data(&sb));
  881         }
  882 }
  883 
  884 #else /* _KERNEL */
  885 
  886 void
  887 ctl_io_error_print(union ctl_io *io, struct scsi_inquiry_data *inq_data,
  888                    FILE *ofile)
  889 {
  890         char str[512];
  891 
  892         fprintf(ofile, "%s", ctl_io_error_string(io, inq_data, str,
  893                 sizeof(str)));
  894 }
  895 
  896 #endif /* _KERNEL */
  897 
  898 /*
  899  * vim: ts=8
  900  */

Cache object: 50a31b045dddb1b86b3478478334b0a6


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