1 #include <linux/slab.h>
7 int Check_D_LogCHS(WORD
*, BYTE
*, BYTE
*);
8 void Initialize_D_Media(void);
9 void PowerOff_D_Media(void);
10 int Check_D_MediaPower(void);
11 int Check_D_MediaExist(void);
12 int Check_D_MediaWP(void);
13 int Check_D_MediaFmt(struct us_data
*);
14 int Check_D_MediaFmtForEraseAll(struct us_data
*);
15 int Conv_D_MediaAddr(struct us_data
*, DWORD
);
16 int Inc_D_MediaAddr(struct us_data
*);
17 int Check_D_FirstSect(void);
18 int Check_D_LastSect(void);
19 int Media_D_ReadOneSect(struct us_data
*, WORD
, BYTE
*);
20 int Media_D_WriteOneSect(struct us_data
*, WORD
, BYTE
*);
21 int Media_D_CopyBlockHead(struct us_data
*);
22 int Media_D_CopyBlockTail(struct us_data
*);
23 int Media_D_EraseOneBlock(void);
24 int Media_D_EraseAllBlock(void);
26 int Copy_D_BlockAll(struct us_data
*, DWORD
);
27 int Copy_D_BlockHead(struct us_data
*);
28 int Copy_D_BlockTail(struct us_data
*);
29 int Reassign_D_BlockHead(struct us_data
*);
31 int Assign_D_WriteBlock(void);
32 int Release_D_ReadBlock(struct us_data
*);
33 int Release_D_WriteBlock(struct us_data
*);
34 int Release_D_CopySector(struct us_data
*);
36 int Copy_D_PhyOneSect(struct us_data
*);
37 int Read_D_PhyOneSect(struct us_data
*, WORD
, BYTE
*);
38 int Write_D_PhyOneSect(struct us_data
*, WORD
, BYTE
*);
39 int Erase_D_PhyOneBlock(struct us_data
*);
41 int Set_D_PhyFmtValue(struct us_data
*);
42 int Search_D_CIS(struct us_data
*);
43 int Make_D_LogTable(struct us_data
*);
44 void Check_D_BlockIsFull(void);
46 int MarkFail_D_PhyOneBlock(struct us_data
*);
50 static BYTE WorkBuf
[SECTSIZE
];
51 static BYTE Redundant
[REDTSIZE
];
52 static BYTE WorkRedund
[REDTSIZE
];
53 /* 128 x 1000, Log2Phy[MAX_ZONENUM][MAX_LOGBLOCK]; */
54 static WORD
*Log2Phy
[MAX_ZONENUM
];
55 static BYTE Assign
[MAX_ZONENUM
][MAX_BLOCKNUM
/ 8];
56 static WORD AssignStart
[MAX_ZONENUM
];
60 static DWORD SectCopyMode
;
62 /* BIT Control Macro */
63 static BYTE BitData
[] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 };
64 #define Set_D_Bit(a, b) (a[(BYTE)((b) / 8)] |= BitData[(b) % 8])
65 #define Clr_D_Bit(a, b) (a[(BYTE)((b) / 8)] &= ~BitData[(b) % 8])
66 #define Chk_D_Bit(a, b) (a[(BYTE)((b) / 8)] & BitData[(b) % 8])
68 BYTE IsSSFDCCompliance
;
72 /* ----- SM_FreeMem() ------------------------------------------------- */
77 pr_info("SM_FreeMem start\n");
78 for (i
= 0; i
< MAX_ZONENUM
; i
++) {
79 if (Log2Phy
[i
] != NULL
) {
80 pr_info("Free Zone = %x, Addr = %p\n", i
, Log2Phy
[i
]);
88 /* SmartMedia Read/Write/Erase Function */
89 /* ----- Media_D_ReadSector() ------------------------------------------- */
90 int Media_D_ReadSector(struct us_data
*us
, DWORD start
, WORD count
, BYTE
*buf
)
94 if (Conv_D_MediaAddr(us
, start
))
98 len
= Ssfdc
.MaxSectors
- Media
.Sector
;
104 if (Media_D_ReadOneSect(us
, bn
, buf
)) {
105 ErrCode
= ERR_EccReadErr
;
115 buf
+= bn
* SECTSIZE
;
117 if (Inc_D_MediaAddr(us
))
124 /* ----- Media_D_CopySector() ------------------------------------------ */
125 int Media_D_CopySector(struct us_data
*us
, DWORD start
, WORD count
, BYTE
*buf
)
129 /* pr_info("Media_D_CopySector !!!\n"); */
130 if (Conv_D_MediaAddr(us
, start
))
134 if (Assign_D_WriteBlock())
137 len
= Ssfdc
.MaxSectors
- Media
.Sector
;
143 if (Ssfdc_D_CopyBlock(us
, bn
, buf
, Redundant
)) {
144 ErrCode
= ERR_WriteFault
;
149 if (Release_D_CopySector(us
)) {
150 if (ErrCode
== ERR_HwError
) {
151 ErrCode
= ERR_WriteFault
;
160 buf
+= bn
* SECTSIZE
;
162 if (Inc_D_MediaAddr(us
))
169 /* ----- Release_D_CopySector() ------------------------------------------ */
170 int Release_D_CopySector(struct us_data
*us
)
172 Log2Phy
[Media
.Zone
][Media
.LogBlock
] = WriteBlock
;
173 Media
.PhyBlock
= ReadBlock
;
175 if (Media
.PhyBlock
== NO_ASSIGN
) {
176 Media
.PhyBlock
= WriteBlock
;
180 Clr_D_Bit(Assign
[Media
.Zone
], Media
.PhyBlock
);
181 Media
.PhyBlock
= WriteBlock
;
186 /* SmartMedia Physical Format Test Subroutine */
187 /* ----- Check_D_MediaFmt() --------------------------------------------- */
188 int Check_D_MediaFmt(struct us_data
*us
)
190 pr_info("Check_D_MediaFmt\n");
196 SectCopyMode
= COMPLETED
;
198 if (Set_D_PhyFmtValue(us
)) {
199 ErrCode
= ERR_UnknownMedia
;
203 if (Search_D_CIS(us
)) {
204 ErrCode
= ERR_IllegalFmt
;
208 MediaChange
= SMSUCCESS
;
212 /* SmartMedia Physical Address Control Subroutine */
213 /* ----- Conv_D_MediaAddr() --------------------------------------------- */
214 int Conv_D_MediaAddr(struct us_data
*us
, DWORD addr
)
218 temp
= addr
/ Ssfdc
.MaxSectors
;
219 Media
.Zone
= (BYTE
) (temp
/ Ssfdc
.MaxLogBlocks
);
221 if (Log2Phy
[Media
.Zone
] == NULL
) {
222 if (Make_D_LogTable(us
)) {
223 ErrCode
= ERR_IllegalFmt
;
228 Media
.Sector
= (BYTE
) (addr
% Ssfdc
.MaxSectors
);
229 Media
.LogBlock
= (WORD
) (temp
% Ssfdc
.MaxLogBlocks
);
231 if (Media
.Zone
< Ssfdc
.MaxZones
) {
232 Clr_D_RedundantData(Redundant
);
233 Set_D_LogBlockAddr(Redundant
);
234 Media
.PhyBlock
= Log2Phy
[Media
.Zone
][Media
.LogBlock
];
238 ErrCode
= ERR_OutOfLBA
;
242 /* ----- Inc_D_MediaAddr() ---------------------------------------------- */
243 int Inc_D_MediaAddr(struct us_data
*us
)
245 WORD LogBlock
= Media
.LogBlock
;
247 if (++Media
.Sector
< Ssfdc
.MaxSectors
)
250 if (Log2Phy
[Media
.Zone
] == NULL
) {
251 if (Make_D_LogTable(us
)) {
252 ErrCode
= ERR_IllegalFmt
;
258 Media
.LogBlock
= LogBlock
;
260 if (++Media
.LogBlock
< Ssfdc
.MaxLogBlocks
) {
261 Clr_D_RedundantData(Redundant
);
262 Set_D_LogBlockAddr(Redundant
);
263 Media
.PhyBlock
= Log2Phy
[Media
.Zone
][Media
.LogBlock
];
269 if (++Media
.Zone
< Ssfdc
.MaxZones
) {
270 if (Log2Phy
[Media
.Zone
] == NULL
) {
271 if (Make_D_LogTable(us
)) {
272 ErrCode
= ERR_IllegalFmt
;
279 Clr_D_RedundantData(Redundant
);
280 Set_D_LogBlockAddr(Redundant
);
281 Media
.PhyBlock
= Log2Phy
[Media
.Zone
][Media
.LogBlock
];
286 ErrCode
= ERR_OutOfLBA
;
291 /* SmartMedia Read/Write Subroutine with Retry */
292 /* ----- Media_D_ReadOneSect() ------------------------------------------ */
293 int Media_D_ReadOneSect(struct us_data
*us
, WORD count
, BYTE
*buf
)
297 if (!Read_D_PhyOneSect(us
, count
, buf
))
299 if (ErrCode
== ERR_HwError
)
301 if (ErrCode
== ERR_DataStatus
)
304 #ifdef RDERR_REASSIGN
305 if (Ssfdc
.Attribute
& MWP
) {
306 if (ErrCode
== ERR_CorReadErr
)
312 for (retry
= 0; retry
< 2; retry
++) {
313 if (Copy_D_BlockAll(us
,
314 (err
== ERR_EccReadErr
) ? REQ_FAIL
: REQ_ERASE
)) {
315 if (ErrCode
== ERR_HwError
)
321 if (ErrCode
== ERR_CorReadErr
)
328 if (ErrCode
== ERR_CorReadErr
)
335 /* SmartMedia Physical Sector Data Copy Subroutine */
336 /* ----- Copy_D_BlockAll() ---------------------------------------------- */
337 int Copy_D_BlockAll(struct us_data
*us
, DWORD mode
)
343 if (Assign_D_WriteBlock())
345 if (mode
== REQ_FAIL
)
346 SectCopyMode
= REQ_FAIL
;
348 for (Media
.Sector
= 0; Media
.Sector
< Ssfdc
.MaxSectors
;
350 if (Copy_D_PhyOneSect(us
)) {
351 if (ErrCode
== ERR_HwError
)
353 if (Release_D_WriteBlock(us
))
356 ErrCode
= ERR_WriteFault
;
357 Media
.PhyBlock
= ReadBlock
;
364 if (Release_D_ReadBlock(us
))
367 Media
.PhyBlock
= WriteBlock
;
372 /* SmartMedia Physical Block Assign/Release Subroutine */
373 /* ----- Assign_D_WriteBlock() ------------------------------------------ */
374 int Assign_D_WriteBlock(void)
376 ReadBlock
= Media
.PhyBlock
;
378 for (WriteBlock
= AssignStart
[Media
.Zone
];
379 WriteBlock
< Ssfdc
.MaxBlocks
; WriteBlock
++) {
380 if (!Chk_D_Bit(Assign
[Media
.Zone
], WriteBlock
)) {
381 Set_D_Bit(Assign
[Media
.Zone
], WriteBlock
);
382 AssignStart
[Media
.Zone
] = WriteBlock
+ 1;
383 Media
.PhyBlock
= WriteBlock
;
384 SectCopyMode
= REQ_ERASE
;
390 WriteBlock
< AssignStart
[Media
.Zone
]; WriteBlock
++) {
391 if (!Chk_D_Bit(Assign
[Media
.Zone
], WriteBlock
)) {
392 Set_D_Bit(Assign
[Media
.Zone
], WriteBlock
);
393 AssignStart
[Media
.Zone
] = WriteBlock
+ 1;
394 Media
.PhyBlock
= WriteBlock
;
395 SectCopyMode
= REQ_ERASE
;
400 WriteBlock
= NO_ASSIGN
;
401 ErrCode
= ERR_WriteFault
;
406 /* ----- Release_D_ReadBlock() ------------------------------------------ */
407 int Release_D_ReadBlock(struct us_data
*us
)
412 SectCopyMode
= COMPLETED
;
414 if (mode
== COMPLETED
)
417 Log2Phy
[Media
.Zone
][Media
.LogBlock
] = WriteBlock
;
418 Media
.PhyBlock
= ReadBlock
;
420 if (Media
.PhyBlock
== NO_ASSIGN
) {
421 Media
.PhyBlock
= WriteBlock
;
425 if (mode
== REQ_ERASE
) {
426 if (Erase_D_PhyOneBlock(us
)) {
427 if (ErrCode
== ERR_HwError
)
429 if (MarkFail_D_PhyOneBlock(us
))
432 Clr_D_Bit(Assign
[Media
.Zone
], Media
.PhyBlock
);
433 } else if (MarkFail_D_PhyOneBlock(us
))
436 Media
.PhyBlock
= WriteBlock
;
440 /* ----- Release_D_WriteBlock() ----------------------------------------- */
441 int Release_D_WriteBlock(struct us_data
*us
)
443 SectCopyMode
= COMPLETED
;
444 Media
.PhyBlock
= WriteBlock
;
446 if (MarkFail_D_PhyOneBlock(us
))
449 Media
.PhyBlock
= ReadBlock
;
453 /* SmartMedia Physical Sector Data Copy Subroutine */
454 /* ----- Copy_D_PhyOneSect() -------------------------------------------- */
455 int Copy_D_PhyOneSect(struct us_data
*us
)
460 /* pr_info("Copy_D_PhyOneSect --- Secotr = %x\n", Media.Sector); */
461 if (ReadBlock
!= NO_ASSIGN
) {
462 Media
.PhyBlock
= ReadBlock
;
463 for (retry
= 0; retry
< 2; retry
++) {
466 if (Ssfdc_D_ReadCisSect(us
, WorkBuf
,
468 ErrCode
= ERR_HwError
;
473 if (Check_D_CISdata(WorkBuf
, WorkRedund
)) {
474 ErrCode
= ERR_HwError
;
480 if (Ssfdc_D_ReadSect(us
, WorkBuf
, WorkRedund
)) {
481 ErrCode
= ERR_HwError
;
485 if (Check_D_DataStatus(WorkRedund
)) {
489 if (!Check_D_ReadError(WorkRedund
)) {
493 if (!Check_D_Correct(WorkBuf
, WorkRedund
)) {
499 SectCopyMode
= REQ_FAIL
;
503 for (i
= 0; i
< SECTSIZE
; i
++)
504 WorkBuf
[i
] = DUMMY_DATA
;
505 Clr_D_RedundantData(WorkRedund
);
508 Set_D_LogBlockAddr(WorkRedund
);
510 Set_D_RightECC(WorkRedund
);
511 Set_D_DataStaus(WorkRedund
);
514 Media
.PhyBlock
= WriteBlock
;
516 if (Ssfdc_D_WriteSectForCopy(us
, WorkBuf
, WorkRedund
)) {
517 ErrCode
= ERR_HwError
;
521 if (Ssfdc_D_CheckStatus()) {
522 ErrCode
= ERR_WriteFault
;
526 Media
.PhyBlock
= ReadBlock
;
530 /* SmartMedia Physical Sector Read/Write/Erase Subroutine */
531 /* ----- Read_D_PhyOneSect() -------------------------------------------- */
532 int Read_D_PhyOneSect(struct us_data
*us
, WORD count
, BYTE
*buf
)
537 if (Media
.PhyBlock
== NO_ASSIGN
) {
538 for (i
= 0; i
< SECTSIZE
; i
++)
543 for (retry
= 0; retry
< 2; retry
++) {
547 if (Ssfdc_D_ReadCisSect(us
, WorkBuf
, WorkRedund
)) {
548 ErrCode
= ERR_HwError
;
552 if (Check_D_CISdata(WorkBuf
, WorkRedund
)) {
553 ErrCode
= ERR_HwError
;
559 if (Ssfdc_D_ReadBlock(us
, count
, buf
, Redundant
)) {
560 ErrCode
= ERR_HwError
;
564 if (Check_D_DataStatus(Redundant
)) {
565 ErrCode
= ERR_DataStatus
;
569 if (!Check_D_ReadError(Redundant
))
572 if (!Check_D_Correct(buf
, Redundant
)) {
573 ErrCode
= ERR_CorReadErr
;
578 ErrCode
= ERR_EccReadErr
;
582 /* ----- Erase_D_PhyOneBlock() ------------------------------------------ */
583 int Erase_D_PhyOneBlock(struct us_data
*us
)
585 if (Ssfdc_D_EraseBlock(us
)) {
586 ErrCode
= ERR_HwError
;
590 if (Ssfdc_D_CheckStatus()) {
591 ErrCode
= ERR_WriteFault
;
598 /* SmartMedia Physical Format Check Local Subroutine */
599 /* ----- Set_D_PhyFmtValue() -------------------------------------------- */
600 int Set_D_PhyFmtValue(struct us_data
*us
)
602 if (Set_D_SsfdcModel(us
->SM_DeviceID
))
608 /* ----- Search_D_CIS() ------------------------------------------------- */
609 int Search_D_CIS(struct us_data
*us
)
614 for (Media
.PhyBlock
= 0;
615 Media
.PhyBlock
< (Ssfdc
.MaxBlocks
- Ssfdc
.MaxLogBlocks
- 1);
617 if (Ssfdc_D_ReadRedtData(us
, Redundant
)) {
622 if (!Check_D_FailBlock(Redundant
))
626 if (Media
.PhyBlock
== (Ssfdc
.MaxBlocks
- Ssfdc
.MaxLogBlocks
- 1)) {
631 while (Media
.Sector
< CIS_SEARCH_SECT
) {
633 if (Ssfdc_D_ReadRedtData(us
, Redundant
)) {
638 if (!Check_D_DataStatus(Redundant
)) {
639 if (Ssfdc_D_ReadSect(us
, WorkBuf
, Redundant
)) {
644 if (Check_D_CISdata(WorkBuf
, Redundant
)) {
649 CisArea
.PhyBlock
= Media
.PhyBlock
;
650 CisArea
.Sector
= Media
.Sector
;
662 /* ----- Make_D_LogTable() ---------------------------------------------- */
663 int Make_D_LogTable(struct us_data
*us
)
665 WORD phyblock
, logblock
;
667 if (Log2Phy
[Media
.Zone
] == NULL
) {
668 Log2Phy
[Media
.Zone
] = kmalloc(MAX_LOGBLOCK
* sizeof(WORD
),
670 /* pr_info("ExAllocatePool Zone = %x, Addr = %x\n",
671 Media.Zone, Log2Phy[Media.Zone]); */
672 if (Log2Phy
[Media
.Zone
] == NULL
)
678 /* pr_info("Make_D_LogTable --- MediaZone = 0x%x\n",
680 for (Media
.LogBlock
= 0; Media
.LogBlock
< Ssfdc
.MaxLogBlocks
;
682 Log2Phy
[Media
.Zone
][Media
.LogBlock
] = NO_ASSIGN
;
684 for (Media
.PhyBlock
= 0; Media
.PhyBlock
< (MAX_BLOCKNUM
/ 8);
686 Assign
[Media
.Zone
][Media
.PhyBlock
] = 0x00;
688 for (Media
.PhyBlock
= 0; Media
.PhyBlock
< Ssfdc
.MaxBlocks
;
690 if ((!Media
.Zone
) && (Media
.PhyBlock
<= CisArea
.PhyBlock
)) {
691 Set_D_Bit(Assign
[Media
.Zone
], Media
.PhyBlock
);
695 if (Ssfdc_D_ReadRedtData(us
, Redundant
)) {
700 if (!Check_D_DataBlank(Redundant
))
703 Set_D_Bit(Assign
[Media
.Zone
], Media
.PhyBlock
);
705 if (Check_D_FailBlock(Redundant
))
708 if (Load_D_LogBlockAddr(Redundant
))
711 if (Media
.LogBlock
>= Ssfdc
.MaxLogBlocks
)
714 if (Log2Phy
[Media
.Zone
][Media
.LogBlock
] == NO_ASSIGN
) {
715 Log2Phy
[Media
.Zone
][Media
.LogBlock
] = Media
.PhyBlock
;
719 phyblock
= Media
.PhyBlock
;
720 logblock
= Media
.LogBlock
;
721 Media
.Sector
= (BYTE
)(Ssfdc
.MaxSectors
- 1);
723 if (Ssfdc_D_ReadRedtData(us
, Redundant
)) {
728 if (!Load_D_LogBlockAddr(Redundant
) &&
729 (Media
.LogBlock
== logblock
)) {
730 Media
.PhyBlock
= Log2Phy
[Media
.Zone
][logblock
];
732 if (Ssfdc_D_ReadRedtData(us
, Redundant
)) {
737 Media
.PhyBlock
= phyblock
;
739 if (!Load_D_LogBlockAddr(Redundant
)) {
740 if (Media
.LogBlock
!= logblock
) {
742 Log2Phy
[Media
.Zone
][logblock
];
743 Log2Phy
[Media
.Zone
][logblock
] =
747 Media
.PhyBlock
= Log2Phy
[Media
.Zone
][logblock
];
748 Log2Phy
[Media
.Zone
][logblock
] = phyblock
;
753 Media
.PhyBlock
= phyblock
;
755 AssignStart
[Media
.Zone
] = 0;
757 } /* End for (Media.Zone<MAX_ZONENUM) */
763 /* ----- MarkFail_D_PhyOneBlock() --------------------------------------- */
764 int MarkFail_D_PhyOneBlock(struct us_data
*us
)
769 Set_D_FailBlock(WorkRedund
);
771 for (Media
.Sector
= 0; Media
.Sector
< Ssfdc
.MaxSectors
;
773 if (Ssfdc_D_WriteRedtData(us
, WorkRedund
)) {
776 ErrCode
= ERR_HwError
;
779 } /* NO Status Check */