1 #include <linux/slab.h>
2 #include <asm/byteorder.h>
10 * MS_ReaderCopyBlock()
12 int MS_ReaderCopyBlock(struct us_data
*us
, WORD oldphy
, WORD newphy
,
13 WORD PhyBlockAddr
, BYTE PageNum
, PBYTE buf
, WORD len
)
15 struct bulk_cb_wrap
*bcb
= (struct bulk_cb_wrap
*) us
->iobuf
;
18 /* printk(KERN_INFO "MS_ReaderCopyBlock --- PhyBlockAddr = %x,
19 PageNum = %x\n", PhyBlockAddr, PageNum); */
20 result
= ENE_LoadBinCode(us
, MS_RW_PATTERN
);
21 if (result
!= USB_STOR_XFER_GOOD
)
22 return USB_STOR_TRANSPORT_ERROR
;
24 memset(bcb
, 0, sizeof(struct bulk_cb_wrap
));
25 bcb
->Signature
= cpu_to_le32(US_BULK_CB_SIGN
);
26 bcb
->DataTransferLength
= 0x200*len
;
30 bcb
->CDB
[4] = (BYTE
)(oldphy
);
31 bcb
->CDB
[3] = (BYTE
)(oldphy
>>8);
32 bcb
->CDB
[2] = 0; /* (BYTE)(oldphy>>16) */
33 bcb
->CDB
[7] = (BYTE
)(newphy
);
34 bcb
->CDB
[6] = (BYTE
)(newphy
>>8);
35 bcb
->CDB
[5] = 0; /* (BYTE)(newphy>>16) */
36 bcb
->CDB
[9] = (BYTE
)(PhyBlockAddr
);
37 bcb
->CDB
[8] = (BYTE
)(PhyBlockAddr
>>8);
38 bcb
->CDB
[10] = PageNum
;
40 result
= ENE_SendScsiCmd(us
, FDIR_WRITE
, buf
, 0);
41 if (result
!= USB_STOR_XFER_GOOD
)
42 return USB_STOR_TRANSPORT_ERROR
;
44 return USB_STOR_TRANSPORT_GOOD
;
50 int MS_ReaderReadPage(struct us_data
*us
, DWORD PhyBlockAddr
,
51 BYTE PageNum
, PDWORD PageBuf
, MS_LibTypeExtdat
*ExtraDat
)
53 struct bulk_cb_wrap
*bcb
= (struct bulk_cb_wrap
*) us
->iobuf
;
56 DWORD bn
= PhyBlockAddr
* 0x20 + PageNum
;
58 /* printk(KERN_INFO "MS --- MS_ReaderReadPage,
59 PhyBlockAddr = %x, PageNum = %x\n", PhyBlockAddr, PageNum); */
61 result
= ENE_LoadBinCode(us
, MS_RW_PATTERN
);
62 if (result
!= USB_STOR_XFER_GOOD
)
63 return USB_STOR_TRANSPORT_ERROR
;
66 memset(bcb
, 0, sizeof(struct bulk_cb_wrap
));
67 bcb
->Signature
= cpu_to_le32(US_BULK_CB_SIGN
);
68 bcb
->DataTransferLength
= 0x200;
72 bcb
->CDB
[5] = (BYTE
)(bn
);
73 bcb
->CDB
[4] = (BYTE
)(bn
>>8);
74 bcb
->CDB
[3] = (BYTE
)(bn
>>16);
75 bcb
->CDB
[2] = (BYTE
)(bn
>>24);
77 result
= ENE_SendScsiCmd(us
, FDIR_READ
, PageBuf
, 0);
78 if (result
!= USB_STOR_XFER_GOOD
)
79 return USB_STOR_TRANSPORT_ERROR
;
82 memset(bcb
, 0, sizeof(struct bulk_cb_wrap
));
83 bcb
->Signature
= cpu_to_le32(US_BULK_CB_SIGN
);
84 bcb
->DataTransferLength
= 0x4;
88 bcb
->CDB
[5] = (BYTE
)(PageNum
);
89 bcb
->CDB
[4] = (BYTE
)(PhyBlockAddr
);
90 bcb
->CDB
[3] = (BYTE
)(PhyBlockAddr
>>8);
91 bcb
->CDB
[2] = (BYTE
)(PhyBlockAddr
>>16);
94 result
= ENE_SendScsiCmd(us
, FDIR_READ
, &ExtBuf
, 0);
95 if (result
!= USB_STOR_XFER_GOOD
)
96 return USB_STOR_TRANSPORT_ERROR
;
98 ExtraDat
->reserved
= 0;
99 ExtraDat
->intr
= 0x80; /* Not yet,fireware support */
100 ExtraDat
->status0
= 0x10; /* Not yet,fireware support */
101 ExtraDat
->status1
= 0x00; /* Not yet,fireware support */
102 ExtraDat
->ovrflg
= ExtBuf
[0];
103 ExtraDat
->mngflg
= ExtBuf
[1];
104 ExtraDat
->logadr
= MemStickLogAddr(ExtBuf
[2], ExtBuf
[3]);
106 return USB_STOR_TRANSPORT_GOOD
;
110 * MS_ReaderEraseBlock()
112 int MS_ReaderEraseBlock(struct us_data
*us
, DWORD PhyBlockAddr
)
114 struct bulk_cb_wrap
*bcb
= (struct bulk_cb_wrap
*) us
->iobuf
;
116 DWORD bn
= PhyBlockAddr
;
118 /* printk(KERN_INFO "MS --- MS_ReaderEraseBlock,
119 PhyBlockAddr = %x\n", PhyBlockAddr); */
120 result
= ENE_LoadBinCode(us
, MS_RW_PATTERN
);
121 if (result
!= USB_STOR_XFER_GOOD
)
122 return USB_STOR_TRANSPORT_ERROR
;
124 memset(bcb
, 0, sizeof(struct bulk_cb_wrap
));
125 bcb
->Signature
= cpu_to_le32(US_BULK_CB_SIGN
);
126 bcb
->DataTransferLength
= 0x200;
130 bcb
->CDB
[4] = (BYTE
)(bn
);
131 bcb
->CDB
[3] = (BYTE
)(bn
>>8);
132 bcb
->CDB
[2] = (BYTE
)(bn
>>16);
134 result
= ENE_SendScsiCmd(us
, FDIR_READ
, NULL
, 0);
135 if (result
!= USB_STOR_XFER_GOOD
)
136 return USB_STOR_TRANSPORT_ERROR
;
138 return USB_STOR_TRANSPORT_GOOD
;
144 int MS_CardInit(struct us_data
*us
)
148 PBYTE PageBuffer0
= NULL
, PageBuffer1
= NULL
;
149 MS_LibTypeExtdat extdat
;
150 WORD btBlk1st
, btBlk2nd
;
153 printk(KERN_INFO
"MS_CardInit start\n");
155 MS_LibFreeAllocatedArea(us
);
157 PageBuffer0
= kmalloc(MS_BYTES_PER_PAGE
, GFP_KERNEL
);
158 PageBuffer1
= kmalloc(MS_BYTES_PER_PAGE
, GFP_KERNEL
);
159 if ((PageBuffer0
== NULL
) || (PageBuffer1
== NULL
)) {
160 result
= MS_NO_MEMORY_ERROR
;
164 btBlk1st
= btBlk2nd
= MS_LB_NOT_USED
;
167 for (TmpBlock
= 0; TmpBlock
< MS_MAX_INITIAL_ERROR_BLOCKS
+2;
169 switch (MS_ReaderReadPage(us
, TmpBlock
, 0,
170 (DWORD
*)PageBuffer0
, &extdat
)) {
171 case MS_STATUS_SUCCESS
:
173 case MS_STATUS_INT_ERROR
:
175 case MS_STATUS_ERROR
:
180 if ((extdat
.ovrflg
& MS_REG_OVR_BKST
) == MS_REG_OVR_BKST_NG
)
183 if (((extdat
.mngflg
& MS_REG_MNG_SYSFLG
) == MS_REG_MNG_SYSFLG_USER
) ||
184 (be16_to_cpu(((MemStickBootBlockPage0
*)PageBuffer0
)->header
.wBlockID
) != MS_BOOT_BLOCK_ID
) ||
185 (be16_to_cpu(((MemStickBootBlockPage0
*)PageBuffer0
)->header
.wFormatVersion
) != MS_BOOT_BLOCK_FORMAT_VERSION
) ||
186 (((MemStickBootBlockPage0
*)PageBuffer0
)->header
.bNumberOfDataEntry
!= MS_BOOT_BLOCK_DATA_ENTRIES
))
189 if (btBlk1st
!= MS_LB_NOT_USED
) {
195 memcpy(PageBuffer1
, PageBuffer0
, MS_BYTES_PER_PAGE
);
197 (MS_REG_ST1_DTER
| MS_REG_ST1_EXER
| MS_REG_ST1_FGER
))
201 if (btBlk1st
== MS_LB_NOT_USED
) {
202 result
= MS_STATUS_ERROR
;
207 if ((extdat
.status0
& MS_REG_ST0_WP
) == MS_REG_ST0_WP_ON
)
208 MS_LibCtrlSet(us
, MS_LIB_CTRL_WRPROTECT
);
210 result
= MS_STATUS_ERROR
;
212 if (btBlk1stErred
== 0)
213 result
= MS_LibProcessBootBlock(us
, btBlk1st
, PageBuffer1
);
216 if (result
&& (btBlk2nd
!= MS_LB_NOT_USED
))
217 result
= MS_LibProcessBootBlock(us
, btBlk2nd
, PageBuffer0
);
220 result
= MS_STATUS_ERROR
;
224 for (TmpBlock
= 0; TmpBlock
< btBlk1st
; TmpBlock
++)
225 us
->MS_Lib
.Phy2LogMap
[TmpBlock
] = MS_LB_INITIAL_ERROR
;
227 us
->MS_Lib
.Phy2LogMap
[btBlk1st
] = MS_LB_BOOT_BLOCK
;
229 if (btBlk2nd
!= MS_LB_NOT_USED
) {
230 for (TmpBlock
= btBlk1st
+ 1; TmpBlock
< btBlk2nd
; TmpBlock
++)
231 us
->MS_Lib
.Phy2LogMap
[TmpBlock
] = MS_LB_INITIAL_ERROR
;
232 us
->MS_Lib
.Phy2LogMap
[btBlk2nd
] = MS_LB_BOOT_BLOCK
;
235 result
= MS_LibScanLogicalBlockNumber(us
, btBlk1st
);
239 for (TmpBlock
= MS_PHYSICAL_BLOCKS_PER_SEGMENT
;
240 TmpBlock
< us
->MS_Lib
.NumberOfPhyBlock
;
241 TmpBlock
+= MS_PHYSICAL_BLOCKS_PER_SEGMENT
) {
242 if (MS_CountFreeBlock(us
, TmpBlock
) == 0) {
243 MS_LibCtrlSet(us
, MS_LIB_CTRL_WRPROTECT
);
249 if (MS_LibAllocWriteBuf(us
)) {
250 result
= MS_NO_MEMORY_ERROR
;
254 result
= MS_STATUS_SUCCESS
;
260 printk(KERN_INFO
"MS_CardInit end\n");
265 * MS_LibCheckDisableBlock()
267 int MS_LibCheckDisableBlock(struct us_data
*us
, WORD PhyBlock
)
269 PWORD PageBuf
= NULL
;
270 DWORD result
= MS_STATUS_SUCCESS
;
271 DWORD blk
, index
= 0;
272 MS_LibTypeExtdat extdat
;
274 PageBuf
= kmalloc(MS_BYTES_PER_PAGE
, GFP_KERNEL
);
275 if (PageBuf
== NULL
) {
276 result
= MS_NO_MEMORY_ERROR
;
280 MS_ReaderReadPage(us
, PhyBlock
, 1, (DWORD
*)PageBuf
, &extdat
);
282 blk
= be16_to_cpu(PageBuf
[index
]);
283 if (blk
== MS_LB_NOT_USED
)
285 if (blk
== us
->MS_Lib
.Log2PhyMap
[0]) {
286 result
= MS_ERROR_FLASH_READ
;
298 * MS_LibFreeAllocatedArea()
300 void MS_LibFreeAllocatedArea(struct us_data
*us
)
302 MS_LibFreeWriteBuf(us
);
303 MS_LibFreeLogicalMap(us
);
305 us
->MS_Lib
.flags
= 0;
306 us
->MS_Lib
.BytesPerSector
= 0;
307 us
->MS_Lib
.SectorsPerCylinder
= 0;
309 us
->MS_Lib
.cardType
= 0;
310 us
->MS_Lib
.blockSize
= 0;
311 us
->MS_Lib
.PagesPerBlock
= 0;
313 us
->MS_Lib
.NumberOfPhyBlock
= 0;
314 us
->MS_Lib
.NumberOfLogBlock
= 0;
318 * MS_LibFreeWriteBuf()
320 void MS_LibFreeWriteBuf(struct us_data
*us
)
322 us
->MS_Lib
.wrtblk
= (WORD
)-1; /* set to -1 */
324 /* memset((fdoExt)->MS_Lib.pagemap, 0,
325 sizeof((fdoExt)->MS_Lib.pagemap)) */
326 MS_LibClearPageMap(us
);
328 if (us
->MS_Lib
.blkpag
) {
329 kfree((BYTE
*)(us
->MS_Lib
.blkpag
)); /* Arnold test ... */
330 us
->MS_Lib
.blkpag
= NULL
;
333 if (us
->MS_Lib
.blkext
) {
334 kfree((BYTE
*)(us
->MS_Lib
.blkext
)); /* Arnold test ... */
335 us
->MS_Lib
.blkext
= NULL
;
340 * MS_LibFreeLogicalMap()
342 int MS_LibFreeLogicalMap(struct us_data
*us
)
344 kfree(us
->MS_Lib
.Phy2LogMap
);
345 us
->MS_Lib
.Phy2LogMap
= NULL
;
347 kfree(us
->MS_Lib
.Log2PhyMap
);
348 us
->MS_Lib
.Log2PhyMap
= NULL
;
354 * MS_LibProcessBootBlock()
356 int MS_LibProcessBootBlock(struct us_data
*us
, WORD PhyBlock
, BYTE
*PageData
)
358 MemStickBootBlockSysEnt
*SysEntry
;
359 MemStickBootBlockSysInf
*SysInfo
;
363 MS_LibTypeExtdat ExtraData
;
366 PageBuffer
= kmalloc(MS_BYTES_PER_PAGE
, GFP_KERNEL
);
367 if (PageBuffer
== NULL
)
372 SysInfo
= &(((MemStickBootBlockPage0
*)PageData
)->sysinf
);
374 if ((SysInfo
->bMsClass
!= MS_SYSINF_MSCLASS_TYPE_1
) ||
375 (be16_to_cpu(SysInfo
->wPageSize
) != MS_SYSINF_PAGE_SIZE
) ||
376 ((SysInfo
->bSecuritySupport
& MS_SYSINF_SECURITY
) == MS_SYSINF_SECURITY_SUPPORT
) ||
377 (SysInfo
->bReserved1
!= MS_SYSINF_RESERVED1
) ||
378 (SysInfo
->bReserved2
!= MS_SYSINF_RESERVED2
) ||
379 (SysInfo
->bFormatType
!= MS_SYSINF_FORMAT_FAT
) ||
380 (SysInfo
->bUsage
!= MS_SYSINF_USAGE_GENERAL
))
383 switch (us
->MS_Lib
.cardType
= SysInfo
->bCardType
) {
384 case MS_SYSINF_CARDTYPE_RDONLY
:
385 MS_LibCtrlSet(us
, MS_LIB_CTRL_RDONLY
);
387 case MS_SYSINF_CARDTYPE_RDWR
:
388 MS_LibCtrlReset(us
, MS_LIB_CTRL_RDONLY
);
390 case MS_SYSINF_CARDTYPE_HYBRID
:
395 us
->MS_Lib
.blockSize
= be16_to_cpu(SysInfo
->wBlockSize
);
396 us
->MS_Lib
.NumberOfPhyBlock
= be16_to_cpu(SysInfo
->wBlockNumber
);
397 us
->MS_Lib
.NumberOfLogBlock
= be16_to_cpu(SysInfo
->wTotalBlockNumber
)
399 us
->MS_Lib
.PagesPerBlock
= us
->MS_Lib
.blockSize
* SIZE_OF_KIRO
/
401 us
->MS_Lib
.NumberOfSegment
= us
->MS_Lib
.NumberOfPhyBlock
/
402 MS_PHYSICAL_BLOCKS_PER_SEGMENT
;
403 us
->MS_Model
= be16_to_cpu(SysInfo
->wMemorySize
);
405 /*Allocate to all number of logicalblock and physicalblock */
406 if (MS_LibAllocLogicalMap(us
))
409 /* Mark the book block */
410 MS_LibSetBootBlockMark(us
, PhyBlock
);
412 SysEntry
= &(((MemStickBootBlockPage0
*)PageData
)->sysent
);
414 for (i
= 0; i
< MS_NUMBER_OF_SYSTEM_ENTRY
; i
++) {
415 DWORD EntryOffset
, EntrySize
;
417 EntryOffset
= be32_to_cpu(SysEntry
->entry
[i
].dwStart
);
419 if (EntryOffset
== 0xffffff)
421 EntrySize
= be32_to_cpu(SysEntry
->entry
[i
].dwSize
);
426 if (EntryOffset
+ MS_BYTES_PER_PAGE
+ EntrySize
>
427 us
->MS_Lib
.blockSize
* (DWORD
)SIZE_OF_KIRO
)
431 BYTE PrevPageNumber
= 0;
434 if (SysEntry
->entry
[i
].bType
!=
435 MS_SYSENT_TYPE_INVALID_BLOCK
)
438 while (EntrySize
> 0) {
440 PageNumber
= (BYTE
)(EntryOffset
/
441 MS_BYTES_PER_PAGE
+ 1);
442 if (PageNumber
!= PrevPageNumber
) {
443 switch (MS_ReaderReadPage(us
, PhyBlock
,
444 PageNumber
, (DWORD
*)PageBuffer
,
446 case MS_STATUS_SUCCESS
:
448 case MS_STATUS_WRITE_PROTECT
:
449 case MS_ERROR_FLASH_READ
:
450 case MS_STATUS_ERROR
:
455 PrevPageNumber
= PageNumber
;
458 phyblk
= be16_to_cpu(*(WORD
*)(PageBuffer
+
459 (EntryOffset
% MS_BYTES_PER_PAGE
)));
461 MS_LibSetInitialErrorBlock(us
, phyblk
);
466 } else if (i
== 1) { /* CIS/IDI */
467 MemStickBootBlockIDI
*idi
;
469 if (SysEntry
->entry
[i
].bType
!= MS_SYSENT_TYPE_CIS_IDI
)
472 switch (MS_ReaderReadPage(us
, PhyBlock
,
473 (BYTE
)(EntryOffset
/ MS_BYTES_PER_PAGE
+ 1),
474 (DWORD
*)PageBuffer
, &ExtraData
)) {
475 case MS_STATUS_SUCCESS
:
477 case MS_STATUS_WRITE_PROTECT
:
478 case MS_ERROR_FLASH_READ
:
479 case MS_STATUS_ERROR
:
484 idi
= &((MemStickBootBlockCIS_IDI
*)(PageBuffer
+
485 (EntryOffset
% MS_BYTES_PER_PAGE
)))->idi
.idi
;
486 if (le16_to_cpu(idi
->wIDIgeneralConfiguration
) !=
490 us
->MS_Lib
.BytesPerSector
=
491 le16_to_cpu(idi
->wIDIbytesPerSector
);
492 if (us
->MS_Lib
.BytesPerSector
!= MS_BYTES_PER_PAGE
)
501 MS_LibFreeLogicalMap(us
);
510 * MS_LibAllocLogicalMap()
512 int MS_LibAllocLogicalMap(struct us_data
*us
)
517 us
->MS_Lib
.Phy2LogMap
= kmalloc(us
->MS_Lib
.NumberOfPhyBlock
*
518 sizeof(WORD
), GFP_KERNEL
);
519 us
->MS_Lib
.Log2PhyMap
= kmalloc(us
->MS_Lib
.NumberOfLogBlock
*
520 sizeof(WORD
), GFP_KERNEL
);
522 if ((us
->MS_Lib
.Phy2LogMap
== NULL
) ||
523 (us
->MS_Lib
.Log2PhyMap
== NULL
)) {
524 MS_LibFreeLogicalMap(us
);
528 for (i
= 0; i
< us
->MS_Lib
.NumberOfPhyBlock
; i
++)
529 us
->MS_Lib
.Phy2LogMap
[i
] = MS_LB_NOT_USED
;
531 for (i
= 0; i
< us
->MS_Lib
.NumberOfLogBlock
; i
++)
532 us
->MS_Lib
.Log2PhyMap
[i
] = MS_LB_NOT_USED
;
538 * MS_LibSetBootBlockMark()
540 int MS_LibSetBootBlockMark(struct us_data
*us
, WORD phyblk
)
542 return MS_LibSetLogicalBlockMark(us
, phyblk
, MS_LB_BOOT_BLOCK
);
546 * MS_LibSetLogicalBlockMark()
548 int MS_LibSetLogicalBlockMark(struct us_data
*us
, WORD phyblk
, WORD mark
)
550 if (phyblk
>= us
->MS_Lib
.NumberOfPhyBlock
)
553 us
->MS_Lib
.Phy2LogMap
[phyblk
] = mark
;
559 * MS_LibSetInitialErrorBlock()
561 int MS_LibSetInitialErrorBlock(struct us_data
*us
, WORD phyblk
)
563 return MS_LibSetLogicalBlockMark(us
, phyblk
, MS_LB_INITIAL_ERROR
);
567 * MS_LibScanLogicalBlockNumber()
569 int MS_LibScanLogicalBlockNumber(struct us_data
*us
, WORD btBlk1st
)
571 WORD PhyBlock
, newblk
, i
;
572 WORD LogStart
, LogEnde
;
573 MS_LibTypeExtdat extdat
;
575 DWORD count
= 0, index
= 0;
577 for (PhyBlock
= 0; PhyBlock
< us
->MS_Lib
.NumberOfPhyBlock
;) {
578 MS_LibPhy2LogRange(PhyBlock
, &LogStart
, &LogEnde
);
580 for (i
= 0; i
< MS_PHYSICAL_BLOCKS_PER_SEGMENT
;
582 switch (MS_LibConv2Logical(us
, PhyBlock
)) {
583 case MS_STATUS_ERROR
:
589 if (count
== PhyBlock
) {
590 MS_LibReadExtraBlock(us
, PhyBlock
,
594 index
= (PhyBlock
% 0x80) * 4;
596 extdat
.ovrflg
= buf
[index
];
597 extdat
.mngflg
= buf
[index
+1];
598 extdat
.logadr
= MemStickLogAddr(buf
[index
+2],
601 if ((extdat
.ovrflg
& MS_REG_OVR_BKST
) !=
602 MS_REG_OVR_BKST_OK
) {
603 MS_LibSetAcquiredErrorBlock(us
, PhyBlock
);
607 if ((extdat
.mngflg
& MS_REG_MNG_ATFLG
) ==
608 MS_REG_MNG_ATFLG_ATTBL
) {
609 MS_LibErasePhyBlock(us
, PhyBlock
);
613 if (extdat
.logadr
!= MS_LB_NOT_USED
) {
614 if ((extdat
.logadr
< LogStart
) ||
615 (LogEnde
<= extdat
.logadr
)) {
616 MS_LibErasePhyBlock(us
, PhyBlock
);
620 newblk
= MS_LibConv2Physical(us
, extdat
.logadr
);
622 if (newblk
!= MS_LB_NOT_USED
) {
623 if (extdat
.logadr
== 0) {
624 MS_LibSetLogicalPair(us
,
627 if (MS_LibCheckDisableBlock(us
,
629 MS_LibSetLogicalPair(us
,
630 extdat
.logadr
, newblk
);
635 MS_LibReadExtra(us
, newblk
, 0, &extdat
);
636 if ((extdat
.ovrflg
& MS_REG_OVR_UDST
) ==
637 MS_REG_OVR_UDST_UPDATING
) {
638 MS_LibErasePhyBlock(us
,
642 MS_LibErasePhyBlock(us
, newblk
);
646 MS_LibSetLogicalPair(us
, extdat
.logadr
,
652 return MS_STATUS_SUCCESS
;
656 * MS_LibAllocWriteBuf()
658 int MS_LibAllocWriteBuf(struct us_data
*us
)
660 us
->MS_Lib
.wrtblk
= (WORD
)-1;
662 us
->MS_Lib
.blkpag
= kmalloc(us
->MS_Lib
.PagesPerBlock
*
663 us
->MS_Lib
.BytesPerSector
, GFP_KERNEL
);
664 us
->MS_Lib
.blkext
= kmalloc(us
->MS_Lib
.PagesPerBlock
*
665 sizeof(MS_LibTypeExtdat
), GFP_KERNEL
);
667 if ((us
->MS_Lib
.blkpag
== NULL
) || (us
->MS_Lib
.blkext
== NULL
)) {
668 MS_LibFreeWriteBuf(us
);
672 MS_LibClearWriteBuf(us
);
678 * MS_LibClearWriteBuf()
680 void MS_LibClearWriteBuf(struct us_data
*us
)
684 us
->MS_Lib
.wrtblk
= (WORD
)-1;
685 MS_LibClearPageMap(us
);
687 if (us
->MS_Lib
.blkpag
)
688 memset(us
->MS_Lib
.blkpag
, 0xff,
689 us
->MS_Lib
.PagesPerBlock
* us
->MS_Lib
.BytesPerSector
);
691 if (us
->MS_Lib
.blkext
) {
692 for (i
= 0; i
< us
->MS_Lib
.PagesPerBlock
; i
++) {
693 us
->MS_Lib
.blkext
[i
].status1
= MS_REG_ST1_DEFAULT
;
694 us
->MS_Lib
.blkext
[i
].ovrflg
= MS_REG_OVR_DEFAULT
;
695 us
->MS_Lib
.blkext
[i
].mngflg
= MS_REG_MNG_DEFAULT
;
696 us
->MS_Lib
.blkext
[i
].logadr
= MS_LB_NOT_USED
;
702 * MS_LibPhy2LogRange()
704 void MS_LibPhy2LogRange(WORD PhyBlock
, WORD
*LogStart
, WORD
*LogEnde
)
706 PhyBlock
/= MS_PHYSICAL_BLOCKS_PER_SEGMENT
;
709 *LogStart
= MS_LOGICAL_BLOCKS_IN_1ST_SEGMENT
+
710 (PhyBlock
- 1) * MS_LOGICAL_BLOCKS_PER_SEGMENT
;/*496*/
711 *LogEnde
= *LogStart
+ MS_LOGICAL_BLOCKS_PER_SEGMENT
;/*496*/
714 *LogEnde
= MS_LOGICAL_BLOCKS_IN_1ST_SEGMENT
;/*494*/
719 * MS_LibReadExtraBlock()
721 int MS_LibReadExtraBlock(struct us_data
*us
, DWORD PhyBlock
,
722 BYTE PageNum
, BYTE blen
, void *buf
)
724 struct bulk_cb_wrap
*bcb
= (struct bulk_cb_wrap
*) us
->iobuf
;
727 /* printk("MS_LibReadExtraBlock --- PhyBlock = %x,
728 PageNum = %x, blen = %x\n", PhyBlock, PageNum, blen); */
730 /* Read Extra Data */
731 memset(bcb
, 0, sizeof(struct bulk_cb_wrap
));
732 bcb
->Signature
= cpu_to_le32(US_BULK_CB_SIGN
);
733 bcb
->DataTransferLength
= 0x4 * blen
;
737 bcb
->CDB
[5] = (BYTE
)(PageNum
);
738 bcb
->CDB
[4] = (BYTE
)(PhyBlock
);
739 bcb
->CDB
[3] = (BYTE
)(PhyBlock
>>8);
740 bcb
->CDB
[2] = (BYTE
)(PhyBlock
>>16);
743 result
= ENE_SendScsiCmd(us
, FDIR_READ
, buf
, 0);
744 if (result
!= USB_STOR_XFER_GOOD
)
745 return USB_STOR_TRANSPORT_ERROR
;
747 return USB_STOR_TRANSPORT_GOOD
;
753 int MS_LibReadExtra(struct us_data
*us
, DWORD PhyBlock
,
754 BYTE PageNum
, MS_LibTypeExtdat
*ExtraDat
)
756 struct bulk_cb_wrap
*bcb
= (struct bulk_cb_wrap
*) us
->iobuf
;
760 /* printk("MS_LibReadExtra --- PhyBlock = %x, PageNum = %x\n"
761 , PhyBlock, PageNum); */
762 memset(bcb
, 0, sizeof(struct bulk_cb_wrap
));
763 bcb
->Signature
= cpu_to_le32(US_BULK_CB_SIGN
);
764 bcb
->DataTransferLength
= 0x4;
768 bcb
->CDB
[5] = (BYTE
)(PageNum
);
769 bcb
->CDB
[4] = (BYTE
)(PhyBlock
);
770 bcb
->CDB
[3] = (BYTE
)(PhyBlock
>>8);
771 bcb
->CDB
[2] = (BYTE
)(PhyBlock
>>16);
774 result
= ENE_SendScsiCmd(us
, FDIR_READ
, &ExtBuf
, 0);
775 if (result
!= USB_STOR_XFER_GOOD
)
776 return USB_STOR_TRANSPORT_ERROR
;
778 ExtraDat
->reserved
= 0;
779 ExtraDat
->intr
= 0x80; /* Not yet, waiting for fireware support */
780 ExtraDat
->status0
= 0x10; /* Not yet, waiting for fireware support */
781 ExtraDat
->status1
= 0x00; /* Not yet, waiting for fireware support */
782 ExtraDat
->ovrflg
= ExtBuf
[0];
783 ExtraDat
->mngflg
= ExtBuf
[1];
784 ExtraDat
->logadr
= MemStickLogAddr(ExtBuf
[2], ExtBuf
[3]);
786 return USB_STOR_TRANSPORT_GOOD
;
790 * MS_LibSetAcquiredErrorBlock()
792 int MS_LibSetAcquiredErrorBlock(struct us_data
*us
, WORD phyblk
)
796 if (phyblk
>= us
->MS_Lib
.NumberOfPhyBlock
)
799 log
= us
->MS_Lib
.Phy2LogMap
[phyblk
];
801 if (log
< us
->MS_Lib
.NumberOfLogBlock
)
802 us
->MS_Lib
.Log2PhyMap
[log
] = MS_LB_NOT_USED
;
804 if (us
->MS_Lib
.Phy2LogMap
[phyblk
] != MS_LB_INITIAL_ERROR
)
805 us
->MS_Lib
.Phy2LogMap
[phyblk
] = MS_LB_ACQUIRED_ERROR
;
811 * MS_LibErasePhyBlock()
813 int MS_LibErasePhyBlock(struct us_data
*us
, WORD phyblk
)
817 if (phyblk
>= us
->MS_Lib
.NumberOfPhyBlock
)
818 return MS_STATUS_ERROR
;
820 log
= us
->MS_Lib
.Phy2LogMap
[phyblk
];
822 if (log
< us
->MS_Lib
.NumberOfLogBlock
)
823 us
->MS_Lib
.Log2PhyMap
[log
] = MS_LB_NOT_USED
;
825 us
->MS_Lib
.Phy2LogMap
[phyblk
] = MS_LB_NOT_USED
;
827 if (MS_LibIsWritable(us
)) {
828 switch (MS_ReaderEraseBlock(us
, phyblk
)) {
829 case MS_STATUS_SUCCESS
:
830 us
->MS_Lib
.Phy2LogMap
[phyblk
] = MS_LB_NOT_USED_ERASED
;
831 return MS_STATUS_SUCCESS
;
832 case MS_ERROR_FLASH_ERASE
:
833 case MS_STATUS_INT_ERROR
:
834 MS_LibErrorPhyBlock(us
, phyblk
);
835 return MS_ERROR_FLASH_ERASE
;
836 case MS_STATUS_ERROR
:
838 MS_LibCtrlSet(us
, MS_LIB_CTRL_RDONLY
);
839 MS_LibSetAcquiredErrorBlock(us
, phyblk
);
840 return MS_STATUS_ERROR
;
844 MS_LibSetAcquiredErrorBlock(us
, phyblk
);
846 return MS_STATUS_SUCCESS
;
850 * MS_LibErrorPhyBlock()
852 int MS_LibErrorPhyBlock(struct us_data
*us
, WORD phyblk
)
854 if (phyblk
>= us
->MS_Lib
.NumberOfPhyBlock
)
855 return MS_STATUS_ERROR
;
857 MS_LibSetAcquiredErrorBlock(us
, phyblk
);
859 if (MS_LibIsWritable(us
))
860 return MS_LibOverwriteExtra(us
, phyblk
, 0,
861 (BYTE
)(~MS_REG_OVR_BKST
& BYTE_MASK
));
864 return MS_STATUS_SUCCESS
;
868 * MS_LibOverwriteExtra()
870 int MS_LibOverwriteExtra(struct us_data
*us
, DWORD PhyBlockAddr
,
871 BYTE PageNum
, BYTE OverwriteFlag
)
873 struct bulk_cb_wrap
*bcb
= (struct bulk_cb_wrap
*) us
->iobuf
;
876 /* printk("MS --- MS_LibOverwriteExtra, \
877 PhyBlockAddr = %x, PageNum = %x\n", PhyBlockAddr, PageNum); */
878 result
= ENE_LoadBinCode(us
, MS_RW_PATTERN
);
879 if (result
!= USB_STOR_XFER_GOOD
)
880 return USB_STOR_TRANSPORT_ERROR
;
882 memset(bcb
, 0, sizeof(struct bulk_cb_wrap
));
883 bcb
->Signature
= cpu_to_le32(US_BULK_CB_SIGN
);
884 bcb
->DataTransferLength
= 0x4;
888 bcb
->CDB
[5] = (BYTE
)(PageNum
);
889 bcb
->CDB
[4] = (BYTE
)(PhyBlockAddr
);
890 bcb
->CDB
[3] = (BYTE
)(PhyBlockAddr
>>8);
891 bcb
->CDB
[2] = (BYTE
)(PhyBlockAddr
>>16);
892 bcb
->CDB
[6] = OverwriteFlag
;
897 result
= ENE_SendScsiCmd(us
, FDIR_READ
, NULL
, 0);
898 if (result
!= USB_STOR_XFER_GOOD
)
899 return USB_STOR_TRANSPORT_ERROR
;
901 return USB_STOR_TRANSPORT_GOOD
;
905 * MS_LibForceSetLogicalPair()
907 int MS_LibForceSetLogicalPair(struct us_data
*us
, WORD logblk
, WORD phyblk
)
909 if (logblk
== MS_LB_NOT_USED
)
912 if ((logblk
>= us
->MS_Lib
.NumberOfLogBlock
) ||
913 (phyblk
>= us
->MS_Lib
.NumberOfPhyBlock
))
916 us
->MS_Lib
.Phy2LogMap
[phyblk
] = logblk
;
917 us
->MS_Lib
.Log2PhyMap
[logblk
] = phyblk
;
923 * MS_LibSetLogicalPair()
925 int MS_LibSetLogicalPair(struct us_data
*us
, WORD logblk
, WORD phyblk
)
927 if ((logblk
>= us
->MS_Lib
.NumberOfLogBlock
) ||
928 (phyblk
>= us
->MS_Lib
.NumberOfPhyBlock
))
931 us
->MS_Lib
.Phy2LogMap
[phyblk
] = logblk
;
932 us
->MS_Lib
.Log2PhyMap
[logblk
] = phyblk
;
938 * MS_CountFreeBlock()
940 int MS_CountFreeBlock(struct us_data
*us
, WORD PhyBlock
)
944 Ende
= PhyBlock
+ MS_PHYSICAL_BLOCKS_PER_SEGMENT
;
945 for (Count
= 0; PhyBlock
< Ende
; PhyBlock
++) {
946 switch (us
->MS_Lib
.Phy2LogMap
[PhyBlock
]) {
948 case MS_LB_NOT_USED_ERASED
:
959 * MS_LibSearchBlockFromPhysical()
961 int MS_LibSearchBlockFromPhysical(struct us_data
*us
, WORD phyblk
)
965 MS_LibTypeExtdat extdat
;
967 if (phyblk
>= us
->MS_Lib
.NumberOfPhyBlock
)
970 for (blk
= phyblk
+ 1; blk
!= phyblk
; blk
++) {
971 if ((blk
& MS_PHYSICAL_BLOCKS_PER_SEGMENT_MASK
) == 0)
972 blk
-= MS_PHYSICAL_BLOCKS_PER_SEGMENT
;
974 Newblk
= us
->MS_Lib
.Phy2LogMap
[blk
];
975 if (us
->MS_Lib
.Phy2LogMap
[blk
] == MS_LB_NOT_USED_ERASED
)
977 else if (us
->MS_Lib
.Phy2LogMap
[blk
] == MS_LB_NOT_USED
) {
978 switch (MS_LibReadExtra(us
, blk
, 0, &extdat
)) {
979 case MS_STATUS_SUCCESS
:
980 case MS_STATUS_SUCCESS_WITH_ECC
:
982 case MS_NOCARD_ERROR
:
983 return MS_NOCARD_ERROR
;
984 case MS_STATUS_INT_ERROR
:
986 case MS_ERROR_FLASH_READ
:
988 MS_LibSetAcquiredErrorBlock(us
, blk
);
989 /* MS_LibErrorPhyBlock(fdoExt, blk); */
993 if ((extdat
.ovrflg
& MS_REG_OVR_BKST
) !=
994 MS_REG_OVR_BKST_OK
) {
995 MS_LibSetAcquiredErrorBlock(us
, blk
);
999 switch (MS_LibErasePhyBlock(us
, blk
)) {
1000 case MS_STATUS_SUCCESS
:
1002 case MS_STATUS_ERROR
:
1004 case MS_ERROR_FLASH_ERASE
:
1006 MS_LibErrorPhyBlock(us
, blk
);
1016 * MS_LibSearchBlockFromLogical()
1018 int MS_LibSearchBlockFromLogical(struct us_data
*us
, WORD logblk
)
1022 phyblk
= MS_LibConv2Physical(us
, logblk
);
1023 if (phyblk
>= MS_LB_ERROR
) {
1024 if (logblk
>= us
->MS_Lib
.NumberOfLogBlock
)
1027 phyblk
= (logblk
+ MS_NUMBER_OF_BOOT_BLOCK
) /
1028 MS_LOGICAL_BLOCKS_PER_SEGMENT
;
1029 phyblk
*= MS_PHYSICAL_BLOCKS_PER_SEGMENT
;
1030 phyblk
+= MS_PHYSICAL_BLOCKS_PER_SEGMENT
- 1;
1033 return MS_LibSearchBlockFromPhysical(us
, phyblk
);