Merge branch 'drm-nouveau-next' of git://anongit.freedesktop.org/git/nouveau/linux-2.6
[cascardo/linux.git] / drivers / staging / keucr / smilmain.c
1 #include <linux/slab.h>
2 #include "usb.h"
3 #include "scsiglue.h"
4 #include "smcommon.h"
5 #include "smil.h"
6
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);
25
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 *);
30
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 *);
35
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 *);
40
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);
45
46 int  MarkFail_D_PhyOneBlock(struct us_data *);
47
48 DWORD ErrXDCode;
49 DWORD ErrCode;
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];
57 WORD  ReadBlock;
58 WORD  WriteBlock;
59 DWORD MediaChange;
60 static DWORD SectCopyMode;
61
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])
67
68 BYTE     IsSSFDCCompliance;
69 BYTE     IsXDCompliance;
70
71
72 /* ----- SM_FreeMem() ------------------------------------------------- */
73 int SM_FreeMem(void)
74 {
75         int     i;
76
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]);
81                         kfree(Log2Phy[i]);
82                         Log2Phy[i] = NULL;
83                 }
84         }
85         return NO_ERROR;
86 }
87
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)
91 {
92         WORD len, bn;
93
94         if (Conv_D_MediaAddr(us, start))
95                 return ErrCode;
96
97         while (1) {
98                 len = Ssfdc.MaxSectors - Media.Sector;
99                 if (count > len)
100                         bn = len;
101                 else
102                         bn = count;
103
104                 if (Media_D_ReadOneSect(us, bn, buf)) {
105                         ErrCode = ERR_EccReadErr;
106                         return ErrCode;
107                 }
108
109                 Media.Sector += bn;
110                 count -= bn;
111
112                 if (count <= 0)
113                         break;
114
115                 buf += bn * SECTSIZE;
116
117                 if (Inc_D_MediaAddr(us))
118                         return ErrCode;
119         }
120
121         return NO_ERROR;
122 }
123 /* here */
124 /* ----- Media_D_CopySector() ------------------------------------------ */
125 int Media_D_CopySector(struct us_data *us, DWORD start, WORD count, BYTE *buf)
126 {
127         WORD len, bn;
128
129         /* pr_info("Media_D_CopySector !!!\n"); */
130         if (Conv_D_MediaAddr(us, start))
131                 return ErrCode;
132
133         while (1) {
134                 if (Assign_D_WriteBlock())
135                         return ERROR;
136
137                 len = Ssfdc.MaxSectors - Media.Sector;
138                 if (count > len)
139                         bn = len;
140                 else
141                 bn = count;
142
143                 if (Ssfdc_D_CopyBlock(us, bn, buf, Redundant)) {
144                         ErrCode = ERR_WriteFault;
145                         return ErrCode;
146                 }
147
148                 Media.Sector = 0x1F;
149                 if (Release_D_CopySector(us)) {
150                         if (ErrCode == ERR_HwError) {
151                                 ErrCode = ERR_WriteFault;
152                                 return ErrCode;
153                         }
154                 }
155                 count -= bn;
156
157                 if (count <= 0)
158                         break;
159
160                 buf += bn * SECTSIZE;
161
162                 if (Inc_D_MediaAddr(us))
163                         return ErrCode;
164
165         }
166         return NO_ERROR;
167 }
168
169 /* ----- Release_D_CopySector() ------------------------------------------ */
170 int Release_D_CopySector(struct us_data *us)
171 {
172         Log2Phy[Media.Zone][Media.LogBlock] = WriteBlock;
173         Media.PhyBlock = ReadBlock;
174
175         if (Media.PhyBlock == NO_ASSIGN) {
176                 Media.PhyBlock = WriteBlock;
177                 return SMSUCCESS;
178         }
179
180         Clr_D_Bit(Assign[Media.Zone], Media.PhyBlock);
181         Media.PhyBlock = WriteBlock;
182
183         return SMSUCCESS;
184 }
185
186 /* SmartMedia Physical Format Test Subroutine */
187 /* ----- Check_D_MediaFmt() --------------------------------------------- */
188 int Check_D_MediaFmt(struct us_data *us)
189 {
190         pr_info("Check_D_MediaFmt\n");
191
192         if (!MediaChange)
193                 return SMSUCCESS;
194
195         MediaChange  = ERROR;
196         SectCopyMode = COMPLETED;
197
198         if (Set_D_PhyFmtValue(us)) {
199                 ErrCode = ERR_UnknownMedia;
200                 return ERROR;
201         }
202
203         if (Search_D_CIS(us)) {
204                 ErrCode = ERR_IllegalFmt;
205                 return ERROR;
206         }
207
208         MediaChange = SMSUCCESS;
209         return SMSUCCESS;
210 }
211
212 /* SmartMedia Physical Address Control Subroutine */
213 /* ----- Conv_D_MediaAddr() --------------------------------------------- */
214 int Conv_D_MediaAddr(struct us_data *us, DWORD addr)
215 {
216         DWORD temp;
217
218         temp           = addr / Ssfdc.MaxSectors;
219         Media.Zone     = (BYTE) (temp / Ssfdc.MaxLogBlocks);
220
221         if (Log2Phy[Media.Zone] == NULL) {
222                 if (Make_D_LogTable(us)) {
223                         ErrCode = ERR_IllegalFmt;
224                         return ERROR;
225                 }
226         }
227
228         Media.Sector   = (BYTE) (addr % Ssfdc.MaxSectors);
229         Media.LogBlock = (WORD) (temp % Ssfdc.MaxLogBlocks);
230
231         if (Media.Zone < Ssfdc.MaxZones) {
232                 Clr_D_RedundantData(Redundant);
233                 Set_D_LogBlockAddr(Redundant);
234                 Media.PhyBlock = Log2Phy[Media.Zone][Media.LogBlock];
235                 return SMSUCCESS;
236         }
237
238         ErrCode = ERR_OutOfLBA;
239         return ERROR;
240 }
241
242 /* ----- Inc_D_MediaAddr() ---------------------------------------------- */
243 int Inc_D_MediaAddr(struct us_data *us)
244 {
245         WORD        LogBlock = Media.LogBlock;
246
247         if (++Media.Sector < Ssfdc.MaxSectors)
248                 return SMSUCCESS;
249
250         if (Log2Phy[Media.Zone] == NULL) {
251                 if (Make_D_LogTable(us)) {
252                         ErrCode = ERR_IllegalFmt;
253                         return ERROR;
254                 }
255         }
256
257         Media.Sector = 0;
258         Media.LogBlock = LogBlock;
259
260         if (++Media.LogBlock < Ssfdc.MaxLogBlocks) {
261                 Clr_D_RedundantData(Redundant);
262                 Set_D_LogBlockAddr(Redundant);
263                 Media.PhyBlock = Log2Phy[Media.Zone][Media.LogBlock];
264                 return SMSUCCESS;
265         }
266
267         Media.LogBlock = 0;
268
269         if (++Media.Zone < Ssfdc.MaxZones) {
270                 if (Log2Phy[Media.Zone] == NULL) {
271                         if (Make_D_LogTable(us)) {
272                                 ErrCode = ERR_IllegalFmt;
273                                 return ERROR;
274                         }
275                 }
276
277                 Media.LogBlock = 0;
278
279                 Clr_D_RedundantData(Redundant);
280                 Set_D_LogBlockAddr(Redundant);
281                 Media.PhyBlock = Log2Phy[Media.Zone][Media.LogBlock];
282                 return SMSUCCESS;
283         }
284
285         Media.Zone = 0;
286         ErrCode = ERR_OutOfLBA;
287
288         return ERROR;
289 }
290
291 /* SmartMedia Read/Write Subroutine with Retry */
292 /* ----- Media_D_ReadOneSect() ------------------------------------------ */
293 int Media_D_ReadOneSect(struct us_data *us, WORD count, BYTE *buf)
294 {
295         DWORD err, retry;
296
297         if (!Read_D_PhyOneSect(us, count, buf))
298                 return SMSUCCESS;
299         if (ErrCode == ERR_HwError)
300                 return ERROR;
301         if (ErrCode == ERR_DataStatus)
302                 return ERROR;
303
304 #ifdef RDERR_REASSIGN
305         if (Ssfdc.Attribute & MWP) {
306                 if (ErrCode == ERR_CorReadErr)
307                         return SMSUCCESS;
308                 return ERROR;
309         }
310
311         err = ErrCode;
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)
316                                 return ERROR;
317                         continue;
318                 }
319
320                 ErrCode = err;
321                 if (ErrCode == ERR_CorReadErr)
322                         return SMSUCCESS;
323                 return ERROR;
324         }
325
326         MediaChange = ERROR;
327 #else
328         if (ErrCode == ERR_CorReadErr)
329                 return SMSUCCESS;
330 #endif
331
332         return ERROR;
333 }
334
335 /* SmartMedia Physical Sector Data Copy Subroutine */
336 /* ----- Copy_D_BlockAll() ---------------------------------------------- */
337 int Copy_D_BlockAll(struct us_data *us, DWORD mode)
338 {
339         BYTE sect;
340
341         sect = Media.Sector;
342
343         if (Assign_D_WriteBlock())
344                 return ERROR;
345         if (mode == REQ_FAIL)
346                 SectCopyMode = REQ_FAIL;
347
348         for (Media.Sector = 0; Media.Sector < Ssfdc.MaxSectors;
349                                                         Media.Sector++) {
350                 if (Copy_D_PhyOneSect(us)) {
351                         if (ErrCode == ERR_HwError)
352                                 return ERROR;
353                         if (Release_D_WriteBlock(us))
354                                 return ERROR;
355
356                         ErrCode = ERR_WriteFault;
357                         Media.PhyBlock = ReadBlock;
358                         Media.Sector = sect;
359
360                         return ERROR;
361                 }
362         }
363
364         if (Release_D_ReadBlock(us))
365                 return ERROR;
366
367         Media.PhyBlock = WriteBlock;
368         Media.Sector = sect;
369         return SMSUCCESS;
370 }
371
372 /* SmartMedia Physical Block Assign/Release Subroutine */
373 /* ----- Assign_D_WriteBlock() ------------------------------------------ */
374 int Assign_D_WriteBlock(void)
375 {
376         ReadBlock = Media.PhyBlock;
377
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;
385                         return SMSUCCESS;
386                 }
387         }
388
389         for (WriteBlock = 0;
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;
396                         return SMSUCCESS;
397                 }
398         }
399
400         WriteBlock = NO_ASSIGN;
401         ErrCode = ERR_WriteFault;
402
403         return ERROR;
404 }
405
406 /* ----- Release_D_ReadBlock() ------------------------------------------ */
407 int Release_D_ReadBlock(struct us_data *us)
408 {
409         DWORD mode;
410
411         mode = SectCopyMode;
412         SectCopyMode = COMPLETED;
413
414         if (mode == COMPLETED)
415                 return SMSUCCESS;
416
417         Log2Phy[Media.Zone][Media.LogBlock] = WriteBlock;
418         Media.PhyBlock = ReadBlock;
419
420         if (Media.PhyBlock == NO_ASSIGN) {
421                 Media.PhyBlock = WriteBlock;
422                 return SMSUCCESS;
423         }
424
425         if (mode == REQ_ERASE) {
426                 if (Erase_D_PhyOneBlock(us)) {
427                         if (ErrCode == ERR_HwError)
428                                 return ERROR;
429                         if (MarkFail_D_PhyOneBlock(us))
430                                 return ERROR;
431                 } else
432                         Clr_D_Bit(Assign[Media.Zone], Media.PhyBlock);
433         } else if (MarkFail_D_PhyOneBlock(us))
434                 return ERROR;
435
436         Media.PhyBlock = WriteBlock;
437         return SMSUCCESS;
438 }
439
440 /* ----- Release_D_WriteBlock() ----------------------------------------- */
441 int Release_D_WriteBlock(struct us_data *us)
442 {
443         SectCopyMode = COMPLETED;
444         Media.PhyBlock = WriteBlock;
445
446         if (MarkFail_D_PhyOneBlock(us))
447                 return ERROR;
448
449         Media.PhyBlock = ReadBlock;
450         return SMSUCCESS;
451 }
452
453 /* SmartMedia Physical Sector Data Copy Subroutine */
454 /* ----- Copy_D_PhyOneSect() -------------------------------------------- */
455 int Copy_D_PhyOneSect(struct us_data *us)
456 {
457         int           i;
458         DWORD  err, retry;
459
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++) {
464                         if (retry != 0) {
465                                 Ssfdc_D_Reset(us);
466                                 if (Ssfdc_D_ReadCisSect(us, WorkBuf,
467                                                                 WorkRedund)) {
468                                         ErrCode = ERR_HwError;
469                                         MediaChange = ERROR;
470                                         return ERROR;
471                                 }
472
473                                 if (Check_D_CISdata(WorkBuf, WorkRedund)) {
474                                         ErrCode = ERR_HwError;
475                                         MediaChange = ERROR;
476                                         return ERROR;
477                                 }
478                         }
479
480                         if (Ssfdc_D_ReadSect(us, WorkBuf, WorkRedund)) {
481                                 ErrCode = ERR_HwError;
482                                 MediaChange = ERROR;
483                                 return ERROR;
484                         }
485                         if (Check_D_DataStatus(WorkRedund)) {
486                                 err = ERROR;
487                                 break;
488                         }
489                         if (!Check_D_ReadError(WorkRedund)) {
490                                 err = SMSUCCESS;
491                                 break;
492                         }
493                         if (!Check_D_Correct(WorkBuf, WorkRedund)) {
494                                 err = SMSUCCESS;
495                                 break;
496                         }
497
498                         err = ERROR;
499                         SectCopyMode = REQ_FAIL;
500                 }
501         } else {
502                 err = SMSUCCESS;
503                 for (i = 0; i < SECTSIZE; i++)
504                         WorkBuf[i] = DUMMY_DATA;
505                 Clr_D_RedundantData(WorkRedund);
506         }
507
508         Set_D_LogBlockAddr(WorkRedund);
509         if (err == ERROR) {
510                 Set_D_RightECC(WorkRedund);
511                 Set_D_DataStaus(WorkRedund);
512         }
513
514         Media.PhyBlock = WriteBlock;
515
516         if (Ssfdc_D_WriteSectForCopy(us, WorkBuf, WorkRedund)) {
517                 ErrCode = ERR_HwError;
518                 MediaChange = ERROR;
519                 return ERROR;
520         }
521         if (Ssfdc_D_CheckStatus()) {
522                 ErrCode = ERR_WriteFault;
523                 return ERROR;
524         }
525
526         Media.PhyBlock = ReadBlock;
527         return SMSUCCESS;
528 }
529
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)
533 {
534         int           i;
535         DWORD  retry;
536
537         if (Media.PhyBlock == NO_ASSIGN) {
538                 for (i = 0; i < SECTSIZE; i++)
539                         *buf++ = DUMMY_DATA;
540                 return SMSUCCESS;
541         }
542
543         for (retry = 0; retry < 2; retry++) {
544                 if (retry != 0) {
545                         Ssfdc_D_Reset(us);
546
547                         if (Ssfdc_D_ReadCisSect(us, WorkBuf, WorkRedund)) {
548                                 ErrCode = ERR_HwError;
549                                 MediaChange = ERROR;
550                                 return ERROR;
551                         }
552                         if (Check_D_CISdata(WorkBuf, WorkRedund)) {
553                                 ErrCode = ERR_HwError;
554                                 MediaChange = ERROR;
555                                 return ERROR;
556                         }
557                 }
558
559                 if (Ssfdc_D_ReadBlock(us, count, buf, Redundant)) {
560                         ErrCode = ERR_HwError;
561                         MediaChange = ERROR;
562                         return ERROR;
563                 }
564                 if (Check_D_DataStatus(Redundant)) {
565                         ErrCode = ERR_DataStatus;
566                         return ERROR;
567                 }
568
569                 if (!Check_D_ReadError(Redundant))
570                         return SMSUCCESS;
571
572                 if (!Check_D_Correct(buf, Redundant)) {
573                         ErrCode = ERR_CorReadErr;
574                         return ERROR;
575                 }
576         }
577
578         ErrCode = ERR_EccReadErr;
579         return ERROR;
580 }
581
582 /* ----- Erase_D_PhyOneBlock() ------------------------------------------ */
583 int Erase_D_PhyOneBlock(struct us_data *us)
584 {
585         if (Ssfdc_D_EraseBlock(us)) {
586                 ErrCode = ERR_HwError;
587                 MediaChange = ERROR;
588                 return ERROR;
589         }
590         if (Ssfdc_D_CheckStatus()) {
591                 ErrCode = ERR_WriteFault;
592                 return ERROR;
593         }
594
595         return SMSUCCESS;
596 }
597
598 /* SmartMedia Physical Format Check Local Subroutine */
599 /* ----- Set_D_PhyFmtValue() -------------------------------------------- */
600 int Set_D_PhyFmtValue(struct us_data *us)
601 {
602         if (Set_D_SsfdcModel(us->SM_DeviceID))
603                 return ERROR;
604
605         return SMSUCCESS;
606 }
607
608 /* ----- Search_D_CIS() ------------------------------------------------- */
609 int Search_D_CIS(struct us_data *us)
610 {
611         Media.Zone = 0;
612         Media.Sector = 0;
613
614         for (Media.PhyBlock = 0;
615                 Media.PhyBlock < (Ssfdc.MaxBlocks - Ssfdc.MaxLogBlocks - 1);
616                 Media.PhyBlock++) {
617                 if (Ssfdc_D_ReadRedtData(us, Redundant)) {
618                         Ssfdc_D_Reset(us);
619                         return ERROR;
620                 }
621
622                 if (!Check_D_FailBlock(Redundant))
623                         break;
624         }
625
626         if (Media.PhyBlock == (Ssfdc.MaxBlocks - Ssfdc.MaxLogBlocks - 1)) {
627                 Ssfdc_D_Reset(us);
628                 return ERROR;
629         }
630
631         while (Media.Sector < CIS_SEARCH_SECT) {
632                 if (Media.Sector) {
633                         if (Ssfdc_D_ReadRedtData(us, Redundant)) {
634                                 Ssfdc_D_Reset(us);
635                                 return ERROR;
636                         }
637                 }
638                 if (!Check_D_DataStatus(Redundant)) {
639                         if (Ssfdc_D_ReadSect(us, WorkBuf, Redundant)) {
640                                 Ssfdc_D_Reset(us);
641                                 return ERROR;
642                         }
643
644                         if (Check_D_CISdata(WorkBuf, Redundant)) {
645                                 Ssfdc_D_Reset(us);
646                                 return ERROR;
647                         }
648
649                         CisArea.PhyBlock = Media.PhyBlock;
650                         CisArea.Sector = Media.Sector;
651                         Ssfdc_D_Reset(us);
652                         return SMSUCCESS;
653                 }
654
655                 Media.Sector++;
656         }
657
658         Ssfdc_D_Reset(us);
659         return ERROR;
660 }
661
662 /* ----- Make_D_LogTable() ---------------------------------------------- */
663 int Make_D_LogTable(struct us_data *us)
664 {
665         WORD  phyblock, logblock;
666
667         if (Log2Phy[Media.Zone] == NULL) {
668                 Log2Phy[Media.Zone] = kmalloc(MAX_LOGBLOCK * sizeof(WORD),
669                                                                 GFP_KERNEL);
670                 /* pr_info("ExAllocatePool Zone = %x, Addr = %x\n",
671                                 Media.Zone, Log2Phy[Media.Zone]); */
672                 if (Log2Phy[Media.Zone] == NULL)
673                         return ERROR;
674         }
675
676         Media.Sector = 0;
677
678         /* pr_info("Make_D_LogTable --- MediaZone = 0x%x\n",
679                                                 Media.Zone); */
680         for (Media.LogBlock = 0; Media.LogBlock < Ssfdc.MaxLogBlocks;
681                                                 Media.LogBlock++)
682                 Log2Phy[Media.Zone][Media.LogBlock] = NO_ASSIGN;
683
684         for (Media.PhyBlock = 0; Media.PhyBlock < (MAX_BLOCKNUM / 8);
685                                                 Media.PhyBlock++)
686                 Assign[Media.Zone][Media.PhyBlock] = 0x00;
687
688         for (Media.PhyBlock = 0; Media.PhyBlock < Ssfdc.MaxBlocks;
689                                                 Media.PhyBlock++) {
690                 if ((!Media.Zone) && (Media.PhyBlock <= CisArea.PhyBlock)) {
691                         Set_D_Bit(Assign[Media.Zone], Media.PhyBlock);
692                         continue;
693                 }
694
695                 if (Ssfdc_D_ReadRedtData(us, Redundant)) {
696                         Ssfdc_D_Reset(us);
697                         return ERROR;
698                 }
699
700                 if (!Check_D_DataBlank(Redundant))
701                         continue;
702
703                 Set_D_Bit(Assign[Media.Zone], Media.PhyBlock);
704
705                 if (Check_D_FailBlock(Redundant))
706                         continue;
707
708                 if (Load_D_LogBlockAddr(Redundant))
709                         continue;
710
711                 if (Media.LogBlock >= Ssfdc.MaxLogBlocks)
712                         continue;
713
714                 if (Log2Phy[Media.Zone][Media.LogBlock] == NO_ASSIGN) {
715                         Log2Phy[Media.Zone][Media.LogBlock] = Media.PhyBlock;
716                         continue;
717                 }
718
719                 phyblock     = Media.PhyBlock;
720                 logblock     = Media.LogBlock;
721                 Media.Sector = (BYTE)(Ssfdc.MaxSectors - 1);
722
723                 if (Ssfdc_D_ReadRedtData(us, Redundant)) {
724                         Ssfdc_D_Reset(us);
725                         return ERROR;
726                 }
727
728                 if (!Load_D_LogBlockAddr(Redundant) &&
729                                 (Media.LogBlock == logblock)) {
730                         Media.PhyBlock = Log2Phy[Media.Zone][logblock];
731
732                         if (Ssfdc_D_ReadRedtData(us, Redundant)) {
733                                 Ssfdc_D_Reset(us);
734                                 return ERROR;
735                         }
736
737                         Media.PhyBlock = phyblock;
738
739                         if (!Load_D_LogBlockAddr(Redundant)) {
740                                 if (Media.LogBlock != logblock) {
741                                         Media.PhyBlock =
742                                                 Log2Phy[Media.Zone][logblock];
743                                         Log2Phy[Media.Zone][logblock] =
744                                                                 phyblock;
745                                 }
746                         } else {
747                                 Media.PhyBlock = Log2Phy[Media.Zone][logblock];
748                                 Log2Phy[Media.Zone][logblock] = phyblock;
749                         }
750                 }
751
752                 Media.Sector = 0;
753                 Media.PhyBlock = phyblock;
754
755         AssignStart[Media.Zone] = 0;
756
757         } /* End for (Media.Zone<MAX_ZONENUM) */
758
759         Ssfdc_D_Reset(us);
760         return SMSUCCESS;
761 }
762
763 /* ----- MarkFail_D_PhyOneBlock() --------------------------------------- */
764 int MarkFail_D_PhyOneBlock(struct us_data *us)
765 {
766         BYTE sect;
767
768         sect = Media.Sector;
769         Set_D_FailBlock(WorkRedund);
770
771         for (Media.Sector = 0; Media.Sector < Ssfdc.MaxSectors;
772                                                         Media.Sector++) {
773                 if (Ssfdc_D_WriteRedtData(us, WorkRedund)) {
774                         Ssfdc_D_Reset(us);
775                         Media.Sector   = sect;
776                         ErrCode        = ERR_HwError;
777                         MediaChange = ERROR;
778                         return ERROR;
779                 } /* NO Status Check */
780         }
781
782         Ssfdc_D_Reset(us);
783         Media.Sector = sect;
784         return SMSUCCESS;
785 }