jumpshot.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:25k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

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