CTC++ Coverage Report - Execution Profile    #801/1532

Files Summary | Functions Summary | Execution Profile | Index | No Index
First | Previous | Next | Last


File: drivers/usb/storage/protocol.c
Instrumentation mode: function-decision-multicondition
TER: 2 % ( 1/ 41)

Start/ End/    
True False - Line Source

  1 /* Driver for USB Mass Storage compliant devices
  2  *
  3  * $Id: protocol.c,v 1.14 2002/04/22 03:39:43 mdharm Exp $
  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  * Please see http://www.one-eyed-alien.net/~mdharm/linux-usb for more
  30  * information about this driver.
  31  *
  32  * This program is free software; you can redistribute it and/or modify it
  33  * under the terms of the GNU General Public License as published by the
  34  * Free Software Foundation; either version 2, or (at your option) any
  35  * later version.
  36  *
  37  * This program is distributed in the hope that it will be useful, but
  38  * WITHOUT ANY WARRANTY; without even the implied warranty of
  39  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  40  * General Public License for more details.
  41  *
  42  * You should have received a copy of the GNU General Public License along
  43  * with this program; if not, write to the Free Software Foundation, Inc.,
  44  * 675 Mass Ave, Cambridge, MA 02139, USA.
  45  */
  46 
  47 #include <linux/highmem.h>
  48 #include <scsi/scsi.h>
  49 #include <scsi/scsi_cmnd.h>
  50 
  51 #include "usb.h"
  52 #include "protocol.h"
  53 #include "debug.h"
  54 #include "scsiglue.h"
  55 #include "transport.h"
  56 
  57 /***********************************************************************
  58  * Protocol routines
  59  ***********************************************************************/
  60 
 
- 61 void usb_stor_qic157_command(struct scsi_cmnd *srb, struct us_data *us)
  62 {
  63    /* Pad the ATAPI command with zeros 
  64     *
  65     * NOTE: This only works because a scsi_cmnd struct field contains
  66     * a unsigned char cmnd[16], so we know we have storage available
  67     */
- 68    for (; srb->cmd_len<12; srb->cmd_len++)
  69       srb->cmnd[srb->cmd_len] = 0;
  70 
  71    /* set command length to 12 bytes */
  72    srb->cmd_len = 12;
  73 
  74    /* send the command to the transport layer */
  75    usb_stor_invoke_transport(srb, us);
  76 }
  77 
 
- 78 void usb_stor_ATAPI_command(struct scsi_cmnd *srb, struct us_data *us)
  79 {
  80    /* Pad the ATAPI command with zeros 
  81     *
  82     * NOTE: This only works because a scsi_cmnd struct field contains
  83     * a unsigned char cmnd[16], so we know we have storage available
  84     */
  85 
  86    /* Pad the ATAPI command with zeros */
- 87    for (; srb->cmd_len<12; srb->cmd_len++)
  88       srb->cmnd[srb->cmd_len] = 0;
  89 
  90    /* set command length to 12 bytes */
  91    srb->cmd_len = 12;
  92 
  93    /* send the command to the transport layer */
  94    usb_stor_invoke_transport(srb, us);
  95 }
  96 
  97 
 
- 98 void usb_stor_ufi_command(struct scsi_cmnd *srb, struct us_data *us)
  99 {
  100    /* fix some commands -- this is a form of mode translation
  101     * UFI devices only accept 12 byte long commands 
  102     *
  103     * NOTE: This only works because a scsi_cmnd struct field contains
  104     * a unsigned char cmnd[16], so we know we have storage available
  105     */
  106 
  107    /* Pad the ATAPI command with zeros */
- 108    for (; srb->cmd_len<12; srb->cmd_len++)
  109       srb->cmnd[srb->cmd_len] = 0;
  110 
  111    /* set command length to 12 bytes (this affects the transport layer) */
  112    srb->cmd_len = 12;
  113 
  114    /* XXX We should be constantly re-evaluating the need for these */
  115 
  116    /* determine the correct data length for these commands */
    117    switch (srb->cmnd[0]) {
  118 
  119       /* for INQUIRY, UFI devices only ever return 36 bytes */
 - 120    case INQUIRY:
  121       srb->cmnd[4] = 36;
 - 122       break;
  123 
  124       /* again, for MODE_SENSE_10, we get the minimum (8) */
 - 125    case MODE_SENSE_10:
  126       srb->cmnd[7] = 0;
  127       srb->cmnd[8] = 8;
 - 128       break;
  129 
  130       /* for REQUEST_SENSE, UFI devices only ever return 18 bytes */
 - 131    case REQUEST_SENSE:
  132       srb->cmnd[4] = 18;
 - 133       break;
  134    } /* end switch on cmnd[0] */
  135 
  136    /* send the command to the transport layer */
  137    usb_stor_invoke_transport(srb, us);
  138 }
  139 
 
