]> pilppa.org Git - linux-2.6-omap-h63xx.git/blob - drivers/usb/storage/jumpshot.c
Merge branch 'upstream' into upstream-jgarzik
[linux-2.6-omap-h63xx.git] / drivers / usb / storage / jumpshot.c
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.  See the comments
47   * in that routine.
48   */
49
50 #include <linux/errno.h>
51 #include <linux/slab.h>
52
53 #include <scsi/scsi.h>
54 #include <scsi/scsi_cmnd.h>
55
56 #include "usb.h"
57 #include "transport.h"
58 #include "protocol.h"
59 #include "debug.h"
60 #include "jumpshot.h"
61
62
63 static inline int jumpshot_bulk_read(struct us_data *us,
64                                      unsigned char *data, 
65                                      unsigned int len)
66 {
67         if (len == 0)
68                 return USB_STOR_XFER_GOOD;
69
70         US_DEBUGP("jumpshot_bulk_read:  len = %d\n", len);
71         return usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe,
72                         data, len, NULL);
73 }
74
75
76 static inline int jumpshot_bulk_write(struct us_data *us,
77                                       unsigned char *data, 
78                                       unsigned int len)
79 {
80         if (len == 0)
81                 return USB_STOR_XFER_GOOD;
82
83         US_DEBUGP("jumpshot_bulk_write:  len = %d\n", len);
84         return usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe,
85                         data, len, NULL);
86 }
87
88
89 static int jumpshot_get_status(struct us_data  *us)
90 {
91         int rc;
92
93         if (!us)
94                 return USB_STOR_TRANSPORT_ERROR;
95
96         // send the setup
97         rc = usb_stor_ctrl_transfer(us, us->recv_ctrl_pipe,
98                                    0, 0xA0, 0, 7, us->iobuf, 1);
99
100         if (rc != USB_STOR_XFER_GOOD)
101                 return USB_STOR_TRANSPORT_ERROR;
102
103         if (us->iobuf[0] != 0x50) {
104                 US_DEBUGP("jumpshot_get_status:  0x%2x\n",
105                           us->iobuf[0]);
106                 return USB_STOR_TRANSPORT_ERROR;
107         }
108
109         return USB_STOR_TRANSPORT_GOOD;
110 }
111
112 static int jumpshot_read_data(struct us_data *us,
113                               struct jumpshot_info *info,
114                               u32 sector,
115                               u32 sectors)
116 {
117         unsigned char *command = us->iobuf;
118         unsigned char *buffer;
119         unsigned char  thistime;
120         unsigned int totallen, alloclen;
121         int len, result;
122         unsigned int sg_idx = 0, sg_offset = 0;
123
124         // we're working in LBA mode.  according to the ATA spec, 
125         // we can support up to 28-bit addressing.  I don't know if Jumpshot
126         // supports beyond 24-bit addressing.  It's kind of hard to test 
127         // since it requires > 8GB CF card.
128
129         if (sector > 0x0FFFFFFF)
130                 return USB_STOR_TRANSPORT_ERROR;
131
132         totallen = sectors * info->ssize;
133
134         // Since we don't read more than 64 KB at a time, we have to create
135         // a bounce buffer and move the data a piece at a time between the
136         // bounce buffer and the actual transfer buffer.
137
138         alloclen = min(totallen, 65536u);
139         buffer = kmalloc(alloclen, GFP_NOIO);
140         if (buffer == NULL)
141                 return USB_STOR_TRANSPORT_ERROR;
142
143         do {
144                 // loop, never allocate or transfer more than 64k at once
145                 // (min(128k, 255*info->ssize) is the real limit)
146                 len = min(totallen, alloclen);
147                 thistime = (len / info->ssize) & 0xff;
148
149                 command[0] = 0;
150                 command[1] = thistime;
151                 command[2] = sector & 0xFF;
152                 command[3] = (sector >>  8) & 0xFF;
153                 command[4] = (sector >> 16) & 0xFF;
154
155                 command[5] = 0xE0 | ((sector >> 24) & 0x0F);
156                 command[6] = 0x20;
157
158                 // send the setup + command
159                 result = usb_stor_ctrl_transfer(us, us->send_ctrl_pipe,
160                                                0, 0x20, 0, 1, command, 7);
161                 if (result != USB_STOR_XFER_GOOD)
162                         goto leave;
163
164                 // read the result
165                 result = jumpshot_bulk_read(us, buffer, len);
166                 if (result != USB_STOR_XFER_GOOD)
167                         goto leave;
168
169                 US_DEBUGP("jumpshot_read_data:  %d bytes\n", len);
170
171                 // Store the data in the transfer buffer
172                 usb_stor_access_xfer_buf(buffer, len, us->srb,
173                                  &sg_idx, &sg_offset, TO_XFER_BUF);
174
175                 sector += thistime;
176                 totallen -= len;
177         } while (totallen > 0);
178
179         kfree(buffer);
180         return USB_STOR_TRANSPORT_GOOD;
181
182  leave:
183         kfree(buffer);
184         return USB_STOR_TRANSPORT_ERROR;
185 }
186
187
188 static int jumpshot_write_data(struct us_data *us,
189                                struct jumpshot_info *info,
190                                u32 sector,
191                                u32 sectors)
192 {
193         unsigned char *command = us->iobuf;
194         unsigned char *buffer;
195         unsigned char  thistime;
196         unsigned int totallen, alloclen;
197         int len, result, waitcount;
198         unsigned int sg_idx = 0, sg_offset = 0;
199
200         // we're working in LBA mode.  according to the ATA spec, 
201         // we can support up to 28-bit addressing.  I don't know if Jumpshot
202         // supports beyond 24-bit addressing.  It's kind of hard to test 
203         // since it requires > 8GB CF card.
204         //
205         if (sector > 0x0FFFFFFF)
206                 return USB_STOR_TRANSPORT_ERROR;
207
208         totallen = sectors * info->ssize;
209
210         // Since we don't write more than 64 KB at a time, we have to create
211         // a bounce buffer and move the data a piece at a time between the
212         // bounce buffer and the actual transfer buffer.
213
214         alloclen = min(totallen, 65536u);
215         buffer = kmalloc(alloclen, GFP_NOIO);
216         if (buffer == NULL)
217                 return USB_STOR_TRANSPORT_ERROR;
218
219         do {
220                 // loop, never allocate or transfer more than 64k at once
221                 // (min(128k, 255*info->ssize) is the real limit)
222
223                 len = min(totallen, alloclen);
224                 thistime = (len / info->ssize) & 0xff;
225
226                 // Get the data from the transfer buffer
227                 usb_stor_access_xfer_buf(buffer, len, us->srb,
228                                 &sg_idx, &sg_offset, FROM_XFER_BUF);
229
230                 command[0] = 0;
231                 command[1] = thistime;
232                 command[2] = sector & 0xFF;
233                 command[3] = (sector >>  8) & 0xFF;
234                 command[4] = (sector >> 16) & 0xFF;
235
236                 command[5] = 0xE0 | ((sector >> 24) & 0x0F);
237                 command[6] = 0x30;
238
239                 // send the setup + command
240                 result = usb_stor_ctrl_transfer(us, us->send_ctrl_pipe,
241                         0, 0x20, 0, 1, command, 7);
242                 if (result != USB_STOR_XFER_GOOD)
243                         goto leave;
244
245                 // send the data
246                 result = jumpshot_bulk_write(us, buffer, len);
247                 if (result != USB_STOR_XFER_GOOD)
248                         goto leave;
249
250                 // read the result.  apparently the bulk write can complete
251                 // before the jumpshot drive is finished writing.  so we loop
252                 // here until we get a good return code
253                 waitcount = 0;
254                 do {
255                         result = jumpshot_get_status(us);
256                         if (result != USB_STOR_TRANSPORT_GOOD) {
257                                 // I have not experimented to find the smallest value.
258                                 //
259                                 msleep(50); 
260                         }
261                 } while ((result != USB_STOR_TRANSPORT_GOOD) && (waitcount < 10));
262
263                 if (result != USB_STOR_TRANSPORT_GOOD)
264                         US_DEBUGP("jumpshot_write_data:  Gah!  Waitcount = 10.  Bad write!?\n");
265
266                 sector += thistime;
267                 totallen -= len;
268         } while (totallen > 0);
269
270         kfree(buffer);
271         return result;
272
273  leave:
274         kfree(buffer);
275         return USB_STOR_TRANSPORT_ERROR;
276 }
277
278 static int jumpshot_id_device(struct us_data *us,
279                               struct jumpshot_info *info)
280 {
281         unsigned char *command = us->iobuf;
282         unsigned char *reply;
283         int      rc;
284
285         if (!us || !info)
286                 return USB_STOR_TRANSPORT_ERROR;
287
288         command[0] = 0xE0;
289         command[1] = 0xEC;
290         reply = kmalloc(512, GFP_NOIO);
291         if (!reply)
292                 return USB_STOR_TRANSPORT_ERROR;
293
294         // send the setup
295         rc = usb_stor_ctrl_transfer(us, us->send_ctrl_pipe,
296                                    0, 0x20, 0, 6, command, 2);
297
298         if (rc != USB_STOR_XFER_GOOD) {
299                 US_DEBUGP("jumpshot_id_device:  Gah! "
300                           "send_control for read_capacity failed\n");
301                 rc = USB_STOR_TRANSPORT_ERROR;
302                 goto leave;
303         }
304
305         // read the reply
306         rc = jumpshot_bulk_read(us, reply, 512);
307         if (rc != USB_STOR_XFER_GOOD) {
308                 rc = USB_STOR_TRANSPORT_ERROR;
309                 goto leave;
310         }
311
312         info->sectors = ((u32)(reply[117]) << 24) |
313                         ((u32)(reply[116]) << 16) |
314                         ((u32)(reply[115]) <<  8) |
315                         ((u32)(reply[114])      );
316
317         rc = USB_STOR_TRANSPORT_GOOD;
318
319  leave:
320         kfree(reply);
321         return rc;
322 }
323
324 static int jumpshot_handle_mode_sense(struct us_data *us,
325                                       struct scsi_cmnd * srb, 
326                                       int sense_6)
327 {
328         static unsigned char rw_err_page[12] = {
329                 0x1, 0xA, 0x21, 1, 0, 0, 0, 0, 1, 0, 0, 0
330         };
331         static unsigned char cache_page[12] = {
332                 0x8, 0xA, 0x1, 0, 0, 0, 0, 0, 0, 0, 0, 0
333         };
334         static unsigned char rbac_page[12] = {
335                 0x1B, 0xA, 0, 0x81, 0, 0, 0, 0, 0, 0, 0, 0
336         };
337         static unsigned char timer_page[8] = {
338                 0x1C, 0x6, 0, 0, 0, 0
339         };
340         unsigned char pc, page_code;
341         unsigned int i = 0;
342         struct jumpshot_info *info = (struct jumpshot_info *) (us->extra);
343         unsigned char *ptr = us->iobuf;
344
345         pc = srb->cmnd[2] >> 6;
346         page_code = srb->cmnd[2] & 0x3F;
347
348         switch (pc) {
349            case 0x0:
350                 US_DEBUGP("jumpshot_handle_mode_sense:  Current values\n");
351                 break;
352            case 0x1:
353                 US_DEBUGP("jumpshot_handle_mode_sense:  Changeable values\n");
354                 break;
355            case 0x2:
356                 US_DEBUGP("jumpshot_handle_mode_sense:  Default values\n");
357                 break;
358            case 0x3:
359                 US_DEBUGP("jumpshot_handle_mode_sense:  Saves values\n");
360                 break;
361         }
362
363         memset(ptr, 0, 8);
364         if (sense_6) {
365                 ptr[2] = 0x00;          // WP enable: 0x80
366                 i = 4;
367         } else {
368                 ptr[3] = 0x00;          // WP enable: 0x80
369                 i = 8;
370         }
371
372         switch (page_code) {
373            case 0x0:
374                 // vendor-specific mode
375                 info->sense_key = 0x05;
376                 info->sense_asc = 0x24;
377                 info->sense_ascq = 0x00;
378                 return USB_STOR_TRANSPORT_FAILED;
379
380            case 0x1:
381                 memcpy(ptr + i, rw_err_page, sizeof(rw_err_page));
382                 i += sizeof(rw_err_page);
383                 break;
384
385            case 0x8:
386                 memcpy(ptr + i, cache_page, sizeof(cache_page));
387                 i += sizeof(cache_page);
388                 break;
389
390            case 0x1B:
391                 memcpy(ptr + i, rbac_page, sizeof(rbac_page));
392                 i += sizeof(rbac_page);
393                 break;
394
395            case 0x1C:
396                 memcpy(ptr + i, timer_page, sizeof(timer_page));
397                 i += sizeof(timer_page);
398                 break;
399
400            case 0x3F:
401                 memcpy(ptr + i, timer_page, sizeof(timer_page));
402                 i += sizeof(timer_page);
403                 memcpy(ptr + i, rbac_page, sizeof(rbac_page));
404                 i += sizeof(rbac_page);
405                 memcpy(ptr + i, cache_page, sizeof(cache_page));
406                 i += sizeof(cache_page);
407                 memcpy(ptr + i, rw_err_page, sizeof(rw_err_page));
408                 i += sizeof(rw_err_page);
409                 break;
410         }
411
412         if (sense_6)
413                 ptr[0] = i - 1;
414         else
415                 ((__be16 *) ptr)[0] = cpu_to_be16(i - 2);
416         usb_stor_set_xfer_buf(ptr, i, srb);
417
418         return USB_STOR_TRANSPORT_GOOD;
419 }
420
421
422 static void jumpshot_info_destructor(void *extra)
423 {
424         // this routine is a placeholder...
425         // currently, we don't allocate any extra blocks so we're okay
426 }
427
428
429
430 // Transport for the Lexar 'Jumpshot'
431 //
432 int jumpshot_transport(struct scsi_cmnd * srb, struct us_data *us)
433 {
434         struct jumpshot_info *info;
435         int rc;
436         unsigned long block, blocks;
437         unsigned char *ptr = us->iobuf;
438         static unsigned char inquiry_response[8] = {
439                 0x00, 0x80, 0x00, 0x01, 0x1F, 0x00, 0x00, 0x00
440         };
441
442         if (!us->extra) {
443                 us->extra = kzalloc(sizeof(struct jumpshot_info), GFP_NOIO);
444                 if (!us->extra) {
445                         US_DEBUGP("jumpshot_transport:  Gah! Can't allocate storage for jumpshot info struct!\n");
446                         return USB_STOR_TRANSPORT_ERROR;
447                 }
448                 us->extra_destructor = jumpshot_info_destructor;
449         }
450
451         info = (struct jumpshot_info *) (us->extra);
452
453         if (srb->cmnd[0] == INQUIRY) {
454                 US_DEBUGP("jumpshot_transport:  INQUIRY.  Returning bogus response.\n");
455                 memcpy(ptr, inquiry_response, sizeof(inquiry_response));
456                 fill_inquiry_response(us, ptr, 36);
457                 return USB_STOR_TRANSPORT_GOOD;
458         }
459
460         if (srb->cmnd[0] == READ_CAPACITY) {
461                 info->ssize = 0x200;  // hard coded 512 byte sectors as per ATA spec
462
463                 rc = jumpshot_get_status(us);
464                 if (rc != USB_STOR_TRANSPORT_GOOD)
465                         return rc;
466
467                 rc = jumpshot_id_device(us, info);
468                 if (rc != USB_STOR_TRANSPORT_GOOD)
469                         return rc;
470
471                 US_DEBUGP("jumpshot_transport:  READ_CAPACITY:  %ld sectors, %ld bytes per sector\n",
472                           info->sectors, info->ssize);
473
474                 // build the reply
475                 //
476                 ((__be32 *) ptr)[0] = cpu_to_be32(info->sectors - 1);
477                 ((__be32 *) ptr)[1] = cpu_to_be32(info->ssize);
478                 usb_stor_set_xfer_buf(ptr, 8, srb);
479
480                 return USB_STOR_TRANSPORT_GOOD;
481         }
482
483         if (srb->cmnd[0] == MODE_SELECT_10) {
484                 US_DEBUGP("jumpshot_transport:  Gah! MODE_SELECT_10.\n");
485                 return USB_STOR_TRANSPORT_ERROR;
486         }
487
488         if (srb->cmnd[0] == READ_10) {
489                 block = ((u32)(srb->cmnd[2]) << 24) | ((u32)(srb->cmnd[3]) << 16) |
490                         ((u32)(srb->cmnd[4]) <<  8) | ((u32)(srb->cmnd[5]));
491
492                 blocks = ((u32)(srb->cmnd[7]) << 8) | ((u32)(srb->cmnd[8]));
493
494                 US_DEBUGP("jumpshot_transport:  READ_10: read block 0x%04lx  count %ld\n", block, blocks);
495                 return jumpshot_read_data(us, info, block, blocks);
496         }
497
498         if (srb->cmnd[0] == READ_12) {
499                 // I don't think we'll ever see a READ_12 but support it anyway...
500                 //
501                 block = ((u32)(srb->cmnd[2]) << 24) | ((u32)(srb->cmnd[3]) << 16) |
502                         ((u32)(srb->cmnd[4]) <<  8) | ((u32)(srb->cmnd[5]));
503
504                 blocks = ((u32)(srb->cmnd[6]) << 24) | ((u32)(srb->cmnd[7]) << 16) |
505                          ((u32)(srb->cmnd[8]) <<  8) | ((u32)(srb->cmnd[9]));
506
507                 US_DEBUGP("jumpshot_transport:  READ_12: read block 0x%04lx  count %ld\n", block, blocks);
508                 return jumpshot_read_data(us, info, block, blocks);
509         }
510
511         if (srb->cmnd[0] == WRITE_10) {
512                 block = ((u32)(srb->cmnd[2]) << 24) | ((u32)(srb->cmnd[3]) << 16) |
513                         ((u32)(srb->cmnd[4]) <<  8) | ((u32)(srb->cmnd[5]));
514
515                 blocks = ((u32)(srb->cmnd[7]) << 8) | ((u32)(srb->cmnd[8]));
516
517                 US_DEBUGP("jumpshot_transport:  WRITE_10: write block 0x%04lx  count %ld\n", block, blocks);
518                 return jumpshot_write_data(us, info, block, blocks);
519         }
520
521         if (srb->cmnd[0] == WRITE_12) {
522                 // I don't think we'll ever see a WRITE_12 but support it anyway...
523                 //
524                 block = ((u32)(srb->cmnd[2]) << 24) | ((u32)(srb->cmnd[3]) << 16) |
525                         ((u32)(srb->cmnd[4]) <<  8) | ((u32)(srb->cmnd[5]));
526
527                 blocks = ((u32)(srb->cmnd[6]) << 24) | ((u32)(srb->cmnd[7]) << 16) |
528                          ((u32)(srb->cmnd[8]) <<  8) | ((u32)(srb->cmnd[9]));
529
530                 US_DEBUGP("jumpshot_transport:  WRITE_12: write block 0x%04lx  count %ld\n", block, blocks);
531                 return jumpshot_write_data(us, info, block, blocks);
532         }
533
534
535         if (srb->cmnd[0] == TEST_UNIT_READY) {
536                 US_DEBUGP("jumpshot_transport:  TEST_UNIT_READY.\n");
537                 return jumpshot_get_status(us);
538         }
539
540         if (srb->cmnd[0] == REQUEST_SENSE) {
541                 US_DEBUGP("jumpshot_transport:  REQUEST_SENSE.\n");
542
543                 memset(ptr, 0, 18);
544                 ptr[0] = 0xF0;
545                 ptr[2] = info->sense_key;
546                 ptr[7] = 11;
547                 ptr[12] = info->sense_asc;
548                 ptr[13] = info->sense_ascq;
549                 usb_stor_set_xfer_buf(ptr, 18, srb);
550
551                 return USB_STOR_TRANSPORT_GOOD;
552         }
553
554         if (srb->cmnd[0] == MODE_SENSE) {
555                 US_DEBUGP("jumpshot_transport:  MODE_SENSE_6 detected\n");
556                 return jumpshot_handle_mode_sense(us, srb, 1);
557         }
558
559         if (srb->cmnd[0] == MODE_SENSE_10) {
560                 US_DEBUGP("jumpshot_transport:  MODE_SENSE_10 detected\n");
561                 return jumpshot_handle_mode_sense(us, srb, 0);
562         }
563
564         if (srb->cmnd[0] == ALLOW_MEDIUM_REMOVAL) {
565                 // sure.  whatever.  not like we can stop the user from popping
566                 // the media out of the device (no locking doors, etc)
567                 //
568                 return USB_STOR_TRANSPORT_GOOD;
569         }
570
571         if (srb->cmnd[0] == START_STOP) {
572                 /* this is used by sd.c'check_scsidisk_media_change to detect
573                    media change */
574                 US_DEBUGP("jumpshot_transport:  START_STOP.\n");
575                 /* the first jumpshot_id_device after a media change returns
576                    an error (determined experimentally) */
577                 rc = jumpshot_id_device(us, info);
578                 if (rc == USB_STOR_TRANSPORT_GOOD) {
579                         info->sense_key = NO_SENSE;
580                         srb->result = SUCCESS;
581                 } else {
582                         info->sense_key = UNIT_ATTENTION;
583                         srb->result = SAM_STAT_CHECK_CONDITION;
584                 }
585                 return rc;
586         }
587
588         US_DEBUGP("jumpshot_transport:  Gah! Unknown command: %d (0x%x)\n",
589                   srb->cmnd[0], srb->cmnd[0]);
590         info->sense_key = 0x05;
591         info->sense_asc = 0x20;
592         info->sense_ascq = 0x00;
593         return USB_STOR_TRANSPORT_FAILED;
594 }