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