1 #include <linux/slab.h>
7 //----- MS_ReaderCopyBlock() ------------------------------------------
8 int MS_ReaderCopyBlock(struct us_data
*us
, WORD oldphy
, WORD newphy
, WORD PhyBlockAddr
, BYTE PageNum
, PBYTE buf
, WORD len
)
10 struct bulk_cb_wrap
*bcb
= (struct bulk_cb_wrap
*) us
->iobuf
;
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
;
18 memset(bcb
, 0, sizeof(struct bulk_cb_wrap
));
19 bcb
->Signature
= cpu_to_le32(US_BULK_CB_SIGN
);
20 bcb
->DataTransferLength
= 0x200*len
;
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
;
34 result
= ENE_SendScsiCmd(us
, FDIR_WRITE
, buf
, 0);
35 if (result
!= USB_STOR_XFER_GOOD
)
36 return USB_STOR_TRANSPORT_ERROR
;
38 return USB_STOR_TRANSPORT_GOOD
;
41 //----- MS_ReaderReadPage() ------------------------------------------
42 int MS_ReaderReadPage(struct us_data
*us
, DWORD PhyBlockAddr
, BYTE PageNum
, PDWORD PageBuf
, MS_LibTypeExtdat
*ExtraDat
)
44 struct bulk_cb_wrap
*bcb
= (struct bulk_cb_wrap
*) us
->iobuf
;
47 DWORD bn
= PhyBlockAddr
* 0x20 + PageNum
;
49 //printk("MS --- MS_ReaderReadPage, PhyBlockAddr = %x, PageNum = %x\n", PhyBlockAddr, PageNum);
51 result
= ENE_LoadBinCode(us
, MS_RW_PATTERN
);
52 if (result
!= USB_STOR_XFER_GOOD
)
53 return USB_STOR_TRANSPORT_ERROR
;
56 memset(bcb
, 0, sizeof(struct bulk_cb_wrap
));
57 bcb
->Signature
= cpu_to_le32(US_BULK_CB_SIGN
);
58 bcb
->DataTransferLength
= 0x200;
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);
67 result
= ENE_SendScsiCmd(us
, FDIR_READ
, PageBuf
, 0);
68 if (result
!= USB_STOR_XFER_GOOD
)
69 return USB_STOR_TRANSPORT_ERROR
;
72 memset(bcb
, 0, sizeof(struct bulk_cb_wrap
));
73 bcb
->Signature
= cpu_to_le32(US_BULK_CB_SIGN
);
74 bcb
->DataTransferLength
= 0x4;
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);
84 result
= ENE_SendScsiCmd(us
, FDIR_READ
, &ExtBuf
, 0);
85 if (result
!= USB_STOR_XFER_GOOD
)
86 return USB_STOR_TRANSPORT_ERROR
;
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]);
96 return USB_STOR_TRANSPORT_GOOD
;
99 //----- MS_ReaderEraseBlock() ----------------------------------------
100 int MS_ReaderEraseBlock(struct us_data
*us
, DWORD PhyBlockAddr
)
102 struct bulk_cb_wrap
*bcb
= (struct bulk_cb_wrap
*) us
->iobuf
;
104 DWORD bn
= PhyBlockAddr
;
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
;
111 memset(bcb
, 0, sizeof(struct bulk_cb_wrap
));
112 bcb
->Signature
= cpu_to_le32(US_BULK_CB_SIGN
);
113 bcb
->DataTransferLength
= 0x200;
117 bcb
->CDB
[4] = (BYTE
)(bn
);
118 bcb
->CDB
[3] = (BYTE
)(bn
>>8);
119 bcb
->CDB
[2] = (BYTE
)(bn
>>16);
121 result
= ENE_SendScsiCmd(us
, FDIR_READ
, NULL
, 0);
122 if (result
!= USB_STOR_XFER_GOOD
)
123 return USB_STOR_TRANSPORT_ERROR
;
125 return USB_STOR_TRANSPORT_GOOD
;
128 //----- MS_CardInit() ------------------------------------------------
129 int MS_CardInit(struct us_data
*us
)
133 PBYTE PageBuffer0
= NULL
, PageBuffer1
= NULL
;
134 MS_LibTypeExtdat extdat
;
135 WORD btBlk1st
, btBlk2nd
;
138 printk("MS_CardInit start\n");
140 MS_LibFreeAllocatedArea(us
);
142 if (((PageBuffer0
= kmalloc(MS_BYTES_PER_PAGE
, GFP_KERNEL
)) == NULL
) ||
143 ((PageBuffer1
= kmalloc(MS_BYTES_PER_PAGE
, GFP_KERNEL
)) == NULL
))
145 result
= MS_NO_MEMORY_ERROR
;
149 btBlk1st
= btBlk2nd
= MS_LB_NOT_USED
;
152 for (TmpBlock
=0; TmpBlock
< MS_MAX_INITIAL_ERROR_BLOCKS
+2; TmpBlock
++)
154 switch (MS_ReaderReadPage(us
, TmpBlock
, 0, (DWORD
*)PageBuffer0
, &extdat
))
156 case MS_STATUS_SUCCESS
:
158 case MS_STATUS_INT_ERROR
:
160 case MS_STATUS_ERROR
:
165 if ((extdat
.ovrflg
& MS_REG_OVR_BKST
) == MS_REG_OVR_BKST_NG
)
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
))
174 if (btBlk1st
!= MS_LB_NOT_USED
)
181 memcpy(PageBuffer1
, PageBuffer0
, MS_BYTES_PER_PAGE
);
182 if (extdat
.status1
& (MS_REG_ST1_DTER
| MS_REG_ST1_EXER
| MS_REG_ST1_FGER
))
186 if (btBlk1st
== MS_LB_NOT_USED
)
188 result
= MS_STATUS_ERROR
;
193 if ((extdat
.status0
& MS_REG_ST0_WP
) == MS_REG_ST0_WP_ON
)
194 MS_LibCtrlSet(us
, MS_LIB_CTRL_WRPROTECT
);
196 result
= MS_STATUS_ERROR
;
198 if (btBlk1stErred
== 0)
199 result
= MS_LibProcessBootBlock(us
, btBlk1st
, PageBuffer1
); // 1st
201 if (result
&& (btBlk2nd
!= MS_LB_NOT_USED
))
202 result
= MS_LibProcessBootBlock(us
, btBlk2nd
, PageBuffer0
);
206 result
= MS_STATUS_ERROR
;
210 for (TmpBlock
= 0; TmpBlock
< btBlk1st
; TmpBlock
++)
211 us
->MS_Lib
.Phy2LogMap
[TmpBlock
] = MS_LB_INITIAL_ERROR
;
213 us
->MS_Lib
.Phy2LogMap
[btBlk1st
] = MS_LB_BOOT_BLOCK
;
215 if (btBlk2nd
!= MS_LB_NOT_USED
)
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
;
222 result
= MS_LibScanLogicalBlockNumber(us
, btBlk1st
);
226 for (TmpBlock
=MS_PHYSICAL_BLOCKS_PER_SEGMENT
; TmpBlock
<us
->MS_Lib
.NumberOfPhyBlock
; TmpBlock
+=MS_PHYSICAL_BLOCKS_PER_SEGMENT
)
228 if (MS_CountFreeBlock(us
, TmpBlock
) == 0)
230 MS_LibCtrlSet(us
, MS_LIB_CTRL_WRPROTECT
);
236 if (MS_LibAllocWriteBuf(us
))
238 result
= MS_NO_MEMORY_ERROR
;
242 result
= MS_STATUS_SUCCESS
;
245 if (PageBuffer1
) kfree(PageBuffer1
);
246 if (PageBuffer0
) kfree(PageBuffer0
);
248 printk("MS_CardInit end\n");
252 //----- MS_LibCheckDisableBlock() ------------------------------------
253 int MS_LibCheckDisableBlock(struct us_data
*us
, WORD PhyBlock
)
256 DWORD result
=MS_STATUS_SUCCESS
;
258 MS_LibTypeExtdat extdat
;
260 if (((PageBuf
= kmalloc(MS_BYTES_PER_PAGE
, GFP_KERNEL
)) == NULL
))
262 result
= MS_NO_MEMORY_ERROR
;
266 MS_ReaderReadPage(us
, PhyBlock
, 1, (DWORD
*)PageBuf
, &extdat
);
269 blk
= BigEndianWORD(PageBuf
[index
]);
270 if (blk
== MS_LB_NOT_USED
)
272 if (blk
== us
->MS_Lib
.Log2PhyMap
[0])
274 result
= MS_ERROR_FLASH_READ
;
281 if (PageBuf
) kfree(PageBuf
);
285 //----- MS_LibFreeAllocatedArea() ------------------------------------
286 void MS_LibFreeAllocatedArea(struct us_data
*us
)
288 MS_LibFreeWriteBuf(us
);
289 MS_LibFreeLogicalMap(us
);
291 us
->MS_Lib
.flags
= 0;
292 us
->MS_Lib
.BytesPerSector
= 0;
293 us
->MS_Lib
.SectorsPerCylinder
= 0;
295 us
->MS_Lib
.cardType
= 0;
296 us
->MS_Lib
.blockSize
= 0;
297 us
->MS_Lib
.PagesPerBlock
= 0;
299 us
->MS_Lib
.NumberOfPhyBlock
= 0;
300 us
->MS_Lib
.NumberOfLogBlock
= 0;
303 //----- MS_LibFreeWriteBuf() -----------------------------------------
304 void MS_LibFreeWriteBuf(struct us_data
*us
)
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))
309 if (us
->MS_Lib
.blkpag
)
311 kfree((BYTE
*)(us
->MS_Lib
.blkpag
)); // Arnold test ...
312 us
->MS_Lib
.blkpag
= NULL
;
315 if (us
->MS_Lib
.blkext
)
317 kfree((BYTE
*)(us
->MS_Lib
.blkext
)); // Arnold test ...
318 us
->MS_Lib
.blkext
= NULL
;
322 //----- MS_LibFreeLogicalMap() ---------------------------------------
323 int MS_LibFreeLogicalMap(struct us_data
*us
)
325 if (us
->MS_Lib
.Phy2LogMap
)
327 kfree(us
->MS_Lib
.Phy2LogMap
);
328 us
->MS_Lib
.Phy2LogMap
= NULL
;
331 if (us
->MS_Lib
.Log2PhyMap
)
333 kfree(us
->MS_Lib
.Log2PhyMap
);
334 us
->MS_Lib
.Log2PhyMap
= NULL
;
340 //----- MS_LibProcessBootBlock() -------------------------------------
341 int MS_LibProcessBootBlock(struct us_data
*us
, WORD PhyBlock
, BYTE
*PageData
)
343 MemStickBootBlockSysEnt
*SysEntry
;
344 MemStickBootBlockSysInf
*SysInfo
;
348 MS_LibTypeExtdat ExtraData
;
350 if ((PageBuffer
= (BYTE
*)kmalloc(MS_BYTES_PER_PAGE
, GFP_KERNEL
))==NULL
)
355 SysInfo
= &(((MemStickBootBlockPage0
*)PageData
)->sysinf
);
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
))
366 switch (us
->MS_Lib
.cardType
= SysInfo
->bCardType
)
368 case MS_SYSINF_CARDTYPE_RDONLY
:
369 MS_LibCtrlSet(us
, MS_LIB_CTRL_RDONLY
);
371 case MS_SYSINF_CARDTYPE_RDWR
:
372 MS_LibCtrlReset(us
, MS_LIB_CTRL_RDONLY
);
374 case MS_SYSINF_CARDTYPE_HYBRID
:
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
);
386 if (MS_LibAllocLogicalMap(us
)) //Allocate to all number of logicalblock and physicalblock
389 MS_LibSetBootBlockMark(us
, PhyBlock
); //Mark the book block
391 SysEntry
= &(((MemStickBootBlockPage0
*)PageData
)->sysent
);
393 for (i
=0; i
<MS_NUMBER_OF_SYSTEM_ENTRY
; i
++)
395 DWORD EntryOffset
, EntrySize
;
397 if ((EntryOffset
= BigEndianDWORD(SysEntry
->entry
[i
].dwStart
)) == 0xffffff)
400 if ((EntrySize
= BigEndianDWORD(SysEntry
->entry
[i
].dwSize
)) == 0)
403 if (EntryOffset
+ MS_BYTES_PER_PAGE
+ EntrySize
> us
->MS_Lib
.blockSize
* (DWORD
)SIZE_OF_KIRO
)
408 BYTE PrevPageNumber
= 0;
411 if (SysEntry
->entry
[i
].bType
!= MS_SYSENT_TYPE_INVALID_BLOCK
)
414 while (EntrySize
> 0)
416 if ((PageNumber
= (BYTE
)(EntryOffset
/ MS_BYTES_PER_PAGE
+ 1)) != PrevPageNumber
)
418 switch (MS_ReaderReadPage(us
, PhyBlock
, PageNumber
, (DWORD
*)PageBuffer
, &ExtraData
))
420 case MS_STATUS_SUCCESS
:
422 case MS_STATUS_WRITE_PROTECT
:
423 case MS_ERROR_FLASH_READ
:
424 case MS_STATUS_ERROR
:
429 PrevPageNumber
= PageNumber
;
432 if ((phyblk
= BigEndianWORD(*(WORD
*)(PageBuffer
+ (EntryOffset
% MS_BYTES_PER_PAGE
)))) < 0x0fff)
433 MS_LibSetInitialErrorBlock(us
, phyblk
);
441 MemStickBootBlockIDI
*idi
;
443 if (SysEntry
->entry
[i
].bType
!= MS_SYSENT_TYPE_CIS_IDI
)
446 switch (MS_ReaderReadPage(us
, PhyBlock
, (BYTE
)(EntryOffset
/ MS_BYTES_PER_PAGE
+ 1), (DWORD
*)PageBuffer
, &ExtraData
))
448 case MS_STATUS_SUCCESS
:
450 case MS_STATUS_WRITE_PROTECT
:
451 case MS_ERROR_FLASH_READ
:
452 case MS_STATUS_ERROR
:
457 idi
= &((MemStickBootBlockCIS_IDI
*)(PageBuffer
+ (EntryOffset
% MS_BYTES_PER_PAGE
)))->idi
.idi
;
458 if (LittleEndianWORD(idi
->wIDIgeneralConfiguration
) != MS_IDI_GENERAL_CONF
)
461 us
->MS_Lib
.BytesPerSector
= LittleEndianWORD(idi
->wIDIbytesPerSector
);
462 if (us
->MS_Lib
.BytesPerSector
!= MS_BYTES_PER_PAGE
)
470 if (result
) MS_LibFreeLogicalMap(us
);
471 if (PageBuffer
) kfree(PageBuffer
);
477 //----- MS_LibAllocLogicalMap() --------------------------------------
478 int MS_LibAllocLogicalMap(struct us_data
*us
)
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
);
486 if ((us
->MS_Lib
.Phy2LogMap
== NULL
) || (us
->MS_Lib
.Log2PhyMap
== NULL
))
488 MS_LibFreeLogicalMap(us
);
492 for (i
= 0; i
< us
->MS_Lib
.NumberOfPhyBlock
; i
++)
493 us
->MS_Lib
.Phy2LogMap
[i
] = MS_LB_NOT_USED
;
495 for (i
= 0; i
< us
->MS_Lib
.NumberOfLogBlock
; i
++)
496 us
->MS_Lib
.Log2PhyMap
[i
] = MS_LB_NOT_USED
;
501 //----- MS_LibSetBootBlockMark() -------------------------------------
502 int MS_LibSetBootBlockMark(struct us_data
*us
, WORD phyblk
)
504 return MS_LibSetLogicalBlockMark(us
, phyblk
, MS_LB_BOOT_BLOCK
);
507 //----- MS_LibSetLogicalBlockMark() ----------------------------------
508 int MS_LibSetLogicalBlockMark(struct us_data
*us
, WORD phyblk
, WORD mark
)
510 if (phyblk
>= us
->MS_Lib
.NumberOfPhyBlock
)
513 us
->MS_Lib
.Phy2LogMap
[phyblk
] = mark
;
518 //----- MS_LibSetInitialErrorBlock() ---------------------------------
519 int MS_LibSetInitialErrorBlock(struct us_data
*us
, WORD phyblk
)
521 return MS_LibSetLogicalBlockMark(us
, phyblk
, MS_LB_INITIAL_ERROR
);
524 //----- MS_LibScanLogicalBlockNumber() -------------------------------
525 int MS_LibScanLogicalBlockNumber(struct us_data
*us
, WORD btBlk1st
)
527 WORD PhyBlock
, newblk
, i
;
528 WORD LogStart
, LogEnde
;
529 MS_LibTypeExtdat extdat
;
531 DWORD count
=0, index
=0;
533 for (PhyBlock
= 0; PhyBlock
< us
->MS_Lib
.NumberOfPhyBlock
;)
535 MS_LibPhy2LogRange(PhyBlock
, &LogStart
, &LogEnde
);
537 for (i
=0; i
<MS_PHYSICAL_BLOCKS_PER_SEGMENT
; i
++, PhyBlock
++)
539 switch (MS_LibConv2Logical(us
, PhyBlock
))
541 case MS_STATUS_ERROR
:
547 if (count
== PhyBlock
)
549 MS_LibReadExtraBlock(us
, PhyBlock
, 0, 0x80, &buf
);
552 index
= (PhyBlock
% 0x80) * 4;
554 extdat
.ovrflg
= buf
[index
];
555 extdat
.mngflg
= buf
[index
+1];
556 extdat
.logadr
= MemStickLogAddr(buf
[index
+2], buf
[index
+3]);
558 if ((extdat
.ovrflg
& MS_REG_OVR_BKST
) != MS_REG_OVR_BKST_OK
)
560 MS_LibSetAcquiredErrorBlock(us
, PhyBlock
);
564 if ((extdat
.mngflg
& MS_REG_MNG_ATFLG
) == MS_REG_MNG_ATFLG_ATTBL
)
566 MS_LibErasePhyBlock(us
, PhyBlock
);
570 if (extdat
.logadr
!= MS_LB_NOT_USED
)
572 if ((extdat
.logadr
< LogStart
) || (LogEnde
<= extdat
.logadr
))
574 MS_LibErasePhyBlock(us
, PhyBlock
);
578 if ((newblk
= MS_LibConv2Physical(us
, extdat
.logadr
)) != MS_LB_NOT_USED
)
580 if (extdat
.logadr
==0)
582 MS_LibSetLogicalPair(us
, extdat
.logadr
, PhyBlock
);
583 if ( MS_LibCheckDisableBlock(us
, btBlk1st
) )
585 MS_LibSetLogicalPair(us
, extdat
.logadr
, newblk
);
590 MS_LibReadExtra(us
, newblk
, 0, &extdat
);
591 if ((extdat
.ovrflg
& MS_REG_OVR_UDST
) == MS_REG_OVR_UDST_UPDATING
)
593 MS_LibErasePhyBlock(us
, PhyBlock
);
597 MS_LibErasePhyBlock(us
, newblk
);
600 MS_LibSetLogicalPair(us
, extdat
.logadr
, PhyBlock
);
605 return MS_STATUS_SUCCESS
;
608 //----- MS_LibAllocWriteBuf() ----------------------------------------
609 int MS_LibAllocWriteBuf(struct us_data
*us
)
611 us
->MS_Lib
.wrtblk
= (WORD
)-1;
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
);
616 if ((us
->MS_Lib
.blkpag
== NULL
) || (us
->MS_Lib
.blkext
== NULL
))
618 MS_LibFreeWriteBuf(us
);
622 MS_LibClearWriteBuf(us
);
627 //----- MS_LibClearWriteBuf() ----------------------------------------
628 void MS_LibClearWriteBuf(struct us_data
*us
)
632 us
->MS_Lib
.wrtblk
= (WORD
)-1;
633 MS_LibClearPageMap(us
);
635 if (us
->MS_Lib
.blkpag
)
636 memset(us
->MS_Lib
.blkpag
, 0xff, us
->MS_Lib
.PagesPerBlock
* us
->MS_Lib
.BytesPerSector
);
638 if (us
->MS_Lib
.blkext
)
640 for (i
= 0; i
< us
->MS_Lib
.PagesPerBlock
; i
++)
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
;
650 //----- MS_LibPhy2LogRange() -----------------------------------------
651 void MS_LibPhy2LogRange(WORD PhyBlock
, WORD
*LogStart
, WORD
*LogEnde
)
653 PhyBlock
/= MS_PHYSICAL_BLOCKS_PER_SEGMENT
;
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
663 *LogEnde
= MS_LOGICAL_BLOCKS_IN_1ST_SEGMENT
;//494
667 //----- MS_LibReadExtraBlock() --------------------------------------------
668 int MS_LibReadExtraBlock(struct us_data
*us
, DWORD PhyBlock
, BYTE PageNum
, BYTE blen
, void *buf
)
670 struct bulk_cb_wrap
*bcb
= (struct bulk_cb_wrap
*) us
->iobuf
;
673 //printk("MS_LibReadExtraBlock --- PhyBlock = %x, PageNum = %x, blen = %x\n", PhyBlock, PageNum, blen);
676 memset(bcb
, 0, sizeof(struct bulk_cb_wrap
));
677 bcb
->Signature
= cpu_to_le32(US_BULK_CB_SIGN
);
678 bcb
->DataTransferLength
= 0x4 * blen
;
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);
688 result
= ENE_SendScsiCmd(us
, FDIR_READ
, buf
, 0);
689 if (result
!= USB_STOR_XFER_GOOD
)
690 return USB_STOR_TRANSPORT_ERROR
;
692 return USB_STOR_TRANSPORT_GOOD
;
695 //----- MS_LibReadExtra() --------------------------------------------
696 int MS_LibReadExtra(struct us_data
*us
, DWORD PhyBlock
, BYTE PageNum
, MS_LibTypeExtdat
*ExtraDat
)
698 struct bulk_cb_wrap
*bcb
= (struct bulk_cb_wrap
*) us
->iobuf
;
702 //printk("MS_LibReadExtra --- PhyBlock = %x, PageNum = %x\n", PhyBlock, PageNum);
703 memset(bcb
, 0, sizeof(struct bulk_cb_wrap
));
704 bcb
->Signature
= cpu_to_le32(US_BULK_CB_SIGN
);
705 bcb
->DataTransferLength
= 0x4;
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);
715 result
= ENE_SendScsiCmd(us
, FDIR_READ
, &ExtBuf
, 0);
716 if (result
!= USB_STOR_XFER_GOOD
)
717 return USB_STOR_TRANSPORT_ERROR
;
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]);
727 return USB_STOR_TRANSPORT_GOOD
;
730 //----- MS_LibSetAcquiredErrorBlock() --------------------------------
731 int MS_LibSetAcquiredErrorBlock(struct us_data
*us
, WORD phyblk
)
735 if (phyblk
>= us
->MS_Lib
.NumberOfPhyBlock
)
738 if ((log
= us
->MS_Lib
.Phy2LogMap
[phyblk
]) < us
->MS_Lib
.NumberOfLogBlock
)
739 us
->MS_Lib
.Log2PhyMap
[log
] = MS_LB_NOT_USED
;
741 if (us
->MS_Lib
.Phy2LogMap
[phyblk
] != MS_LB_INITIAL_ERROR
)
742 us
->MS_Lib
.Phy2LogMap
[phyblk
] = MS_LB_ACQUIRED_ERROR
;
747 //----- MS_LibErasePhyBlock() ----------------------------------------
748 int MS_LibErasePhyBlock(struct us_data
*us
, WORD phyblk
)
752 if (phyblk
>= us
->MS_Lib
.NumberOfPhyBlock
)
753 return MS_STATUS_ERROR
;
755 if ((log
= us
->MS_Lib
.Phy2LogMap
[phyblk
]) < us
->MS_Lib
.NumberOfLogBlock
)
756 us
->MS_Lib
.Log2PhyMap
[log
] = MS_LB_NOT_USED
;
758 us
->MS_Lib
.Phy2LogMap
[phyblk
] = MS_LB_NOT_USED
;
760 if (MS_LibIsWritable(us
))
762 switch (MS_ReaderEraseBlock(us
, phyblk
))
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
:
773 MS_LibCtrlSet(us
, MS_LIB_CTRL_RDONLY
);
774 MS_LibSetAcquiredErrorBlock(us
, phyblk
);
775 return MS_STATUS_ERROR
;
779 MS_LibSetAcquiredErrorBlock(us
, phyblk
);
781 return MS_STATUS_SUCCESS
;
784 //----- MS_LibErrorPhyBlock() ----------------------------------------
785 int MS_LibErrorPhyBlock(struct us_data
*us
, WORD phyblk
)
787 if (phyblk
>= us
->MS_Lib
.NumberOfPhyBlock
)
788 return MS_STATUS_ERROR
;
790 MS_LibSetAcquiredErrorBlock(us
, phyblk
);
792 if (MS_LibIsWritable(us
))
793 return MS_LibOverwriteExtra(us
, phyblk
, 0, (BYTE
)(~MS_REG_OVR_BKST
));
796 return MS_STATUS_SUCCESS
;
799 //----- MS_LibOverwriteExtra() ---------------------------------------
800 int MS_LibOverwriteExtra(struct us_data
*us
, DWORD PhyBlockAddr
, BYTE PageNum
, BYTE OverwriteFlag
)
802 struct bulk_cb_wrap
*bcb
= (struct bulk_cb_wrap
*) us
->iobuf
;
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
;
810 memset(bcb
, 0, sizeof(struct bulk_cb_wrap
));
811 bcb
->Signature
= cpu_to_le32(US_BULK_CB_SIGN
);
812 bcb
->DataTransferLength
= 0x4;
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
;
825 result
= ENE_SendScsiCmd(us
, FDIR_READ
, NULL
, 0);
826 if (result
!= USB_STOR_XFER_GOOD
)
827 return USB_STOR_TRANSPORT_ERROR
;
829 return USB_STOR_TRANSPORT_GOOD
;
832 //----- MS_LibForceSetLogicalPair() ----------------------------------
833 int MS_LibForceSetLogicalPair(struct us_data
*us
, WORD logblk
, WORD phyblk
)
835 if (logblk
== MS_LB_NOT_USED
)
838 if ((logblk
>= us
->MS_Lib
.NumberOfLogBlock
) || (phyblk
>= us
->MS_Lib
.NumberOfPhyBlock
))
841 us
->MS_Lib
.Phy2LogMap
[phyblk
] = logblk
;
842 us
->MS_Lib
.Log2PhyMap
[logblk
] = phyblk
;
847 //----- MS_LibSetLogicalPair() ---------------------------------------
848 int MS_LibSetLogicalPair(struct us_data
*us
, WORD logblk
, WORD phyblk
)
850 if ((logblk
>= us
->MS_Lib
.NumberOfLogBlock
) || (phyblk
>= us
->MS_Lib
.NumberOfPhyBlock
))
853 us
->MS_Lib
.Phy2LogMap
[phyblk
] = logblk
;
854 us
->MS_Lib
.Log2PhyMap
[logblk
] = phyblk
;
859 //----- MS_CountFreeBlock() ------------------------------------------
860 int MS_CountFreeBlock(struct us_data
*us
, WORD PhyBlock
)
864 Ende
= PhyBlock
+ MS_PHYSICAL_BLOCKS_PER_SEGMENT
;
865 for (Count
= 0; PhyBlock
< Ende
; PhyBlock
++)
867 switch (us
->MS_Lib
.Phy2LogMap
[PhyBlock
])
870 case MS_LB_NOT_USED_ERASED
:
880 //----- MS_LibSearchBlockFromPhysical() ------------------------------
881 int MS_LibSearchBlockFromPhysical(struct us_data
*us
, WORD phyblk
)
885 MS_LibTypeExtdat extdat
;
887 if (phyblk
>= us
->MS_Lib
.NumberOfPhyBlock
)
890 for (blk
= phyblk
+ 1; blk
!= phyblk
; blk
++)
892 if ((blk
& MS_PHYSICAL_BLOCKS_PER_SEGMENT_MASK
) == 0)
893 blk
-= MS_PHYSICAL_BLOCKS_PER_SEGMENT
;
895 Newblk
= us
->MS_Lib
.Phy2LogMap
[blk
];
896 if (us
->MS_Lib
.Phy2LogMap
[blk
] == MS_LB_NOT_USED_ERASED
)
898 else if (us
->MS_Lib
.Phy2LogMap
[blk
] == MS_LB_NOT_USED
)
900 switch (MS_LibReadExtra(us
, blk
, 0, &extdat
))
902 case MS_STATUS_SUCCESS
:
903 case MS_STATUS_SUCCESS_WITH_ECC
:
905 case MS_NOCARD_ERROR
:
906 return MS_NOCARD_ERROR
;
907 case MS_STATUS_INT_ERROR
:
909 case MS_ERROR_FLASH_READ
:
911 MS_LibSetAcquiredErrorBlock(us
, blk
); // MS_LibErrorPhyBlock(fdoExt, blk);
915 if ((extdat
.ovrflg
& MS_REG_OVR_BKST
) != MS_REG_OVR_BKST_OK
)
917 MS_LibSetAcquiredErrorBlock(us
, blk
);
921 switch (MS_LibErasePhyBlock(us
, blk
))
923 case MS_STATUS_SUCCESS
:
925 case MS_STATUS_ERROR
:
927 case MS_ERROR_FLASH_ERASE
:
929 MS_LibErrorPhyBlock(us
, blk
);
938 //----- MS_LibSearchBlockFromLogical() -------------------------------
939 int MS_LibSearchBlockFromLogical(struct us_data
*us
, WORD logblk
)
943 if ((phyblk
=MS_LibConv2Physical(us
, logblk
)) >= MS_LB_ERROR
)
945 if (logblk
>= us
->MS_Lib
.NumberOfLogBlock
)
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;
953 return MS_LibSearchBlockFromPhysical(us
, phyblk
);