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

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


File: drivers/usb/storage/datafab.c
Instrumentation mode: function-decision-multicondition
TER: 0 % ( 0/194)

Start/ End/    
True False - Line Source

  1 /* Driver for Datafab USB Compact Flash reader
  2  *
  3  * $Id: datafab.c,v 1.7 2002/02/25 00:40:13 mdharm Exp $
  4  *
  5  * datafab driver v0.1:
  6  *
  7  * First release
  8  *
  9  * Current development and maintenance by:
  10  *   (c) 2000 Jimmie Mayfield (mayfield+datafab@sackheads.org)
  11  *
  12  *   Many thanks to Robert Baruch for the SanDisk SmartMedia reader driver
  13  *   which I used as a template for this driver.
  14  *
  15  *   Some bugfixes and scatter-gather code by Gregory P. Smith 
  16  *   (greg-usb@electricrain.com)
  17  *
  18  *   Fix for media change by Joerg Schneider (js@joergschneider.com)
  19  *
  20  * Other contributors:
  21  *   (c) 2002 Alan Stern <stern@rowland.org>
  22  *
  23  * This program is free software; you can redistribute it and/or modify it
  24  * under the terms of the GNU General Public License as published by the
  25  * Free Software Foundation; either version 2, or (at your option) any
  26  * later version.
  27  *
  28  * This program is distributed in the hope that it will be useful, but
  29  * WITHOUT ANY WARRANTY; without even the implied warranty of
  30  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  31  * General Public License for more details.
  32  *
  33  * You should have received a copy of the GNU General Public License along
  34  * with this program; if not, write to the Free Software Foundation, Inc.,
  35  * 675 Mass Ave, Cambridge, MA 02139, USA.
  36  */
  37 
  38 /*
  39  * This driver attempts to support USB CompactFlash reader/writer devices
  40  * based on Datafab USB-to-ATA chips.  It was specifically developed for the 
  41  * Datafab MDCFE-B USB CompactFlash reader but has since been found to work 
  42  * with a variety of Datafab-based devices from a number of manufacturers.
  43  * I've received a report of this driver working with a Datafab-based
  44  * SmartMedia device though please be aware that I'm personally unable to
  45  * test SmartMedia support.
  46  *
  47  * This driver supports reading and writing.  If you're truly paranoid,
  48  * however, you can force the driver into a write-protected state by setting
  49  * the WP enable bits in datafab_handle_mode_sense().  See the comments
  50  * in that routine.
  51  */
  52 
  53 #include <linux/sched.h>
  54 #include <linux/errno.h>
  55 #include <linux/slab.h>
  56 
  57 #include <scsi/scsi.h>
  58 #include <scsi/scsi_cmnd.h>
  59 
  60 #include "usb.h"
  61 #include "transport.h"
  62 #include "protocol.h"
  63 #include "debug.h"
  64 #include "datafab.h"
  65 
  66 static int datafab_determine_lun(struct us_data *us,
  67              struct datafab_info *info);
  68 
  69 
  70 static inline int
 
- 71 datafab_bulk_read(struct us_data *us, unsigned char *data, unsigned int len) {
- 72    if (len == 0)
 - 73       return USB_STOR_XFER_GOOD;
  74 
  75    US_DEBUGP("datafab_bulk_read:  len = %d\n", len);
  76    return usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe,
 - 77          data, len, NULL);
  78 }
  79 
  80 
  81 static inline int
 
- 82 datafab_bulk_write(struct us_data *us, unsigned char *data, unsigned int len) {
- 83    if (len == 0)
 - 84       return USB_STOR_XFER_GOOD;
  85 
  86    US_DEBUGP("datafab_bulk_write:  len = %d\n", len);
  87    return usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe,
 - 88          data, len, NULL);
  89 }
  90 
  91 
 
