blob: 9a3fdb4e4fe46ecaddb48e46c468a6f69f247a64 [file] [log] [blame]
Al Cho126bb032010-09-08 00:42:32 -07001#include <linux/slab.h>
2#include "usb.h"
3#include "scsiglue.h"
4#include "transport.h"
5#include "ms.h"
6
7//----- MS_ReaderCopyBlock() ------------------------------------------
8int MS_ReaderCopyBlock(struct us_data *us, WORD oldphy, WORD newphy, WORD PhyBlockAddr, BYTE PageNum, PBYTE buf, WORD len)
9{
10 struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf;
11 int result;
12
13 //printk("MS_ReaderCopyBlock --- PhyBlockAddr = %x, PageNum = %x\n", PhyBlockAddr, PageNum);
14 result = ENE_LoadBinCode(us, MS_RW_PATTERN);
15 if (result != USB_STOR_XFER_GOOD)
16 return USB_STOR_TRANSPORT_ERROR;
17
Konstantin Katuev307ae1d2010-10-29 12:18:18 +110018 memset(bcb, 0, sizeof(struct bulk_cb_wrap));
Al Cho126bb032010-09-08 00:42:32 -070019 bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
20 bcb->DataTransferLength = 0x200*len;
21 bcb->Flags = 0x00;
22 bcb->CDB[0] = 0xF0;
23 bcb->CDB[1] = 0x08;
24 bcb->CDB[4] = (BYTE)(oldphy);
25 bcb->CDB[3] = (BYTE)(oldphy>>8);
26 bcb->CDB[2] = (BYTE)(oldphy>>16);
27 bcb->CDB[7] = (BYTE)(newphy);
28 bcb->CDB[6] = (BYTE)(newphy>>8);
29 bcb->CDB[5] = (BYTE)(newphy>>16);
30 bcb->CDB[9] = (BYTE)(PhyBlockAddr);
31 bcb->CDB[8] = (BYTE)(PhyBlockAddr>>8);
32 bcb->CDB[10] = PageNum;
33
34 result = ENE_SendScsiCmd(us, FDIR_WRITE, buf, 0);
35 if (result != USB_STOR_XFER_GOOD)
36 return USB_STOR_TRANSPORT_ERROR;
37
38 return USB_STOR_TRANSPORT_GOOD;
39}
40
41//----- MS_ReaderReadPage() ------------------------------------------
42int MS_ReaderReadPage(struct us_data *us, DWORD PhyBlockAddr, BYTE PageNum, PDWORD PageBuf, MS_LibTypeExtdat *ExtraDat)
43{
44 struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf;
45 int result;
46 BYTE ExtBuf[4];
47 DWORD bn = PhyBlockAddr * 0x20 + PageNum;
48
49 //printk("MS --- MS_ReaderReadPage, PhyBlockAddr = %x, PageNum = %x\n", PhyBlockAddr, PageNum);
50
51 result = ENE_LoadBinCode(us, MS_RW_PATTERN);
52 if (result != USB_STOR_XFER_GOOD)
53 return USB_STOR_TRANSPORT_ERROR;
54
55 // Read Page Data
Konstantin Katuev307ae1d2010-10-29 12:18:18 +110056 memset(bcb, 0, sizeof(struct bulk_cb_wrap));
Al Cho126bb032010-09-08 00:42:32 -070057 bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
58 bcb->DataTransferLength = 0x200;
59 bcb->Flags = 0x80;
60 bcb->CDB[0] = 0xF1;
61 bcb->CDB[1] = 0x02;
62 bcb->CDB[5] = (BYTE)(bn);
63 bcb->CDB[4] = (BYTE)(bn>>8);
64 bcb->CDB[3] = (BYTE)(bn>>16);
65 bcb->CDB[2] = (BYTE)(bn>>24);
66
67 result = ENE_SendScsiCmd(us, FDIR_READ, PageBuf, 0);
68 if (result != USB_STOR_XFER_GOOD)
69 return USB_STOR_TRANSPORT_ERROR;
70
71 // Read Extra Data
Konstantin Katuev307ae1d2010-10-29 12:18:18 +110072 memset(bcb, 0, sizeof(struct bulk_cb_wrap));
Al Cho126bb032010-09-08 00:42:32 -070073 bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
74 bcb->DataTransferLength = 0x4;
75 bcb->Flags = 0x80;
76 bcb->CDB[0] = 0xF1;
77 bcb->CDB[1] = 0x03;
78 bcb->CDB[5] = (BYTE)(PageNum);
79 bcb->CDB[4] = (BYTE)(PhyBlockAddr);
80 bcb->CDB[3] = (BYTE)(PhyBlockAddr>>8);
81 bcb->CDB[2] = (BYTE)(PhyBlockAddr>>16);
82 bcb->CDB[6] = 0x01;
83
84 result = ENE_SendScsiCmd(us, FDIR_READ, &ExtBuf, 0);
85 if (result != USB_STOR_XFER_GOOD)
86 return USB_STOR_TRANSPORT_ERROR;
87
88 ExtraDat->reserved = 0;
89 ExtraDat->intr = 0x80; // Not yet, ¥ý°²³], µ¥ fireware support
90 ExtraDat->status0 = 0x10; // Not yet, ¥ý°²³], µ¥ fireware support
91 ExtraDat->status1 = 0x00; // Not yet, ¥ý°²³], µ¥ fireware support
92 ExtraDat->ovrflg = ExtBuf[0];
93 ExtraDat->mngflg = ExtBuf[1];
94 ExtraDat->logadr = MemStickLogAddr(ExtBuf[2], ExtBuf[3]);
95
96 return USB_STOR_TRANSPORT_GOOD;
97}
98
99//----- MS_ReaderEraseBlock() ----------------------------------------
100int MS_ReaderEraseBlock(struct us_data *us, DWORD PhyBlockAddr)
101{
102 struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf;
103 int result;
104 DWORD bn = PhyBlockAddr;
105
106 //printk("MS --- MS_ReaderEraseBlock, PhyBlockAddr = %x\n", PhyBlockAddr);
107 result = ENE_LoadBinCode(us, MS_RW_PATTERN);
108 if (result != USB_STOR_XFER_GOOD)
109 return USB_STOR_TRANSPORT_ERROR;
110
Konstantin Katuev307ae1d2010-10-29 12:18:18 +1100111 memset(bcb, 0, sizeof(struct bulk_cb_wrap));
Al Cho126bb032010-09-08 00:42:32 -0700112 bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
113 bcb->DataTransferLength = 0x200;
114 bcb->Flags = 0x80;
115 bcb->CDB[0] = 0xF2;
116 bcb->CDB[1] = 0x06;
117 bcb->CDB[4] = (BYTE)(bn);
118 bcb->CDB[3] = (BYTE)(bn>>8);
119 bcb->CDB[2] = (BYTE)(bn>>16);
120
121 result = ENE_SendScsiCmd(us, FDIR_READ, NULL, 0);
122 if (result != USB_STOR_XFER_GOOD)
123 return USB_STOR_TRANSPORT_ERROR;
124
125 return USB_STOR_TRANSPORT_GOOD;
126}
127
128//----- MS_CardInit() ------------------------------------------------
129int MS_CardInit(struct us_data *us)
130{
131 DWORD result=0;
132 WORD TmpBlock;
133 PBYTE PageBuffer0 = NULL, PageBuffer1 = NULL;
134 MS_LibTypeExtdat extdat;
135 WORD btBlk1st, btBlk2nd;
136 DWORD btBlk1stErred;
137
138 printk("MS_CardInit start\n");
139
140 MS_LibFreeAllocatedArea(us);
141
142 if (((PageBuffer0 = kmalloc(MS_BYTES_PER_PAGE, GFP_KERNEL)) == NULL) ||
143 ((PageBuffer1 = kmalloc(MS_BYTES_PER_PAGE, GFP_KERNEL)) == NULL))
144 {
145 result = MS_NO_MEMORY_ERROR;
146 goto exit;
147 }
148
149 btBlk1st = btBlk2nd = MS_LB_NOT_USED;
150 btBlk1stErred = 0;
151
152 for (TmpBlock=0; TmpBlock < MS_MAX_INITIAL_ERROR_BLOCKS+2; TmpBlock++)
153 {
154 switch (MS_ReaderReadPage(us, TmpBlock, 0, (DWORD *)PageBuffer0, &extdat))
155 {
156 case MS_STATUS_SUCCESS:
157 break;
158 case MS_STATUS_INT_ERROR:
159 break;
160 case MS_STATUS_ERROR:
161 default:
162 continue;
163 }
164
165 if ((extdat.ovrflg & MS_REG_OVR_BKST) == MS_REG_OVR_BKST_NG)
166 continue;
167
168 if (((extdat.mngflg & MS_REG_MNG_SYSFLG) == MS_REG_MNG_SYSFLG_USER) ||
169 (BigEndianWORD(((MemStickBootBlockPage0 *)PageBuffer0)->header.wBlockID) != MS_BOOT_BLOCK_ID) ||
170 (BigEndianWORD(((MemStickBootBlockPage0 *)PageBuffer0)->header.wFormatVersion) != MS_BOOT_BLOCK_FORMAT_VERSION) ||
171 (((MemStickBootBlockPage0 *)PageBuffer0)->header.bNumberOfDataEntry != MS_BOOT_BLOCK_DATA_ENTRIES))
172 continue;
173
174 if (btBlk1st != MS_LB_NOT_USED)
175 {
176 btBlk2nd = TmpBlock;
177 break;
178 }
179
180 btBlk1st = TmpBlock;
181 memcpy(PageBuffer1, PageBuffer0, MS_BYTES_PER_PAGE);
182 if (extdat.status1 & (MS_REG_ST1_DTER | MS_REG_ST1_EXER | MS_REG_ST1_FGER))
183 btBlk1stErred = 1;
184 }
185
186 if (btBlk1st == MS_LB_NOT_USED)
187 {
188 result = MS_STATUS_ERROR;
189 goto exit;
190 }
191
192 // write protect
193 if ((extdat.status0 & MS_REG_ST0_WP) == MS_REG_ST0_WP_ON)
194 MS_LibCtrlSet(us, MS_LIB_CTRL_WRPROTECT);
195
196 result = MS_STATUS_ERROR;
197 // 1st Boot Block
198 if (btBlk1stErred == 0)
199 result = MS_LibProcessBootBlock(us, btBlk1st, PageBuffer1); // 1st
200 // 2nd Boot Block
201 if (result && (btBlk2nd != MS_LB_NOT_USED))
202 result = MS_LibProcessBootBlock(us, btBlk2nd, PageBuffer0);
203
204 if (result)
205 {
206 result = MS_STATUS_ERROR;
207 goto exit;
208 }
209
210 for (TmpBlock = 0; TmpBlock < btBlk1st; TmpBlock++)
211 us->MS_Lib.Phy2LogMap[TmpBlock] = MS_LB_INITIAL_ERROR;
212
213 us->MS_Lib.Phy2LogMap[btBlk1st] = MS_LB_BOOT_BLOCK;
214
215 if (btBlk2nd != MS_LB_NOT_USED)
216 {
217 for (TmpBlock = btBlk1st + 1; TmpBlock < btBlk2nd; TmpBlock++)
218 us->MS_Lib.Phy2LogMap[TmpBlock] = MS_LB_INITIAL_ERROR;
219 us->MS_Lib.Phy2LogMap[btBlk2nd] = MS_LB_BOOT_BLOCK;
220 }
221
222 result = MS_LibScanLogicalBlockNumber(us, btBlk1st);
223 if (result)
224 goto exit;
225
226 for (TmpBlock=MS_PHYSICAL_BLOCKS_PER_SEGMENT; TmpBlock<us->MS_Lib.NumberOfPhyBlock; TmpBlock+=MS_PHYSICAL_BLOCKS_PER_SEGMENT)
227 {
228 if (MS_CountFreeBlock(us, TmpBlock) == 0)
229 {
230 MS_LibCtrlSet(us, MS_LIB_CTRL_WRPROTECT);
231 break;
232 }
233 }
234
235 // write
236 if (MS_LibAllocWriteBuf(us))
237 {
238 result = MS_NO_MEMORY_ERROR;
239 goto exit;
240 }
241
242 result = MS_STATUS_SUCCESS;
243
244exit:
245 if (PageBuffer1) kfree(PageBuffer1);
246 if (PageBuffer0) kfree(PageBuffer0);
247
248 printk("MS_CardInit end\n");
249 return result;
250}
251
252//----- MS_LibCheckDisableBlock() ------------------------------------
253int MS_LibCheckDisableBlock(struct us_data *us, WORD PhyBlock)
254{
255 PWORD PageBuf=NULL;
256 DWORD result=MS_STATUS_SUCCESS;
257 DWORD blk, index=0;
258 MS_LibTypeExtdat extdat;
259
260 if (((PageBuf = kmalloc(MS_BYTES_PER_PAGE, GFP_KERNEL)) == NULL))
261 {
262 result = MS_NO_MEMORY_ERROR;
263 goto exit;
264 }
265
266 MS_ReaderReadPage(us, PhyBlock, 1, (DWORD *)PageBuf, &extdat);
267 do
268 {
269 blk = BigEndianWORD(PageBuf[index]);
270 if (blk == MS_LB_NOT_USED)
271 break;
272 if (blk == us->MS_Lib.Log2PhyMap[0])
273 {
274 result = MS_ERROR_FLASH_READ;
275 break;
276 }
277 index++;
278 } while(1);
279
280exit:
281 if (PageBuf) kfree(PageBuf);
282 return result;
283}
284
285//----- MS_LibFreeAllocatedArea() ------------------------------------
286void MS_LibFreeAllocatedArea(struct us_data *us)
287{
288 MS_LibFreeWriteBuf(us);
289 MS_LibFreeLogicalMap(us);
290
291 us->MS_Lib.flags = 0;
292 us->MS_Lib.BytesPerSector = 0;
293 us->MS_Lib.SectorsPerCylinder = 0;
294
295 us->MS_Lib.cardType = 0;
296 us->MS_Lib.blockSize = 0;
297 us->MS_Lib.PagesPerBlock = 0;
298
299 us->MS_Lib.NumberOfPhyBlock = 0;
300 us->MS_Lib.NumberOfLogBlock = 0;
301}
302
303//----- MS_LibFreeWriteBuf() -----------------------------------------
304void MS_LibFreeWriteBuf(struct us_data *us)
305{
306 us->MS_Lib.wrtblk = (WORD)-1; //set to -1
307 MS_LibClearPageMap(us); // memset((fdoExt)->MS_Lib.pagemap, 0, sizeof((fdoExt)->MS_Lib.pagemap))
308
309 if (us->MS_Lib.blkpag)
310 {
311 kfree((BYTE *)(us->MS_Lib.blkpag)); // Arnold test ...
312 us->MS_Lib.blkpag = NULL;
313 }
314
315 if (us->MS_Lib.blkext)
316 {
317 kfree((BYTE *)(us->MS_Lib.blkext)); // Arnold test ...
318 us->MS_Lib.blkext = NULL;
319 }
320}
321
322//----- MS_LibFreeLogicalMap() ---------------------------------------
323int MS_LibFreeLogicalMap(struct us_data *us)
324{
325 if (us->MS_Lib.Phy2LogMap)
326 {
327 kfree(us->MS_Lib.Phy2LogMap);
328 us->MS_Lib.Phy2LogMap = NULL;
329 }
330
331 if (us->MS_Lib.Log2PhyMap)
332 {
333 kfree(us->MS_Lib.Log2PhyMap);
334 us->MS_Lib.Log2PhyMap = NULL;
335 }
336
337 return 0;
338}
339
340//----- MS_LibProcessBootBlock() -------------------------------------
341int MS_LibProcessBootBlock(struct us_data *us, WORD PhyBlock, BYTE *PageData)
342{
343 MemStickBootBlockSysEnt *SysEntry;
344 MemStickBootBlockSysInf *SysInfo;
345 DWORD i, result;
346 BYTE PageNumber;
347 BYTE *PageBuffer;
348 MS_LibTypeExtdat ExtraData;
349
350 if ((PageBuffer = (BYTE *)kmalloc(MS_BYTES_PER_PAGE, GFP_KERNEL))==NULL)
351 return (DWORD)-1;
352
353 result = (DWORD)-1;
354
355 SysInfo= &(((MemStickBootBlockPage0 *)PageData)->sysinf);
356
357 if ((SysInfo->bMsClass != MS_SYSINF_MSCLASS_TYPE_1) ||
358 (BigEndianWORD(SysInfo->wPageSize) != MS_SYSINF_PAGE_SIZE) ||
359 ((SysInfo->bSecuritySupport & MS_SYSINF_SECURITY) == MS_SYSINF_SECURITY_SUPPORT) ||
360 (SysInfo->bReserved1 != MS_SYSINF_RESERVED1) ||
361 (SysInfo->bReserved2 != MS_SYSINF_RESERVED2) ||
362 (SysInfo->bFormatType!= MS_SYSINF_FORMAT_FAT) ||
363 (SysInfo->bUsage != MS_SYSINF_USAGE_GENERAL))
364 goto exit;
365
366 switch (us->MS_Lib.cardType = SysInfo->bCardType)
367 {
368 case MS_SYSINF_CARDTYPE_RDONLY:
369 MS_LibCtrlSet(us, MS_LIB_CTRL_RDONLY);
370 break;
371 case MS_SYSINF_CARDTYPE_RDWR:
372 MS_LibCtrlReset(us, MS_LIB_CTRL_RDONLY);
373 break;
374 case MS_SYSINF_CARDTYPE_HYBRID:
375 default:
376 goto exit;
377 }
378
379 us->MS_Lib.blockSize = BigEndianWORD(SysInfo->wBlockSize);
380 us->MS_Lib.NumberOfPhyBlock = BigEndianWORD(SysInfo->wBlockNumber);
381 us->MS_Lib.NumberOfLogBlock = BigEndianWORD(SysInfo->wTotalBlockNumber)- 2;
382 us->MS_Lib.PagesPerBlock = us->MS_Lib.blockSize * SIZE_OF_KIRO / MS_BYTES_PER_PAGE;
383 us->MS_Lib.NumberOfSegment = us->MS_Lib.NumberOfPhyBlock / MS_PHYSICAL_BLOCKS_PER_SEGMENT;
384 us->MS_Model = BigEndianWORD(SysInfo->wMemorySize);
385
386 if (MS_LibAllocLogicalMap(us)) //Allocate to all number of logicalblock and physicalblock
387 goto exit;
388
389 MS_LibSetBootBlockMark(us, PhyBlock); //Mark the book block
390
391 SysEntry = &(((MemStickBootBlockPage0 *)PageData)->sysent);
392
393 for (i=0; i<MS_NUMBER_OF_SYSTEM_ENTRY; i++)
394 {
395 DWORD EntryOffset, EntrySize;
396
397 if ((EntryOffset = BigEndianDWORD(SysEntry->entry[i].dwStart)) == 0xffffff)
398 continue;
399
400 if ((EntrySize = BigEndianDWORD(SysEntry->entry[i].dwSize)) == 0)
401 continue;
402
403 if (EntryOffset + MS_BYTES_PER_PAGE + EntrySize > us->MS_Lib.blockSize * (DWORD)SIZE_OF_KIRO)
404 continue;
405
406 if (i == 0)
407 {
408 BYTE PrevPageNumber = 0;
409 WORD phyblk;
410
411 if (SysEntry->entry[i].bType != MS_SYSENT_TYPE_INVALID_BLOCK)
412 goto exit;
413
414 while (EntrySize > 0)
415 {
416 if ((PageNumber = (BYTE)(EntryOffset / MS_BYTES_PER_PAGE + 1)) != PrevPageNumber)
417 {
418 switch (MS_ReaderReadPage(us, PhyBlock, PageNumber, (DWORD *)PageBuffer, &ExtraData))
419 {
420 case MS_STATUS_SUCCESS:
421 break;
422 case MS_STATUS_WRITE_PROTECT:
423 case MS_ERROR_FLASH_READ:
424 case MS_STATUS_ERROR:
425 default:
426 goto exit;
427 }
428
429 PrevPageNumber = PageNumber;
430 }
431
432 if ((phyblk = BigEndianWORD(*(WORD *)(PageBuffer + (EntryOffset % MS_BYTES_PER_PAGE)))) < 0x0fff)
433 MS_LibSetInitialErrorBlock(us, phyblk);
434
435 EntryOffset += 2;
436 EntrySize -= 2;
437 }
438 }
439 else if (i == 1)
440 { // CIS/IDI
441 MemStickBootBlockIDI *idi;
442
443 if (SysEntry->entry[i].bType != MS_SYSENT_TYPE_CIS_IDI)
444 goto exit;
445
446 switch (MS_ReaderReadPage(us, PhyBlock, (BYTE)(EntryOffset / MS_BYTES_PER_PAGE + 1), (DWORD *)PageBuffer, &ExtraData))
447 {
448 case MS_STATUS_SUCCESS:
449 break;
450 case MS_STATUS_WRITE_PROTECT:
451 case MS_ERROR_FLASH_READ:
452 case MS_STATUS_ERROR:
453 default:
454 goto exit;
455 }
456
457 idi = &((MemStickBootBlockCIS_IDI *)(PageBuffer + (EntryOffset % MS_BYTES_PER_PAGE)))->idi.idi;
458 if (LittleEndianWORD(idi->wIDIgeneralConfiguration) != MS_IDI_GENERAL_CONF)
459 goto exit;
460
461 us->MS_Lib.BytesPerSector = LittleEndianWORD(idi->wIDIbytesPerSector);
462 if (us->MS_Lib.BytesPerSector != MS_BYTES_PER_PAGE)
463 goto exit;
464 }
465 } // End for ..
466
467 result = 0;
468
469exit:
470 if (result) MS_LibFreeLogicalMap(us);
471 if (PageBuffer) kfree(PageBuffer);
472
473 result = 0;
474 return result;
475}
476
477//----- MS_LibAllocLogicalMap() --------------------------------------
478int MS_LibAllocLogicalMap(struct us_data *us)
479{
480 DWORD i;
481
482
483 us->MS_Lib.Phy2LogMap = (WORD *)kmalloc(us->MS_Lib.NumberOfPhyBlock * sizeof(WORD), GFP_KERNEL);
484 us->MS_Lib.Log2PhyMap = (WORD *)kmalloc(us->MS_Lib.NumberOfLogBlock * sizeof(WORD), GFP_KERNEL);
485
486 if ((us->MS_Lib.Phy2LogMap == NULL) || (us->MS_Lib.Log2PhyMap == NULL))
487 {
488 MS_LibFreeLogicalMap(us);
489 return (DWORD)-1;
490 }
491
492 for (i = 0; i < us->MS_Lib.NumberOfPhyBlock; i++)
493 us->MS_Lib.Phy2LogMap[i] = MS_LB_NOT_USED;
494
495 for (i = 0; i < us->MS_Lib.NumberOfLogBlock; i++)
496 us->MS_Lib.Log2PhyMap[i] = MS_LB_NOT_USED;
497
498 return 0;
499}
500
501//----- MS_LibSetBootBlockMark() -------------------------------------
502int MS_LibSetBootBlockMark(struct us_data *us, WORD phyblk)
503{
504 return MS_LibSetLogicalBlockMark(us, phyblk, MS_LB_BOOT_BLOCK);
505}
506
507//----- MS_LibSetLogicalBlockMark() ----------------------------------
508int MS_LibSetLogicalBlockMark(struct us_data *us, WORD phyblk, WORD mark)
509{
510 if (phyblk >= us->MS_Lib.NumberOfPhyBlock)
511 return (DWORD)-1;
512
513 us->MS_Lib.Phy2LogMap[phyblk] = mark;
514
515 return 0;
516}
517
518//----- MS_LibSetInitialErrorBlock() ---------------------------------
519int MS_LibSetInitialErrorBlock(struct us_data *us, WORD phyblk)
520{
521 return MS_LibSetLogicalBlockMark(us, phyblk, MS_LB_INITIAL_ERROR);
522}
523
524//----- MS_LibScanLogicalBlockNumber() -------------------------------
525int MS_LibScanLogicalBlockNumber(struct us_data *us, WORD btBlk1st)
526{
527 WORD PhyBlock, newblk, i;
528 WORD LogStart, LogEnde;
529 MS_LibTypeExtdat extdat;
530 BYTE buf[0x200];
531 DWORD count=0, index=0;
532
533 for (PhyBlock = 0; PhyBlock < us->MS_Lib.NumberOfPhyBlock;)
534 {
535 MS_LibPhy2LogRange(PhyBlock, &LogStart, &LogEnde);
536
537 for (i=0; i<MS_PHYSICAL_BLOCKS_PER_SEGMENT; i++, PhyBlock++)
538 {
539 switch (MS_LibConv2Logical(us, PhyBlock))
540 {
541 case MS_STATUS_ERROR:
542 continue;
543 default:
544 break;
545 }
546
547 if (count == PhyBlock)
548 {
549 MS_LibReadExtraBlock(us, PhyBlock, 0, 0x80, &buf);
550 count += 0x80;
551 }
552 index = (PhyBlock % 0x80) * 4;
553
554 extdat.ovrflg = buf[index];
555 extdat.mngflg = buf[index+1];
556 extdat.logadr = MemStickLogAddr(buf[index+2], buf[index+3]);
557
558 if ((extdat.ovrflg & MS_REG_OVR_BKST) != MS_REG_OVR_BKST_OK)
559 {
560 MS_LibSetAcquiredErrorBlock(us, PhyBlock);
561 continue;
562 }
563
564 if ((extdat.mngflg & MS_REG_MNG_ATFLG) == MS_REG_MNG_ATFLG_ATTBL)
565 {
566 MS_LibErasePhyBlock(us, PhyBlock);
567 continue;
568 }
569
570 if (extdat.logadr != MS_LB_NOT_USED)
571 {
572 if ((extdat.logadr < LogStart) || (LogEnde <= extdat.logadr))
573 {
574 MS_LibErasePhyBlock(us, PhyBlock);
575 continue;
576 }
577
578 if ((newblk = MS_LibConv2Physical(us, extdat.logadr)) != MS_LB_NOT_USED)
579 {
580 if (extdat.logadr==0)
581 {
582 MS_LibSetLogicalPair(us, extdat.logadr, PhyBlock);
583 if ( MS_LibCheckDisableBlock(us, btBlk1st) )
584 {
585 MS_LibSetLogicalPair(us, extdat.logadr, newblk);
586 continue;
587 }
588 }
589
590 MS_LibReadExtra(us, newblk, 0, &extdat);
591 if ((extdat.ovrflg & MS_REG_OVR_UDST) == MS_REG_OVR_UDST_UPDATING)
592 {
593 MS_LibErasePhyBlock(us, PhyBlock);
594 continue;
595 }
596 else
597 MS_LibErasePhyBlock(us, newblk);
598 }
599
600 MS_LibSetLogicalPair(us, extdat.logadr, PhyBlock);
601 }
602 }
603 } //End for ...
604
605 return MS_STATUS_SUCCESS;
606}
607
608//----- MS_LibAllocWriteBuf() ----------------------------------------
609int MS_LibAllocWriteBuf(struct us_data *us)
610{
611 us->MS_Lib.wrtblk = (WORD)-1;
612
613 us->MS_Lib.blkpag = (BYTE *)kmalloc(us->MS_Lib.PagesPerBlock * us->MS_Lib.BytesPerSector, GFP_KERNEL);
614 us->MS_Lib.blkext = (MS_LibTypeExtdat *)kmalloc(us->MS_Lib.PagesPerBlock * sizeof(MS_LibTypeExtdat), GFP_KERNEL);
615
616 if ((us->MS_Lib.blkpag == NULL) || (us->MS_Lib.blkext == NULL))
617 {
618 MS_LibFreeWriteBuf(us);
619 return (DWORD)-1;
620 }
621
622 MS_LibClearWriteBuf(us);
623
624 return 0;
625}
626
627//----- MS_LibClearWriteBuf() ----------------------------------------
628void MS_LibClearWriteBuf(struct us_data *us)
629{
630 int i;
631
632 us->MS_Lib.wrtblk = (WORD)-1;
633 MS_LibClearPageMap(us);
634
635 if (us->MS_Lib.blkpag)
636 memset(us->MS_Lib.blkpag, 0xff, us->MS_Lib.PagesPerBlock * us->MS_Lib.BytesPerSector);
637
638 if (us->MS_Lib.blkext)
639 {
640 for (i = 0; i < us->MS_Lib.PagesPerBlock; i++)
641 {
642 us->MS_Lib.blkext[i].status1 = MS_REG_ST1_DEFAULT;
643 us->MS_Lib.blkext[i].ovrflg = MS_REG_OVR_DEFAULT;
644 us->MS_Lib.blkext[i].mngflg = MS_REG_MNG_DEFAULT;
645 us->MS_Lib.blkext[i].logadr = MS_LB_NOT_USED;
646 }
647 }
648}
649
650//----- MS_LibPhy2LogRange() -----------------------------------------
651void MS_LibPhy2LogRange(WORD PhyBlock, WORD *LogStart, WORD *LogEnde)
652{
653 PhyBlock /= MS_PHYSICAL_BLOCKS_PER_SEGMENT;
654
655 if (PhyBlock)
656 {
657 *LogStart = MS_LOGICAL_BLOCKS_IN_1ST_SEGMENT + (PhyBlock - 1) * MS_LOGICAL_BLOCKS_PER_SEGMENT;//496
658 *LogEnde = *LogStart + MS_LOGICAL_BLOCKS_PER_SEGMENT;//496
659 }
660 else
661 {
662 *LogStart = 0;
663 *LogEnde = MS_LOGICAL_BLOCKS_IN_1ST_SEGMENT;//494
664 }
665}
666
667//----- MS_LibReadExtraBlock() --------------------------------------------
668int MS_LibReadExtraBlock(struct us_data *us, DWORD PhyBlock, BYTE PageNum, BYTE blen, void *buf)
669{
670 struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf;
671 int result;
672
673 //printk("MS_LibReadExtraBlock --- PhyBlock = %x, PageNum = %x, blen = %x\n", PhyBlock, PageNum, blen);
674
675 // Read Extra Data
Konstantin Katuev307ae1d2010-10-29 12:18:18 +1100676 memset(bcb, 0, sizeof(struct bulk_cb_wrap));
Al Cho126bb032010-09-08 00:42:32 -0700677 bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
678 bcb->DataTransferLength = 0x4 * blen;
679 bcb->Flags = 0x80;
680 bcb->CDB[0] = 0xF1;
681 bcb->CDB[1] = 0x03;
682 bcb->CDB[5] = (BYTE)(PageNum);
683 bcb->CDB[4] = (BYTE)(PhyBlock);
684 bcb->CDB[3] = (BYTE)(PhyBlock>>8);
685 bcb->CDB[2] = (BYTE)(PhyBlock>>16);
686 bcb->CDB[6] = blen;
687
688 result = ENE_SendScsiCmd(us, FDIR_READ, buf, 0);
689 if (result != USB_STOR_XFER_GOOD)
690 return USB_STOR_TRANSPORT_ERROR;
691
692 return USB_STOR_TRANSPORT_GOOD;
693}
694
695//----- MS_LibReadExtra() --------------------------------------------
696int MS_LibReadExtra(struct us_data *us, DWORD PhyBlock, BYTE PageNum, MS_LibTypeExtdat *ExtraDat)
697{
698 struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf;
699 int result;
700 BYTE ExtBuf[4];
701
702 //printk("MS_LibReadExtra --- PhyBlock = %x, PageNum = %x\n", PhyBlock, PageNum);
Konstantin Katuev307ae1d2010-10-29 12:18:18 +1100703 memset(bcb, 0, sizeof(struct bulk_cb_wrap));
Al Cho126bb032010-09-08 00:42:32 -0700704 bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
705 bcb->DataTransferLength = 0x4;
706 bcb->Flags = 0x80;
707 bcb->CDB[0] = 0xF1;
708 bcb->CDB[1] = 0x03;
709 bcb->CDB[5] = (BYTE)(PageNum);
710 bcb->CDB[4] = (BYTE)(PhyBlock);
711 bcb->CDB[3] = (BYTE)(PhyBlock>>8);
712 bcb->CDB[2] = (BYTE)(PhyBlock>>16);
713 bcb->CDB[6] = 0x01;
714
715 result = ENE_SendScsiCmd(us, FDIR_READ, &ExtBuf, 0);
716 if (result != USB_STOR_XFER_GOOD)
717 return USB_STOR_TRANSPORT_ERROR;
718
719 ExtraDat->reserved = 0;
720 ExtraDat->intr = 0x80; // Not yet, waiting for fireware support
721 ExtraDat->status0 = 0x10; // Not yet, waiting for fireware support
722 ExtraDat->status1 = 0x00; // Not yet, waiting for fireware support
723 ExtraDat->ovrflg = ExtBuf[0];
724 ExtraDat->mngflg = ExtBuf[1];
725 ExtraDat->logadr = MemStickLogAddr(ExtBuf[2], ExtBuf[3]);
726
727 return USB_STOR_TRANSPORT_GOOD;
728}
729
730//----- MS_LibSetAcquiredErrorBlock() --------------------------------
731int MS_LibSetAcquiredErrorBlock(struct us_data *us, WORD phyblk)
732{
733 WORD log;
734
735 if (phyblk >= us->MS_Lib.NumberOfPhyBlock)
736 return (DWORD)-1;
737
738 if ((log = us->MS_Lib.Phy2LogMap[phyblk]) < us->MS_Lib.NumberOfLogBlock)
739 us->MS_Lib.Log2PhyMap[log] = MS_LB_NOT_USED;
740
741 if (us->MS_Lib.Phy2LogMap[phyblk] != MS_LB_INITIAL_ERROR)
742 us->MS_Lib.Phy2LogMap[phyblk] = MS_LB_ACQUIRED_ERROR;
743
744 return 0;
745}
746
747//----- MS_LibErasePhyBlock() ----------------------------------------
748int MS_LibErasePhyBlock(struct us_data *us, WORD phyblk)
749{
750 WORD log;
751
752 if (phyblk >= us->MS_Lib.NumberOfPhyBlock)
753 return MS_STATUS_ERROR;
754
755 if ((log = us->MS_Lib.Phy2LogMap[phyblk]) < us->MS_Lib.NumberOfLogBlock)
756 us->MS_Lib.Log2PhyMap[log] = MS_LB_NOT_USED;
757
758 us->MS_Lib.Phy2LogMap[phyblk] = MS_LB_NOT_USED;
759
760 if (MS_LibIsWritable(us))
761 {
762 switch (MS_ReaderEraseBlock(us, phyblk))
763 {
764 case MS_STATUS_SUCCESS:
765 us->MS_Lib.Phy2LogMap[phyblk] = MS_LB_NOT_USED_ERASED;
766 return MS_STATUS_SUCCESS;
767 case MS_ERROR_FLASH_ERASE:
768 case MS_STATUS_INT_ERROR :
769 MS_LibErrorPhyBlock(us, phyblk);
770 return MS_ERROR_FLASH_ERASE;
771 case MS_STATUS_ERROR:
772 default:
773 MS_LibCtrlSet(us, MS_LIB_CTRL_RDONLY);
774 MS_LibSetAcquiredErrorBlock(us, phyblk);
775 return MS_STATUS_ERROR;
776 }
777 }
778
779 MS_LibSetAcquiredErrorBlock(us, phyblk);
780
781 return MS_STATUS_SUCCESS;
782}
783
784//----- MS_LibErrorPhyBlock() ----------------------------------------
785int MS_LibErrorPhyBlock(struct us_data *us, WORD phyblk)
786{
787 if (phyblk >= us->MS_Lib.NumberOfPhyBlock)
788 return MS_STATUS_ERROR;
789
790 MS_LibSetAcquiredErrorBlock(us, phyblk);
791
792 if (MS_LibIsWritable(us))
793 return MS_LibOverwriteExtra(us, phyblk, 0, (BYTE)(~MS_REG_OVR_BKST));
794
795
796 return MS_STATUS_SUCCESS;
797}
798
799//----- MS_LibOverwriteExtra() ---------------------------------------
800int MS_LibOverwriteExtra(struct us_data *us, DWORD PhyBlockAddr, BYTE PageNum, BYTE OverwriteFlag)
801{
802 struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf;
803 int result;
804
805 //printk("MS --- MS_LibOverwriteExtra, PhyBlockAddr = %x, PageNum = %x\n", PhyBlockAddr, PageNum);
806 result = ENE_LoadBinCode(us, MS_RW_PATTERN);
807 if (result != USB_STOR_XFER_GOOD)
808 return USB_STOR_TRANSPORT_ERROR;
809
Konstantin Katuev307ae1d2010-10-29 12:18:18 +1100810 memset(bcb, 0, sizeof(struct bulk_cb_wrap));
Al Cho126bb032010-09-08 00:42:32 -0700811 bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
812 bcb->DataTransferLength = 0x4;
813 bcb->Flags = 0x80;
814 bcb->CDB[0] = 0xF2;
815 bcb->CDB[1] = 0x05;
816 bcb->CDB[5] = (BYTE)(PageNum);
817 bcb->CDB[4] = (BYTE)(PhyBlockAddr);
818 bcb->CDB[3] = (BYTE)(PhyBlockAddr>>8);
819 bcb->CDB[2] = (BYTE)(PhyBlockAddr>>16);
820 bcb->CDB[6] = OverwriteFlag;
821 bcb->CDB[7] = 0xFF;
822 bcb->CDB[8] = 0xFF;
823 bcb->CDB[9] = 0xFF;
824
825 result = ENE_SendScsiCmd(us, FDIR_READ, NULL, 0);
826 if (result != USB_STOR_XFER_GOOD)
827 return USB_STOR_TRANSPORT_ERROR;
828
829 return USB_STOR_TRANSPORT_GOOD;
830}
831
832//----- MS_LibForceSetLogicalPair() ----------------------------------
833int MS_LibForceSetLogicalPair(struct us_data *us, WORD logblk, WORD phyblk)
834{
835 if (logblk == MS_LB_NOT_USED)
836 return 0;
837
838 if ((logblk >= us->MS_Lib.NumberOfLogBlock) || (phyblk >= us->MS_Lib.NumberOfPhyBlock))
839 return (DWORD)-1;
840
841 us->MS_Lib.Phy2LogMap[phyblk] = logblk;
842 us->MS_Lib.Log2PhyMap[logblk] = phyblk;
843
844 return 0;
845}
846
847//----- MS_LibSetLogicalPair() ---------------------------------------
848int MS_LibSetLogicalPair(struct us_data *us, WORD logblk, WORD phyblk)
849{
850 if ((logblk >= us->MS_Lib.NumberOfLogBlock) || (phyblk >= us->MS_Lib.NumberOfPhyBlock))
851 return (DWORD)-1;
852
853 us->MS_Lib.Phy2LogMap[phyblk] = logblk;
854 us->MS_Lib.Log2PhyMap[logblk] = phyblk;
855
856 return 0;
857}
858
859//----- MS_CountFreeBlock() ------------------------------------------
860int MS_CountFreeBlock(struct us_data *us, WORD PhyBlock)
861{
862 DWORD Ende, Count;
863
864 Ende = PhyBlock + MS_PHYSICAL_BLOCKS_PER_SEGMENT;
865 for (Count = 0; PhyBlock < Ende; PhyBlock++)
866 {
867 switch (us->MS_Lib.Phy2LogMap[PhyBlock])
868 {
869 case MS_LB_NOT_USED:
870 case MS_LB_NOT_USED_ERASED:
871 Count++;
872 default:
873 break;
874 }
875 }
876
877 return Count;
878}
879
880//----- MS_LibSearchBlockFromPhysical() ------------------------------
881int MS_LibSearchBlockFromPhysical(struct us_data *us, WORD phyblk)
882{
883 WORD Newblk;
884 WORD blk;
885 MS_LibTypeExtdat extdat;
886
887 if (phyblk >= us->MS_Lib.NumberOfPhyBlock)
888 return MS_LB_ERROR;
889
890 for (blk = phyblk + 1; blk != phyblk; blk++)
891 {
892 if ((blk & MS_PHYSICAL_BLOCKS_PER_SEGMENT_MASK) == 0)
893 blk -= MS_PHYSICAL_BLOCKS_PER_SEGMENT;
894
895 Newblk = us->MS_Lib.Phy2LogMap[blk];
896 if (us->MS_Lib.Phy2LogMap[blk] == MS_LB_NOT_USED_ERASED)
897 return blk;
898 else if (us->MS_Lib.Phy2LogMap[blk] == MS_LB_NOT_USED)
899 {
900 switch (MS_LibReadExtra(us, blk, 0, &extdat))
901 {
902 case MS_STATUS_SUCCESS :
903 case MS_STATUS_SUCCESS_WITH_ECC:
904 break;
905 case MS_NOCARD_ERROR:
906 return MS_NOCARD_ERROR;
907 case MS_STATUS_INT_ERROR:
908 return MS_LB_ERROR;
909 case MS_ERROR_FLASH_READ:
910 default:
911 MS_LibSetAcquiredErrorBlock(us, blk); // MS_LibErrorPhyBlock(fdoExt, blk);
912 continue;
913 } // End switch
914
915 if ((extdat.ovrflg & MS_REG_OVR_BKST) != MS_REG_OVR_BKST_OK)
916 {
917 MS_LibSetAcquiredErrorBlock(us, blk);
918 continue;
919 }
920
921 switch (MS_LibErasePhyBlock(us, blk))
922 {
923 case MS_STATUS_SUCCESS:
924 return blk;
925 case MS_STATUS_ERROR:
926 return MS_LB_ERROR;
927 case MS_ERROR_FLASH_ERASE:
928 default:
929 MS_LibErrorPhyBlock(us, blk);
930 break;
931 }
932 }
933 } // End for
934
935 return MS_LB_ERROR;
936}
937
938//----- MS_LibSearchBlockFromLogical() -------------------------------
939int MS_LibSearchBlockFromLogical(struct us_data *us, WORD logblk)
940{
941 WORD phyblk;
942
943 if ((phyblk=MS_LibConv2Physical(us, logblk)) >= MS_LB_ERROR)
944 {
945 if (logblk >= us->MS_Lib.NumberOfLogBlock)
946 return MS_LB_ERROR;
947
948 phyblk = (logblk + MS_NUMBER_OF_BOOT_BLOCK) / MS_LOGICAL_BLOCKS_PER_SEGMENT;
949 phyblk *= MS_PHYSICAL_BLOCKS_PER_SEGMENT;
950 phyblk += MS_PHYSICAL_BLOCKS_PER_SEGMENT - 1;
951 }
952
953 return MS_LibSearchBlockFromPhysical(us, phyblk);
954}
955
956