Commit | Line | Data |
---|---|---|
5fd54ace | 1 | // SPDX-License-Identifier: GPL-2.0+ |
f0183a33 FB |
2 | /* |
3 | * Driver for SanDisk SDDR-55 SmartMedia reader | |
1da177e4 LT |
4 | * |
5 | * SDDR55 driver v0.1: | |
6 | * | |
7 | * First release | |
8 | * | |
9 | * Current development and maintenance by: | |
10 | * (c) 2002 Simon Munton | |
1da177e4 LT |
11 | */ |
12 | ||
13 | #include <linux/jiffies.h> | |
14 | #include <linux/errno.h> | |
70fcc005 | 15 | #include <linux/module.h> |
1da177e4 LT |
16 | #include <linux/slab.h> |
17 | ||
18 | #include <scsi/scsi.h> | |
19 | #include <scsi/scsi_cmnd.h> | |
20 | ||
21 | #include "usb.h" | |
22 | #include "transport.h" | |
23 | #include "protocol.h" | |
24 | #include "debug.h" | |
aa519be3 AM |
25 | #include "scsiglue.h" |
26 | ||
27 | #define DRV_NAME "ums-sddr55" | |
70fcc005 | 28 | |
4246b06a MG |
29 | MODULE_DESCRIPTION("Driver for SanDisk SDDR-55 SmartMedia reader"); |
30 | MODULE_AUTHOR("Simon Munton"); | |
31 | MODULE_LICENSE("GPL"); | |
32bca2df | 32 | MODULE_IMPORT_NS(USB_STORAGE); |
70fcc005 AS |
33 | |
34 | /* | |
35 | * The table of devices | |
36 | */ | |
37 | #define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \ | |
38 | vendorName, productName, useProtocol, useTransport, \ | |
39 | initFunction, flags) \ | |
40 | { USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \ | |
f61870ee | 41 | .driver_info = (flags) } |
70fcc005 | 42 | |
566b8bbf | 43 | static struct usb_device_id sddr55_usb_ids[] = { |
70fcc005 AS |
44 | # include "unusual_sddr55.h" |
45 | { } /* Terminating entry */ | |
46 | }; | |
47 | MODULE_DEVICE_TABLE(usb, sddr55_usb_ids); | |
48 | ||
49 | #undef UNUSUAL_DEV | |
50 | ||
51 | /* | |
52 | * The flags table | |
53 | */ | |
54 | #define UNUSUAL_DEV(idVendor, idProduct, bcdDeviceMin, bcdDeviceMax, \ | |
55 | vendor_name, product_name, use_protocol, use_transport, \ | |
56 | init_function, Flags) \ | |
57 | { \ | |
58 | .vendorName = vendor_name, \ | |
59 | .productName = product_name, \ | |
60 | .useProtocol = use_protocol, \ | |
61 | .useTransport = use_transport, \ | |
62 | .initFunction = init_function, \ | |
63 | } | |
64 | ||
65 | static struct us_unusual_dev sddr55_unusual_dev_list[] = { | |
66 | # include "unusual_sddr55.h" | |
67 | { } /* Terminating entry */ | |
68 | }; | |
69 | ||
70 | #undef UNUSUAL_DEV | |
1da177e4 LT |
71 | |
72 | ||
73 | #define short_pack(lsb,msb) ( ((u16)(lsb)) | ( ((u16)(msb))<<8 ) ) | |
74 | #define LSB_of(s) ((s)&0xFF) | |
75 | #define MSB_of(s) ((s)>>8) | |
76 | #define PAGESIZE 512 | |
77 | ||
78 | #define set_sense_info(sk, asc, ascq) \ | |
79 | do { \ | |
80 | info->sense_data[2] = sk; \ | |
81 | info->sense_data[12] = asc; \ | |
82 | info->sense_data[13] = ascq; \ | |
83 | } while (0) | |
84 | ||
85 | ||
86 | struct sddr55_card_info { | |
87 | unsigned long capacity; /* Size of card in bytes */ | |
88 | int max_log_blks; /* maximum number of logical blocks */ | |
89 | int pageshift; /* log2 of pagesize */ | |
90 | int smallpageshift; /* 1 if pagesize == 256 */ | |
91 | int blocksize; /* Size of block in pages */ | |
92 | int blockshift; /* log2 of blocksize */ | |
93 | int blockmask; /* 2^blockshift - 1 */ | |
94 | int read_only; /* non zero if card is write protected */ | |
95 | int force_read_only; /* non zero if we find a map error*/ | |
96 | int *lba_to_pba; /* logical to physical map */ | |
97 | int *pba_to_lba; /* physical to logical map */ | |
98 | int fatal_error; /* set if we detect something nasty */ | |
99 | unsigned long last_access; /* number of jiffies since we last talked to device */ | |
100 | unsigned char sense_data[18]; | |
101 | }; | |
102 | ||
103 | ||
104 | #define NOT_ALLOCATED 0xffffffff | |
105 | #define BAD_BLOCK 0xffff | |
106 | #define CIS_BLOCK 0x400 | |
107 | #define UNUSED_BLOCK 0x3ff | |
108 | ||
109 | static int | |
110 | sddr55_bulk_transport(struct us_data *us, int direction, | |
111 | unsigned char *data, unsigned int len) { | |
112 | struct sddr55_card_info *info = (struct sddr55_card_info *)us->extra; | |
113 | unsigned int pipe = (direction == DMA_FROM_DEVICE) ? | |
114 | us->recv_bulk_pipe : us->send_bulk_pipe; | |
115 | ||
116 | if (!len) | |
117 | return USB_STOR_XFER_GOOD; | |
118 | info->last_access = jiffies; | |
119 | return usb_stor_bulk_transfer_buf(us, pipe, data, len, NULL); | |
120 | } | |
121 | ||
f0183a33 FB |
122 | /* |
123 | * check if card inserted, if there is, update read_only status | |
1da177e4 LT |
124 | * return non zero if no card |
125 | */ | |
126 | ||
127 | static int sddr55_status(struct us_data *us) | |
128 | { | |
129 | int result; | |
130 | unsigned char *command = us->iobuf; | |
131 | unsigned char *status = us->iobuf; | |
132 | struct sddr55_card_info *info = (struct sddr55_card_info *)us->extra; | |
133 | ||
134 | /* send command */ | |
135 | memset(command, 0, 8); | |
136 | command[5] = 0xB0; | |
137 | command[7] = 0x80; | |
138 | result = sddr55_bulk_transport(us, | |
139 | DMA_TO_DEVICE, command, 8); | |
140 | ||
191648d0 | 141 | usb_stor_dbg(us, "Result for send_command in status %d\n", result); |
1da177e4 LT |
142 | |
143 | if (result != USB_STOR_XFER_GOOD) { | |
144 | set_sense_info (4, 0, 0); /* hardware error */ | |
145 | return USB_STOR_TRANSPORT_ERROR; | |
146 | } | |
147 | ||
148 | result = sddr55_bulk_transport(us, | |
149 | DMA_FROM_DEVICE, status, 4); | |
150 | ||
151 | /* expect to get short transfer if no card fitted */ | |
152 | if (result == USB_STOR_XFER_SHORT || result == USB_STOR_XFER_STALLED) { | |
153 | /* had a short transfer, no card inserted, free map memory */ | |
1bc3c9e1 JJ |
154 | kfree(info->lba_to_pba); |
155 | kfree(info->pba_to_lba); | |
1da177e4 LT |
156 | info->lba_to_pba = NULL; |
157 | info->pba_to_lba = NULL; | |
158 | ||
159 | info->fatal_error = 0; | |
160 | info->force_read_only = 0; | |
161 | ||
162 | set_sense_info (2, 0x3a, 0); /* not ready, medium not present */ | |
163 | return USB_STOR_TRANSPORT_FAILED; | |
164 | } | |
165 | ||
166 | if (result != USB_STOR_XFER_GOOD) { | |
167 | set_sense_info (4, 0, 0); /* hardware error */ | |
168 | return USB_STOR_TRANSPORT_FAILED; | |
169 | } | |
170 | ||
171 | /* check write protect status */ | |
172 | info->read_only = (status[0] & 0x20); | |
173 | ||
174 | /* now read status */ | |
175 | result = sddr55_bulk_transport(us, | |
176 | DMA_FROM_DEVICE, status, 2); | |
177 | ||
178 | if (result != USB_STOR_XFER_GOOD) { | |
179 | set_sense_info (4, 0, 0); /* hardware error */ | |
180 | } | |
181 | ||
182 | return (result == USB_STOR_XFER_GOOD ? | |
183 | USB_STOR_TRANSPORT_GOOD : USB_STOR_TRANSPORT_FAILED); | |
184 | } | |
185 | ||
186 | ||
187 | static int sddr55_read_data(struct us_data *us, | |
188 | unsigned int lba, | |
189 | unsigned int page, | |
190 | unsigned short sectors) { | |
191 | ||
192 | int result = USB_STOR_TRANSPORT_GOOD; | |
193 | unsigned char *command = us->iobuf; | |
194 | unsigned char *status = us->iobuf; | |
195 | struct sddr55_card_info *info = (struct sddr55_card_info *)us->extra; | |
196 | unsigned char *buffer; | |
197 | ||
198 | unsigned int pba; | |
199 | unsigned long address; | |
200 | ||
201 | unsigned short pages; | |
1f6f31a0 JA |
202 | unsigned int len, offset; |
203 | struct scatterlist *sg; | |
1da177e4 LT |
204 | |
205 | // Since we only read in one block at a time, we have to create | |
206 | // a bounce buffer and move the data a piece at a time between the | |
207 | // bounce buffer and the actual transfer buffer. | |
208 | ||
209 | len = min((unsigned int) sectors, (unsigned int) info->blocksize >> | |
210 | info->smallpageshift) * PAGESIZE; | |
211 | buffer = kmalloc(len, GFP_NOIO); | |
212 | if (buffer == NULL) | |
213 | return USB_STOR_TRANSPORT_ERROR; /* out of memory */ | |
1f6f31a0 JA |
214 | offset = 0; |
215 | sg = NULL; | |
1da177e4 LT |
216 | |
217 | while (sectors>0) { | |
218 | ||
219 | /* have we got to end? */ | |
220 | if (lba >= info->max_log_blks) | |
221 | break; | |
222 | ||
223 | pba = info->lba_to_pba[lba]; | |
224 | ||
225 | // Read as many sectors as possible in this block | |
226 | ||
227 | pages = min((unsigned int) sectors << info->smallpageshift, | |
228 | info->blocksize - page); | |
229 | len = pages << info->pageshift; | |
230 | ||
191648d0 JP |
231 | usb_stor_dbg(us, "Read %02X pages, from PBA %04X (LBA %04X) page %02X\n", |
232 | pages, pba, lba, page); | |
1da177e4 LT |
233 | |
234 | if (pba == NOT_ALLOCATED) { | |
235 | /* no pba for this lba, fill with zeroes */ | |
236 | memset (buffer, 0, len); | |
237 | } else { | |
238 | ||
239 | address = (pba << info->blockshift) + page; | |
240 | ||
241 | command[0] = 0; | |
242 | command[1] = LSB_of(address>>16); | |
243 | command[2] = LSB_of(address>>8); | |
244 | command[3] = LSB_of(address); | |
245 | ||
246 | command[4] = 0; | |
247 | command[5] = 0xB0; | |
248 | command[6] = LSB_of(pages << (1 - info->smallpageshift)); | |
249 | command[7] = 0x85; | |
250 | ||
251 | /* send command */ | |
252 | result = sddr55_bulk_transport(us, | |
253 | DMA_TO_DEVICE, command, 8); | |
254 | ||
191648d0 JP |
255 | usb_stor_dbg(us, "Result for send_command in read_data %d\n", |
256 | result); | |
1da177e4 LT |
257 | |
258 | if (result != USB_STOR_XFER_GOOD) { | |
259 | result = USB_STOR_TRANSPORT_ERROR; | |
260 | goto leave; | |
261 | } | |
262 | ||
263 | /* read data */ | |
264 | result = sddr55_bulk_transport(us, | |
265 | DMA_FROM_DEVICE, buffer, len); | |
266 | ||
267 | if (result != USB_STOR_XFER_GOOD) { | |
268 | result = USB_STOR_TRANSPORT_ERROR; | |
269 | goto leave; | |
270 | } | |
271 | ||
272 | /* now read status */ | |
273 | result = sddr55_bulk_transport(us, | |
274 | DMA_FROM_DEVICE, status, 2); | |
275 | ||
276 | if (result != USB_STOR_XFER_GOOD) { | |
277 | result = USB_STOR_TRANSPORT_ERROR; | |
278 | goto leave; | |
279 | } | |
280 | ||
281 | /* check status for error */ | |
282 | if (status[0] == 0xff && status[1] == 0x4) { | |
283 | set_sense_info (3, 0x11, 0); | |
284 | result = USB_STOR_TRANSPORT_FAILED; | |
285 | goto leave; | |
286 | } | |
287 | } | |
288 | ||
289 | // Store the data in the transfer buffer | |
290 | usb_stor_access_xfer_buf(buffer, len, us->srb, | |
1f6f31a0 | 291 | &sg, &offset, TO_XFER_BUF); |
1da177e4 LT |
292 | |
293 | page = 0; | |
294 | lba++; | |
295 | sectors -= pages >> info->smallpageshift; | |
296 | } | |
297 | ||
298 | result = USB_STOR_TRANSPORT_GOOD; | |
299 | ||
300 | leave: | |
301 | kfree(buffer); | |
302 | ||
303 | return result; | |
304 | } | |
305 | ||
306 | static int sddr55_write_data(struct us_data *us, | |
307 | unsigned int lba, | |
308 | unsigned int page, | |
309 | unsigned short sectors) { | |
310 | ||
311 | int result = USB_STOR_TRANSPORT_GOOD; | |
312 | unsigned char *command = us->iobuf; | |
313 | unsigned char *status = us->iobuf; | |
314 | struct sddr55_card_info *info = (struct sddr55_card_info *)us->extra; | |
315 | unsigned char *buffer; | |
316 | ||
317 | unsigned int pba; | |
318 | unsigned int new_pba; | |
319 | unsigned long address; | |
320 | ||
321 | unsigned short pages; | |
322 | int i; | |
1f6f31a0 JA |
323 | unsigned int len, offset; |
324 | struct scatterlist *sg; | |
1da177e4 LT |
325 | |
326 | /* check if we are allowed to write */ | |
327 | if (info->read_only || info->force_read_only) { | |
328 | set_sense_info (7, 0x27, 0); /* read only */ | |
329 | return USB_STOR_TRANSPORT_FAILED; | |
330 | } | |
331 | ||
332 | // Since we only write one block at a time, we have to create | |
333 | // a bounce buffer and move the data a piece at a time between the | |
334 | // bounce buffer and the actual transfer buffer. | |
335 | ||
336 | len = min((unsigned int) sectors, (unsigned int) info->blocksize >> | |
337 | info->smallpageshift) * PAGESIZE; | |
338 | buffer = kmalloc(len, GFP_NOIO); | |
339 | if (buffer == NULL) | |
340 | return USB_STOR_TRANSPORT_ERROR; | |
1f6f31a0 JA |
341 | offset = 0; |
342 | sg = NULL; | |
1da177e4 LT |
343 | |
344 | while (sectors > 0) { | |
345 | ||
346 | /* have we got to end? */ | |
347 | if (lba >= info->max_log_blks) | |
348 | break; | |
349 | ||
350 | pba = info->lba_to_pba[lba]; | |
351 | ||
352 | // Write as many sectors as possible in this block | |
353 | ||
354 | pages = min((unsigned int) sectors << info->smallpageshift, | |
355 | info->blocksize - page); | |
356 | len = pages << info->pageshift; | |
357 | ||
358 | // Get the data from the transfer buffer | |
359 | usb_stor_access_xfer_buf(buffer, len, us->srb, | |
1f6f31a0 | 360 | &sg, &offset, FROM_XFER_BUF); |
1da177e4 | 361 | |
191648d0 JP |
362 | usb_stor_dbg(us, "Write %02X pages, to PBA %04X (LBA %04X) page %02X\n", |
363 | pages, pba, lba, page); | |
1da177e4 LT |
364 | |
365 | command[4] = 0; | |
366 | ||
367 | if (pba == NOT_ALLOCATED) { | |
368 | /* no pba allocated for this lba, find a free pba to use */ | |
369 | ||
370 | int max_pba = (info->max_log_blks / 250 ) * 256; | |
371 | int found_count = 0; | |
372 | int found_pba = -1; | |
373 | ||
374 | /* set pba to first block in zone lba is in */ | |
375 | pba = (lba / 1000) * 1024; | |
376 | ||
191648d0 | 377 | usb_stor_dbg(us, "No PBA for LBA %04X\n", lba); |
1da177e4 LT |
378 | |
379 | if (max_pba > 1024) | |
380 | max_pba = 1024; | |
381 | ||
382 | /* | |
383 | * Scan through the map looking for an unused block | |
384 | * leave 16 unused blocks at start (or as many as | |
385 | * possible) since the sddr55 seems to reuse a used | |
386 | * block when it shouldn't if we don't leave space. | |
387 | */ | |
388 | for (i = 0; i < max_pba; i++, pba++) { | |
389 | if (info->pba_to_lba[pba] == UNUSED_BLOCK) { | |
390 | found_pba = pba; | |
391 | if (found_count++ > 16) | |
392 | break; | |
393 | } | |
394 | } | |
395 | ||
396 | pba = found_pba; | |
397 | ||
398 | if (pba == -1) { | |
399 | /* oh dear */ | |
191648d0 | 400 | usb_stor_dbg(us, "Couldn't find unallocated block\n"); |
1da177e4 LT |
401 | |
402 | set_sense_info (3, 0x31, 0); /* medium error */ | |
403 | result = USB_STOR_TRANSPORT_FAILED; | |
404 | goto leave; | |
405 | } | |
406 | ||
191648d0 JP |
407 | usb_stor_dbg(us, "Allocating PBA %04X for LBA %04X\n", |
408 | pba, lba); | |
1da177e4 LT |
409 | |
410 | /* set writing to unallocated block flag */ | |
411 | command[4] = 0x40; | |
412 | } | |
413 | ||
414 | address = (pba << info->blockshift) + page; | |
415 | ||
416 | command[1] = LSB_of(address>>16); | |
417 | command[2] = LSB_of(address>>8); | |
418 | command[3] = LSB_of(address); | |
419 | ||
420 | /* set the lba into the command, modulo 1000 */ | |
421 | command[0] = LSB_of(lba % 1000); | |
422 | command[6] = MSB_of(lba % 1000); | |
423 | ||
424 | command[4] |= LSB_of(pages >> info->smallpageshift); | |
425 | command[5] = 0xB0; | |
426 | command[7] = 0x86; | |
427 | ||
428 | /* send command */ | |
429 | result = sddr55_bulk_transport(us, | |
430 | DMA_TO_DEVICE, command, 8); | |
431 | ||
432 | if (result != USB_STOR_XFER_GOOD) { | |
191648d0 JP |
433 | usb_stor_dbg(us, "Result for send_command in write_data %d\n", |
434 | result); | |
1da177e4 LT |
435 | |
436 | /* set_sense_info is superfluous here? */ | |
437 | set_sense_info (3, 0x3, 0);/* peripheral write error */ | |
438 | result = USB_STOR_TRANSPORT_FAILED; | |
439 | goto leave; | |
440 | } | |
441 | ||
442 | /* send the data */ | |
443 | result = sddr55_bulk_transport(us, | |
444 | DMA_TO_DEVICE, buffer, len); | |
445 | ||
446 | if (result != USB_STOR_XFER_GOOD) { | |
191648d0 JP |
447 | usb_stor_dbg(us, "Result for send_data in write_data %d\n", |
448 | result); | |
1da177e4 LT |
449 | |
450 | /* set_sense_info is superfluous here? */ | |
451 | set_sense_info (3, 0x3, 0);/* peripheral write error */ | |
452 | result = USB_STOR_TRANSPORT_FAILED; | |
453 | goto leave; | |
454 | } | |
455 | ||
456 | /* now read status */ | |
457 | result = sddr55_bulk_transport(us, DMA_FROM_DEVICE, status, 6); | |
458 | ||
459 | if (result != USB_STOR_XFER_GOOD) { | |
191648d0 JP |
460 | usb_stor_dbg(us, "Result for get_status in write_data %d\n", |
461 | result); | |
1da177e4 LT |
462 | |
463 | /* set_sense_info is superfluous here? */ | |
464 | set_sense_info (3, 0x3, 0);/* peripheral write error */ | |
465 | result = USB_STOR_TRANSPORT_FAILED; | |
466 | goto leave; | |
467 | } | |
468 | ||
469 | new_pba = (status[3] + (status[4] << 8) + (status[5] << 16)) | |
470 | >> info->blockshift; | |
471 | ||
472 | /* check status for error */ | |
473 | if (status[0] == 0xff && status[1] == 0x4) { | |
474 | info->pba_to_lba[new_pba] = BAD_BLOCK; | |
475 | ||
476 | set_sense_info (3, 0x0c, 0); | |
477 | result = USB_STOR_TRANSPORT_FAILED; | |
478 | goto leave; | |
479 | } | |
480 | ||
191648d0 JP |
481 | usb_stor_dbg(us, "Updating maps for LBA %04X: old PBA %04X, new PBA %04X\n", |
482 | lba, pba, new_pba); | |
1da177e4 LT |
483 | |
484 | /* update the lba<->pba maps, note new_pba might be the same as pba */ | |
485 | info->lba_to_pba[lba] = new_pba; | |
486 | info->pba_to_lba[pba] = UNUSED_BLOCK; | |
487 | ||
488 | /* check that new_pba wasn't already being used */ | |
489 | if (info->pba_to_lba[new_pba] != UNUSED_BLOCK) { | |
490 | printk(KERN_ERR "sddr55 error: new PBA %04X already in use for LBA %04X\n", | |
491 | new_pba, info->pba_to_lba[new_pba]); | |
492 | info->fatal_error = 1; | |
493 | set_sense_info (3, 0x31, 0); | |
494 | result = USB_STOR_TRANSPORT_FAILED; | |
495 | goto leave; | |
496 | } | |
497 | ||
498 | /* update the pba<->lba maps for new_pba */ | |
499 | info->pba_to_lba[new_pba] = lba % 1000; | |
500 | ||
501 | page = 0; | |
502 | lba++; | |
503 | sectors -= pages >> info->smallpageshift; | |
504 | } | |
505 | result = USB_STOR_TRANSPORT_GOOD; | |
506 | ||
507 | leave: | |
508 | kfree(buffer); | |
509 | return result; | |
510 | } | |
511 | ||
512 | static int sddr55_read_deviceID(struct us_data *us, | |
513 | unsigned char *manufacturerID, | |
514 | unsigned char *deviceID) { | |
515 | ||
516 | int result; | |
517 | unsigned char *command = us->iobuf; | |
518 | unsigned char *content = us->iobuf; | |
519 | ||
520 | memset(command, 0, 8); | |
521 | command[5] = 0xB0; | |
522 | command[7] = 0x84; | |
523 | result = sddr55_bulk_transport(us, DMA_TO_DEVICE, command, 8); | |
524 | ||
191648d0 JP |
525 | usb_stor_dbg(us, "Result of send_control for device ID is %d\n", |
526 | result); | |
1da177e4 LT |
527 | |
528 | if (result != USB_STOR_XFER_GOOD) | |
529 | return USB_STOR_TRANSPORT_ERROR; | |
530 | ||
531 | result = sddr55_bulk_transport(us, | |
532 | DMA_FROM_DEVICE, content, 4); | |
533 | ||
534 | if (result != USB_STOR_XFER_GOOD) | |
535 | return USB_STOR_TRANSPORT_ERROR; | |
536 | ||
537 | *manufacturerID = content[0]; | |
538 | *deviceID = content[1]; | |
539 | ||
540 | if (content[0] != 0xff) { | |
541 | result = sddr55_bulk_transport(us, | |
542 | DMA_FROM_DEVICE, content, 2); | |
543 | } | |
544 | ||
545 | return USB_STOR_TRANSPORT_GOOD; | |
546 | } | |
547 | ||
548 | ||
70fcc005 AS |
549 | static int sddr55_reset(struct us_data *us) |
550 | { | |
1da177e4 LT |
551 | return 0; |
552 | } | |
553 | ||
554 | ||
555 | static unsigned long sddr55_get_capacity(struct us_data *us) { | |
556 | ||
3f649ab7 KC |
557 | unsigned char manufacturerID; |
558 | unsigned char deviceID; | |
1da177e4 LT |
559 | int result; |
560 | struct sddr55_card_info *info = (struct sddr55_card_info *)us->extra; | |
561 | ||
191648d0 | 562 | usb_stor_dbg(us, "Reading capacity...\n"); |
1da177e4 LT |
563 | |
564 | result = sddr55_read_deviceID(us, | |
565 | &manufacturerID, | |
566 | &deviceID); | |
567 | ||
191648d0 | 568 | usb_stor_dbg(us, "Result of read_deviceID is %d\n", result); |
1da177e4 LT |
569 | |
570 | if (result != USB_STOR_XFER_GOOD) | |
571 | return 0; | |
572 | ||
191648d0 JP |
573 | usb_stor_dbg(us, "Device ID = %02X\n", deviceID); |
574 | usb_stor_dbg(us, "Manuf ID = %02X\n", manufacturerID); | |
1da177e4 LT |
575 | |
576 | info->pageshift = 9; | |
577 | info->smallpageshift = 0; | |
578 | info->blocksize = 16; | |
579 | info->blockshift = 4; | |
580 | info->blockmask = 15; | |
581 | ||
582 | switch (deviceID) { | |
583 | ||
584 | case 0x6e: // 1MB | |
585 | case 0xe8: | |
586 | case 0xec: | |
587 | info->pageshift = 8; | |
588 | info->smallpageshift = 1; | |
589 | return 0x00100000; | |
590 | ||
591 | case 0xea: // 2MB | |
592 | case 0x64: | |
593 | info->pageshift = 8; | |
594 | info->smallpageshift = 1; | |
df561f66 | 595 | fallthrough; |
1da177e4 LT |
596 | case 0x5d: // 5d is a ROM card with pagesize 512. |
597 | return 0x00200000; | |
598 | ||
599 | case 0xe3: // 4MB | |
600 | case 0xe5: | |
601 | case 0x6b: | |
602 | case 0xd5: | |
603 | return 0x00400000; | |
604 | ||
605 | case 0xe6: // 8MB | |
606 | case 0xd6: | |
607 | return 0x00800000; | |
608 | ||
609 | case 0x73: // 16MB | |
610 | info->blocksize = 32; | |
611 | info->blockshift = 5; | |
612 | info->blockmask = 31; | |
613 | return 0x01000000; | |
614 | ||
615 | case 0x75: // 32MB | |
616 | info->blocksize = 32; | |
617 | info->blockshift = 5; | |
618 | info->blockmask = 31; | |
619 | return 0x02000000; | |
620 | ||
621 | case 0x76: // 64MB | |
622 | info->blocksize = 32; | |
623 | info->blockshift = 5; | |
624 | info->blockmask = 31; | |
625 | return 0x04000000; | |
626 | ||
627 | case 0x79: // 128MB | |
628 | info->blocksize = 32; | |
629 | info->blockshift = 5; | |
630 | info->blockmask = 31; | |
631 | return 0x08000000; | |
632 | ||
633 | default: // unknown | |
634 | return 0; | |
635 | ||
636 | } | |
637 | } | |
638 | ||
639 | static int sddr55_read_map(struct us_data *us) { | |
640 | ||
641 | struct sddr55_card_info *info = (struct sddr55_card_info *)(us->extra); | |
642 | int numblocks; | |
643 | unsigned char *buffer; | |
644 | unsigned char *command = us->iobuf; | |
645 | int i; | |
646 | unsigned short lba; | |
647 | unsigned short max_lba; | |
648 | int result; | |
649 | ||
650 | if (!info->capacity) | |
651 | return -1; | |
652 | ||
653 | numblocks = info->capacity >> (info->blockshift + info->pageshift); | |
654 | ||
6da2ec56 | 655 | buffer = kmalloc_array(numblocks, 2, GFP_NOIO ); |
1da177e4 LT |
656 | |
657 | if (!buffer) | |
658 | return -1; | |
659 | ||
660 | memset(command, 0, 8); | |
661 | command[5] = 0xB0; | |
662 | command[6] = numblocks * 2 / 256; | |
663 | command[7] = 0x8A; | |
664 | ||
665 | result = sddr55_bulk_transport(us, DMA_TO_DEVICE, command, 8); | |
666 | ||
667 | if ( result != USB_STOR_XFER_GOOD) { | |
668 | kfree (buffer); | |
669 | return -1; | |
670 | } | |
671 | ||
672 | result = sddr55_bulk_transport(us, DMA_FROM_DEVICE, buffer, numblocks * 2); | |
673 | ||
674 | if ( result != USB_STOR_XFER_GOOD) { | |
675 | kfree (buffer); | |
676 | return -1; | |
677 | } | |
678 | ||
679 | result = sddr55_bulk_transport(us, DMA_FROM_DEVICE, command, 2); | |
680 | ||
681 | if ( result != USB_STOR_XFER_GOOD) { | |
682 | kfree (buffer); | |
683 | return -1; | |
684 | } | |
685 | ||
1bc3c9e1 JJ |
686 | kfree(info->lba_to_pba); |
687 | kfree(info->pba_to_lba); | |
6da2ec56 KC |
688 | info->lba_to_pba = kmalloc_array(numblocks, sizeof(int), GFP_NOIO); |
689 | info->pba_to_lba = kmalloc_array(numblocks, sizeof(int), GFP_NOIO); | |
1da177e4 LT |
690 | |
691 | if (info->lba_to_pba == NULL || info->pba_to_lba == NULL) { | |
1bc3c9e1 JJ |
692 | kfree(info->lba_to_pba); |
693 | kfree(info->pba_to_lba); | |
1da177e4 LT |
694 | info->lba_to_pba = NULL; |
695 | info->pba_to_lba = NULL; | |
696 | kfree(buffer); | |
697 | return -1; | |
698 | } | |
699 | ||
700 | memset(info->lba_to_pba, 0xff, numblocks*sizeof(int)); | |
701 | memset(info->pba_to_lba, 0xff, numblocks*sizeof(int)); | |
702 | ||
703 | /* set maximum lba */ | |
704 | max_lba = info->max_log_blks; | |
705 | if (max_lba > 1000) | |
706 | max_lba = 1000; | |
707 | ||
f0183a33 FB |
708 | /* |
709 | * Each block is 64 bytes of control data, so block i is located in | |
710 | * scatterlist block i*64/128k = i*(2^6)*(2^-17) = i*(2^-11) | |
711 | */ | |
1da177e4 LT |
712 | |
713 | for (i=0; i<numblocks; i++) { | |
714 | int zone = i / 1024; | |
715 | ||
716 | lba = short_pack(buffer[i * 2], buffer[i * 2 + 1]); | |
717 | ||
f0183a33 FB |
718 | /* |
719 | * Every 1024 physical blocks ("zone"), the LBA numbers | |
1da177e4 LT |
720 | * go back to zero, but are within a higher |
721 | * block of LBA's. Also, there is a maximum of | |
722 | * 1000 LBA's per zone. In other words, in PBA | |
723 | * 1024-2047 you will find LBA 0-999 which are | |
724 | * really LBA 1000-1999. Yes, this wastes 24 | |
725 | * physical blocks per zone. Go figure. | |
726 | * These devices can have blocks go bad, so there | |
727 | * are 24 spare blocks to use when blocks do go bad. | |
728 | */ | |
729 | ||
f0183a33 FB |
730 | /* |
731 | * SDDR55 returns 0xffff for a bad block, and 0x400 for the | |
1da177e4 LT |
732 | * CIS block. (Is this true for cards 8MB or less??) |
733 | * Record these in the physical to logical map | |
734 | */ | |
735 | ||
736 | info->pba_to_lba[i] = lba; | |
737 | ||
738 | if (lba >= max_lba) { | |
739 | continue; | |
740 | } | |
741 | ||
742 | if (info->lba_to_pba[lba + zone * 1000] != NOT_ALLOCATED && | |
743 | !info->force_read_only) { | |
6f8aa65b FS |
744 | printk(KERN_WARNING |
745 | "sddr55: map inconsistency at LBA %04X\n", | |
746 | lba + zone * 1000); | |
1da177e4 LT |
747 | info->force_read_only = 1; |
748 | } | |
749 | ||
750 | if (lba<0x10 || (lba>=0x3E0 && lba<0x3EF)) | |
191648d0 | 751 | usb_stor_dbg(us, "LBA %04X <-> PBA %04X\n", lba, i); |
1da177e4 LT |
752 | |
753 | info->lba_to_pba[lba + zone * 1000] = i; | |
754 | } | |
755 | ||
756 | kfree(buffer); | |
757 | return 0; | |
758 | } | |
759 | ||
760 | ||
761 | static void sddr55_card_info_destructor(void *extra) { | |
762 | struct sddr55_card_info *info = (struct sddr55_card_info *)extra; | |
763 | ||
764 | if (!extra) | |
765 | return; | |
766 | ||
1bc3c9e1 JJ |
767 | kfree(info->lba_to_pba); |
768 | kfree(info->pba_to_lba); | |
1da177e4 LT |
769 | } |
770 | ||
771 | ||
772 | /* | |
773 | * Transport for the Sandisk SDDR-55 | |
774 | */ | |
70fcc005 | 775 | static int sddr55_transport(struct scsi_cmnd *srb, struct us_data *us) |
1da177e4 LT |
776 | { |
777 | int result; | |
778 | static unsigned char inquiry_response[8] = { | |
779 | 0x00, 0x80, 0x00, 0x02, 0x1F, 0x00, 0x00, 0x00 | |
780 | }; | |
781 | // write-protected for now, no block descriptor support | |
782 | static unsigned char mode_page_01[20] = { | |
783 | 0x0, 0x12, 0x00, 0x80, 0x0, 0x0, 0x0, 0x0, | |
784 | 0x01, 0x0A, | |
785 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 | |
786 | }; | |
787 | unsigned char *ptr = us->iobuf; | |
788 | unsigned long capacity; | |
789 | unsigned int lba; | |
790 | unsigned int pba; | |
791 | unsigned int page; | |
792 | unsigned short pages; | |
793 | struct sddr55_card_info *info; | |
794 | ||
795 | if (!us->extra) { | |
887c2560 | 796 | us->extra = kzalloc( |
1da177e4 LT |
797 | sizeof(struct sddr55_card_info), GFP_NOIO); |
798 | if (!us->extra) | |
799 | return USB_STOR_TRANSPORT_ERROR; | |
1da177e4 LT |
800 | us->extra_destructor = sddr55_card_info_destructor; |
801 | } | |
802 | ||
803 | info = (struct sddr55_card_info *)(us->extra); | |
804 | ||
805 | if (srb->cmnd[0] == REQUEST_SENSE) { | |
191648d0 JP |
806 | usb_stor_dbg(us, "request sense %02x/%02x/%02x\n", |
807 | info->sense_data[2], | |
808 | info->sense_data[12], | |
809 | info->sense_data[13]); | |
1da177e4 LT |
810 | |
811 | memcpy (ptr, info->sense_data, sizeof info->sense_data); | |
812 | ptr[0] = 0x70; | |
813 | ptr[7] = 11; | |
814 | usb_stor_set_xfer_buf (ptr, sizeof info->sense_data, srb); | |
815 | memset (info->sense_data, 0, sizeof info->sense_data); | |
816 | ||
817 | return USB_STOR_TRANSPORT_GOOD; | |
818 | } | |
819 | ||
820 | memset (info->sense_data, 0, sizeof info->sense_data); | |
821 | ||
f0183a33 FB |
822 | /* |
823 | * Dummy up a response for INQUIRY since SDDR55 doesn't | |
824 | * respond to INQUIRY commands | |
825 | */ | |
1da177e4 LT |
826 | |
827 | if (srb->cmnd[0] == INQUIRY) { | |
828 | memcpy(ptr, inquiry_response, 8); | |
829 | fill_inquiry_response(us, ptr, 36); | |
830 | return USB_STOR_TRANSPORT_GOOD; | |
831 | } | |
832 | ||
f0183a33 FB |
833 | /* |
834 | * only check card status if the map isn't allocated, ie no card seen yet | |
1da177e4 LT |
835 | * or if it's been over half a second since we last accessed it |
836 | */ | |
837 | if (info->lba_to_pba == NULL || time_after(jiffies, info->last_access + HZ/2)) { | |
838 | ||
839 | /* check to see if a card is fitted */ | |
840 | result = sddr55_status (us); | |
841 | if (result) { | |
842 | result = sddr55_status (us); | |
843 | if (!result) { | |
844 | set_sense_info (6, 0x28, 0); /* new media, set unit attention, not ready to ready */ | |
845 | } | |
846 | return USB_STOR_TRANSPORT_FAILED; | |
847 | } | |
848 | } | |
849 | ||
f0183a33 FB |
850 | /* |
851 | * if we detected a problem with the map when writing, | |
852 | * don't allow any more access | |
853 | */ | |
1da177e4 LT |
854 | if (info->fatal_error) { |
855 | ||
856 | set_sense_info (3, 0x31, 0); | |
857 | return USB_STOR_TRANSPORT_FAILED; | |
858 | } | |
859 | ||
860 | if (srb->cmnd[0] == READ_CAPACITY) { | |
861 | ||
862 | capacity = sddr55_get_capacity(us); | |
863 | ||
864 | if (!capacity) { | |
865 | set_sense_info (3, 0x30, 0); /* incompatible medium */ | |
866 | return USB_STOR_TRANSPORT_FAILED; | |
867 | } | |
868 | ||
869 | info->capacity = capacity; | |
870 | ||
f0183a33 FB |
871 | /* |
872 | * figure out the maximum logical block number, allowing for | |
873 | * the fact that only 250 out of every 256 are used | |
874 | */ | |
1da177e4 LT |
875 | info->max_log_blks = ((info->capacity >> (info->pageshift + info->blockshift)) / 256) * 250; |
876 | ||
f0183a33 FB |
877 | /* |
878 | * Last page in the card, adjust as we only use 250 out of | |
879 | * every 256 pages | |
880 | */ | |
1da177e4 LT |
881 | capacity = (capacity / 256) * 250; |
882 | ||
883 | capacity /= PAGESIZE; | |
884 | capacity--; | |
885 | ||
886 | ((__be32 *) ptr)[0] = cpu_to_be32(capacity); | |
887 | ((__be32 *) ptr)[1] = cpu_to_be32(PAGESIZE); | |
888 | usb_stor_set_xfer_buf(ptr, 8, srb); | |
889 | ||
890 | sddr55_read_map(us); | |
891 | ||
892 | return USB_STOR_TRANSPORT_GOOD; | |
893 | } | |
894 | ||
895 | if (srb->cmnd[0] == MODE_SENSE_10) { | |
896 | ||
897 | memcpy(ptr, mode_page_01, sizeof mode_page_01); | |
898 | ptr[3] = (info->read_only || info->force_read_only) ? 0x80 : 0; | |
899 | usb_stor_set_xfer_buf(ptr, sizeof(mode_page_01), srb); | |
900 | ||
901 | if ( (srb->cmnd[2] & 0x3F) == 0x01 ) { | |
191648d0 | 902 | usb_stor_dbg(us, "Dummy up request for mode page 1\n"); |
1da177e4 LT |
903 | return USB_STOR_TRANSPORT_GOOD; |
904 | ||
905 | } else if ( (srb->cmnd[2] & 0x3F) == 0x3F ) { | |
191648d0 | 906 | usb_stor_dbg(us, "Dummy up request for all mode pages\n"); |
1da177e4 LT |
907 | return USB_STOR_TRANSPORT_GOOD; |
908 | } | |
909 | ||
910 | set_sense_info (5, 0x24, 0); /* invalid field in command */ | |
911 | return USB_STOR_TRANSPORT_FAILED; | |
912 | } | |
913 | ||
914 | if (srb->cmnd[0] == ALLOW_MEDIUM_REMOVAL) { | |
915 | ||
191648d0 JP |
916 | usb_stor_dbg(us, "%s medium removal. Not that I can do anything about it...\n", |
917 | (srb->cmnd[4]&0x03) ? "Prevent" : "Allow"); | |
1da177e4 LT |
918 | |
919 | return USB_STOR_TRANSPORT_GOOD; | |
920 | ||
921 | } | |
922 | ||
923 | if (srb->cmnd[0] == READ_10 || srb->cmnd[0] == WRITE_10) { | |
924 | ||
925 | page = short_pack(srb->cmnd[3], srb->cmnd[2]); | |
926 | page <<= 16; | |
927 | page |= short_pack(srb->cmnd[5], srb->cmnd[4]); | |
928 | pages = short_pack(srb->cmnd[8], srb->cmnd[7]); | |
929 | ||
930 | page <<= info->smallpageshift; | |
931 | ||
932 | // convert page to block and page-within-block | |
933 | ||
934 | lba = page >> info->blockshift; | |
935 | page = page & info->blockmask; | |
936 | ||
937 | // locate physical block corresponding to logical block | |
938 | ||
939 | if (lba >= info->max_log_blks) { | |
940 | ||
191648d0 JP |
941 | usb_stor_dbg(us, "Error: Requested LBA %04X exceeds maximum block %04X\n", |
942 | lba, info->max_log_blks - 1); | |
1da177e4 LT |
943 | |
944 | set_sense_info (5, 0x24, 0); /* invalid field in command */ | |
945 | ||
946 | return USB_STOR_TRANSPORT_FAILED; | |
947 | } | |
948 | ||
949 | pba = info->lba_to_pba[lba]; | |
950 | ||
951 | if (srb->cmnd[0] == WRITE_10) { | |
191648d0 JP |
952 | usb_stor_dbg(us, "WRITE_10: write block %04X (LBA %04X) page %01X pages %d\n", |
953 | pba, lba, page, pages); | |
1da177e4 LT |
954 | |
955 | return sddr55_write_data(us, lba, page, pages); | |
956 | } else { | |
191648d0 JP |
957 | usb_stor_dbg(us, "READ_10: read block %04X (LBA %04X) page %01X pages %d\n", |
958 | pba, lba, page, pages); | |
1da177e4 LT |
959 | |
960 | return sddr55_read_data(us, lba, page, pages); | |
961 | } | |
962 | } | |
963 | ||
964 | ||
965 | if (srb->cmnd[0] == TEST_UNIT_READY) { | |
966 | return USB_STOR_TRANSPORT_GOOD; | |
967 | } | |
968 | ||
969 | if (srb->cmnd[0] == START_STOP) { | |
970 | return USB_STOR_TRANSPORT_GOOD; | |
971 | } | |
972 | ||
973 | set_sense_info (5, 0x20, 0); /* illegal command */ | |
974 | ||
975 | return USB_STOR_TRANSPORT_FAILED; // FIXME: sense buffer? | |
976 | } | |
977 | ||
aa519be3 | 978 | static struct scsi_host_template sddr55_host_template; |
70fcc005 AS |
979 | |
980 | static int sddr55_probe(struct usb_interface *intf, | |
981 | const struct usb_device_id *id) | |
982 | { | |
983 | struct us_data *us; | |
984 | int result; | |
985 | ||
986 | result = usb_stor_probe1(&us, intf, id, | |
aa519be3 AM |
987 | (id - sddr55_usb_ids) + sddr55_unusual_dev_list, |
988 | &sddr55_host_template); | |
70fcc005 AS |
989 | if (result) |
990 | return result; | |
991 | ||
992 | us->transport_name = "SDDR55"; | |
993 | us->transport = sddr55_transport; | |
994 | us->transport_reset = sddr55_reset; | |
995 | us->max_lun = 0; | |
996 | ||
997 | result = usb_stor_probe2(us); | |
998 | return result; | |
999 | } | |
1000 | ||
1001 | static struct usb_driver sddr55_driver = { | |
aa519be3 | 1002 | .name = DRV_NAME, |
70fcc005 AS |
1003 | .probe = sddr55_probe, |
1004 | .disconnect = usb_stor_disconnect, | |
1005 | .suspend = usb_stor_suspend, | |
1006 | .resume = usb_stor_resume, | |
1007 | .reset_resume = usb_stor_reset_resume, | |
1008 | .pre_reset = usb_stor_pre_reset, | |
1009 | .post_reset = usb_stor_post_reset, | |
1010 | .id_table = sddr55_usb_ids, | |
1011 | .soft_unbind = 1, | |
e73b2db6 | 1012 | .no_dynamic_id = 1, |
70fcc005 AS |
1013 | }; |
1014 | ||
aa519be3 | 1015 | module_usb_stor_driver(sddr55_driver, sddr55_host_template, DRV_NAME); |