- 92 static int datafab_read_data(struct us_data *us,
  93               struct datafab_info *info,
  94               u32 sector,
  95               u32 sectors)
  96 {
  97    unsigned char *command = us->iobuf;
  98    unsigned char *buffer;
  99    unsigned char  thistime;
  100    unsigned int totallen, alloclen;
  101    int len, result;
  102    unsigned int sg_idx = 0, sg_offset = 0;
  103 
  104    // we're working in LBA mode.  according to the ATA spec, 
  105    // we can support up to 28-bit addressing.  I don't know if Datafab
  106    // supports beyond 24-bit addressing.  It's kind of hard to test 
  107    // since it requires > 8GB CF card.
  108    //
- 109    if (sectors > 0x0FFFFFFF)
 - 110       return USB_STOR_TRANSPORT_ERROR;
  111 
- 112    if (info->lun == -1) {
  113       result = datafab_determine_lun(us, info);
- 114       if (result != USB_STOR_TRANSPORT_GOOD)
 - 115          return result;
  116    }
  117 
  118    totallen = sectors * info->ssize;
  119 
  120    // Since we don't read more than 64 KB at a time, we have to create
  121    // a bounce buffer and move the data a piece at a time between the
  122    // bounce buffer and the actual transfer buffer.
  123 
  124    alloclen = min(totallen, 65536u);
  125    buffer = kmalloc(alloclen, GFP_NOIO);
- 126    if (buffer == NULL)
 - 127       return USB_STOR_TRANSPORT_ERROR;
  128 
    129    do {
  130       // loop, never allocate or transfer more than 64k at once
  131       // (min(128k, 255*info->ssize) is the real limit)
  132 
  133       len = min(totallen, alloclen);
  134       thistime = (len / info->ssize) & 0xff;
  135 
  136       command[0] = 0;
  137       command[1] = thistime;
  138       command[2] = sector & 0xFF;
  139       command[3] = (sector >> 8) & 0xFF;
  140       command[4] = (sector >> 16) & 0xFF;
  141 
  142       command[5] = 0xE0 + (info->lun << 4);
  143       command[5] |= (sector >> 24) & 0x0F;
  144       command[6] = 0x20;
  145       command[7] = 0x01;
  146 
  147       // send the read command
  148       result = datafab_bulk_write(us, command, 8);
- 149       if (result != USB_STOR_XFER_GOOD)
 - 150          goto leave;
  151 
  152       // read the result
  153       result = datafab_bulk_read(us, buffer, len);
- 154       if (result != USB_STOR_XFER_GOOD)
 - 155          goto leave;
  156 
  157       // Store the data in the transfer buffer
  158       usb_stor_access_xfer_buf(buffer, len, us->srb,
  159              &sg_idx, &sg_offset, TO_XFER_BUF);
  160 
  161       sector += thistime;
  162       totallen -= len;
- 163    } while (totallen > 0);
  164 
  165    kfree(buffer);
 - 166    return USB_STOR_TRANSPORT_GOOD;
  167 
  168  leave:
  169    kfree(buffer);
 - 170    return USB_STOR_TRANSPORT_ERROR;
  171 }
  172 
  173 
 
