Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0+
0002 /*
0003  * Driver for USB Mass Storage compliant devices
0004  *
0005  * Current development and maintenance by:
0006  *   (c) 1999-2002 Matthew Dharm (mdharm-usb@one-eyed-alien.net)
0007  *
0008  * Developed with the assistance of:
0009  *   (c) 2000 David L. Brown, Jr. (usb-storage@davidb.org)
0010  *   (c) 2002 Alan Stern (stern@rowland.org)
0011  *
0012  * Initial work by:
0013  *   (c) 1999 Michael Gee (michael@linuxspecific.com)
0014  *
0015  * This driver is based on the 'USB Mass Storage Class' document. This
0016  * describes in detail the protocol used to communicate with such
0017  * devices.  Clearly, the designers had SCSI and ATAPI commands in
0018  * mind when they created this document.  The commands are all very
0019  * similar to commands in the SCSI-II and ATAPI specifications.
0020  *
0021  * It is important to note that in a number of cases this class
0022  * exhibits class-specific exemptions from the USB specification.
0023  * Notably the usage of NAK, STALL and ACK differs from the norm, in
0024  * that they are used to communicate wait, failed and OK on commands.
0025  *
0026  * Also, for certain devices, the interrupt endpoint is used to convey
0027  * status of a command.
0028  */
0029 
0030 #include <linux/highmem.h>
0031 #include <linux/export.h>
0032 #include <scsi/scsi.h>
0033 #include <scsi/scsi_cmnd.h>
0034 
0035 #include "usb.h"
0036 #include "protocol.h"
0037 #include "debug.h"
0038 #include "scsiglue.h"
0039 #include "transport.h"
0040 
0041 /***********************************************************************
0042  * Protocol routines
0043  ***********************************************************************/
0044 
0045 void usb_stor_pad12_command(struct scsi_cmnd *srb, struct us_data *us)
0046 {
0047     /*
0048      * Pad the SCSI command with zeros out to 12 bytes.  If the
0049      * command already is 12 bytes or longer, leave it alone.
0050      *
0051      * NOTE: This only works because a scsi_cmnd struct field contains
0052      * a unsigned char cmnd[16], so we know we have storage available
0053      */
0054     for (; srb->cmd_len < 12; srb->cmd_len++)
0055         srb->cmnd[srb->cmd_len] = 0;
0056 
0057     /* send the command to the transport layer */
0058     usb_stor_invoke_transport(srb, us);
0059 }
0060 
0061 void usb_stor_ufi_command(struct scsi_cmnd *srb, struct us_data *us)
0062 {
0063     /*
0064      * fix some commands -- this is a form of mode translation
0065      * UFI devices only accept 12 byte long commands
0066      *
0067      * NOTE: This only works because a scsi_cmnd struct field contains
0068      * a unsigned char cmnd[16], so we know we have storage available
0069      */
0070 
0071     /* Pad the ATAPI command with zeros */
0072     for (; srb->cmd_len < 12; srb->cmd_len++)
0073         srb->cmnd[srb->cmd_len] = 0;
0074 
0075     /* set command length to 12 bytes (this affects the transport layer) */
0076     srb->cmd_len = 12;
0077 
0078     /* XXX We should be constantly re-evaluating the need for these */
0079 
0080     /* determine the correct data length for these commands */
0081     switch (srb->cmnd[0]) {
0082 
0083         /* for INQUIRY, UFI devices only ever return 36 bytes */
0084     case INQUIRY:
0085         srb->cmnd[4] = 36;
0086         break;
0087 
0088         /* again, for MODE_SENSE_10, we get the minimum (8) */
0089     case MODE_SENSE_10:
0090         srb->cmnd[7] = 0;
0091         srb->cmnd[8] = 8;
0092         break;
0093 
0094         /* for REQUEST_SENSE, UFI devices only ever return 18 bytes */
0095     case REQUEST_SENSE:
0096         srb->cmnd[4] = 18;
0097         break;
0098     } /* end switch on cmnd[0] */
0099 
0100     /* send the command to the transport layer */
0101     usb_stor_invoke_transport(srb, us);
0102 }
0103 
0104 void usb_stor_transparent_scsi_command(struct scsi_cmnd *srb,
0105                        struct us_data *us)
0106 {
0107     /* send the command to the transport layer */
0108     usb_stor_invoke_transport(srb, us);
0109 }
0110 EXPORT_SYMBOL_GPL(usb_stor_transparent_scsi_command);
0111 
0112 /***********************************************************************
0113  * Scatter-gather transfer buffer access routines
0114  ***********************************************************************/
0115 
0116 /*
0117  * Copy a buffer of length buflen to/from the srb's transfer buffer.
0118  * Update the **sgptr and *offset variables so that the next copy will
0119  * pick up from where this one left off.
0120  */
0121 unsigned int usb_stor_access_xfer_buf(unsigned char *buffer,
0122     unsigned int buflen, struct scsi_cmnd *srb, struct scatterlist **sgptr,
0123     unsigned int *offset, enum xfer_buf_dir dir)
0124 {
0125     unsigned int cnt = 0;
0126     struct scatterlist *sg = *sgptr;
0127     struct sg_mapping_iter miter;
0128     unsigned int nents = scsi_sg_count(srb);
0129 
0130     if (sg)
0131         nents = sg_nents(sg);
0132     else
0133         sg = scsi_sglist(srb);
0134 
0135     sg_miter_start(&miter, sg, nents, dir == FROM_XFER_BUF ?
0136         SG_MITER_FROM_SG: SG_MITER_TO_SG);
0137 
0138     if (!sg_miter_skip(&miter, *offset))
0139         return cnt;
0140 
0141     while (sg_miter_next(&miter) && cnt < buflen) {
0142         unsigned int len = min_t(unsigned int, miter.length,
0143                 buflen - cnt);
0144 
0145         if (dir == FROM_XFER_BUF)
0146             memcpy(buffer + cnt, miter.addr, len);
0147         else
0148             memcpy(miter.addr, buffer + cnt, len);
0149 
0150         if (*offset + len < miter.piter.sg->length) {
0151             *offset += len;
0152             *sgptr = miter.piter.sg;
0153         } else {
0154             *offset = 0;
0155             *sgptr = sg_next(miter.piter.sg);
0156         }
0157         cnt += len;
0158     }
0159     sg_miter_stop(&miter);
0160 
0161     return cnt;
0162 }
0163 EXPORT_SYMBOL_GPL(usb_stor_access_xfer_buf);
0164 
0165 /*
0166  * Store the contents of buffer into srb's transfer buffer and set the
0167  * SCSI residue.
0168  */
0169 void usb_stor_set_xfer_buf(unsigned char *buffer,
0170     unsigned int buflen, struct scsi_cmnd *srb)
0171 {
0172     unsigned int offset = 0;
0173     struct scatterlist *sg = NULL;
0174 
0175     buflen = min(buflen, scsi_bufflen(srb));
0176     buflen = usb_stor_access_xfer_buf(buffer, buflen, srb, &sg, &offset,
0177             TO_XFER_BUF);
0178     if (buflen < scsi_bufflen(srb))
0179         scsi_set_resid(srb, scsi_bufflen(srb) - buflen);
0180 }
0181 EXPORT_SYMBOL_GPL(usb_stor_set_xfer_buf);