jumpshot.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:26k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

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