- 174 static int datafab_write_data(struct us_data *us,
  175                struct datafab_info *info,
  176                u32 sector,
  177                u32 sectors)
  178 {
  179    unsigned char *command = us->iobuf;
  180    unsigned char *reply = us->iobuf;
  181    unsigned char *buffer;
  182    unsigned char thistime;
  183    unsigned int totallen, alloclen;
  184    int len, result;
  185    unsigned int sg_idx = 0, sg_offset = 0;
  186 
  187    // we're working in LBA mode.  according to the ATA spec, 
  188    // we can support up to 28-bit addressing.  I don't know if Datafab
  189    // supports beyond 24-bit addressing.  It's kind of hard to test 
  190    // since it requires > 8GB CF card.
  191    //
- 192    if (sectors > 0x0FFFFFFF)
 - 193       return USB_STOR_TRANSPORT_ERROR;
  194 
- 195    if (info->lun == -1) {
  196       result = datafab_determine_lun(us, info);
- 197       if (result != USB_STOR_TRANSPORT_GOOD)
 - 198          return result;
  199    }
  200 
  201    totallen = sectors * info->ssize;
  202 
  203    // Since we don't write more than 64 KB at a time, we have to create
  204    // a bounce buffer and move the data a piece at a time between the
  205    // bounce buffer and the actual transfer buffer.
  206 
  207    alloclen = min(totallen, 65536u);
  208    buffer = kmalloc(alloclen, GFP_NOIO);
- 209    if (buffer == NULL)
 - 210       return USB_STOR_TRANSPORT_ERROR;
  211 
    212    do {
  213       // loop, never allocate or transfer more than 64k at once
  214       // (min(128k, 255*info->ssize) is the real limit)
  215 
  216       len = min(totallen, alloclen);
  217       thistime = (len / info->ssize) & 0xff;
  218 
  219       // Get the data from the transfer buffer
  220       usb_stor_access_xfer_buf(buffer, len, us->srb,
  221             &sg_idx, &sg_offset, FROM_XFER_BUF);
  222 
  223       command[0] = 0;
  224       command[1] = thistime;
  225       command[2] = sector & 0xFF;
  226       command[3] = (sector >> 8) & 0xFF;
  227       command[4] = (sector >> 16) & 0xFF;
  228 
  229       command[5] = 0xE0 + (info->lun << 4);
  230       command[5] |= (sector >> 24) & 0x0F;
  231       command[6] = 0x30;
  232       command[7] = 0x02;
  233 
  234       // send the command
  235       result = datafab_bulk_write(us, command, 8);
- 236       if (result != USB_STOR_XFER_GOOD)
 - 237          goto leave;
  238 
  239       // send the data
  240       result = datafab_bulk_write(us, buffer, len);
- 241       if (result != USB_STOR_XFER_GOOD)
 - 242          goto leave;
  243 
  244       // read the result
  245       result = datafab_bulk_read(us, reply, 2);
- 246       if (result != USB_STOR_XFER_GOOD)
 - 247          goto leave;
  248 
- 249       if (reply[0] != 0x50 && reply[1] != 0) {
 - 249     T && T
 - 249     T && F
 - 249     F && _
  250          US_DEBUGP("datafab_write_data:  Gah! "
  251               "write return code: %02x %02x\n",
  252               reply[0], reply[1]);
  253          result = USB_STOR_TRANSPORT_ERROR;
 - 254          goto leave;
  255       }
  256 
  257       sector += thistime;
  258       totallen -= len;
- 259    } while (totallen > 0);
  260 
  261    kfree(buffer);
 - 262    return USB_STOR_TRANSPORT_GOOD;
  263 
  264  leave:
  265    kfree(buffer);
 - 266    return USB_STOR_TRANSPORT_ERROR;
  267 }
  268 
  269 
 
- 270 static int datafab_determine_lun(struct us_data *us,
  271              struct datafab_info *info)
  272 {
  273    // Dual-slot readers can be thought of as dual-LUN devices.
  274    // We need to determine which card slot is being used.
  275    // We'll send an IDENTIFY DEVICE command and see which LUN responds...
  276    //
  277    // There might be a better way of doing this?
  278 
  279    static unsigned char scommand[8] = { 0, 1, 0, 0, 0, 0xa0, 0xec, 1 };
  280    unsigned char *command = us->iobuf;
  281    unsigned char *buf;
  282    int count = 0, rc;
  283 
- 284    if (!us || !info)
 - 284   T || _
 - 284   F || T
 - 284   F || F
 - 285       return USB_STOR_TRANSPORT_ERROR;
  286 
  287    memcpy(command, scommand, 8);
  288    buf = kmalloc(512, GFP_NOIO);
- 289    if (!buf)
 - 290       return USB_STOR_TRANSPORT_ERROR;
  291 
  292    US_DEBUGP("datafab_determine_lun:  locating...\n");
  293 
  294    // we'll try 3 times before giving up...
  295    //
- 296    while (count++ < 3) {
  297       command[5] = 0xa0;
  298 
  299       rc = datafab_bulk_write(us, command, 8);
- 300       if (rc != USB_STOR_XFER_GOOD) {
  301          rc = USB_STOR_TRANSPORT_ERROR;
 - 302          goto leave;
  303       }
  304 
  305       rc = datafab_bulk_read(us, buf, 512);
- 306       if (rc == USB_STOR_XFER_GOOD) {
  307          info->lun = 0;
  308          rc = USB_STOR_TRANSPORT_GOOD;
 - 309          goto leave;
  310       }
  311 
  312       command[5] = 0xb0;
  313 
  314       rc = datafab_bulk_write(us, command, 8);
- 315       if (rc != USB_STOR_XFER_GOOD) {
  316          rc = USB_STOR_TRANSPORT_ERROR;
 - 317          goto leave;
  318       }
  319 
  320       rc = datafab_bulk_read(us, buf, 512);
- 321       if (rc == USB_STOR_XFER_GOOD) {
  322          info->lun = 1;
  323          rc = USB_STOR_TRANSPORT_GOOD;
 - 324          goto leave;
  325       }
  326 
  327       msleep(20);
  328    }
  329 
  330    rc = USB_STOR_TRANSPORT_ERROR;
  331 
  332  leave:
  333    kfree(buf);
 - 334    return rc;
  335 }
  336 
 
