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