linux-old/drivers/usb/storage/jumpshot.c
<<
>>
Prefs
   1/* Driver for Lexar "Jumpshot" Compact Flash reader
   2 *
   3 * $Id: jumpshot.c,v 1.7 2002/02/25 00:40:13 mdharm Exp $
   4 *
   5 * jumpshot driver v0.1:
   6 *
   7 * First release
   8 *
   9 * Current development and maintenance by:
  10 *   (c) 2000 Jimmie Mayfield (mayfield+usb@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 * Developed with the assistance of:
  21 *
  22 *   (C) 2002 Alan Stern <stern@rowland.org>
  23 *
  24 * This program is free software; you can redistribute it and/or modify it
  25 * under the terms of the GNU General Public License as published by the
  26 * Free Software Foundation; either version 2, or (at your option) any
  27 * later version.
  28 *
  29 * This program is distributed in the hope that it will be useful, but
  30 * WITHOUT ANY WARRANTY; without even the implied warranty of
  31 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  32 * General Public License for more details.
  33 *
  34 * You should have received a copy of the GNU General Public License along
  35 * with this program; if not, write to the Free Software Foundation, Inc.,
  36 * 675 Mass Ave, Cambridge, MA 02139, USA.
  37 */
  38 
  39 /*
  40  * This driver attempts to support the Lexar Jumpshot USB CompactFlash 
  41  * reader.  Like many other USB CompactFlash readers, the Jumpshot contains
  42  * a USB-to-ATA chip. 
  43  *
  44  * This driver supports reading and writing.  If you're truly paranoid,
  45  * however, you can force the driver into a write-protected state by setting
  46  * the WP enable bits in jumpshot_handle_mode_sense.  Basically this means
  47  * setting mode_param_header[3] = 0x80.  
  48  */
  49
  50#include "transport.h"
  51#include "protocol.h"
  52#include "usb.h"
  53#include "debug.h"
  54#include "jumpshot.h"
  55
  56#include <linux/sched.h>
  57#include <linux/errno.h>
  58#include <linux/slab.h>
  59
  60extern int usb_stor_control_msg(struct us_data *us, unsigned int pipe,
  61                                u8 request, u8 requesttype, u16 value,
  62                                u16 index, void *data, u16 size);
  63extern int usb_stor_bulk_msg(struct us_data *us, void *data, int pipe,
  64                             unsigned int len, unsigned int *act_len);
  65
  66#if 0
  67static void jumpshot_dump_data(unsigned char *data, int len)
  68{
  69        unsigned char buf[80];
  70        int sofar = 0;
  71
  72        if (!data)
  73                return;
  74
  75        memset(buf, 0, sizeof(buf));
  76
  77        for (sofar = 0; sofar < len; sofar++) {
  78                sprintf(buf + strlen(buf), "%02x ",
  79                        ((unsigned int) data[sofar]) & 0xFF);
  80
  81                if (sofar % 16 == 15) {
  82                        US_DEBUGP("jumpshot:  %s\n", buf);
  83                        memset(buf, 0, sizeof(buf));
  84                }
  85        }
  86
  87        if (strlen(buf) != 0)
  88                US_DEBUGP("jumpshot:  %s\n", buf);
  89}
  90#endif
  91
  92/*
  93 * Send a control message and wait for the response.
  94 *
  95 * us - the pointer to the us_data structure for the device to use
  96 *
  97 * request - the URB Setup Packet's first 6 bytes. The first byte always
  98 *  corresponds to the request type, and the second byte always corresponds
  99 *  to the request.  The other 4 bytes do not correspond to value and index,
 100 *  since they are used in a custom way by the SCM protocol.
 101 *
 102 * xfer_data - a buffer from which to get, or to which to store, any data
 103 *  that gets send or received, respectively, with the URB. Even though
 104 *  it looks like we allocate a buffer in this code for the data, xfer_data
 105 *  must contain enough allocated space.
 106 *
 107 * xfer_len - the number of bytes to send or receive with the URB.
 108 *
 109 * This routine snarfed from the SanDisk SDDR-09 driver
 110 *
 111 */
 112static int jumpshot_send_control(struct us_data  *us,
 113                                 int pipe,
 114                                 unsigned char request,
 115                                 unsigned char requesttype,
 116                                 unsigned short value,
 117                                 unsigned short index,
 118                                 unsigned char *xfer_data,
 119                                 unsigned int xfer_len)
 120{
 121        int result;
 122
 123        // Send the URB to the device and wait for a response.
 124
 125        /* Why are request and request type reversed in this call? */
 126
 127        result = usb_stor_control_msg(us, pipe,
 128                                      request, requesttype,
 129                                      value, index, xfer_data, xfer_len);
 130
 131        // Check the return code for the command.
 132
 133        if (result < 0) {
 134                /* if the command was aborted, indicate that */
 135                if (result == -ECONNRESET)
 136                        return USB_STOR_TRANSPORT_ABORTED;
 137
 138                /* a stall is a fatal condition from the device */
 139                if (result == -EPIPE) {
 140                        US_DEBUGP("jumpshot_send_control:  -- Stall on control pipe. Clearing\n");
 141                        result = usb_stor_clear_halt(us, pipe);
 142                        US_DEBUGP("jumpshot_send_control:  -- usb_stor_clear_halt() returns %d\n", result);
 143                        return USB_STOR_TRANSPORT_FAILED;
 144                }
 145
 146                /* Uh oh... serious problem here */
 147                return USB_STOR_TRANSPORT_ERROR;
 148        }
 149
 150        return USB_STOR_TRANSPORT_GOOD;
 151}
 152
 153
 154static int jumpshot_raw_bulk(int direction,
 155                             struct us_data *us,
 156                             unsigned char *data, 
 157                             unsigned int len)
 158{
 159        int result;
 160        int act_len;
 161        int pipe;
 162
 163        if (direction == SCSI_DATA_READ)
 164                pipe = usb_rcvbulkpipe(us->pusb_dev, us->ep_in);
 165        else
 166                pipe = usb_sndbulkpipe(us->pusb_dev, us->ep_out);
 167
 168        result = usb_stor_bulk_msg(us, data, pipe, len, &act_len);
 169
 170        // if we stall, we need to clear it before we go on
 171        if (result == -EPIPE) {
 172                US_DEBUGP("jumpshot_raw_bulk:  EPIPE. clearing endpoint halt for"
 173                          " pipe 0x%x, stalled at %d bytes\n", pipe, act_len);
 174                usb_stor_clear_halt(us, pipe);
 175        }
 176
 177        if (result) {
 178                // NAK - that means we've retried a few times already
 179                if (result == -ETIMEDOUT) {
 180                        US_DEBUGP("jumpshot_raw_bulk:  device NAKed\n");
 181                        return US_BULK_TRANSFER_FAILED;
 182                }
 183
 184                // -ECONNRESET -- we canceled this transfer
 185                if (result == -ECONNRESET) {
 186                        US_DEBUGP("jumpshot_raw_bulk:  transfer aborted\n");
 187                        return US_BULK_TRANSFER_ABORTED;
 188                }
 189
 190                if (result == -EPIPE) {
 191                        US_DEBUGP("jumpshot_raw_bulk:  output pipe stalled\n");
 192                        return USB_STOR_TRANSPORT_FAILED;
 193                }
 194
 195                // the catch-all case
 196                US_DEBUGP("jumpshot_raw_bulk:  unknown error\n");
 197                return US_BULK_TRANSFER_FAILED;
 198        }
 199
 200        if (act_len != len) {
 201                US_DEBUGP("jumpshot_raw_bulk:  Warning. Transferred only %d bytes\n", act_len);
 202                return US_BULK_TRANSFER_SHORT;
 203        }
 204
 205        US_DEBUGP("jumpshot_raw_bulk:  Transfered %d of %d bytes\n", act_len, len);
 206        return US_BULK_TRANSFER_GOOD;
 207}
 208
 209static inline int jumpshot_bulk_read(struct us_data *us,
 210                                     unsigned char *data, 
 211                                     unsigned int len)
 212{
 213        if (len == 0)
 214                return USB_STOR_TRANSPORT_GOOD;
 215
 216        US_DEBUGP("jumpshot_bulk_read:  len = %d\n", len);
 217        return jumpshot_raw_bulk(SCSI_DATA_READ, us, data, len);
 218}
 219
 220
 221static inline int jumpshot_bulk_write(struct us_data *us,
 222                                      unsigned char *data, 
 223                                      unsigned int len)
 224{
 225        if (len == 0)
 226                return USB_STOR_TRANSPORT_GOOD;
 227
 228        US_DEBUGP("jumpshot_bulk_write:  len = %d\n", len);
 229        return jumpshot_raw_bulk(SCSI_DATA_WRITE, us, data, len);
 230}
 231
 232
 233static int jumpshot_get_status(struct us_data  *us)
 234{
 235        unsigned char reply;
 236        int rc;
 237
 238        if (!us)
 239                return USB_STOR_TRANSPORT_ERROR;
 240
 241        // send the setup
 242        rc = jumpshot_send_control(us,
 243                                   usb_rcvctrlpipe(us->pusb_dev, 0),
 244                                   0, 0xA0, 0, 7, &reply, 1);
 245
 246        if (rc != USB_STOR_TRANSPORT_GOOD)
 247                return rc;
 248
 249        if (reply != 0x50) {
 250                US_DEBUGP("jumpshot_get_status:  0x%2x\n",
 251                          (unsigned short) (reply));
 252                return USB_STOR_TRANSPORT_ERROR;
 253        }
 254
 255        return USB_STOR_TRANSPORT_GOOD;
 256}
 257
 258static int jumpshot_read_data(struct us_data *us,
 259                              struct jumpshot_info *info,
 260                              u32 sector,
 261                              u32 sectors, 
 262                              unsigned char *dest, 
 263                              int use_sg)
 264{
 265        unsigned char command[] = { 0, 0, 0, 0, 0, 0xe0, 0x20 };
 266        unsigned char *buffer = NULL;
 267        unsigned char *ptr;
 268        unsigned char  thistime;
 269        struct scatterlist *sg = NULL;
 270        int totallen, len, result;
 271        int sg_idx = 0, current_sg_offset = 0;
 272        int transferred;
 273
 274        // we're working in LBA mode.  according to the ATA spec, 
 275        // we can support up to 28-bit addressing.  I don't know if Jumpshot
 276        // supports beyond 24-bit addressing.  It's kind of hard to test 
 277        // since it requires > 8GB CF card.
 278        //
 279        if (sector > 0x0FFFFFFF)
 280                return USB_STOR_TRANSPORT_ERROR;
 281
 282        // If we're using scatter-gather, we have to create a new
 283        // buffer to read all of the data in first, since a
 284        // scatter-gather buffer could in theory start in the middle
 285        // of a page, which would be bad. A developer who wants a
 286        // challenge might want to write a limited-buffer
 287        // version of this code.
 288
 289        totallen = sectors * info->ssize;
 290
 291        do {
 292               // loop, never allocate or transfer more than 64k at once (min(128k, 255*info->ssize) is the real limit)
 293                len = min_t(int, totallen, 65536);
 294
 295                if (use_sg) {
 296                        sg = (struct scatterlist *) dest;
 297                        buffer = kmalloc(len, GFP_NOIO);
 298                        if (buffer == NULL)
 299                                return USB_STOR_TRANSPORT_ERROR;
 300                        ptr = buffer;
 301                } else {
 302                        ptr = dest;
 303                }
 304
 305                thistime = (len / info->ssize) & 0xff;
 306
 307                command[0] = 0;
 308                command[1] = thistime;
 309                command[2] = sector & 0xFF;
 310                command[3] = (sector >>  8) & 0xFF;
 311                command[4] = (sector >> 16) & 0xFF;
 312
 313                command[5] |= (sector >> 24) & 0x0F;
 314
 315                // send the setup + command
 316                result = jumpshot_send_control(us,
 317                                               usb_sndctrlpipe(us->pusb_dev, 0),
 318                                               0, 0x20, 0, 1, command, 7);
 319                if (result != USB_STOR_TRANSPORT_GOOD) {
 320                        if (use_sg)
 321                                kfree(buffer);
 322                        return result;
 323                }
 324
 325                // read the result
 326                result = jumpshot_bulk_read(us, ptr, len);
 327                if (result != USB_STOR_TRANSPORT_GOOD) {
 328                        if (use_sg)
 329                                kfree(buffer);
 330                        return result;
 331                }
 332
 333                US_DEBUGP("jumpshot_read_data:  %d bytes\n", len);
 334                //jumpshot_dump_data(ptr, len);
 335        
 336                sectors -= thistime;
 337                sector  += thistime;
 338
 339                if (use_sg) {
 340                        transferred = 0;
 341                        while (sg_idx < use_sg && transferred < len) {
 342                                if (len - transferred >= sg[sg_idx].length - current_sg_offset) {
 343                                        US_DEBUGP("jumpshot_read_data:  adding %d bytes to %d byte sg buffer\n", sg[sg_idx].length - current_sg_offset, sg[sg_idx].length);
 344                                        memcpy(sg[sg_idx].address + current_sg_offset,
 345                                               buffer + transferred,
 346                                               sg[sg_idx].length - current_sg_offset);
 347                                        transferred += sg[sg_idx].length - current_sg_offset;
 348                                        current_sg_offset = 0;
 349                                        // on to the next sg buffer
 350                                        ++sg_idx;
 351                                } else {
 352                                        US_DEBUGP("jumpshot_read_data:  adding %d bytes to %d byte sg buffer\n", len - transferred, sg[sg_idx].length);
 353                                        memcpy(sg[sg_idx].address + current_sg_offset,
 354                                               buffer + transferred,
 355                                               len - transferred);
 356                                        current_sg_offset += len - transferred;
 357                                        // this sg buffer is only partially full and we're out of data to copy in
 358                                        break;
 359                                }
 360                        }
 361                        kfree(buffer);
 362                } else {
 363                        dest += len;
 364                }
 365
 366                totallen -= len;
 367        } while (totallen > 0);
 368
 369        return USB_STOR_TRANSPORT_GOOD;
 370}
 371
 372
 373static int jumpshot_write_data(struct us_data *us,
 374                               struct jumpshot_info *info,
 375                               u32 sector,
 376                               u32 sectors, 
 377                               unsigned char *src, 
 378                               int use_sg)
 379{
 380        unsigned char command[7] = { 0, 0, 0, 0, 0, 0xE0, 0x30 };
 381        unsigned char *buffer = NULL;
 382        unsigned char *ptr;
 383        unsigned char  thistime;
 384        struct scatterlist *sg = NULL;
 385        int totallen, len, result, waitcount;
 386        int sg_idx = 0, current_sg_offset = 0;
 387        int transferred;
 388
 389        // we're working in LBA mode.  according to the ATA spec, 
 390        // we can support up to 28-bit addressing.  I don't know if Jumpshot
 391        // supports beyond 24-bit addressing.  It's kind of hard to test 
 392        // since it requires > 8GB CF card.
 393        //
 394        if (sector > 0x0FFFFFFF)
 395                return USB_STOR_TRANSPORT_ERROR;
 396
 397        // If we're using scatter-gather, we have to create a new
 398        // buffer to read all of the data in first, since a
 399        // scatter-gather buffer could in theory start in the middle
 400        // of a page, which would be bad. A developer who wants a
 401        // challenge might want to write a limited-buffer
 402        // version of this code.
 403
 404        totallen = sectors * info->ssize;
 405
 406        do {
 407                // loop, never allocate or transfer more than 64k at once (min(128k, 255*info->ssize) is the real limit)
 408                len = min_t(int, totallen, 65536);
 409
 410                if (use_sg) {
 411                        sg = (struct scatterlist *) src;
 412                        buffer = kmalloc(len, GFP_NOIO);
 413                        if (buffer == NULL)
 414                                return USB_STOR_TRANSPORT_ERROR;
 415                        ptr = buffer;
 416
 417                        memset(buffer, 0, len);
 418
 419                        // copy the data from the sg bufs into the big contiguous buf
 420                        //
 421                        transferred = 0;
 422                        while (transferred < len) {
 423                                if (len - transferred >= sg[sg_idx].length - current_sg_offset) {
 424                                        US_DEBUGP("jumpshot_write_data:  getting %d bytes from %d byte sg buffer\n", sg[sg_idx].length - current_sg_offset, sg[sg_idx].length);
 425                                        memcpy(ptr + transferred,
 426                                               sg[sg_idx].address + current_sg_offset,
 427                                               sg[sg_idx].length - current_sg_offset);
 428                                        transferred += sg[sg_idx].length - current_sg_offset;
 429                                        current_sg_offset = 0;
 430                                        // on to the next sg buffer
 431                                        ++sg_idx;
 432                                } else {
 433                                        US_DEBUGP("jumpshot_write_data:  getting %d bytes from %d byte sg buffer\n", len - transferred, sg[sg_idx].length);
 434                                        memcpy(ptr + transferred,
 435                                               sg[sg_idx].address + current_sg_offset,
 436                                               len - transferred);
 437                                        current_sg_offset += len - transferred;
 438                                        // we only copied part of this sg buffer
 439                                        break;
 440                                }
 441                        }
 442                } else {
 443                        ptr = src;
 444                }
 445
 446                thistime = (len / info->ssize) & 0xff;
 447
 448                command[0] = 0;
 449                command[1] = thistime;
 450                command[2] = sector & 0xFF;
 451                command[3] = (sector >>  8) & 0xFF;
 452                command[4] = (sector >> 16) & 0xFF;
 453
 454                command[5] |= (sector >> 24) & 0x0F;
 455
 456                // send the setup + command
 457                result = jumpshot_send_control(us,
 458                                               usb_sndctrlpipe(us->pusb_dev, 0),
 459                                               0, 0x20, 0, 1, command, 7);
 460
 461                // send the data
 462                result = jumpshot_bulk_write(us, ptr, len);
 463                if (result != USB_STOR_TRANSPORT_GOOD) {
 464                        if (use_sg)
 465                                kfree(buffer);
 466                        return result;
 467                }
 468
 469                // read the result.  apparently the bulk write can complete before the
 470                // jumpshot drive is finished writing.  so we loop here until we
 471                // get a good return code
 472                waitcount = 0;
 473                do {
 474                        result = jumpshot_get_status(us);
 475                        if (result != USB_STOR_TRANSPORT_GOOD) {
 476                                // I have not experimented to find the smallest value.
 477                                //
 478                                wait_ms(50); 
 479                        }
 480                } while ((result != USB_STOR_TRANSPORT_GOOD) && (waitcount < 10));
 481
 482                if (result != USB_STOR_TRANSPORT_GOOD)
 483                        US_DEBUGP("jumpshot_write_data:  Gah!  Waitcount = 10.  Bad write!?\n");
 484                
 485                sectors -= thistime;
 486                sector  += thistime;
 487
 488                if (use_sg) {
 489                        kfree(buffer);
 490                } else {
 491                        src += len;
 492                }
 493
 494                totallen -= len;
 495        } while (totallen > 0);
 496
 497        return result;
 498}
 499
 500static int jumpshot_id_device(struct us_data *us,
 501                              struct jumpshot_info *info)
 502{
 503        unsigned char command[2] = { 0xe0, 0xec };
 504        unsigned char reply[512];
 505        int      rc;
 506
 507        if (!us || !info)
 508                return USB_STOR_TRANSPORT_ERROR;
 509
 510        // send the setup
 511        rc = jumpshot_send_control(us,
 512                                   usb_sndctrlpipe(us->pusb_dev, 0),
 513                                   0, 0x20, 0, 6, command, 2);
 514
 515        if (rc != USB_STOR_TRANSPORT_GOOD) {
 516                US_DEBUGP("jumpshot_id_device:  Gah! send_control for read_capacity failed\n");
 517                return rc;
 518        }
 519
 520        // read the reply
 521        rc = jumpshot_bulk_read(us, reply, sizeof(reply));
 522        if (rc != USB_STOR_TRANSPORT_GOOD)
 523                return rc;
 524
 525        info->sectors = ((u32)(reply[117]) << 24) |
 526                        ((u32)(reply[116]) << 16) |
 527                        ((u32)(reply[115]) <<  8) |
 528                        ((u32)(reply[114])      );
 529
 530        return USB_STOR_TRANSPORT_GOOD;
 531}
 532
 533static int jumpshot_handle_mode_sense(struct us_data *us,
 534                                      Scsi_Cmnd * srb, 
 535                                      unsigned char *ptr,
 536                                      int sense_6)
 537{
 538        unsigned char mode_param_header[8] = {
 539                0, 0, 0, 0, 0, 0, 0, 0
 540        };
 541        unsigned char rw_err_page[12] = {
 542                0x1, 0xA, 0x21, 1, 0, 0, 0, 0, 1, 0, 0, 0
 543        };
 544        unsigned char cache_page[12] = {
 545                0x8, 0xA, 0x1, 0, 0, 0, 0, 0, 0, 0, 0, 0
 546        };
 547        unsigned char rbac_page[12] = {
 548                0x1B, 0xA, 0, 0x81, 0, 0, 0, 0, 0, 0, 0, 0
 549        };
 550        unsigned char timer_page[8] = {
 551                0x1C, 0x6, 0, 0, 0, 0
 552        };
 553        unsigned char pc, page_code;
 554        unsigned short total_len = 0;
 555        unsigned short param_len, i = 0;
 556
 557
 558        if (sense_6)
 559                param_len = srb->cmnd[4];
 560        else
 561                param_len = ((u32) (srb->cmnd[7]) >> 8) | ((u32) (srb->cmnd[8]));
 562
 563
 564        pc = srb->cmnd[2] >> 6;
 565        page_code = srb->cmnd[2] & 0x3F;
 566
 567        switch (pc) {
 568           case 0x0:
 569                US_DEBUGP("jumpshot_handle_mode_sense:  Current values\n");
 570                break;
 571           case 0x1:
 572                US_DEBUGP("jumpshot_handle_mode_sense:  Changeable values\n");
 573                break;
 574           case 0x2:
 575                US_DEBUGP("jumpshot_handle_mode_sense:  Default values\n");
 576                break;
 577           case 0x3:
 578                US_DEBUGP("jumpshot_handle_mode_sense:  Saves values\n");
 579                break;
 580        }
 581
 582        mode_param_header[3] = 0x80;    // write enable
 583
 584        switch (page_code) {
 585           case 0x0:
 586                // vendor-specific mode
 587                return USB_STOR_TRANSPORT_ERROR;
 588
 589           case 0x1:
 590                total_len = sizeof(rw_err_page);
 591                mode_param_header[0] = total_len >> 8;
 592                mode_param_header[1] = total_len & 0xFF;
 593                mode_param_header[3] = 0x00;    // WP enable: 0x80
 594
 595                memcpy(ptr, mode_param_header, sizeof(mode_param_header));
 596                i += sizeof(mode_param_header);
 597                memcpy(ptr + i, rw_err_page, sizeof(rw_err_page));
 598                break;
 599
 600           case 0x8:
 601                total_len = sizeof(cache_page);
 602                mode_param_header[0] = total_len >> 8;
 603                mode_param_header[1] = total_len & 0xFF;
 604                mode_param_header[3] = 0x00;    // WP enable: 0x80
 605
 606                memcpy(ptr, mode_param_header, sizeof(mode_param_header));
 607                i += sizeof(mode_param_header);
 608                memcpy(ptr + i, cache_page, sizeof(cache_page));
 609                break;
 610
 611           case 0x1B:
 612                total_len = sizeof(rbac_page);
 613                mode_param_header[0] = total_len >> 8;
 614                mode_param_header[1] = total_len & 0xFF;
 615                mode_param_header[3] = 0x00;    // WP enable: 0x80
 616
 617                memcpy(ptr, mode_param_header, sizeof(mode_param_header));
 618                i += sizeof(mode_param_header);
 619                memcpy(ptr + i, rbac_page, sizeof(rbac_page));
 620                break;
 621
 622           case 0x1C:
 623                total_len = sizeof(timer_page);
 624                mode_param_header[0] = total_len >> 8;
 625                mode_param_header[1] = total_len & 0xFF;
 626                mode_param_header[3] = 0x00;    // WP enable: 0x80
 627
 628                memcpy(ptr, mode_param_header, sizeof(mode_param_header));
 629                i += sizeof(mode_param_header);
 630                memcpy(ptr + i, timer_page, sizeof(timer_page));
 631                break;
 632
 633           case 0x3F:
 634                total_len = sizeof(timer_page) + sizeof(rbac_page) +
 635                    sizeof(cache_page) + sizeof(rw_err_page);
 636                mode_param_header[0] = total_len >> 8;
 637                mode_param_header[1] = total_len & 0xFF;
 638                mode_param_header[3] = 0x00;    // WP enable: 0x80
 639
 640                memcpy(ptr, mode_param_header, sizeof(mode_param_header));
 641                i += sizeof(mode_param_header);
 642                memcpy(ptr + i, timer_page, sizeof(timer_page));
 643                i += sizeof(timer_page);
 644                memcpy(ptr + i, rbac_page, sizeof(rbac_page));
 645                i += sizeof(rbac_page);
 646                memcpy(ptr + i, cache_page, sizeof(cache_page));
 647                i += sizeof(cache_page);
 648                memcpy(ptr + i, rw_err_page, sizeof(rw_err_page));
 649                break;
 650        }
 651
 652        return USB_STOR_TRANSPORT_GOOD;
 653}
 654
 655
 656void jumpshot_info_destructor(void *extra)
 657{
 658        // this routine is a placeholder...
 659        // currently, we don't allocate any extra blocks so we're okay
 660}
 661
 662
 663
 664// Transport for the Lexar 'Jumpshot'
 665//
 666int jumpshot_transport(Scsi_Cmnd * srb, struct us_data *us)
 667{
 668        struct jumpshot_info *info;
 669        int rc;
 670        unsigned long block, blocks;
 671        unsigned char *ptr = NULL;
 672        unsigned char inquiry_response[36] = {
 673                0x00, 0x80, 0x00, 0x01, 0x1F, 0x00, 0x00, 0x00
 674        };
 675
 676
 677        if (!us->extra) {
 678                us->extra = kmalloc(sizeof(struct jumpshot_info), GFP_NOIO);
 679                if (!us->extra) {
 680                        US_DEBUGP("jumpshot_transport:  Gah! Can't allocate storage for jumpshot info struct!\n");
 681                        return USB_STOR_TRANSPORT_ERROR;
 682                }
 683                memset(us->extra, 0, sizeof(struct jumpshot_info));
 684                us->extra_destructor = jumpshot_info_destructor;
 685        }
 686
 687        info = (struct jumpshot_info *) (us->extra);
 688        ptr = (unsigned char *) srb->request_buffer;
 689
 690        if (srb->cmnd[0] == INQUIRY) {
 691                US_DEBUGP("jumpshot_transport:  INQUIRY.  Returning bogus response.\n");
 692                memset(inquiry_response + 8, 0, 28);
 693                fill_inquiry_response(us, inquiry_response, 36);
 694                return USB_STOR_TRANSPORT_GOOD;
 695        }
 696
 697        if (srb->cmnd[0] == READ_CAPACITY) {
 698                info->ssize = 0x200;  // hard coded 512 byte sectors as per ATA spec
 699
 700                rc = jumpshot_get_status(us);
 701                if (rc != USB_STOR_TRANSPORT_GOOD)
 702                        return rc;
 703
 704                rc = jumpshot_id_device(us, info);
 705                if (rc != USB_STOR_TRANSPORT_GOOD)
 706                        return rc;
 707
 708                US_DEBUGP("jumpshot_transport:  READ_CAPACITY:  %ld sectors, %ld bytes per sector\n",
 709                          info->sectors, info->ssize);
 710
 711                // build the reply
 712                //
 713                ptr[0] = (info->sectors >> 24) & 0xFF;
 714                ptr[1] = (info->sectors >> 16) & 0xFF;
 715                ptr[2] = (info->sectors >> 8) & 0xFF;
 716                ptr[3] = (info->sectors) & 0xFF;
 717
 718                ptr[4] = (info->ssize >> 24) & 0xFF;
 719                ptr[5] = (info->ssize >> 16) & 0xFF;
 720                ptr[6] = (info->ssize >> 8) & 0xFF;
 721                ptr[7] = (info->ssize) & 0xFF;
 722
 723                return USB_STOR_TRANSPORT_GOOD;
 724        }
 725
 726        if (srb->cmnd[0] == MODE_SELECT_10) {
 727                US_DEBUGP("jumpshot_transport:  Gah! MODE_SELECT_10.\n");
 728                return USB_STOR_TRANSPORT_ERROR;
 729        }
 730
 731        if (srb->cmnd[0] == READ_10) {
 732                block = ((u32)(srb->cmnd[2]) << 24) | ((u32)(srb->cmnd[3]) << 16) |
 733                        ((u32)(srb->cmnd[4]) <<  8) | ((u32)(srb->cmnd[5]));
 734
 735                blocks = ((u32)(srb->cmnd[7]) << 8) | ((u32)(srb->cmnd[8]));
 736
 737                US_DEBUGP("jumpshot_transport:  READ_10: read block 0x%04lx  count %ld\n", block, blocks);
 738                return jumpshot_read_data(us, info, block, blocks, ptr, srb->use_sg);
 739        }
 740
 741        if (srb->cmnd[0] == READ_12) {
 742                // I don't think we'll ever see a READ_12 but support it anyway...
 743                //
 744                block = ((u32)(srb->cmnd[2]) << 24) | ((u32)(srb->cmnd[3]) << 16) |
 745                        ((u32)(srb->cmnd[4]) <<  8) | ((u32)(srb->cmnd[5]));
 746
 747                blocks = ((u32)(srb->cmnd[6]) << 24) | ((u32)(srb->cmnd[7]) << 16) |
 748                         ((u32)(srb->cmnd[8]) <<  8) | ((u32)(srb->cmnd[9]));
 749
 750                US_DEBUGP("jumpshot_transport:  READ_12: read block 0x%04lx  count %ld\n", block, blocks);
 751                return jumpshot_read_data(us, info, block, blocks, ptr, srb->use_sg);
 752        }
 753
 754        if (srb->cmnd[0] == WRITE_10) {
 755                block = ((u32)(srb->cmnd[2]) << 24) | ((u32)(srb->cmnd[3]) << 16) |
 756                        ((u32)(srb->cmnd[4]) <<  8) | ((u32)(srb->cmnd[5]));
 757
 758                blocks = ((u32)(srb->cmnd[7]) << 8) | ((u32)(srb->cmnd[8]));
 759
 760                US_DEBUGP("jumpshot_transport:  WRITE_10: write block 0x%04lx  count %ld\n", block, blocks);
 761                return jumpshot_write_data(us, info, block, blocks, ptr, srb->use_sg);
 762        }
 763
 764        if (srb->cmnd[0] == WRITE_12) {
 765                // I don't think we'll ever see a WRITE_12 but support it anyway...
 766                //
 767                block = ((u32)(srb->cmnd[2]) << 24) | ((u32)(srb->cmnd[3]) << 16) |
 768                        ((u32)(srb->cmnd[4]) <<  8) | ((u32)(srb->cmnd[5]));
 769
 770                blocks = ((u32)(srb->cmnd[6]) << 24) | ((u32)(srb->cmnd[7]) << 16) |
 771                         ((u32)(srb->cmnd[8]) <<  8) | ((u32)(srb->cmnd[9]));
 772
 773                US_DEBUGP("jumpshot_transport:  WRITE_12: write block 0x%04lx  count %ld\n", block, blocks);
 774                return jumpshot_write_data(us, info, block, blocks, ptr, srb->use_sg);
 775        }
 776
 777
 778        if (srb->cmnd[0] == TEST_UNIT_READY) {
 779                US_DEBUGP("jumpshot_transport:  TEST_UNIT_READY.\n");
 780                return jumpshot_get_status(us);
 781        }
 782
 783        if (srb->cmnd[0] == REQUEST_SENSE) {
 784                US_DEBUGP("jumpshot_transport:  REQUEST_SENSE.  Returning NO SENSE for now\n");
 785
 786                ptr[0] = 0xF0;
 787                ptr[2] = info->sense_key;
 788                ptr[7] = 11;
 789                ptr[12] = info->sense_asc;
 790                ptr[13] = info->sense_ascq;
 791
 792                return USB_STOR_TRANSPORT_GOOD;
 793        }
 794
 795        if (srb->cmnd[0] == MODE_SENSE) {
 796                US_DEBUGP("jumpshot_transport:  MODE_SENSE_6 detected\n");
 797                return jumpshot_handle_mode_sense(us, srb, ptr, TRUE);
 798        }
 799
 800        if (srb->cmnd[0] == MODE_SENSE_10) {
 801                US_DEBUGP("jumpshot_transport:  MODE_SENSE_10 detected\n");
 802                return jumpshot_handle_mode_sense(us, srb, ptr, FALSE);
 803        }
 804        
 805        if (srb->cmnd[0] == ALLOW_MEDIUM_REMOVAL) {
 806                // sure.  whatever.  not like we can stop the user from popping
 807                // the media out of the device (no locking doors, etc)
 808                //
 809                return USB_STOR_TRANSPORT_GOOD;
 810        }
 811        
 812        if (srb->cmnd[0] == START_STOP) {
 813                /* this is used by sd.c'check_scsidisk_media_change to detect
 814                   media change */
 815                US_DEBUGP("jumpshot_transport:  START_STOP.\n");
 816                /* the first jumpshot_id_device after a media change returns
 817                   an error (determined experimentally) */
 818                rc = jumpshot_id_device(us, info);
 819                if (rc == USB_STOR_TRANSPORT_GOOD) {
 820                        info->sense_key = NO_SENSE;
 821                        srb->result = SUCCESS;
 822                } else {
 823                        info->sense_key = UNIT_ATTENTION;
 824                        srb->result = CHECK_CONDITION;
 825                }
 826                return rc;
 827        }
 828
 829        US_DEBUGP("jumpshot_transport:  Gah! Unknown command: %d (0x%x)\n", srb->cmnd[0], srb->cmnd[0]);
 830        return USB_STOR_TRANSPORT_ERROR;
 831}
 832
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.