- 337 static int datafab_id_device(struct us_data *us,
  338               struct datafab_info *info)
  339 {
  340    // this is a variation of the ATA "IDENTIFY DEVICE" command...according
  341    // to the ATA spec, 'Sector Count' isn't used but the Windows driver
  342    // sets this bit so we do too...
  343    //
  344    static unsigned char scommand[8] = { 0, 1, 0, 0, 0, 0xa0, 0xec, 1 };
  345    unsigned char *command = us->iobuf;
  346    unsigned char *reply;
  347    int rc;
  348 
- 349    if (!us || !info)
 - 349   T || _
 - 349   F || T
 - 349   F || F
 - 350       return USB_STOR_TRANSPORT_ERROR;
  351 
- 352    if (info->lun == -1) {
  353       rc = datafab_determine_lun(us, info);
- 354       if (rc != USB_STOR_TRANSPORT_GOOD)
 - 355          return rc;
  356    }
  357 
  358    memcpy(command, scommand, 8);
  359    reply = kmalloc(512, GFP_NOIO);
- 360    if (!reply)
 - 361       return USB_STOR_TRANSPORT_ERROR;
  362 
  363    command[5] += (info->lun << 4);
  364 
  365    rc = datafab_bulk_write(us, command, 8);
- 366    if (rc != USB_STOR_XFER_GOOD) {
  367       rc = USB_STOR_TRANSPORT_ERROR;
 - 368       goto leave;
  369    }
  370 
  371    // we'll go ahead and extract the media capacity while we're here...
  372    //
  373    rc = datafab_bulk_read(us, reply, 512);
- 374    if (rc == USB_STOR_XFER_GOOD) {
  375       // capacity is at word offset 57-58
  376       //
  377       info->sectors = ((u32)(reply[117]) << 24) | 
  378             ((u32)(reply[116]) << 16) |
  379             ((u32)(reply[115]) <<  8) | 
  380             ((u32)(reply[114])      );
  381       rc = USB_STOR_TRANSPORT_GOOD;
 - 382       goto leave;
  383    }
  384 
  385    rc = USB_STOR_TRANSPORT_ERROR;
  386 
  387  leave:
  388    kfree(reply);
 - 389    return rc;
  390 }
  391 
  392 
 
