Staging: keucr driver: fix uninitialized variable & proper memset length
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / drivers / staging / keucr / ms.c
blob9a3fdb4e4fe46ecaddb48e46c468a6f69f247a64
1 #include <linux/slab.h>
2 #include "usb.h"
3 #include "scsiglue.h"
4 #include "transport.h"
5 #include "ms.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;
11 int result;
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;
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;
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;
45 int result;
46 BYTE ExtBuf[4];
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;
55 // Read Page Data
56 memset(bcb, 0, sizeof(struct bulk_cb_wrap));
57 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);
67 result = ENE_SendScsiCmd(us, FDIR_READ, PageBuf, 0);
68 if (result != USB_STOR_XFER_GOOD)
69 return USB_STOR_TRANSPORT_ERROR;
71 // Read Extra Data
72 memset(bcb, 0, sizeof(struct bulk_cb_wrap));
73 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;
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;
103 int result;
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;
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);
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)
131 DWORD result=0;
132 WORD TmpBlock;
133 PBYTE PageBuffer0 = NULL, PageBuffer1 = NULL;
134 MS_LibTypeExtdat extdat;
135 WORD btBlk1st, btBlk2nd;
136 DWORD btBlk1stErred;
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;
146 goto exit;
149 btBlk1st = btBlk2nd = MS_LB_NOT_USED;
150 btBlk1stErred = 0;
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:
157 break;
158 case MS_STATUS_INT_ERROR:
159 break;
160 case MS_STATUS_ERROR:
161 default:
162 continue;
165 if ((extdat.ovrflg & MS_REG_OVR_BKST) == MS_REG_OVR_BKST_NG)
166 continue;
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;
174 if (btBlk1st != MS_LB_NOT_USED)
176 btBlk2nd = TmpBlock;
177 break;
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;
186 if (btBlk1st == MS_LB_NOT_USED)
188 result = MS_STATUS_ERROR;
189 goto exit;
192 // write protect
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;
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);
204 if (result)
206 result = MS_STATUS_ERROR;
207 goto exit;
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);
223 if (result)
224 goto exit;
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);
231 break;
235 // write
236 if (MS_LibAllocWriteBuf(us))
238 result = MS_NO_MEMORY_ERROR;
239 goto exit;
242 result = MS_STATUS_SUCCESS;
244 exit:
245 if (PageBuffer1) kfree(PageBuffer1);
246 if (PageBuffer0) kfree(PageBuffer0);
248 printk("MS_CardInit end\n");
249 return result;
252 //----- MS_LibCheckDisableBlock() ------------------------------------
253 int MS_LibCheckDisableBlock(struct us_data *us, WORD PhyBlock)
255 PWORD PageBuf=NULL;
256 DWORD result=MS_STATUS_SUCCESS;
257 DWORD blk, index=0;
258 MS_LibTypeExtdat extdat;
260 if (((PageBuf = kmalloc(MS_BYTES_PER_PAGE, GFP_KERNEL)) == NULL))
262 result = MS_NO_MEMORY_ERROR;
263 goto exit;
266 MS_ReaderReadPage(us, PhyBlock, 1, (DWORD *)PageBuf, &extdat);
269 blk = BigEndianWORD(PageBuf[index]);
270 if (blk == MS_LB_NOT_USED)
271 break;
272 if (blk == us->MS_Lib.Log2PhyMap[0])
274 result = MS_ERROR_FLASH_READ;
275 break;
277 index++;
278 } while(1);
280 exit:
281 if (PageBuf) kfree(PageBuf);
282 return result;
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;
337 return 0;
340 //----- MS_LibProcessBootBlock() -------------------------------------
341 int MS_LibProcessBootBlock(struct us_data *us, WORD PhyBlock, BYTE *PageData)
343 MemStickBootBlockSysEnt *SysEntry;
344 MemStickBootBlockSysInf *SysInfo;
345 DWORD i, result;
346 BYTE PageNumber;
347 BYTE *PageBuffer;
348 MS_LibTypeExtdat ExtraData;
350 if ((PageBuffer = (BYTE *)kmalloc(MS_BYTES_PER_PAGE, GFP_KERNEL))==NULL)
351 return (DWORD)-1;
353 result = (DWORD)-1;
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))
364 goto exit;
366 switch (us->MS_Lib.cardType = SysInfo->bCardType)
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;
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
387 goto exit;
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)
398 continue;
400 if ((EntrySize = BigEndianDWORD(SysEntry->entry[i].dwSize)) == 0)
401 continue;
403 if (EntryOffset + MS_BYTES_PER_PAGE + EntrySize > us->MS_Lib.blockSize * (DWORD)SIZE_OF_KIRO)
404 continue;
406 if (i == 0)
408 BYTE PrevPageNumber = 0;
409 WORD phyblk;
411 if (SysEntry->entry[i].bType != MS_SYSENT_TYPE_INVALID_BLOCK)
412 goto exit;
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:
421 break;
422 case MS_STATUS_WRITE_PROTECT:
423 case MS_ERROR_FLASH_READ:
424 case MS_STATUS_ERROR:
425 default:
426 goto exit;
429 PrevPageNumber = PageNumber;
432 if ((phyblk = BigEndianWORD(*(WORD *)(PageBuffer + (EntryOffset % MS_BYTES_PER_PAGE)))) < 0x0fff)
433 MS_LibSetInitialErrorBlock(us, phyblk);
435 EntryOffset += 2;
436 EntrySize -= 2;
439 else if (i == 1)
440 { // CIS/IDI
441 MemStickBootBlockIDI *idi;
443 if (SysEntry->entry[i].bType != MS_SYSENT_TYPE_CIS_IDI)
444 goto exit;
446 switch (MS_ReaderReadPage(us, PhyBlock, (BYTE)(EntryOffset / MS_BYTES_PER_PAGE + 1), (DWORD *)PageBuffer, &ExtraData))
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;
457 idi = &((MemStickBootBlockCIS_IDI *)(PageBuffer + (EntryOffset % MS_BYTES_PER_PAGE)))->idi.idi;
458 if (LittleEndianWORD(idi->wIDIgeneralConfiguration) != MS_IDI_GENERAL_CONF)
459 goto exit;
461 us->MS_Lib.BytesPerSector = LittleEndianWORD(idi->wIDIbytesPerSector);
462 if (us->MS_Lib.BytesPerSector != MS_BYTES_PER_PAGE)
463 goto exit;
465 } // End for ..
467 result = 0;
469 exit:
470 if (result) MS_LibFreeLogicalMap(us);
471 if (PageBuffer) kfree(PageBuffer);
473 result = 0;
474 return result;
477 //----- MS_LibAllocLogicalMap() --------------------------------------
478 int MS_LibAllocLogicalMap(struct us_data *us)
480 DWORD i;
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);
489 return (DWORD)-1;
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;
498 return 0;
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)
511 return (DWORD)-1;
513 us->MS_Lib.Phy2LogMap[phyblk] = mark;
515 return 0;
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;
530 BYTE buf[0x200];
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:
542 continue;
543 default:
544 break;
547 if (count == PhyBlock)
549 MS_LibReadExtraBlock(us, PhyBlock, 0, 0x80, &buf);
550 count += 0x80;
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);
561 continue;
564 if ((extdat.mngflg & MS_REG_MNG_ATFLG) == MS_REG_MNG_ATFLG_ATTBL)
566 MS_LibErasePhyBlock(us, PhyBlock);
567 continue;
570 if (extdat.logadr != MS_LB_NOT_USED)
572 if ((extdat.logadr < LogStart) || (LogEnde <= extdat.logadr))
574 MS_LibErasePhyBlock(us, PhyBlock);
575 continue;
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);
586 continue;
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);
594 continue;
596 else
597 MS_LibErasePhyBlock(us, newblk);
600 MS_LibSetLogicalPair(us, extdat.logadr, PhyBlock);
603 } //End for ...
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);
619 return (DWORD)-1;
622 MS_LibClearWriteBuf(us);
624 return 0;
627 //----- MS_LibClearWriteBuf() ----------------------------------------
628 void MS_LibClearWriteBuf(struct us_data *us)
630 int i;
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;
655 if (PhyBlock)
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
660 else
662 *LogStart = 0;
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;
671 int result;
673 //printk("MS_LibReadExtraBlock --- PhyBlock = %x, PageNum = %x, blen = %x\n", PhyBlock, PageNum, blen);
675 // Read Extra Data
676 memset(bcb, 0, sizeof(struct bulk_cb_wrap));
677 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;
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;
699 int result;
700 BYTE ExtBuf[4];
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;
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;
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)
733 WORD log;
735 if (phyblk >= us->MS_Lib.NumberOfPhyBlock)
736 return (DWORD)-1;
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;
744 return 0;
747 //----- MS_LibErasePhyBlock() ----------------------------------------
748 int MS_LibErasePhyBlock(struct us_data *us, WORD phyblk)
750 WORD log;
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:
772 default:
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;
803 int result;
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;
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;
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)
836 return 0;
838 if ((logblk >= us->MS_Lib.NumberOfLogBlock) || (phyblk >= us->MS_Lib.NumberOfPhyBlock))
839 return (DWORD)-1;
841 us->MS_Lib.Phy2LogMap[phyblk] = logblk;
842 us->MS_Lib.Log2PhyMap[logblk] = phyblk;
844 return 0;
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))
851 return (DWORD)-1;
853 us->MS_Lib.Phy2LogMap[phyblk] = logblk;
854 us->MS_Lib.Log2PhyMap[logblk] = phyblk;
856 return 0;
859 //----- MS_CountFreeBlock() ------------------------------------------
860 int MS_CountFreeBlock(struct us_data *us, WORD PhyBlock)
862 DWORD Ende, Count;
864 Ende = PhyBlock + MS_PHYSICAL_BLOCKS_PER_SEGMENT;
865 for (Count = 0; PhyBlock < Ende; PhyBlock++)
867 switch (us->MS_Lib.Phy2LogMap[PhyBlock])
869 case MS_LB_NOT_USED:
870 case MS_LB_NOT_USED_ERASED:
871 Count++;
872 default:
873 break;
877 return Count;
880 //----- MS_LibSearchBlockFromPhysical() ------------------------------
881 int MS_LibSearchBlockFromPhysical(struct us_data *us, WORD phyblk)
883 WORD Newblk;
884 WORD blk;
885 MS_LibTypeExtdat extdat;
887 if (phyblk >= us->MS_Lib.NumberOfPhyBlock)
888 return MS_LB_ERROR;
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)
897 return blk;
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:
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
915 if ((extdat.ovrflg & MS_REG_OVR_BKST) != MS_REG_OVR_BKST_OK)
917 MS_LibSetAcquiredErrorBlock(us, blk);
918 continue;
921 switch (MS_LibErasePhyBlock(us, blk))
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;
933 } // End for
935 return MS_LB_ERROR;
938 //----- MS_LibSearchBlockFromLogical() -------------------------------
939 int MS_LibSearchBlockFromLogical(struct us_data *us, WORD logblk)
941 WORD phyblk;
943 if ((phyblk=MS_LibConv2Physical(us, logblk)) >= MS_LB_ERROR)
945 if (logblk >= us->MS_Lib.NumberOfLogBlock)
946 return MS_LB_ERROR;
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);