Commit | Line | Data |
---|---|---|
e80b0fad MD |
1 | /* |
2 | * Driver for Alauda-based card readers | |
3 | * | |
4 | * Current development and maintenance by: | |
5 | * (c) 2005 Daniel Drake <dsd@gentoo.org> | |
6 | * | |
7 | * The 'Alauda' is a chip manufacturered by RATOC for OEM use. | |
8 | * | |
9 | * Alauda implements a vendor-specific command set to access two media reader | |
10 | * ports (XD, SmartMedia). This driver converts SCSI commands to the commands | |
11 | * which are accepted by these devices. | |
12 | * | |
13 | * The driver was developed through reverse-engineering, with the help of the | |
14 | * sddr09 driver which has many similarities, and with some help from the | |
15 | * (very old) vendor-supplied GPL sma03 driver. | |
16 | * | |
17 | * For protocol info, see http://alauda.sourceforge.net | |
18 | * | |
19 | * This program is free software; you can redistribute it and/or modify it | |
20 | * under the terms of the GNU General Public License as published by the | |
21 | * Free Software Foundation; either version 2, or (at your option) any | |
22 | * later version. | |
23 | * | |
24 | * This program is distributed in the hope that it will be useful, but | |
25 | * WITHOUT ANY WARRANTY; without even the implied warranty of | |
26 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
27 | * General Public License for more details. | |
28 | * | |
29 | * You should have received a copy of the GNU General Public License along | |
30 | * with this program; if not, write to the Free Software Foundation, Inc., | |
31 | * 675 Mass Ave, Cambridge, MA 02139, USA. | |
32 | */ | |
33 | ||
a74bba3b AS |
34 | #include <linux/module.h> |
35 | ||
e80b0fad MD |
36 | #include <scsi/scsi.h> |
37 | #include <scsi/scsi_cmnd.h> | |
38 | #include <scsi/scsi_device.h> | |
39 | ||
40 | #include "usb.h" | |
41 | #include "transport.h" | |
42 | #include "protocol.h" | |
43 | #include "debug.h" | |
a74bba3b | 44 | |
4246b06a MG |
45 | MODULE_DESCRIPTION("Driver for Alauda-based card readers"); |
46 | MODULE_AUTHOR("Daniel Drake <dsd@gentoo.org>"); | |
47 | MODULE_LICENSE("GPL"); | |
48 | ||
a74bba3b AS |
49 | /* |
50 | * Status bytes | |
51 | */ | |
52 | #define ALAUDA_STATUS_ERROR 0x01 | |
53 | #define ALAUDA_STATUS_READY 0x40 | |
54 | ||
55 | /* | |
56 | * Control opcodes (for request field) | |
57 | */ | |
58 | #define ALAUDA_GET_XD_MEDIA_STATUS 0x08 | |
59 | #define ALAUDA_GET_SM_MEDIA_STATUS 0x98 | |
60 | #define ALAUDA_ACK_XD_MEDIA_CHANGE 0x0a | |
61 | #define ALAUDA_ACK_SM_MEDIA_CHANGE 0x9a | |
62 | #define ALAUDA_GET_XD_MEDIA_SIG 0x86 | |
63 | #define ALAUDA_GET_SM_MEDIA_SIG 0x96 | |
64 | ||
65 | /* | |
66 | * Bulk command identity (byte 0) | |
67 | */ | |
68 | #define ALAUDA_BULK_CMD 0x40 | |
69 | ||
70 | /* | |
71 | * Bulk opcodes (byte 1) | |
72 | */ | |
73 | #define ALAUDA_BULK_GET_REDU_DATA 0x85 | |
74 | #define ALAUDA_BULK_READ_BLOCK 0x94 | |
75 | #define ALAUDA_BULK_ERASE_BLOCK 0xa3 | |
76 | #define ALAUDA_BULK_WRITE_BLOCK 0xb4 | |
77 | #define ALAUDA_BULK_GET_STATUS2 0xb7 | |
78 | #define ALAUDA_BULK_RESET_MEDIA 0xe0 | |
79 | ||
80 | /* | |
81 | * Port to operate on (byte 8) | |
82 | */ | |
83 | #define ALAUDA_PORT_XD 0x00 | |
84 | #define ALAUDA_PORT_SM 0x01 | |
85 | ||
86 | /* | |
87 | * LBA and PBA are unsigned ints. Special values. | |
88 | */ | |
89 | #define UNDEF 0xffff | |
90 | #define SPARE 0xfffe | |
91 | #define UNUSABLE 0xfffd | |
92 | ||
93 | struct alauda_media_info { | |
94 | unsigned long capacity; /* total media size in bytes */ | |
95 | unsigned int pagesize; /* page size in bytes */ | |
96 | unsigned int blocksize; /* number of pages per block */ | |
97 | unsigned int uzonesize; /* number of usable blocks per zone */ | |
98 | unsigned int zonesize; /* number of blocks per zone */ | |
99 | unsigned int blockmask; /* mask to get page from address */ | |
100 | ||
101 | unsigned char pageshift; | |
102 | unsigned char blockshift; | |
103 | unsigned char zoneshift; | |
104 | ||
105 | u16 **lba_to_pba; /* logical to physical block map */ | |
106 | u16 **pba_to_lba; /* physical to logical block map */ | |
107 | }; | |
108 | ||
109 | struct alauda_info { | |
110 | struct alauda_media_info port[2]; | |
111 | int wr_ep; /* endpoint to write data out of */ | |
112 | ||
113 | unsigned char sense_key; | |
114 | unsigned long sense_asc; /* additional sense code */ | |
115 | unsigned long sense_ascq; /* additional sense code qualifier */ | |
116 | }; | |
e80b0fad MD |
117 | |
118 | #define short_pack(lsb,msb) ( ((u16)(lsb)) | ( ((u16)(msb))<<8 ) ) | |
119 | #define LSB_of(s) ((s)&0xFF) | |
120 | #define MSB_of(s) ((s)>>8) | |
121 | ||
122 | #define MEDIA_PORT(us) us->srb->device->lun | |
123 | #define MEDIA_INFO(us) ((struct alauda_info *)us->extra)->port[MEDIA_PORT(us)] | |
124 | ||
125 | #define PBA_LO(pba) ((pba & 0xF) << 5) | |
126 | #define PBA_HI(pba) (pba >> 3) | |
127 | #define PBA_ZONE(pba) (pba >> 11) | |
128 | ||
a74bba3b AS |
129 | static int init_alauda(struct us_data *us); |
130 | ||
131 | ||
132 | /* | |
133 | * The table of devices | |
134 | */ | |
135 | #define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \ | |
136 | vendorName, productName, useProtocol, useTransport, \ | |
137 | initFunction, flags) \ | |
138 | { USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \ | |
139 | .driver_info = (flags)|(USB_US_TYPE_STOR<<24) } | |
140 | ||
141 | struct usb_device_id alauda_usb_ids[] = { | |
142 | # include "unusual_alauda.h" | |
143 | { } /* Terminating entry */ | |
144 | }; | |
145 | MODULE_DEVICE_TABLE(usb, alauda_usb_ids); | |
146 | ||
147 | #undef UNUSUAL_DEV | |
148 | ||
149 | /* | |
150 | * The flags table | |
151 | */ | |
152 | #define UNUSUAL_DEV(idVendor, idProduct, bcdDeviceMin, bcdDeviceMax, \ | |
153 | vendor_name, product_name, use_protocol, use_transport, \ | |
154 | init_function, Flags) \ | |
155 | { \ | |
156 | .vendorName = vendor_name, \ | |
157 | .productName = product_name, \ | |
158 | .useProtocol = use_protocol, \ | |
159 | .useTransport = use_transport, \ | |
160 | .initFunction = init_function, \ | |
161 | } | |
162 | ||
163 | static struct us_unusual_dev alauda_unusual_dev_list[] = { | |
164 | # include "unusual_alauda.h" | |
165 | { } /* Terminating entry */ | |
166 | }; | |
167 | ||
168 | #undef UNUSUAL_DEV | |
169 | ||
170 | ||
e80b0fad MD |
171 | /* |
172 | * Media handling | |
173 | */ | |
174 | ||
175 | struct alauda_card_info { | |
176 | unsigned char id; /* id byte */ | |
177 | unsigned char chipshift; /* 1<<cs bytes total capacity */ | |
178 | unsigned char pageshift; /* 1<<ps bytes in a page */ | |
179 | unsigned char blockshift; /* 1<<bs pages per block */ | |
180 | unsigned char zoneshift; /* 1<<zs blocks per zone */ | |
181 | }; | |
182 | ||
183 | static struct alauda_card_info alauda_card_ids[] = { | |
184 | /* NAND flash */ | |
185 | { 0x6e, 20, 8, 4, 8}, /* 1 MB */ | |
186 | { 0xe8, 20, 8, 4, 8}, /* 1 MB */ | |
187 | { 0xec, 20, 8, 4, 8}, /* 1 MB */ | |
188 | { 0x64, 21, 8, 4, 9}, /* 2 MB */ | |
189 | { 0xea, 21, 8, 4, 9}, /* 2 MB */ | |
190 | { 0x6b, 22, 9, 4, 9}, /* 4 MB */ | |
191 | { 0xe3, 22, 9, 4, 9}, /* 4 MB */ | |
192 | { 0xe5, 22, 9, 4, 9}, /* 4 MB */ | |
193 | { 0xe6, 23, 9, 4, 10}, /* 8 MB */ | |
194 | { 0x73, 24, 9, 5, 10}, /* 16 MB */ | |
195 | { 0x75, 25, 9, 5, 10}, /* 32 MB */ | |
196 | { 0x76, 26, 9, 5, 10}, /* 64 MB */ | |
197 | { 0x79, 27, 9, 5, 10}, /* 128 MB */ | |
198 | { 0x71, 28, 9, 5, 10}, /* 256 MB */ | |
199 | ||
200 | /* MASK ROM */ | |
201 | { 0x5d, 21, 9, 4, 8}, /* 2 MB */ | |
202 | { 0xd5, 22, 9, 4, 9}, /* 4 MB */ | |
203 | { 0xd6, 23, 9, 4, 10}, /* 8 MB */ | |
204 | { 0x57, 24, 9, 4, 11}, /* 16 MB */ | |
205 | { 0x58, 25, 9, 4, 12}, /* 32 MB */ | |
206 | { 0,} | |
207 | }; | |
208 | ||
209 | static struct alauda_card_info *alauda_card_find_id(unsigned char id) { | |
210 | int i; | |
211 | ||
212 | for (i = 0; alauda_card_ids[i].id != 0; i++) | |
213 | if (alauda_card_ids[i].id == id) | |
214 | return &(alauda_card_ids[i]); | |
215 | return NULL; | |
216 | } | |
217 | ||
218 | /* | |
219 | * ECC computation. | |
220 | */ | |
221 | ||
222 | static unsigned char parity[256]; | |
223 | static unsigned char ecc2[256]; | |
224 | ||
225 | static void nand_init_ecc(void) { | |
226 | int i, j, a; | |
227 | ||
228 | parity[0] = 0; | |
229 | for (i = 1; i < 256; i++) | |
230 | parity[i] = (parity[i&(i-1)] ^ 1); | |
231 | ||
232 | for (i = 0; i < 256; i++) { | |
233 | a = 0; | |
234 | for (j = 0; j < 8; j++) { | |
235 | if (i & (1<<j)) { | |
236 | if ((j & 1) == 0) | |
237 | a ^= 0x04; | |
238 | if ((j & 2) == 0) | |
239 | a ^= 0x10; | |
240 | if ((j & 4) == 0) | |
241 | a ^= 0x40; | |
242 | } | |
243 | } | |
244 | ecc2[i] = ~(a ^ (a<<1) ^ (parity[i] ? 0xa8 : 0)); | |
245 | } | |
246 | } | |
247 | ||
248 | /* compute 3-byte ecc on 256 bytes */ | |
249 | static void nand_compute_ecc(unsigned char *data, unsigned char *ecc) { | |
250 | int i, j, a; | |
251 | unsigned char par, bit, bits[8]; | |
252 | ||
253 | par = 0; | |
254 | for (j = 0; j < 8; j++) | |
255 | bits[j] = 0; | |
256 | ||
257 | /* collect 16 checksum bits */ | |
258 | for (i = 0; i < 256; i++) { | |
259 | par ^= data[i]; | |
260 | bit = parity[data[i]]; | |
261 | for (j = 0; j < 8; j++) | |
262 | if ((i & (1<<j)) == 0) | |
263 | bits[j] ^= bit; | |
264 | } | |
265 | ||
266 | /* put 4+4+4 = 12 bits in the ecc */ | |
267 | a = (bits[3] << 6) + (bits[2] << 4) + (bits[1] << 2) + bits[0]; | |
268 | ecc[0] = ~(a ^ (a<<1) ^ (parity[par] ? 0xaa : 0)); | |
269 | ||
270 | a = (bits[7] << 6) + (bits[6] << 4) + (bits[5] << 2) + bits[4]; | |
271 | ecc[1] = ~(a ^ (a<<1) ^ (parity[par] ? 0xaa : 0)); | |
272 | ||
273 | ecc[2] = ecc2[par]; | |
274 | } | |
275 | ||
276 | static int nand_compare_ecc(unsigned char *data, unsigned char *ecc) { | |
277 | return (data[0] == ecc[0] && data[1] == ecc[1] && data[2] == ecc[2]); | |
278 | } | |
279 | ||
280 | static void nand_store_ecc(unsigned char *data, unsigned char *ecc) { | |
281 | memcpy(data, ecc, 3); | |
282 | } | |
283 | ||
284 | /* | |
285 | * Alauda driver | |
286 | */ | |
287 | ||
288 | /* | |
289 | * Forget our PBA <---> LBA mappings for a particular port | |
290 | */ | |
291 | static void alauda_free_maps (struct alauda_media_info *media_info) | |
292 | { | |
293 | unsigned int shift = media_info->zoneshift | |
294 | + media_info->blockshift + media_info->pageshift; | |
295 | unsigned int num_zones = media_info->capacity >> shift; | |
296 | unsigned int i; | |
297 | ||
298 | if (media_info->lba_to_pba != NULL) | |
299 | for (i = 0; i < num_zones; i++) { | |
300 | kfree(media_info->lba_to_pba[i]); | |
301 | media_info->lba_to_pba[i] = NULL; | |
302 | } | |
303 | ||
304 | if (media_info->pba_to_lba != NULL) | |
305 | for (i = 0; i < num_zones; i++) { | |
306 | kfree(media_info->pba_to_lba[i]); | |
307 | media_info->pba_to_lba[i] = NULL; | |
308 | } | |
309 | } | |
310 | ||
311 | /* | |
312 | * Returns 2 bytes of status data | |
313 | * The first byte describes media status, and second byte describes door status | |
314 | */ | |
315 | static int alauda_get_media_status(struct us_data *us, unsigned char *data) | |
316 | { | |
317 | int rc; | |
318 | unsigned char command; | |
319 | ||
320 | if (MEDIA_PORT(us) == ALAUDA_PORT_XD) | |
321 | command = ALAUDA_GET_XD_MEDIA_STATUS; | |
322 | else | |
323 | command = ALAUDA_GET_SM_MEDIA_STATUS; | |
324 | ||
325 | rc = usb_stor_ctrl_transfer(us, us->recv_ctrl_pipe, | |
326 | command, 0xc0, 0, 1, data, 2); | |
327 | ||
328 | US_DEBUGP("alauda_get_media_status: Media status %02X %02X\n", | |
329 | data[0], data[1]); | |
330 | ||
331 | return rc; | |
332 | } | |
333 | ||
334 | /* | |
335 | * Clears the "media was changed" bit so that we know when it changes again | |
336 | * in the future. | |
337 | */ | |
338 | static int alauda_ack_media(struct us_data *us) | |
339 | { | |
340 | unsigned char command; | |
341 | ||
342 | if (MEDIA_PORT(us) == ALAUDA_PORT_XD) | |
343 | command = ALAUDA_ACK_XD_MEDIA_CHANGE; | |
344 | else | |
345 | command = ALAUDA_ACK_SM_MEDIA_CHANGE; | |
346 | ||
347 | return usb_stor_ctrl_transfer(us, us->send_ctrl_pipe, | |
348 | command, 0x40, 0, 1, NULL, 0); | |
349 | } | |
350 | ||
351 | /* | |
352 | * Retrieves a 4-byte media signature, which indicates manufacturer, capacity, | |
353 | * and some other details. | |
354 | */ | |
355 | static int alauda_get_media_signature(struct us_data *us, unsigned char *data) | |
356 | { | |
357 | unsigned char command; | |
358 | ||
359 | if (MEDIA_PORT(us) == ALAUDA_PORT_XD) | |
360 | command = ALAUDA_GET_XD_MEDIA_SIG; | |
361 | else | |
362 | command = ALAUDA_GET_SM_MEDIA_SIG; | |
363 | ||
364 | return usb_stor_ctrl_transfer(us, us->recv_ctrl_pipe, | |
365 | command, 0xc0, 0, 0, data, 4); | |
366 | } | |
367 | ||
368 | /* | |
369 | * Resets the media status (but not the whole device?) | |
370 | */ | |
371 | static int alauda_reset_media(struct us_data *us) | |
372 | { | |
373 | unsigned char *command = us->iobuf; | |
374 | ||
375 | memset(command, 0, 9); | |
376 | command[0] = ALAUDA_BULK_CMD; | |
377 | command[1] = ALAUDA_BULK_RESET_MEDIA; | |
378 | command[8] = MEDIA_PORT(us); | |
379 | ||
380 | return usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe, | |
381 | command, 9, NULL); | |
382 | } | |
383 | ||
384 | /* | |
385 | * Examines the media and deduces capacity, etc. | |
386 | */ | |
387 | static int alauda_init_media(struct us_data *us) | |
388 | { | |
389 | unsigned char *data = us->iobuf; | |
390 | int ready = 0; | |
391 | struct alauda_card_info *media_info; | |
392 | unsigned int num_zones; | |
393 | ||
394 | while (ready == 0) { | |
395 | msleep(20); | |
396 | ||
397 | if (alauda_get_media_status(us, data) != USB_STOR_XFER_GOOD) | |
398 | return USB_STOR_TRANSPORT_ERROR; | |
399 | ||
400 | if (data[0] & 0x10) | |
401 | ready = 1; | |
402 | } | |
403 | ||
404 | US_DEBUGP("alauda_init_media: We are ready for action!\n"); | |
405 | ||
406 | if (alauda_ack_media(us) != USB_STOR_XFER_GOOD) | |
407 | return USB_STOR_TRANSPORT_ERROR; | |
408 | ||
409 | msleep(10); | |
410 | ||
411 | if (alauda_get_media_status(us, data) != USB_STOR_XFER_GOOD) | |
412 | return USB_STOR_TRANSPORT_ERROR; | |
413 | ||
414 | if (data[0] != 0x14) { | |
415 | US_DEBUGP("alauda_init_media: Media not ready after ack\n"); | |
416 | return USB_STOR_TRANSPORT_ERROR; | |
417 | } | |
418 | ||
419 | if (alauda_get_media_signature(us, data) != USB_STOR_XFER_GOOD) | |
420 | return USB_STOR_TRANSPORT_ERROR; | |
421 | ||
422 | US_DEBUGP("alauda_init_media: Media signature: %02X %02X %02X %02X\n", | |
423 | data[0], data[1], data[2], data[3]); | |
424 | media_info = alauda_card_find_id(data[1]); | |
425 | if (media_info == NULL) { | |
6f8aa65b FS |
426 | printk(KERN_WARNING |
427 | "alauda_init_media: Unrecognised media signature: " | |
e80b0fad MD |
428 | "%02X %02X %02X %02X\n", |
429 | data[0], data[1], data[2], data[3]); | |
430 | return USB_STOR_TRANSPORT_ERROR; | |
431 | } | |
432 | ||
433 | MEDIA_INFO(us).capacity = 1 << media_info->chipshift; | |
434 | US_DEBUGP("Found media with capacity: %ldMB\n", | |
435 | MEDIA_INFO(us).capacity >> 20); | |
436 | ||
437 | MEDIA_INFO(us).pageshift = media_info->pageshift; | |
438 | MEDIA_INFO(us).blockshift = media_info->blockshift; | |
439 | MEDIA_INFO(us).zoneshift = media_info->zoneshift; | |
440 | ||
441 | MEDIA_INFO(us).pagesize = 1 << media_info->pageshift; | |
442 | MEDIA_INFO(us).blocksize = 1 << media_info->blockshift; | |
443 | MEDIA_INFO(us).zonesize = 1 << media_info->zoneshift; | |
444 | ||
445 | MEDIA_INFO(us).uzonesize = ((1 << media_info->zoneshift) / 128) * 125; | |
446 | MEDIA_INFO(us).blockmask = MEDIA_INFO(us).blocksize - 1; | |
447 | ||
448 | num_zones = MEDIA_INFO(us).capacity >> (MEDIA_INFO(us).zoneshift | |
449 | + MEDIA_INFO(us).blockshift + MEDIA_INFO(us).pageshift); | |
450 | MEDIA_INFO(us).pba_to_lba = kcalloc(num_zones, sizeof(u16*), GFP_NOIO); | |
451 | MEDIA_INFO(us).lba_to_pba = kcalloc(num_zones, sizeof(u16*), GFP_NOIO); | |
452 | ||
453 | if (alauda_reset_media(us) != USB_STOR_XFER_GOOD) | |
454 | return USB_STOR_TRANSPORT_ERROR; | |
455 | ||
456 | return USB_STOR_TRANSPORT_GOOD; | |
457 | } | |
458 | ||
459 | /* | |
460 | * Examines the media status and does the right thing when the media has gone, | |
461 | * appeared, or changed. | |
462 | */ | |
463 | static int alauda_check_media(struct us_data *us) | |
464 | { | |
465 | struct alauda_info *info = (struct alauda_info *) us->extra; | |
466 | unsigned char status[2]; | |
467 | int rc; | |
468 | ||
469 | rc = alauda_get_media_status(us, status); | |
470 | ||
471 | /* Check for no media or door open */ | |
472 | if ((status[0] & 0x80) || ((status[0] & 0x1F) == 0x10) | |
473 | || ((status[1] & 0x01) == 0)) { | |
474 | US_DEBUGP("alauda_check_media: No media, or door open\n"); | |
475 | alauda_free_maps(&MEDIA_INFO(us)); | |
476 | info->sense_key = 0x02; | |
477 | info->sense_asc = 0x3A; | |
478 | info->sense_ascq = 0x00; | |
479 | return USB_STOR_TRANSPORT_FAILED; | |
480 | } | |
481 | ||
482 | /* Check for media change */ | |
483 | if (status[0] & 0x08) { | |
484 | US_DEBUGP("alauda_check_media: Media change detected\n"); | |
485 | alauda_free_maps(&MEDIA_INFO(us)); | |
486 | alauda_init_media(us); | |
487 | ||
488 | info->sense_key = UNIT_ATTENTION; | |
489 | info->sense_asc = 0x28; | |
490 | info->sense_ascq = 0x00; | |
491 | return USB_STOR_TRANSPORT_FAILED; | |
492 | } | |
493 | ||
494 | return USB_STOR_TRANSPORT_GOOD; | |
495 | } | |
496 | ||
497 | /* | |
498 | * Checks the status from the 2nd status register | |
499 | * Returns 3 bytes of status data, only the first is known | |
500 | */ | |
501 | static int alauda_check_status2(struct us_data *us) | |
502 | { | |
503 | int rc; | |
504 | unsigned char command[] = { | |
505 | ALAUDA_BULK_CMD, ALAUDA_BULK_GET_STATUS2, | |
506 | 0, 0, 0, 0, 3, 0, MEDIA_PORT(us) | |
507 | }; | |
508 | unsigned char data[3]; | |
509 | ||
510 | rc = usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe, | |
511 | command, 9, NULL); | |
512 | if (rc != USB_STOR_XFER_GOOD) | |
513 | return rc; | |
514 | ||
515 | rc = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe, | |
516 | data, 3, NULL); | |
517 | if (rc != USB_STOR_XFER_GOOD) | |
518 | return rc; | |
519 | ||
520 | US_DEBUGP("alauda_check_status2: %02X %02X %02X\n", data[0], data[1], data[2]); | |
521 | if (data[0] & ALAUDA_STATUS_ERROR) | |
522 | return USB_STOR_XFER_ERROR; | |
523 | ||
524 | return USB_STOR_XFER_GOOD; | |
525 | } | |
526 | ||
527 | /* | |
528 | * Gets the redundancy data for the first page of a PBA | |
529 | * Returns 16 bytes. | |
530 | */ | |
531 | static int alauda_get_redu_data(struct us_data *us, u16 pba, unsigned char *data) | |
532 | { | |
533 | int rc; | |
534 | unsigned char command[] = { | |
535 | ALAUDA_BULK_CMD, ALAUDA_BULK_GET_REDU_DATA, | |
536 | PBA_HI(pba), PBA_ZONE(pba), 0, PBA_LO(pba), 0, 0, MEDIA_PORT(us) | |
537 | }; | |
538 | ||
539 | rc = usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe, | |
540 | command, 9, NULL); | |
541 | if (rc != USB_STOR_XFER_GOOD) | |
542 | return rc; | |
543 | ||
544 | return usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe, | |
545 | data, 16, NULL); | |
546 | } | |
547 | ||
548 | /* | |
549 | * Finds the first unused PBA in a zone | |
550 | * Returns the absolute PBA of an unused PBA, or 0 if none found. | |
551 | */ | |
552 | static u16 alauda_find_unused_pba(struct alauda_media_info *info, | |
553 | unsigned int zone) | |
554 | { | |
555 | u16 *pba_to_lba = info->pba_to_lba[zone]; | |
556 | unsigned int i; | |
557 | ||
558 | for (i = 0; i < info->zonesize; i++) | |
559 | if (pba_to_lba[i] == UNDEF) | |
560 | return (zone << info->zoneshift) + i; | |
561 | ||
562 | return 0; | |
563 | } | |
564 | ||
565 | /* | |
566 | * Reads the redundancy data for all PBA's in a zone | |
567 | * Produces lba <--> pba mappings | |
568 | */ | |
569 | static int alauda_read_map(struct us_data *us, unsigned int zone) | |
570 | { | |
571 | unsigned char *data = us->iobuf; | |
572 | int result; | |
573 | int i, j; | |
574 | unsigned int zonesize = MEDIA_INFO(us).zonesize; | |
575 | unsigned int uzonesize = MEDIA_INFO(us).uzonesize; | |
576 | unsigned int lba_offset, lba_real, blocknum; | |
577 | unsigned int zone_base_lba = zone * uzonesize; | |
578 | unsigned int zone_base_pba = zone * zonesize; | |
579 | u16 *lba_to_pba = kcalloc(zonesize, sizeof(u16), GFP_NOIO); | |
580 | u16 *pba_to_lba = kcalloc(zonesize, sizeof(u16), GFP_NOIO); | |
581 | if (lba_to_pba == NULL || pba_to_lba == NULL) { | |
582 | result = USB_STOR_TRANSPORT_ERROR; | |
583 | goto error; | |
584 | } | |
585 | ||
586 | US_DEBUGP("alauda_read_map: Mapping blocks for zone %d\n", zone); | |
587 | ||
588 | /* 1024 PBA's per zone */ | |
589 | for (i = 0; i < zonesize; i++) | |
590 | lba_to_pba[i] = pba_to_lba[i] = UNDEF; | |
591 | ||
592 | for (i = 0; i < zonesize; i++) { | |
593 | blocknum = zone_base_pba + i; | |
594 | ||
595 | result = alauda_get_redu_data(us, blocknum, data); | |
596 | if (result != USB_STOR_XFER_GOOD) { | |
597 | result = USB_STOR_TRANSPORT_ERROR; | |
598 | goto error; | |
599 | } | |
600 | ||
601 | /* special PBAs have control field 0^16 */ | |
602 | for (j = 0; j < 16; j++) | |
603 | if (data[j] != 0) | |
604 | goto nonz; | |
605 | pba_to_lba[i] = UNUSABLE; | |
606 | US_DEBUGP("alauda_read_map: PBA %d has no logical mapping\n", blocknum); | |
607 | continue; | |
608 | ||
609 | nonz: | |
610 | /* unwritten PBAs have control field FF^16 */ | |
611 | for (j = 0; j < 16; j++) | |
612 | if (data[j] != 0xff) | |
613 | goto nonff; | |
614 | continue; | |
615 | ||
616 | nonff: | |
617 | /* normal PBAs start with six FFs */ | |
618 | if (j < 6) { | |
619 | US_DEBUGP("alauda_read_map: PBA %d has no logical mapping: " | |
620 | "reserved area = %02X%02X%02X%02X " | |
621 | "data status %02X block status %02X\n", | |
622 | blocknum, data[0], data[1], data[2], data[3], | |
623 | data[4], data[5]); | |
624 | pba_to_lba[i] = UNUSABLE; | |
625 | continue; | |
626 | } | |
627 | ||
628 | if ((data[6] >> 4) != 0x01) { | |
629 | US_DEBUGP("alauda_read_map: PBA %d has invalid address " | |
630 | "field %02X%02X/%02X%02X\n", | |
631 | blocknum, data[6], data[7], data[11], data[12]); | |
632 | pba_to_lba[i] = UNUSABLE; | |
633 | continue; | |
634 | } | |
635 | ||
636 | /* check even parity */ | |
637 | if (parity[data[6] ^ data[7]]) { | |
6f8aa65b FS |
638 | printk(KERN_WARNING |
639 | "alauda_read_map: Bad parity in LBA for block %d" | |
e80b0fad MD |
640 | " (%02X %02X)\n", i, data[6], data[7]); |
641 | pba_to_lba[i] = UNUSABLE; | |
642 | continue; | |
643 | } | |
644 | ||
645 | lba_offset = short_pack(data[7], data[6]); | |
646 | lba_offset = (lba_offset & 0x07FF) >> 1; | |
647 | lba_real = lba_offset + zone_base_lba; | |
648 | ||
649 | /* | |
650 | * Every 1024 physical blocks ("zone"), the LBA numbers | |
651 | * go back to zero, but are within a higher block of LBA's. | |
652 | * Also, there is a maximum of 1000 LBA's per zone. | |
653 | * In other words, in PBA 1024-2047 you will find LBA 0-999 | |
654 | * which are really LBA 1000-1999. This allows for 24 bad | |
655 | * or special physical blocks per zone. | |
656 | */ | |
657 | ||
658 | if (lba_offset >= uzonesize) { | |
6f8aa65b FS |
659 | printk(KERN_WARNING |
660 | "alauda_read_map: Bad low LBA %d for block %d\n", | |
e80b0fad MD |
661 | lba_real, blocknum); |
662 | continue; | |
663 | } | |
664 | ||
665 | if (lba_to_pba[lba_offset] != UNDEF) { | |
6f8aa65b FS |
666 | printk(KERN_WARNING |
667 | "alauda_read_map: " | |
668 | "LBA %d seen for PBA %d and %d\n", | |
e80b0fad MD |
669 | lba_real, lba_to_pba[lba_offset], blocknum); |
670 | continue; | |
671 | } | |
672 | ||
673 | pba_to_lba[i] = lba_real; | |
674 | lba_to_pba[lba_offset] = blocknum; | |
675 | continue; | |
676 | } | |
677 | ||
678 | MEDIA_INFO(us).lba_to_pba[zone] = lba_to_pba; | |
679 | MEDIA_INFO(us).pba_to_lba[zone] = pba_to_lba; | |
680 | result = 0; | |
681 | goto out; | |
682 | ||
683 | error: | |
684 | kfree(lba_to_pba); | |
685 | kfree(pba_to_lba); | |
686 | out: | |
687 | return result; | |
688 | } | |
689 | ||
690 | /* | |
691 | * Checks to see whether we have already mapped a certain zone | |
692 | * If we haven't, the map is generated | |
693 | */ | |
694 | static void alauda_ensure_map_for_zone(struct us_data *us, unsigned int zone) | |
695 | { | |
696 | if (MEDIA_INFO(us).lba_to_pba[zone] == NULL | |
697 | || MEDIA_INFO(us).pba_to_lba[zone] == NULL) | |
698 | alauda_read_map(us, zone); | |
699 | } | |
700 | ||
701 | /* | |
702 | * Erases an entire block | |
703 | */ | |
704 | static int alauda_erase_block(struct us_data *us, u16 pba) | |
705 | { | |
706 | int rc; | |
707 | unsigned char command[] = { | |
708 | ALAUDA_BULK_CMD, ALAUDA_BULK_ERASE_BLOCK, PBA_HI(pba), | |
709 | PBA_ZONE(pba), 0, PBA_LO(pba), 0x02, 0, MEDIA_PORT(us) | |
710 | }; | |
711 | unsigned char buf[2]; | |
712 | ||
713 | US_DEBUGP("alauda_erase_block: Erasing PBA %d\n", pba); | |
714 | ||
715 | rc = usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe, | |
716 | command, 9, NULL); | |
717 | if (rc != USB_STOR_XFER_GOOD) | |
718 | return rc; | |
719 | ||
720 | rc = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe, | |
721 | buf, 2, NULL); | |
722 | if (rc != USB_STOR_XFER_GOOD) | |
723 | return rc; | |
724 | ||
725 | US_DEBUGP("alauda_erase_block: Erase result: %02X %02X\n", | |
726 | buf[0], buf[1]); | |
727 | return rc; | |
728 | } | |
729 | ||
730 | /* | |
731 | * Reads data from a certain offset page inside a PBA, including interleaved | |
732 | * redundancy data. Returns (pagesize+64)*pages bytes in data. | |
733 | */ | |
734 | static int alauda_read_block_raw(struct us_data *us, u16 pba, | |
735 | unsigned int page, unsigned int pages, unsigned char *data) | |
736 | { | |
737 | int rc; | |
738 | unsigned char command[] = { | |
739 | ALAUDA_BULK_CMD, ALAUDA_BULK_READ_BLOCK, PBA_HI(pba), | |
740 | PBA_ZONE(pba), 0, PBA_LO(pba) + page, pages, 0, MEDIA_PORT(us) | |
741 | }; | |
742 | ||
743 | US_DEBUGP("alauda_read_block: pba %d page %d count %d\n", | |
744 | pba, page, pages); | |
745 | ||
746 | rc = usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe, | |
747 | command, 9, NULL); | |
748 | if (rc != USB_STOR_XFER_GOOD) | |
749 | return rc; | |
750 | ||
751 | return usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe, | |
752 | data, (MEDIA_INFO(us).pagesize + 64) * pages, NULL); | |
753 | } | |
754 | ||
755 | /* | |
756 | * Reads data from a certain offset page inside a PBA, excluding redundancy | |
757 | * data. Returns pagesize*pages bytes in data. Note that data must be big enough | |
758 | * to hold (pagesize+64)*pages bytes of data, but you can ignore those 'extra' | |
759 | * trailing bytes outside this function. | |
760 | */ | |
761 | static int alauda_read_block(struct us_data *us, u16 pba, | |
762 | unsigned int page, unsigned int pages, unsigned char *data) | |
763 | { | |
764 | int i, rc; | |
765 | unsigned int pagesize = MEDIA_INFO(us).pagesize; | |
766 | ||
767 | rc = alauda_read_block_raw(us, pba, page, pages, data); | |
768 | if (rc != USB_STOR_XFER_GOOD) | |
769 | return rc; | |
770 | ||
771 | /* Cut out the redundancy data */ | |
772 | for (i = 0; i < pages; i++) { | |
773 | int dest_offset = i * pagesize; | |
774 | int src_offset = i * (pagesize + 64); | |
775 | memmove(data + dest_offset, data + src_offset, pagesize); | |
776 | } | |
777 | ||
778 | return rc; | |
779 | } | |
780 | ||
781 | /* | |
782 | * Writes an entire block of data and checks status after write. | |
783 | * Redundancy data must be already included in data. Data should be | |
784 | * (pagesize+64)*blocksize bytes in length. | |
785 | */ | |
786 | static int alauda_write_block(struct us_data *us, u16 pba, unsigned char *data) | |
787 | { | |
788 | int rc; | |
789 | struct alauda_info *info = (struct alauda_info *) us->extra; | |
790 | unsigned char command[] = { | |
791 | ALAUDA_BULK_CMD, ALAUDA_BULK_WRITE_BLOCK, PBA_HI(pba), | |
792 | PBA_ZONE(pba), 0, PBA_LO(pba), 32, 0, MEDIA_PORT(us) | |
793 | }; | |
794 | ||
795 | US_DEBUGP("alauda_write_block: pba %d\n", pba); | |
796 | ||
797 | rc = usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe, | |
798 | command, 9, NULL); | |
799 | if (rc != USB_STOR_XFER_GOOD) | |
800 | return rc; | |
801 | ||
802 | rc = usb_stor_bulk_transfer_buf(us, info->wr_ep, data, | |
803 | (MEDIA_INFO(us).pagesize + 64) * MEDIA_INFO(us).blocksize, | |
804 | NULL); | |
805 | if (rc != USB_STOR_XFER_GOOD) | |
806 | return rc; | |
807 | ||
808 | return alauda_check_status2(us); | |
809 | } | |
810 | ||
811 | /* | |
812 | * Write some data to a specific LBA. | |
813 | */ | |
814 | static int alauda_write_lba(struct us_data *us, u16 lba, | |
815 | unsigned int page, unsigned int pages, | |
816 | unsigned char *ptr, unsigned char *blockbuffer) | |
817 | { | |
818 | u16 pba, lbap, new_pba; | |
819 | unsigned char *bptr, *cptr, *xptr; | |
820 | unsigned char ecc[3]; | |
821 | int i, result; | |
822 | unsigned int uzonesize = MEDIA_INFO(us).uzonesize; | |
823 | unsigned int zonesize = MEDIA_INFO(us).zonesize; | |
824 | unsigned int pagesize = MEDIA_INFO(us).pagesize; | |
825 | unsigned int blocksize = MEDIA_INFO(us).blocksize; | |
826 | unsigned int lba_offset = lba % uzonesize; | |
827 | unsigned int new_pba_offset; | |
828 | unsigned int zone = lba / uzonesize; | |
829 | ||
830 | alauda_ensure_map_for_zone(us, zone); | |
831 | ||
832 | pba = MEDIA_INFO(us).lba_to_pba[zone][lba_offset]; | |
833 | if (pba == 1) { | |
834 | /* Maybe it is impossible to write to PBA 1. | |
835 | Fake success, but don't do anything. */ | |
6f8aa65b FS |
836 | printk(KERN_WARNING |
837 | "alauda_write_lba: avoid writing to pba 1\n"); | |
e80b0fad MD |
838 | return USB_STOR_TRANSPORT_GOOD; |
839 | } | |
840 | ||
841 | new_pba = alauda_find_unused_pba(&MEDIA_INFO(us), zone); | |
842 | if (!new_pba) { | |
6f8aa65b FS |
843 | printk(KERN_WARNING |
844 | "alauda_write_lba: Out of unused blocks\n"); | |
e80b0fad MD |
845 | return USB_STOR_TRANSPORT_ERROR; |
846 | } | |
847 | ||
848 | /* read old contents */ | |
849 | if (pba != UNDEF) { | |
850 | result = alauda_read_block_raw(us, pba, 0, | |
851 | blocksize, blockbuffer); | |
852 | if (result != USB_STOR_XFER_GOOD) | |
853 | return result; | |
854 | } else { | |
855 | memset(blockbuffer, 0, blocksize * (pagesize + 64)); | |
856 | } | |
857 | ||
858 | lbap = (lba_offset << 1) | 0x1000; | |
859 | if (parity[MSB_of(lbap) ^ LSB_of(lbap)]) | |
860 | lbap ^= 1; | |
861 | ||
862 | /* check old contents and fill lba */ | |
863 | for (i = 0; i < blocksize; i++) { | |
864 | bptr = blockbuffer + (i * (pagesize + 64)); | |
865 | cptr = bptr + pagesize; | |
866 | nand_compute_ecc(bptr, ecc); | |
867 | if (!nand_compare_ecc(cptr+13, ecc)) { | |
868 | US_DEBUGP("Warning: bad ecc in page %d- of pba %d\n", | |
869 | i, pba); | |
870 | nand_store_ecc(cptr+13, ecc); | |
871 | } | |
872 | nand_compute_ecc(bptr + (pagesize / 2), ecc); | |
873 | if (!nand_compare_ecc(cptr+8, ecc)) { | |
874 | US_DEBUGP("Warning: bad ecc in page %d+ of pba %d\n", | |
875 | i, pba); | |
876 | nand_store_ecc(cptr+8, ecc); | |
877 | } | |
878 | cptr[6] = cptr[11] = MSB_of(lbap); | |
879 | cptr[7] = cptr[12] = LSB_of(lbap); | |
880 | } | |
881 | ||
882 | /* copy in new stuff and compute ECC */ | |
883 | xptr = ptr; | |
884 | for (i = page; i < page+pages; i++) { | |
885 | bptr = blockbuffer + (i * (pagesize + 64)); | |
886 | cptr = bptr + pagesize; | |
887 | memcpy(bptr, xptr, pagesize); | |
888 | xptr += pagesize; | |
889 | nand_compute_ecc(bptr, ecc); | |
890 | nand_store_ecc(cptr+13, ecc); | |
891 | nand_compute_ecc(bptr + (pagesize / 2), ecc); | |
892 | nand_store_ecc(cptr+8, ecc); | |
893 | } | |
894 | ||
895 | result = alauda_write_block(us, new_pba, blockbuffer); | |
896 | if (result != USB_STOR_XFER_GOOD) | |
897 | return result; | |
898 | ||
899 | new_pba_offset = new_pba - (zone * zonesize); | |
900 | MEDIA_INFO(us).pba_to_lba[zone][new_pba_offset] = lba; | |
901 | MEDIA_INFO(us).lba_to_pba[zone][lba_offset] = new_pba; | |
902 | US_DEBUGP("alauda_write_lba: Remapped LBA %d to PBA %d\n", | |
903 | lba, new_pba); | |
904 | ||
905 | if (pba != UNDEF) { | |
906 | unsigned int pba_offset = pba - (zone * zonesize); | |
907 | result = alauda_erase_block(us, pba); | |
908 | if (result != USB_STOR_XFER_GOOD) | |
909 | return result; | |
910 | MEDIA_INFO(us).pba_to_lba[zone][pba_offset] = UNDEF; | |
911 | } | |
912 | ||
913 | return USB_STOR_TRANSPORT_GOOD; | |
914 | } | |
915 | ||
916 | /* | |
917 | * Read data from a specific sector address | |
918 | */ | |
919 | static int alauda_read_data(struct us_data *us, unsigned long address, | |
920 | unsigned int sectors) | |
921 | { | |
922 | unsigned char *buffer; | |
923 | u16 lba, max_lba; | |
1f6f31a0 | 924 | unsigned int page, len, offset; |
e80b0fad MD |
925 | unsigned int blockshift = MEDIA_INFO(us).blockshift; |
926 | unsigned int pageshift = MEDIA_INFO(us).pageshift; | |
927 | unsigned int blocksize = MEDIA_INFO(us).blocksize; | |
928 | unsigned int pagesize = MEDIA_INFO(us).pagesize; | |
929 | unsigned int uzonesize = MEDIA_INFO(us).uzonesize; | |
1f6f31a0 | 930 | struct scatterlist *sg; |
e80b0fad MD |
931 | int result; |
932 | ||
933 | /* | |
934 | * Since we only read in one block at a time, we have to create | |
935 | * a bounce buffer and move the data a piece at a time between the | |
936 | * bounce buffer and the actual transfer buffer. | |
937 | * We make this buffer big enough to hold temporary redundancy data, | |
938 | * which we use when reading the data blocks. | |
939 | */ | |
940 | ||
941 | len = min(sectors, blocksize) * (pagesize + 64); | |
942 | buffer = kmalloc(len, GFP_NOIO); | |
943 | if (buffer == NULL) { | |
6f8aa65b | 944 | printk(KERN_WARNING "alauda_read_data: Out of memory\n"); |
e80b0fad MD |
945 | return USB_STOR_TRANSPORT_ERROR; |
946 | } | |
947 | ||
948 | /* Figure out the initial LBA and page */ | |
949 | lba = address >> blockshift; | |
950 | page = (address & MEDIA_INFO(us).blockmask); | |
951 | max_lba = MEDIA_INFO(us).capacity >> (blockshift + pageshift); | |
952 | ||
953 | result = USB_STOR_TRANSPORT_GOOD; | |
1f6f31a0 JA |
954 | offset = 0; |
955 | sg = NULL; | |
e80b0fad MD |
956 | |
957 | while (sectors > 0) { | |
958 | unsigned int zone = lba / uzonesize; /* integer division */ | |
959 | unsigned int lba_offset = lba - (zone * uzonesize); | |
960 | unsigned int pages; | |
961 | u16 pba; | |
962 | alauda_ensure_map_for_zone(us, zone); | |
963 | ||
964 | /* Not overflowing capacity? */ | |
965 | if (lba >= max_lba) { | |
966 | US_DEBUGP("Error: Requested lba %u exceeds " | |
967 | "maximum %u\n", lba, max_lba); | |
968 | result = USB_STOR_TRANSPORT_ERROR; | |
969 | break; | |
970 | } | |
971 | ||
972 | /* Find number of pages we can read in this block */ | |
973 | pages = min(sectors, blocksize - page); | |
974 | len = pages << pageshift; | |
975 | ||
976 | /* Find where this lba lives on disk */ | |
977 | pba = MEDIA_INFO(us).lba_to_pba[zone][lba_offset]; | |
978 | ||
979 | if (pba == UNDEF) { /* this lba was never written */ | |
980 | US_DEBUGP("Read %d zero pages (LBA %d) page %d\n", | |
981 | pages, lba, page); | |
982 | ||
983 | /* This is not really an error. It just means | |
984 | that the block has never been written. | |
985 | Instead of returning USB_STOR_TRANSPORT_ERROR | |
986 | it is better to return all zero data. */ | |
987 | ||
988 | memset(buffer, 0, len); | |
989 | } else { | |
990 | US_DEBUGP("Read %d pages, from PBA %d" | |
991 | " (LBA %d) page %d\n", | |
992 | pages, pba, lba, page); | |
993 | ||
994 | result = alauda_read_block(us, pba, page, pages, buffer); | |
995 | if (result != USB_STOR_TRANSPORT_GOOD) | |
996 | break; | |
997 | } | |
998 | ||
999 | /* Store the data in the transfer buffer */ | |
1000 | usb_stor_access_xfer_buf(buffer, len, us->srb, | |
1f6f31a0 | 1001 | &sg, &offset, TO_XFER_BUF); |
e80b0fad MD |
1002 | |
1003 | page = 0; | |
1004 | lba++; | |
1005 | sectors -= pages; | |
1006 | } | |
1007 | ||
1008 | kfree(buffer); | |
1009 | return result; | |
1010 | } | |
1011 | ||
1012 | /* | |
1013 | * Write data to a specific sector address | |
1014 | */ | |
1015 | static int alauda_write_data(struct us_data *us, unsigned long address, | |
1016 | unsigned int sectors) | |
1017 | { | |
1018 | unsigned char *buffer, *blockbuffer; | |
1f6f31a0 | 1019 | unsigned int page, len, offset; |
e80b0fad MD |
1020 | unsigned int blockshift = MEDIA_INFO(us).blockshift; |
1021 | unsigned int pageshift = MEDIA_INFO(us).pageshift; | |
1022 | unsigned int blocksize = MEDIA_INFO(us).blocksize; | |
1023 | unsigned int pagesize = MEDIA_INFO(us).pagesize; | |
1f6f31a0 | 1024 | struct scatterlist *sg; |
e80b0fad MD |
1025 | u16 lba, max_lba; |
1026 | int result; | |
1027 | ||
1028 | /* | |
1029 | * Since we don't write the user data directly to the device, | |
1030 | * we have to create a bounce buffer and move the data a piece | |
1031 | * at a time between the bounce buffer and the actual transfer buffer. | |
1032 | */ | |
1033 | ||
1034 | len = min(sectors, blocksize) * pagesize; | |
1035 | buffer = kmalloc(len, GFP_NOIO); | |
1036 | if (buffer == NULL) { | |
6f8aa65b | 1037 | printk(KERN_WARNING "alauda_write_data: Out of memory\n"); |
e80b0fad MD |
1038 | return USB_STOR_TRANSPORT_ERROR; |
1039 | } | |
1040 | ||
1041 | /* | |
1042 | * We also need a temporary block buffer, where we read in the old data, | |
1043 | * overwrite parts with the new data, and manipulate the redundancy data | |
1044 | */ | |
1045 | blockbuffer = kmalloc((pagesize + 64) * blocksize, GFP_NOIO); | |
1046 | if (blockbuffer == NULL) { | |
6f8aa65b | 1047 | printk(KERN_WARNING "alauda_write_data: Out of memory\n"); |
e80b0fad MD |
1048 | kfree(buffer); |
1049 | return USB_STOR_TRANSPORT_ERROR; | |
1050 | } | |
1051 | ||
1052 | /* Figure out the initial LBA and page */ | |
1053 | lba = address >> blockshift; | |
1054 | page = (address & MEDIA_INFO(us).blockmask); | |
1055 | max_lba = MEDIA_INFO(us).capacity >> (pageshift + blockshift); | |
1056 | ||
1057 | result = USB_STOR_TRANSPORT_GOOD; | |
1f6f31a0 JA |
1058 | offset = 0; |
1059 | sg = NULL; | |
e80b0fad MD |
1060 | |
1061 | while (sectors > 0) { | |
1062 | /* Write as many sectors as possible in this block */ | |
1063 | unsigned int pages = min(sectors, blocksize - page); | |
1064 | len = pages << pageshift; | |
1065 | ||
1066 | /* Not overflowing capacity? */ | |
1067 | if (lba >= max_lba) { | |
1068 | US_DEBUGP("alauda_write_data: Requested lba %u exceeds " | |
1069 | "maximum %u\n", lba, max_lba); | |
1070 | result = USB_STOR_TRANSPORT_ERROR; | |
1071 | break; | |
1072 | } | |
1073 | ||
1074 | /* Get the data from the transfer buffer */ | |
1075 | usb_stor_access_xfer_buf(buffer, len, us->srb, | |
1f6f31a0 | 1076 | &sg, &offset, FROM_XFER_BUF); |
e80b0fad MD |
1077 | |
1078 | result = alauda_write_lba(us, lba, page, pages, buffer, | |
1079 | blockbuffer); | |
1080 | if (result != USB_STOR_TRANSPORT_GOOD) | |
1081 | break; | |
1082 | ||
1083 | page = 0; | |
1084 | lba++; | |
1085 | sectors -= pages; | |
1086 | } | |
1087 | ||
1088 | kfree(buffer); | |
1089 | kfree(blockbuffer); | |
1090 | return result; | |
1091 | } | |
1092 | ||
1093 | /* | |
1094 | * Our interface with the rest of the world | |
1095 | */ | |
1096 | ||
1097 | static void alauda_info_destructor(void *extra) | |
1098 | { | |
1099 | struct alauda_info *info = (struct alauda_info *) extra; | |
1100 | int port; | |
1101 | ||
1102 | if (!info) | |
1103 | return; | |
1104 | ||
1105 | for (port = 0; port < 2; port++) { | |
1106 | struct alauda_media_info *media_info = &info->port[port]; | |
1107 | ||
1108 | alauda_free_maps(media_info); | |
1109 | kfree(media_info->lba_to_pba); | |
1110 | kfree(media_info->pba_to_lba); | |
1111 | } | |
1112 | } | |
1113 | ||
1114 | /* | |
1115 | * Initialize alauda_info struct and find the data-write endpoint | |
1116 | */ | |
a74bba3b | 1117 | static int init_alauda(struct us_data *us) |
e80b0fad MD |
1118 | { |
1119 | struct alauda_info *info; | |
1120 | struct usb_host_interface *altsetting = us->pusb_intf->cur_altsetting; | |
1121 | nand_init_ecc(); | |
1122 | ||
1123 | us->extra = kzalloc(sizeof(struct alauda_info), GFP_NOIO); | |
1124 | if (!us->extra) { | |
1125 | US_DEBUGP("init_alauda: Gah! Can't allocate storage for" | |
1126 | "alauda info struct!\n"); | |
1127 | return USB_STOR_TRANSPORT_ERROR; | |
1128 | } | |
1129 | info = (struct alauda_info *) us->extra; | |
1130 | us->extra_destructor = alauda_info_destructor; | |
1131 | ||
1132 | info->wr_ep = usb_sndbulkpipe(us->pusb_dev, | |
1133 | altsetting->endpoint[0].desc.bEndpointAddress | |
1134 | & USB_ENDPOINT_NUMBER_MASK); | |
1135 | ||
1136 | return USB_STOR_TRANSPORT_GOOD; | |
1137 | } | |
1138 | ||
a74bba3b | 1139 | static int alauda_transport(struct scsi_cmnd *srb, struct us_data *us) |
e80b0fad MD |
1140 | { |
1141 | int rc; | |
1142 | struct alauda_info *info = (struct alauda_info *) us->extra; | |
1143 | unsigned char *ptr = us->iobuf; | |
1144 | static unsigned char inquiry_response[36] = { | |
1145 | 0x00, 0x80, 0x00, 0x01, 0x1F, 0x00, 0x00, 0x00 | |
1146 | }; | |
1147 | ||
1148 | if (srb->cmnd[0] == INQUIRY) { | |
1149 | US_DEBUGP("alauda_transport: INQUIRY. " | |
1150 | "Returning bogus response.\n"); | |
1151 | memcpy(ptr, inquiry_response, sizeof(inquiry_response)); | |
1152 | fill_inquiry_response(us, ptr, 36); | |
1153 | return USB_STOR_TRANSPORT_GOOD; | |
1154 | } | |
1155 | ||
1156 | if (srb->cmnd[0] == TEST_UNIT_READY) { | |
1157 | US_DEBUGP("alauda_transport: TEST_UNIT_READY.\n"); | |
1158 | return alauda_check_media(us); | |
1159 | } | |
1160 | ||
1161 | if (srb->cmnd[0] == READ_CAPACITY) { | |
1162 | unsigned int num_zones; | |
1163 | unsigned long capacity; | |
1164 | ||
1165 | rc = alauda_check_media(us); | |
1166 | if (rc != USB_STOR_TRANSPORT_GOOD) | |
1167 | return rc; | |
1168 | ||
1169 | num_zones = MEDIA_INFO(us).capacity >> (MEDIA_INFO(us).zoneshift | |
1170 | + MEDIA_INFO(us).blockshift + MEDIA_INFO(us).pageshift); | |
1171 | ||
1172 | capacity = num_zones * MEDIA_INFO(us).uzonesize | |
1173 | * MEDIA_INFO(us).blocksize; | |
1174 | ||
1175 | /* Report capacity and page size */ | |
1176 | ((__be32 *) ptr)[0] = cpu_to_be32(capacity - 1); | |
1177 | ((__be32 *) ptr)[1] = cpu_to_be32(512); | |
1178 | ||
1179 | usb_stor_set_xfer_buf(ptr, 8, srb); | |
1180 | return USB_STOR_TRANSPORT_GOOD; | |
1181 | } | |
1182 | ||
1183 | if (srb->cmnd[0] == READ_10) { | |
1184 | unsigned int page, pages; | |
1185 | ||
1186 | rc = alauda_check_media(us); | |
1187 | if (rc != USB_STOR_TRANSPORT_GOOD) | |
1188 | return rc; | |
1189 | ||
1190 | page = short_pack(srb->cmnd[3], srb->cmnd[2]); | |
1191 | page <<= 16; | |
1192 | page |= short_pack(srb->cmnd[5], srb->cmnd[4]); | |
1193 | pages = short_pack(srb->cmnd[8], srb->cmnd[7]); | |
1194 | ||
1195 | US_DEBUGP("alauda_transport: READ_10: page %d pagect %d\n", | |
1196 | page, pages); | |
1197 | ||
1198 | return alauda_read_data(us, page, pages); | |
1199 | } | |
1200 | ||
1201 | if (srb->cmnd[0] == WRITE_10) { | |
1202 | unsigned int page, pages; | |
1203 | ||
1204 | rc = alauda_check_media(us); | |
1205 | if (rc != USB_STOR_TRANSPORT_GOOD) | |
1206 | return rc; | |
1207 | ||
1208 | page = short_pack(srb->cmnd[3], srb->cmnd[2]); | |
1209 | page <<= 16; | |
1210 | page |= short_pack(srb->cmnd[5], srb->cmnd[4]); | |
1211 | pages = short_pack(srb->cmnd[8], srb->cmnd[7]); | |
1212 | ||
1213 | US_DEBUGP("alauda_transport: WRITE_10: page %d pagect %d\n", | |
1214 | page, pages); | |
1215 | ||
1216 | return alauda_write_data(us, page, pages); | |
1217 | } | |
1218 | ||
1219 | if (srb->cmnd[0] == REQUEST_SENSE) { | |
1220 | US_DEBUGP("alauda_transport: REQUEST_SENSE.\n"); | |
1221 | ||
1222 | memset(ptr, 0, 18); | |
1223 | ptr[0] = 0xF0; | |
1224 | ptr[2] = info->sense_key; | |
1225 | ptr[7] = 11; | |
1226 | ptr[12] = info->sense_asc; | |
1227 | ptr[13] = info->sense_ascq; | |
1228 | usb_stor_set_xfer_buf(ptr, 18, srb); | |
1229 | ||
1230 | return USB_STOR_TRANSPORT_GOOD; | |
1231 | } | |
1232 | ||
1233 | if (srb->cmnd[0] == ALLOW_MEDIUM_REMOVAL) { | |
1234 | /* sure. whatever. not like we can stop the user from popping | |
1235 | the media out of the device (no locking doors, etc) */ | |
1236 | return USB_STOR_TRANSPORT_GOOD; | |
1237 | } | |
1238 | ||
1239 | US_DEBUGP("alauda_transport: Gah! Unknown command: %d (0x%x)\n", | |
1240 | srb->cmnd[0], srb->cmnd[0]); | |
1241 | info->sense_key = 0x05; | |
1242 | info->sense_asc = 0x20; | |
1243 | info->sense_ascq = 0x00; | |
1244 | return USB_STOR_TRANSPORT_FAILED; | |
1245 | } | |
1246 | ||
a74bba3b AS |
1247 | static int alauda_probe(struct usb_interface *intf, |
1248 | const struct usb_device_id *id) | |
1249 | { | |
1250 | struct us_data *us; | |
1251 | int result; | |
1252 | ||
1253 | result = usb_stor_probe1(&us, intf, id, | |
1254 | (id - alauda_usb_ids) + alauda_unusual_dev_list); | |
1255 | if (result) | |
1256 | return result; | |
1257 | ||
1258 | us->transport_name = "Alauda Control/Bulk"; | |
1259 | us->transport = alauda_transport; | |
1260 | us->transport_reset = usb_stor_Bulk_reset; | |
1261 | us->max_lun = 1; | |
1262 | ||
1263 | result = usb_stor_probe2(us); | |
1264 | return result; | |
1265 | } | |
1266 | ||
1267 | static struct usb_driver alauda_driver = { | |
1268 | .name = "ums-alauda", | |
1269 | .probe = alauda_probe, | |
1270 | .disconnect = usb_stor_disconnect, | |
1271 | .suspend = usb_stor_suspend, | |
1272 | .resume = usb_stor_resume, | |
1273 | .reset_resume = usb_stor_reset_resume, | |
1274 | .pre_reset = usb_stor_pre_reset, | |
1275 | .post_reset = usb_stor_post_reset, | |
1276 | .id_table = alauda_usb_ids, | |
1277 | .soft_unbind = 1, | |
1278 | }; | |
1279 | ||
1280 | static int __init alauda_init(void) | |
1281 | { | |
1282 | return usb_register(&alauda_driver); | |
1283 | } | |
1284 | ||
1285 | static void __exit alauda_exit(void) | |
1286 | { | |
1287 | usb_deregister(&alauda_driver); | |
1288 | } | |
1289 | ||
1290 | module_init(alauda_init); | |
1291 | module_exit(alauda_exit); |