- 393 static int datafab_handle_mode_sense(struct us_data *us,
  394                  struct scsi_cmnd * srb, 
  395                  int sense_6)
  396 {
  397    static unsigned char rw_err_page[12] = {
  398       0x1, 0xA, 0x21, 1, 0, 0, 0, 0, 1, 0, 0, 0
  399    };
  400    static unsigned char cache_page[12] = {
  401       0x8, 0xA, 0x1, 0, 0, 0, 0, 0, 0, 0, 0, 0
  402    };
  403    static unsigned char rbac_page[12] = {
  404       0x1B, 0xA, 0, 0x81, 0, 0, 0, 0, 0, 0, 0, 0
  405    };
  406    static unsigned char timer_page[8] = {
  407       0x1C, 0x6, 0, 0, 0, 0
  408    };
  409    unsigned char pc, page_code;
  410    unsigned int i = 0;
  411    struct datafab_info *info = (struct datafab_info *) (us->extra);
  412    unsigned char *ptr = us->iobuf;
  413 
  414    // most of this stuff is just a hack to get things working.  the
  415    // datafab reader doesn't present a SCSI interface so we
  416    // fudge the SCSI commands...
  417    //
  418 
  419    pc = srb->cmnd[2] >> 6;
  420    page_code = srb->cmnd[2] & 0x3F;
  421 
    422    switch (pc) {
 - 423       case 0x0:
  424       US_DEBUGP("datafab_handle_mode_sense:  Current values\n");
 - 425       break;
 - 426       case 0x1:
  427       US_DEBUGP("datafab_handle_mode_sense:  Changeable values\n");
 - 428       break;
 - 429       case 0x2:
  430       US_DEBUGP("datafab_handle_mode_sense:  Default values\n");
 - 431       break;
 - 432       case 0x3:
  433       US_DEBUGP("datafab_handle_mode_sense:  Saves values\n");
 - 434       break;
  435    }
  436 
  437    memset(ptr, 0, 8);
- 438    if (sense_6) {
  439       ptr[2] = 0x00;      // WP enable: 0x80
  440       i = 4;
    441    } else {
  442       ptr[3] = 0x00;      // WP enable: 0x80
  443       i = 8;
  444    }
  445 
    446    switch (page_code) {
 - 447       default:
  448       // vendor-specific mode
  449       info->sense_key = 0x05;
  450       info->sense_asc = 0x24;
  451       info->sense_ascq = 0x00;
 - 452       return USB_STOR_TRANSPORT_FAILED;
  453 
 - 454       case 0x1:
  455       memcpy(ptr + i, rw_err_page, sizeof(rw_err_page));
  456       i += sizeof(rw_err_page);
 - 457       break;
  458 
 - 459       case 0x8:
  460       memcpy(ptr + i, cache_page, sizeof(cache_page));
  461       i += sizeof(cache_page);
 - 462       break;
  463 
 - 464       case 0x1B:
  465       memcpy(ptr + i, rbac_page, sizeof(rbac_page));
  466       i += sizeof(rbac_page);
 - 467       break;
  468 
 - 469       case 0x1C:
  470       memcpy(ptr + i, timer_page, sizeof(timer_page));
  471       i += sizeof(timer_page);
 - 472       break;
  473 
 - 474       case 0x3F:      // retrieve all pages
  475       memcpy(ptr + i, timer_page, sizeof(timer_page));
  476       i += sizeof(timer_page);
  477       memcpy(ptr + i, rbac_page, sizeof(rbac_page));
  478       i += sizeof(rbac_page);
  479       memcpy(ptr + i, cache_page, sizeof(cache_page));
  480       i += sizeof(cache_page);
  481       memcpy(ptr + i, rw_err_page, sizeof(rw_err_page));
  482       i += sizeof(rw_err_page);
 - 483       break;
  484    }
  485 
- 486    if (sense_6)
  487       ptr[0] = i - 1;
    488    else
    489       ((__be16 *) ptr)[0] = cpu_to_be16(i - 2);
- 489   ternary-?: __builtin_constant_p ( ( __u16 ) ..
  490    usb_stor_set_xfer_buf(ptr, i, srb);
  491 
 - 492    return USB_STOR_TRANSPORT_GOOD;
  493 }
  494 
 
- 495 static void datafab_info_destructor(void *extra)
  496 {
  497    // this routine is a placeholder...
  498    // currently, we don't allocate any extra memory so we're okay
  499 }
  500 
  501 
  502 // Transport for the Datafab MDCFE-B
  503 //
 
- 504 int datafab_transport(struct scsi_cmnd * srb, struct us_data *us)
  505 {
  506    struct datafab_info *info;
  507    int rc;
  508    unsigned long block, blocks;
  509    unsigned char *ptr = us->iobuf;
  510    static unsigned char inquiry_reply[8] = {
  511       0x00, 0x80, 0x00, 0x01, 0x1F, 0x00, 0x00, 0x00
  512    };
  513 
- 514    if (!us->extra) {
  515       us->extra = kmalloc(sizeof(struct datafab_info), GFP_NOIO);
- 516       if (!us->extra) {
  517          US_DEBUGP("datafab_transport:  Gah! "
  518               "Can't allocate storage for Datafab info struct!\n");
 - 519          return USB_STOR_TRANSPORT_ERROR;
  520       }
  521       memset(us->extra, 0, sizeof(struct datafab_info));
  522       us->extra_destructor = datafab_info_destructor;
  523         ((struct datafab_info *)us->extra)->lun = -1;
  524    }
  525 
  526    info = (struct datafab_info *) (us->extra);
  527 
- 528    if (srb->cmnd[0] == INQUIRY) {
  529