1 #include <linux/slab.h>
9 void _Set_D_SsfdcRdCmd(BYTE);
10 void _Set_D_SsfdcRdAddr(BYTE);
11 void _Set_D_SsfdcRdChip(void);
12 void _Set_D_SsfdcRdStandby(void);
13 void _Start_D_SsfdcRdHwECC(void);
14 void _Stop_D_SsfdcRdHwECC(void);
15 void _Load_D_SsfdcRdHwECC(BYTE);
16 void _Set_D_SsfdcWrCmd(BYTE);
17 void _Set_D_SsfdcWrAddr(BYTE);
18 void _Set_D_SsfdcWrBlock(void);
19 void _Set_D_SsfdcWrStandby(void);
20 void _Start_D_SsfdcWrHwECC(void);
21 void _Load_D_SsfdcWrHwECC(BYTE);
22 int _Check_D_SsfdcBusy(WORD);
23 int _Check_D_SsfdcStatus(void);
24 void _Reset_D_SsfdcErr(void);
25 void _Read_D_SsfdcBuf(BYTE *);
26 void _Write_D_SsfdcBuf(BYTE *);
27 void _Read_D_SsfdcByte(BYTE *);
28 void _ReadRedt_D_SsfdcBuf(BYTE *);
29 void _WriteRedt_D_SsfdcBuf(BYTE *);
30 BYTE _Check_D_DevCode(BYTE);
32 void _Set_D_ECCdata(BYTE, BYTE *);
33 void _Calc_D_ECCdata(BYTE *);
36 struct SSFDCTYPE Ssfdc;
38 struct CIS_AREA CisArea;
40 static BYTE EccBuf[6];
41 extern PBYTE SMHostAddr;
42 extern DWORD ErrXDCode;
44 extern WORD ReadBlock;
45 extern WORD WriteBlock;
49 #define EVEN 0 /* Even Page for 256byte/page */
50 #define ODD 1 /* Odd Page for 256byte/page */
53 /* SmartMedia Redundant buffer data Control Subroutine
54 *----- Check_D_DataBlank() --------------------------------------------
56 int Check_D_DataBlank(BYTE *redundant)
60 for (i = 0; i < REDTSIZE; i++)
61 if (*redundant++ != 0xFF)
67 /* ----- Check_D_FailBlock() -------------------------------------------- */
68 int Check_D_FailBlock(BYTE *redundant)
70 redundant += REDT_BLOCK;
72 if (*redundant == 0xFF)
76 if (hweight8(*redundant) < 7)
82 /* ----- Check_D_DataStatus() ------------------------------------------- */
83 int Check_D_DataStatus(BYTE *redundant)
85 redundant += REDT_DATA;
87 if (*redundant == 0xFF)
90 ErrXDCode = ERR_DataStatus;
95 if (hweight8(*redundant) < 5)
101 /* ----- Load_D_LogBlockAddr() ------------------------------------------ */
102 int Load_D_LogBlockAddr(BYTE *redundant)
106 addr1 = (WORD)*(redundant + REDT_ADDR1H)*0x0100 + (WORD)*(redundant + REDT_ADDR1L);
107 addr2 = (WORD)*(redundant + REDT_ADDR2H)*0x0100 + (WORD)*(redundant + REDT_ADDR2L);
110 if ((addr1 & 0xF000) == 0x1000) {
111 Media.LogBlock = (addr1 & 0x0FFF) / 2;
115 if (hweight16((WORD)(addr1^addr2)) != 0x01)
118 if ((addr1 & 0xF000) == 0x1000)
119 if (!(hweight16(addr1) & 0x01)) {
120 Media.LogBlock = (addr1 & 0x0FFF) / 2;
124 if ((addr2 & 0xF000) == 0x1000)
125 if (!(hweight16(addr2) & 0x01)) {
126 Media.LogBlock = (addr2 & 0x0FFF) / 2;
133 /* ----- Clr_D_RedundantData() ------------------------------------------ */
134 void Clr_D_RedundantData(BYTE *redundant)
138 for (i = 0; i < REDTSIZE; i++)
139 *(redundant + i) = 0xFF;
142 /* ----- Set_D_LogBlockAddr() ------------------------------------------- */
143 void Set_D_LogBlockAddr(BYTE *redundant)
147 *(redundant + REDT_BLOCK) = 0xFF;
148 *(redundant + REDT_DATA) = 0xFF;
149 addr = Media.LogBlock*2 + 0x1000;
151 if ((hweight16(addr) % 2))
154 *(redundant + REDT_ADDR1H) = *(redundant + REDT_ADDR2H) = (BYTE)(addr / 0x0100);
155 *(redundant + REDT_ADDR1L) = *(redundant + REDT_ADDR2L) = (BYTE)addr;
158 /*----- Set_D_FailBlock() ---------------------------------------------- */
159 void Set_D_FailBlock(BYTE *redundant)
162 for (i = 0; i < REDTSIZE; i++)
163 *redundant++ = (BYTE)((i == REDT_BLOCK) ? 0xF0 : 0xFF);
166 /* ----- Set_D_DataStaus() ---------------------------------------------- */
167 void Set_D_DataStaus(BYTE *redundant)
169 redundant += REDT_DATA;
173 /* SmartMedia Function Command Subroutine
176 /* ----- Ssfdc_D_Reset() ------------------------------------------------ */
177 void Ssfdc_D_Reset(struct us_data *us)
182 /* ----- Ssfdc_D_ReadCisSect() ------------------------------------------ */
183 int Ssfdc_D_ReadCisSect(struct us_data *us, BYTE *buf, BYTE *redundant)
188 zone = Media.Zone; block = Media.PhyBlock; sector = Media.Sector;
190 Media.PhyBlock = CisArea.PhyBlock;
191 Media.Sector = CisArea.Sector;
193 if (Ssfdc_D_ReadSect(us, buf, redundant)) {
194 Media.Zone = zone; Media.PhyBlock = block; Media.Sector = sector;
198 Media.Zone = zone; Media.PhyBlock = block; Media.Sector = sector;
203 /* ----- Ssfdc_D_ReadSect() --------------------------------------------- */
204 int Ssfdc_D_ReadSect(struct us_data *us, BYTE *buf, BYTE *redundant)
206 struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf;
210 result = ENE_LoadBinCode(us, SM_RW_PATTERN);
211 if (result != USB_STOR_XFER_GOOD) {
212 printk("Load SM RW Code Fail !!\n");
213 return USB_STOR_TRANSPORT_ERROR;
216 addr = (WORD)Media.Zone*Ssfdc.MaxBlocks + Media.PhyBlock;
217 addr = addr*(WORD)Ssfdc.MaxSectors + Media.Sector;
220 memset(bcb, 0, sizeof(struct bulk_cb_wrap));
221 bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
222 bcb->DataTransferLength = 0x200;
226 bcb->CDB[4] = (BYTE)addr;
227 bcb->CDB[3] = (BYTE)(addr / 0x0100);
228 bcb->CDB[2] = Media.Zone / 2;
230 result = ENE_SendScsiCmd(us, FDIR_READ, buf, 0);
231 if (result != USB_STOR_XFER_GOOD)
232 return USB_STOR_TRANSPORT_ERROR;
235 memset(bcb, 0, sizeof(struct bulk_cb_wrap));
236 bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
237 bcb->DataTransferLength = 0x10;
241 bcb->CDB[4] = (BYTE)addr;
242 bcb->CDB[3] = (BYTE)(addr / 0x0100);
243 bcb->CDB[2] = Media.Zone / 2;
247 result = ENE_SendScsiCmd(us, FDIR_READ, redundant, 0);
248 if (result != USB_STOR_XFER_GOOD)
249 return USB_STOR_TRANSPORT_ERROR;
251 return USB_STOR_TRANSPORT_GOOD;
254 /* ----- Ssfdc_D_ReadBlock() --------------------------------------------- */
255 int Ssfdc_D_ReadBlock(struct us_data *us, WORD count, BYTE *buf, BYTE *redundant)
257 struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf;
261 result = ENE_LoadBinCode(us, SM_RW_PATTERN);
262 if (result != USB_STOR_XFER_GOOD) {
263 printk("Load SM RW Code Fail !!\n");
264 return USB_STOR_TRANSPORT_ERROR;
267 addr = (WORD)Media.Zone*Ssfdc.MaxBlocks + Media.PhyBlock;
268 addr = addr*(WORD)Ssfdc.MaxSectors + Media.Sector;
271 memset(bcb, 0, sizeof(struct bulk_cb_wrap));
272 bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
273 bcb->DataTransferLength = 0x200*count;
277 bcb->CDB[4] = (BYTE)addr;
278 bcb->CDB[3] = (BYTE)(addr / 0x0100);
279 bcb->CDB[2] = Media.Zone / 2;
281 result = ENE_SendScsiCmd(us, FDIR_READ, buf, 0);
282 if (result != USB_STOR_XFER_GOOD)
283 return USB_STOR_TRANSPORT_ERROR;
286 memset(bcb, 0, sizeof(struct bulk_cb_wrap));
287 bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
288 bcb->DataTransferLength = 0x10;
292 bcb->CDB[4] = (BYTE)addr;
293 bcb->CDB[3] = (BYTE)(addr / 0x0100);
294 bcb->CDB[2] = Media.Zone / 2;
298 result = ENE_SendScsiCmd(us, FDIR_READ, redundant, 0);
299 if (result != USB_STOR_XFER_GOOD)
300 return USB_STOR_TRANSPORT_ERROR;
302 return USB_STOR_TRANSPORT_GOOD;
306 /* ----- Ssfdc_D_CopyBlock() -------------------------------------------- */
307 int Ssfdc_D_CopyBlock(struct us_data *us, WORD count, BYTE *buf, BYTE *redundant)
309 struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf;
311 WORD ReadAddr, WriteAddr;
313 result = ENE_LoadBinCode(us, SM_RW_PATTERN);
314 if (result != USB_STOR_XFER_GOOD) {
315 printk("Load SM RW Code Fail !!\n");
316 return USB_STOR_TRANSPORT_ERROR;
319 ReadAddr = (WORD)Media.Zone*Ssfdc.MaxBlocks + ReadBlock;
320 ReadAddr = ReadAddr*(WORD)Ssfdc.MaxSectors;
321 WriteAddr = (WORD)Media.Zone*Ssfdc.MaxBlocks + WriteBlock;
322 WriteAddr = WriteAddr*(WORD)Ssfdc.MaxSectors;
324 /* Write sect data */
325 memset(bcb, 0, sizeof(struct bulk_cb_wrap));
326 bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
327 bcb->DataTransferLength = 0x200*count;
331 bcb->CDB[7] = (BYTE)WriteAddr;
332 bcb->CDB[6] = (BYTE)(WriteAddr / 0x0100);
333 bcb->CDB[5] = Media.Zone / 2;
334 bcb->CDB[8] = *(redundant + REDT_ADDR1H);
335 bcb->CDB[9] = *(redundant + REDT_ADDR1L);
336 bcb->CDB[10] = Media.Sector;
338 if (ReadBlock != NO_ASSIGN) {
339 bcb->CDB[4] = (BYTE)ReadAddr;
340 bcb->CDB[3] = (BYTE)(ReadAddr / 0x0100);
341 bcb->CDB[2] = Media.Zone / 2;
345 result = ENE_SendScsiCmd(us, FDIR_WRITE, buf, 0);
346 if (result != USB_STOR_XFER_GOOD)
347 return USB_STOR_TRANSPORT_ERROR;
349 return USB_STOR_TRANSPORT_GOOD;
352 /* ----- Ssfdc_D_WriteSectForCopy() ------------------------------------- */
353 int Ssfdc_D_WriteSectForCopy(struct us_data *us, BYTE *buf, BYTE *redundant)
355 struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf;
359 result = ENE_LoadBinCode(us, SM_RW_PATTERN);
360 if (result != USB_STOR_XFER_GOOD) {
361 printk("Load SM RW Code Fail !!\n");
362 return USB_STOR_TRANSPORT_ERROR;
366 addr = (WORD)Media.Zone*Ssfdc.MaxBlocks + Media.PhyBlock;
367 addr = addr*(WORD)Ssfdc.MaxSectors + Media.Sector;
369 /* Write sect data */
370 memset(bcb, 0, sizeof(struct bulk_cb_wrap));
371 bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
372 bcb->DataTransferLength = 0x200;
376 bcb->CDB[7] = (BYTE)addr;
377 bcb->CDB[6] = (BYTE)(addr / 0x0100);
378 bcb->CDB[5] = Media.Zone / 2;
379 bcb->CDB[8] = *(redundant + REDT_ADDR1H);
380 bcb->CDB[9] = *(redundant + REDT_ADDR1L);
382 result = ENE_SendScsiCmd(us, FDIR_WRITE, buf, 0);
383 if (result != USB_STOR_XFER_GOOD)
384 return USB_STOR_TRANSPORT_ERROR;
386 return USB_STOR_TRANSPORT_GOOD;
390 /* ----- Ssfdc_D_EraseBlock() ------------------------------------------- */
391 int Ssfdc_D_EraseBlock(struct us_data *us)
393 struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf;
397 result = ENE_LoadBinCode(us, SM_RW_PATTERN);
398 if (result != USB_STOR_XFER_GOOD) {
399 printk("Load SM RW Code Fail !!\n");
400 return USB_STOR_TRANSPORT_ERROR;
403 addr = (WORD)Media.Zone*Ssfdc.MaxBlocks + Media.PhyBlock;
404 addr = addr*(WORD)Ssfdc.MaxSectors;
406 memset(bcb, 0, sizeof(struct bulk_cb_wrap));
407 bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
408 bcb->DataTransferLength = 0x200;
412 bcb->CDB[7] = (BYTE)addr;
413 bcb->CDB[6] = (BYTE)(addr / 0x0100);
414 bcb->CDB[5] = Media.Zone / 2;
416 result = ENE_SendScsiCmd(us, FDIR_READ, NULL, 0);
417 if (result != USB_STOR_XFER_GOOD)
418 return USB_STOR_TRANSPORT_ERROR;
420 return USB_STOR_TRANSPORT_GOOD;
424 /*----- Ssfdc_D_ReadRedtData() ----------------------------------------- */
425 int Ssfdc_D_ReadRedtData(struct us_data *us, BYTE *redundant)
427 struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf;
432 result = ENE_LoadBinCode(us, SM_RW_PATTERN);
433 if (result != USB_STOR_XFER_GOOD) {
434 printk("Load SM RW Code Fail !!\n");
435 return USB_STOR_TRANSPORT_ERROR;
438 addr = (WORD)Media.Zone*Ssfdc.MaxBlocks + Media.PhyBlock;
439 addr = addr*(WORD)Ssfdc.MaxSectors + Media.Sector;
441 memset(bcb, 0, sizeof(struct bulk_cb_wrap));
442 bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
443 bcb->DataTransferLength = 0x10;
447 bcb->CDB[4] = (BYTE)addr;
448 bcb->CDB[3] = (BYTE)(addr / 0x0100);
449 bcb->CDB[2] = Media.Zone / 2;
453 buf = kmalloc(0x10, GFP_KERNEL);
454 result = ENE_SendScsiCmd(us, FDIR_READ, buf, 0);
455 memcpy(redundant, buf, 0x10);
457 if (result != USB_STOR_XFER_GOOD)
458 return USB_STOR_TRANSPORT_ERROR;
460 return USB_STOR_TRANSPORT_GOOD;
464 /* ----- Ssfdc_D_WriteRedtData() ---------------------------------------- */
465 int Ssfdc_D_WriteRedtData(struct us_data *us, BYTE *redundant)
467 struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf;
471 result = ENE_LoadBinCode(us, SM_RW_PATTERN);
472 if (result != USB_STOR_XFER_GOOD) {
473 printk("Load SM RW Code Fail !!\n");
474 return USB_STOR_TRANSPORT_ERROR;
477 addr = (WORD)Media.Zone*Ssfdc.MaxBlocks + Media.PhyBlock;
478 addr = addr*(WORD)Ssfdc.MaxSectors + Media.Sector;
480 memset(bcb, 0, sizeof(struct bulk_cb_wrap));
481 bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
482 bcb->DataTransferLength = 0x10;
486 bcb->CDB[7] = (BYTE)addr;
487 bcb->CDB[6] = (BYTE)(addr / 0x0100);
488 bcb->CDB[5] = Media.Zone / 2;
489 bcb->CDB[8] = *(redundant + REDT_ADDR1H);
490 bcb->CDB[9] = *(redundant + REDT_ADDR1L);
492 result = ENE_SendScsiCmd(us, FDIR_READ, NULL, 0);
493 if (result != USB_STOR_XFER_GOOD)
494 return USB_STOR_TRANSPORT_ERROR;
496 return USB_STOR_TRANSPORT_GOOD;
499 /* ----- Ssfdc_D_CheckStatus() ------------------------------------------ */
500 int Ssfdc_D_CheckStatus(void)
507 /* SmartMedia ID Code Check & Mode Set Subroutine
508 * ----- Set_D_SsfdcModel() ---------------------------------------------
510 int Set_D_SsfdcModel(BYTE dcode)
512 switch (_Check_D_DevCode(dcode)) {
514 Ssfdc.Model = SSFDC1MB;
515 Ssfdc.Attribute = FLASH | AD3CYC | BS16 | PS256;
517 Ssfdc.MaxBlocks = 256;
518 Ssfdc.MaxLogBlocks = 250;
519 Ssfdc.MaxSectors = 8;
522 Ssfdc.Model = SSFDC2MB;
523 Ssfdc.Attribute = FLASH | AD3CYC | BS16 | PS256;
525 Ssfdc.MaxBlocks = 512;
526 Ssfdc.MaxLogBlocks = 500;
527 Ssfdc.MaxSectors = 8;
530 Ssfdc.Model = SSFDC4MB;
531 Ssfdc.Attribute = FLASH | AD3CYC | BS16 | PS512;
533 Ssfdc.MaxBlocks = 512;
534 Ssfdc.MaxLogBlocks = 500;
535 Ssfdc.MaxSectors = 16;
538 Ssfdc.Model = SSFDC8MB;
539 Ssfdc.Attribute = FLASH | AD3CYC | BS16 | PS512;
541 Ssfdc.MaxBlocks = 1024;
542 Ssfdc.MaxLogBlocks = 1000;
543 Ssfdc.MaxSectors = 16;
546 Ssfdc.Model = SSFDC16MB;
547 Ssfdc.Attribute = FLASH | AD3CYC | BS32 | PS512;
549 Ssfdc.MaxBlocks = 1024;
550 Ssfdc.MaxLogBlocks = 1000;
551 Ssfdc.MaxSectors = 32;
554 Ssfdc.Model = SSFDC32MB;
555 Ssfdc.Attribute = FLASH | AD3CYC | BS32 | PS512;
557 Ssfdc.MaxBlocks = 1024;
558 Ssfdc.MaxLogBlocks = 1000;
559 Ssfdc.MaxSectors = 32;
562 Ssfdc.Model = SSFDC64MB;
563 Ssfdc.Attribute = FLASH | AD4CYC | BS32 | PS512;
565 Ssfdc.MaxBlocks = 1024;
566 Ssfdc.MaxLogBlocks = 1000;
567 Ssfdc.MaxSectors = 32;
570 Ssfdc.Model = SSFDC128MB;
571 Ssfdc.Attribute = FLASH | AD4CYC | BS32 | PS512;
573 Ssfdc.MaxBlocks = 1024;
574 Ssfdc.MaxLogBlocks = 1000;
575 Ssfdc.MaxSectors = 32;
578 Ssfdc.Model = SSFDC256MB;
579 Ssfdc.Attribute = FLASH | AD4CYC | BS32 | PS512;
581 Ssfdc.MaxBlocks = 1024;
582 Ssfdc.MaxLogBlocks = 1000;
583 Ssfdc.MaxSectors = 32;
586 Ssfdc.Model = SSFDC512MB;
587 Ssfdc.Attribute = FLASH | AD4CYC | BS32 | PS512;
589 Ssfdc.MaxBlocks = 1024;
590 Ssfdc.MaxLogBlocks = 1000;
591 Ssfdc.MaxSectors = 32;
594 Ssfdc.Model = SSFDC1GB;
595 Ssfdc.Attribute = FLASH | AD4CYC | BS32 | PS512;
597 Ssfdc.MaxBlocks = 1024;
598 Ssfdc.MaxLogBlocks = 1000;
599 Ssfdc.MaxSectors = 32;
602 Ssfdc.Model = SSFDC2GB;
603 Ssfdc.Attribute = FLASH | AD4CYC | BS32 | PS512;
604 Ssfdc.MaxZones = 128;
605 Ssfdc.MaxBlocks = 1024;
606 Ssfdc.MaxLogBlocks = 1000;
607 Ssfdc.MaxSectors = 32;
610 Ssfdc.Model = NOSSFDC;
617 /* ----- _Check_D_DevCode() --------------------------------------------- */
618 BYTE _Check_D_DevCode(BYTE dcode)
623 case 0xEC: return SSFDC1MB; /* 8Mbit (1M) NAND */
625 case 0xEA: return SSFDC2MB; /* 16Mbit (2M) NAND */
628 case 0xE5: return SSFDC4MB; /* 32Mbit (4M) NAND */
629 case 0xE6: return SSFDC8MB; /* 64Mbit (8M) NAND */
630 case 0x73: return SSFDC16MB; /* 128Mbit (16M)NAND */
631 case 0x75: return SSFDC32MB; /* 256Mbit (32M)NAND */
632 case 0x76: return SSFDC64MB; /* 512Mbit (64M)NAND */
633 case 0x79: return SSFDC128MB; /* 1Gbit(128M)NAND */
634 case 0x71: return SSFDC256MB;
635 case 0xDC: return SSFDC512MB;
636 case 0xD3: return SSFDC1GB;
637 case 0xD5: return SSFDC2GB;
638 default: return NOSSFDC;
645 /* SmartMedia ECC Control Subroutine
646 * ----- Check_D_ReadError() ----------------------------------------------
648 int Check_D_ReadError(BYTE *redundant)
653 /* ----- Check_D_Correct() ---------------------------------------------- */
654 int Check_D_Correct(BYTE *buf, BYTE *redundant)
659 /* ----- Check_D_CISdata() ---------------------------------------------- */
660 int Check_D_CISdata(BYTE *buf, BYTE *redundant)
662 BYTE cis[] = {0x01, 0x03, 0xD9, 0x01, 0xFF, 0x18, 0x02,
665 int cis_len = sizeof(cis);
667 if (!IsSSFDCCompliance && !IsXDCompliance)
670 if (!memcmp(redundant + 0x0D, EccBuf, 3))
671 return memcmp(buf, cis, cis_len);
673 if (!_Correct_D_SwECC(buf, redundant + 0x0D, EccBuf))
674 return memcmp(buf, cis, cis_len);
677 if (!memcmp(redundant + 0x08, EccBuf + 0x03, 3))
678 return memcmp(buf, cis, cis_len);
680 if (!_Correct_D_SwECC(buf, redundant + 0x08, EccBuf + 0x03))
681 return memcmp(buf, cis, cis_len);
686 /* ----- Set_D_RightECC() ---------------------------------------------- */
687 void Set_D_RightECC(BYTE *redundant)
689 /* Driver ECC Check */