2056 2056   140 void usb_stor_transparent_scsi_command(struct scsi_cmnd *srb,
  141                    struct us_data *us)
  142 {
  143    /* send the command to the transport layer */
  144    usb_stor_invoke_transport(srb, us);
  145 }
  146 
  147 /***********************************************************************
  148  * Scatter-gather transfer buffer access routines
  149  ***********************************************************************/
  150 
  151 /* Copy a buffer of length buflen to/from the srb's transfer buffer.
  152  * (Note: for scatter-gather transfers (srb->use_sg > 0), srb->request_buffer
  153  * points to a list of s-g entries and we ignore srb->request_bufflen.
  154  * For non-scatter-gather transfers, srb->request_buffer points to the
  155  * transfer buffer itself and srb->request_bufflen is the buffer's length.)
  156  * Update the *index and *offset variables so that the next copy will
  157  * pick up from where this one left off. */
  158 
 
- 159 unsigned int usb_stor_access_xfer_buf(unsigned char *buffer,
  160    unsigned int buflen, struct scsi_cmnd *srb, unsigned int *index,
  161    unsigned int *offset, enum xfer_buf_dir dir)
  162 {
  163    unsigned int cnt;
  164 
  165    /* If not using scatter-gather, just transfer the data directly.
  166     * Make certain it will fit in the available buffer space. */
- 167    if (srb->use_sg == 0) {
- 168       if (*offset >= srb->request_bufflen)
 - 169          return 0;
  170       cnt = min(buflen, srb->request_bufflen - *offset);
- 171       if (dir == TO_XFER_BUF)
  172          memcpy((unsigned char *) srb->request_buffer + *offset,
  173                buffer, cnt);
    174       else
  175          memcpy(buffer, (unsigned char *) srb->request_buffer +
  176                *offset, cnt);
  177       *offset += cnt;
  178 
  179    /* Using scatter-gather.  We have to go through the list one entry
  180     * at a time.  Each s-g entry contains some number of pages, and
  181     * each page has to be kmap()'ed separately.  If the page is already
  182     * in kernel-addressable memory then kmap() will return its address.
  183     * If the page is not directly accessible -- such as a user buffer
  184     * located in high memory -- then kmap() will map it to a temporary
  185     * position in the kernel's virtual address space. */
    186    } else {
  187       struct scatterlist *sg =
  188             (struct scatterlist *) srb->request_buffer
  189             + *index;
  190 
  191       /* This loop handles a single s-g list entry, which may
  192        * include multiple pages.  Find the initial page structure
  193        * and the starting offset within the page, and update
  194        * the *offset and *index values for the next loop. */
  195       cnt = 0;
- 196       while (cnt < buflen && *index < srb->use_sg) {
 - 196     T && T
 - 196     T && F
 - 196     F && _
  197          struct page *page = sg->page +
  198                ((sg->offset + *offset) >> PAGE_SHIFT);
  199          unsigned int poff =
  200                (sg->offset + *offset) & (PAGE_SIZE-1);
  201          unsigned int sglen = sg->length - *offset;
  202 
- 203          if (sglen > buflen - cnt) {
  204 
  205             /* Transfer ends within this s-g entry */
  206             sglen = buflen - cnt;
  207             *offset += sglen;
    208          } else {
  209 
  210             /* Transfer continues to next s-g entry */
  211             *offset = 0;
  212             ++*index;
  213             ++sg;
  214          }
  215 
  216          /* Transfer the data for all the pages in this
  217           * s-g entry.  For each page: call kmap(), do the
  218           * transfer, and call kunmap() immediately after. */
- 219          while (sglen > 0) {
  220             unsigned int plen = min(sglen, (unsigned int)
  221                   PAGE_SIZE - poff);
  222             unsigned char *ptr = kmap(page);
  223 
- 224             if (dir == TO_XFER_BUF)
  225                memcpy(ptr + poff, buffer + cnt, plen);
    226             else
  227                memcpy(buffer + cnt, ptr + poff, plen);
    228             kunmap(page);
- 228       do-while (0)
  229 
  230             /* Start at the beginning of the next page */
  231             poff = 0;
  232             ++page;
  233             cnt += plen;
  234             sglen -= plen;
  235          }
  236       }
  237    }
  238 
  239    /* Return the amount actually transferred */
 - 240    return cnt;
  241 }
  242 
  243 /* Store the contents of buffer into srb's transfer buffer and set the
  244  * SCSI residue. */
 
- 245 void usb_stor_set_xfer_buf(unsigned char *buffer,
  246    unsigned int buflen, struct scsi_cmnd *srb)
  247 {
  248    unsigned int index = 0, offset = 0;
  249 
  250    usb_stor_access_xfer_buf(buffer, buflen, srb, &index, &offset,
  251          TO_XFER_BUF);
- 252    if (buflen < srb->request_bufflen)
  253       srb->resid = srb->request_bufflen - buflen;
  254 }
***TER 2% (1/41) of SOURCE FILE protocol.c

Files Summary | Functions Summary | Execution Profile | Index | No Index
First | Previous | Next | Last | Top