root/drivers/usb/storage/protocol.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. usb_stor_pad12_command
  2. usb_stor_ufi_command
  3. usb_stor_transparent_scsi_command
  4. usb_stor_access_xfer_buf
  5. usb_stor_set_xfer_buf

   1 // SPDX-License-Identifier: GPL-2.0+
   2 /*
   3  * Driver for USB Mass Storage compliant devices
   4  *
   5  * Current development and maintenance by:
   6  *   (c) 1999-2002 Matthew Dharm (mdharm-usb@one-eyed-alien.net)
   7  *
   8  * Developed with the assistance of:
   9  *   (c) 2000 David L. Brown, Jr. (usb-storage@davidb.org)
  10  *   (c) 2002 Alan Stern (stern@rowland.org)
  11  *
  12  * Initial work by:
  13  *   (c) 1999 Michael Gee (michael@linuxspecific.com)
  14  *
  15  * This driver is based on the 'USB Mass Storage Class' document. This
  16  * describes in detail the protocol used to communicate with such
  17  * devices.  Clearly, the designers had SCSI and ATAPI commands in
  18  * mind when they created this document.  The commands are all very
  19  * similar to commands in the SCSI-II and ATAPI specifications.
  20  *
  21  * It is important to note that in a number of cases this class
  22  * exhibits class-specific exemptions from the USB specification.
  23  * Notably the usage of NAK, STALL and ACK differs from the norm, in
  24  * that they are used to communicate wait, failed and OK on commands.
  25  *
  26  * Also, for certain devices, the interrupt endpoint is used to convey
  27  * status of a command.
  28  */
  29 
  30 #include <linux/highmem.h>
  31 #include <linux/export.h>
  32 #include <scsi/scsi.h>
  33 #include <scsi/scsi_cmnd.h>
  34 
  35 #include "usb.h"
  36 #include "protocol.h"
  37 #include "debug.h"
  38 #include "scsiglue.h"
  39 #include "transport.h"
  40 
  41 /***********************************************************************
  42  * Protocol routines
  43  ***********************************************************************/
  44 
  45 void usb_stor_pad12_command(struct scsi_cmnd *srb, struct us_data *us)
  46 {
  47         /*
  48          * Pad the SCSI command with zeros out to 12 bytes.  If the
  49          * command already is 12 bytes or longer, leave it alone.
  50          *
  51          * NOTE: This only works because a scsi_cmnd struct field contains
  52          * a unsigned char cmnd[16], so we know we have storage available
  53          */
  54         for (; srb->cmd_len < 12; srb->cmd_len++)
  55                 srb->cmnd[srb->cmd_len] = 0;
  56 
  57         /* send the command to the transport layer */
  58         usb_stor_invoke_transport(srb, us);
  59 }
  60 
  61 void usb_stor_ufi_command(struct scsi_cmnd *srb, struct us_data *us)
  62 {
  63         /*
  64          * fix some commands -- this is a form of mode translation
  65          * UFI devices only accept 12 byte long commands
  66          *
  67          * NOTE: This only works because a scsi_cmnd struct field contains
  68          * a unsigned char cmnd[16], so we know we have storage available
  69          */
  70 
  71         /* Pad the ATAPI command with zeros */
  72         for (; srb->cmd_len < 12; srb->cmd_len++)
  73                 srb->cmnd[srb->cmd_len] = 0;
  74 
  75         /* set command length to 12 bytes (this affects the transport layer) */
  76         srb->cmd_len = 12;
  77 
  78         /* XXX We should be constantly re-evaluating the need for these */
  79 
  80         /* determine the correct data length for these commands */
  81         switch (srb->cmnd[0]) {
  82 
  83                 /* for INQUIRY, UFI devices only ever return 36 bytes */
  84         case INQUIRY:
  85                 srb->cmnd[4] = 36;
  86                 break;
  87 
  88                 /* again, for MODE_SENSE_10, we get the minimum (8) */
  89         case MODE_SENSE_10:
  90                 srb->cmnd[7] = 0;
  91                 srb->cmnd[8] = 8;
  92                 break;
  93 
  94                 /* for REQUEST_SENSE, UFI devices only ever return 18 bytes */
  95         case REQUEST_SENSE:
  96                 srb->cmnd[4] = 18;
  97                 break;
  98         } /* end switch on cmnd[0] */
  99 
 100         /* send the command to the transport layer */
 101         usb_stor_invoke_transport(srb, us);
 102 }
 103 
 104 void usb_stor_transparent_scsi_command(struct scsi_cmnd *srb,
 105                                        struct us_data *us)
 106 {
 107         /* send the command to the transport layer */
 108         usb_stor_invoke_transport(srb, us);
 109 }
 110 EXPORT_SYMBOL_GPL(usb_stor_transparent_scsi_command);
 111 
 112 /***********************************************************************
 113  * Scatter-gather transfer buffer access routines
 114  ***********************************************************************/
 115 
 116 /*
 117  * Copy a buffer of length buflen to/from the srb's transfer buffer.
 118  * Update the **sgptr and *offset variables so that the next copy will
 119  * pick up from where this one left off.
 120  */
 121 unsigned int usb_stor_access_xfer_buf(unsigned char *buffer,
 122         unsigned int buflen, struct scsi_cmnd *srb, struct scatterlist **sgptr,
 123         unsigned int *offset, enum xfer_buf_dir dir)
 124 {
 125         unsigned int cnt = 0;
 126         struct scatterlist *sg = *sgptr;
 127         struct sg_mapping_iter miter;
 128         unsigned int nents = scsi_sg_count(srb);
 129 
 130         if (sg)
 131                 nents = sg_nents(sg);
 132         else
 133                 sg = scsi_sglist(srb);
 134 
 135         sg_miter_start(&miter, sg, nents, dir == FROM_XFER_BUF ?
 136                 SG_MITER_FROM_SG: SG_MITER_TO_SG);
 137 
 138         if (!sg_miter_skip(&miter, *offset))
 139                 return cnt;
 140 
 141         while (sg_miter_next(&miter) && cnt < buflen) {
 142                 unsigned int len = min_t(unsigned int, miter.length,
 143                                 buflen - cnt);
 144 
 145                 if (dir == FROM_XFER_BUF)
 146                         memcpy(buffer + cnt, miter.addr, len);
 147                 else
 148                         memcpy(miter.addr, buffer + cnt, len);
 149 
 150                 if (*offset + len < miter.piter.sg->length) {
 151                         *offset += len;
 152                         *sgptr = miter.piter.sg;
 153                 } else {
 154                         *offset = 0;
 155                         *sgptr = sg_next(miter.piter.sg);
 156                 }
 157                 cnt += len;
 158         }
 159         sg_miter_stop(&miter);
 160 
 161         return cnt;
 162 }
 163 EXPORT_SYMBOL_GPL(usb_stor_access_xfer_buf);
 164 
 165 /*
 166  * Store the contents of buffer into srb's transfer buffer and set the
 167  * SCSI residue.
 168  */
 169 void usb_stor_set_xfer_buf(unsigned char *buffer,
 170         unsigned int buflen, struct scsi_cmnd *srb)
 171 {
 172         unsigned int offset = 0;
 173         struct scatterlist *sg = NULL;
 174 
 175         buflen = min(buflen, scsi_bufflen(srb));
 176         buflen = usb_stor_access_xfer_buf(buffer, buflen, srb, &sg, &offset,
 177                         TO_XFER_BUF);
 178         if (buflen < scsi_bufflen(srb))
 179                 scsi_set_resid(srb, scsi_bufflen(srb) - buflen);
 180 }
 181 EXPORT_SYMBOL_GPL(usb_stor_set_xfer_buf);

/* [<][>][^][v][top][bottom][index][help] */