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 keucr_media_info Ssfdc;
37 struct keucr_media_address Media;
38 struct keucr_media_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 +
107 (WORD)*(redundant + REDT_ADDR1L);
108 addr2 = (WORD)*(redundant + REDT_ADDR2H)*0x0100 +
109 (WORD)*(redundant + REDT_ADDR2L);
112 if ((addr1 & 0xF000) == 0x1000) {
113 Media.LogBlock = (addr1 & 0x0FFF) / 2;
117 if (hweight16((WORD)(addr1^addr2)) != 0x01)
120 if ((addr1 & 0xF000) == 0x1000)
121 if (!(hweight16(addr1) & 0x01)) {
122 Media.LogBlock = (addr1 & 0x0FFF) / 2;
126 if ((addr2 & 0xF000) == 0x1000)
127 if (!(hweight16(addr2) & 0x01)) {
128 Media.LogBlock = (addr2 & 0x0FFF) / 2;
135 /* ----- Clr_D_RedundantData() ------------------------------------------ */
136 void Clr_D_RedundantData(BYTE *redundant)
140 for (i = 0; i < REDTSIZE; i++)
141 *(redundant + i) = 0xFF;
144 /* ----- Set_D_LogBlockAddr() ------------------------------------------- */
145 void Set_D_LogBlockAddr(BYTE *redundant)
149 *(redundant + REDT_BLOCK) = 0xFF;
150 *(redundant + REDT_DATA) = 0xFF;
151 addr = Media.LogBlock*2 + 0x1000;
153 if ((hweight16(addr) % 2))
156 *(redundant + REDT_ADDR1H) = *(redundant + REDT_ADDR2H) =
157 (BYTE)(addr / 0x0100);
158 *(redundant + REDT_ADDR1L) = *(redundant + REDT_ADDR2L) = (BYTE)addr;
161 /*----- Set_D_FailBlock() ---------------------------------------------- */
162 void Set_D_FailBlock(BYTE *redundant)
165 for (i = 0; i < REDTSIZE; i++)
166 *redundant++ = (BYTE)((i == REDT_BLOCK) ? 0xF0 : 0xFF);
169 /* ----- Set_D_DataStaus() ---------------------------------------------- */
170 void Set_D_DataStaus(BYTE *redundant)
172 redundant += REDT_DATA;
176 /* SmartMedia Function Command Subroutine
179 /* ----- Ssfdc_D_Reset() ------------------------------------------------ */
180 void Ssfdc_D_Reset(struct us_data *us)
185 /* ----- Ssfdc_D_ReadCisSect() ------------------------------------------ */
186 int Ssfdc_D_ReadCisSect(struct us_data *us, BYTE *buf, BYTE *redundant)
191 zone = Media.Zone; block = Media.PhyBlock; sector = Media.Sector;
193 Media.PhyBlock = CisArea.PhyBlock;
194 Media.Sector = CisArea.Sector;
196 if (Ssfdc_D_ReadSect(us, buf, redundant)) {
198 Media.PhyBlock = block;
199 Media.Sector = sector;
203 Media.Zone = zone; Media.PhyBlock = block; Media.Sector = sector;
208 /* ----- Ssfdc_D_ReadSect() --------------------------------------------- */
209 int Ssfdc_D_ReadSect(struct us_data *us, BYTE *buf, BYTE *redundant)
211 struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf;
215 result = ENE_LoadBinCode(us, SM_RW_PATTERN);
216 if (result != USB_STOR_XFER_GOOD) {
217 dev_err(&us->pusb_dev->dev,
218 "Failed to load SmartMedia read/write code\n");
219 return USB_STOR_TRANSPORT_ERROR;
222 addr = (WORD)Media.Zone*Ssfdc.MaxBlocks + Media.PhyBlock;
223 addr = addr*(WORD)Ssfdc.MaxSectors + Media.Sector;
226 memset(bcb, 0, sizeof(struct bulk_cb_wrap));
227 bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
228 bcb->DataTransferLength = 0x200;
232 bcb->CDB[4] = (BYTE)addr;
233 bcb->CDB[3] = (BYTE)(addr / 0x0100);
234 bcb->CDB[2] = Media.Zone / 2;
236 result = ENE_SendScsiCmd(us, FDIR_READ, buf, 0);
237 if (result != USB_STOR_XFER_GOOD)
238 return USB_STOR_TRANSPORT_ERROR;
241 memset(bcb, 0, sizeof(struct bulk_cb_wrap));
242 bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
243 bcb->DataTransferLength = 0x10;
247 bcb->CDB[4] = (BYTE)addr;
248 bcb->CDB[3] = (BYTE)(addr / 0x0100);
249 bcb->CDB[2] = Media.Zone / 2;
253 result = ENE_SendScsiCmd(us, FDIR_READ, redundant, 0);
254 if (result != USB_STOR_XFER_GOOD)
255 return USB_STOR_TRANSPORT_ERROR;
257 return USB_STOR_TRANSPORT_GOOD;
260 /* ----- Ssfdc_D_ReadBlock() --------------------------------------------- */
261 int Ssfdc_D_ReadBlock(struct us_data *us, WORD count, BYTE *buf,
264 struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf;
268 result = ENE_LoadBinCode(us, SM_RW_PATTERN);
269 if (result != USB_STOR_XFER_GOOD) {
270 dev_err(&us->pusb_dev->dev,
271 "Failed to load SmartMedia read/write code\n");
272 return USB_STOR_TRANSPORT_ERROR;
275 addr = (WORD)Media.Zone*Ssfdc.MaxBlocks + Media.PhyBlock;
276 addr = addr*(WORD)Ssfdc.MaxSectors + Media.Sector;
279 memset(bcb, 0, sizeof(struct bulk_cb_wrap));
280 bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
281 bcb->DataTransferLength = 0x200*count;
285 bcb->CDB[4] = (BYTE)addr;
286 bcb->CDB[3] = (BYTE)(addr / 0x0100);
287 bcb->CDB[2] = Media.Zone / 2;
289 result = ENE_SendScsiCmd(us, FDIR_READ, buf, 0);
290 if (result != USB_STOR_XFER_GOOD)
291 return USB_STOR_TRANSPORT_ERROR;
294 memset(bcb, 0, sizeof(struct bulk_cb_wrap));
295 bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
296 bcb->DataTransferLength = 0x10;
300 bcb->CDB[4] = (BYTE)addr;
301 bcb->CDB[3] = (BYTE)(addr / 0x0100);
302 bcb->CDB[2] = Media.Zone / 2;
306 result = ENE_SendScsiCmd(us, FDIR_READ, redundant, 0);
307 if (result != USB_STOR_XFER_GOOD)
308 return USB_STOR_TRANSPORT_ERROR;
310 return USB_STOR_TRANSPORT_GOOD;
314 /* ----- Ssfdc_D_CopyBlock() -------------------------------------------- */
315 int Ssfdc_D_CopyBlock(struct us_data *us, WORD count, BYTE *buf,
318 struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf;
320 WORD ReadAddr, WriteAddr;
322 result = ENE_LoadBinCode(us, SM_RW_PATTERN);
323 if (result != USB_STOR_XFER_GOOD) {
324 dev_err(&us->pusb_dev->dev,
325 "Failed to load SmartMedia read/write code\n");
326 return USB_STOR_TRANSPORT_ERROR;
329 ReadAddr = (WORD)Media.Zone*Ssfdc.MaxBlocks + ReadBlock;
330 ReadAddr = ReadAddr*(WORD)Ssfdc.MaxSectors;
331 WriteAddr = (WORD)Media.Zone*Ssfdc.MaxBlocks + WriteBlock;
332 WriteAddr = WriteAddr*(WORD)Ssfdc.MaxSectors;
334 /* Write sect data */
335 memset(bcb, 0, sizeof(struct bulk_cb_wrap));
336 bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
337 bcb->DataTransferLength = 0x200*count;
341 bcb->CDB[7] = (BYTE)WriteAddr;
342 bcb->CDB[6] = (BYTE)(WriteAddr / 0x0100);
343 bcb->CDB[5] = Media.Zone / 2;
344 bcb->CDB[8] = *(redundant + REDT_ADDR1H);
345 bcb->CDB[9] = *(redundant + REDT_ADDR1L);
346 bcb->CDB[10] = Media.Sector;
348 if (ReadBlock != NO_ASSIGN) {
349 bcb->CDB[4] = (BYTE)ReadAddr;
350 bcb->CDB[3] = (BYTE)(ReadAddr / 0x0100);
351 bcb->CDB[2] = Media.Zone / 2;
355 result = ENE_SendScsiCmd(us, FDIR_WRITE, buf, 0);
356 if (result != USB_STOR_XFER_GOOD)
357 return USB_STOR_TRANSPORT_ERROR;
359 return USB_STOR_TRANSPORT_GOOD;
362 /* ----- Ssfdc_D_WriteSectForCopy() ------------------------------------- */
363 int Ssfdc_D_WriteSectForCopy(struct us_data *us, BYTE *buf, BYTE *redundant)
365 struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf;
369 result = ENE_LoadBinCode(us, SM_RW_PATTERN);
370 if (result != USB_STOR_XFER_GOOD) {
371 dev_err(&us->pusb_dev->dev,
372 "Failed to load SmartMedia read/write code\n");
373 return USB_STOR_TRANSPORT_ERROR;
377 addr = (WORD)Media.Zone*Ssfdc.MaxBlocks + Media.PhyBlock;
378 addr = addr*(WORD)Ssfdc.MaxSectors + Media.Sector;
380 /* Write sect data */
381 memset(bcb, 0, sizeof(struct bulk_cb_wrap));
382 bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
383 bcb->DataTransferLength = 0x200;
387 bcb->CDB[7] = (BYTE)addr;
388 bcb->CDB[6] = (BYTE)(addr / 0x0100);
389 bcb->CDB[5] = Media.Zone / 2;
390 bcb->CDB[8] = *(redundant + REDT_ADDR1H);
391 bcb->CDB[9] = *(redundant + REDT_ADDR1L);
393 result = ENE_SendScsiCmd(us, FDIR_WRITE, buf, 0);
394 if (result != USB_STOR_XFER_GOOD)
395 return USB_STOR_TRANSPORT_ERROR;
397 return USB_STOR_TRANSPORT_GOOD;
401 /* ----- Ssfdc_D_EraseBlock() ------------------------------------------- */
402 int Ssfdc_D_EraseBlock(struct us_data *us)
404 struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf;
408 result = ENE_LoadBinCode(us, SM_RW_PATTERN);
409 if (result != USB_STOR_XFER_GOOD) {
410 dev_err(&us->pusb_dev->dev,
411 "Failed to load SmartMedia read/write code\n");
412 return USB_STOR_TRANSPORT_ERROR;
415 addr = (WORD)Media.Zone*Ssfdc.MaxBlocks + Media.PhyBlock;
416 addr = addr*(WORD)Ssfdc.MaxSectors;
418 memset(bcb, 0, sizeof(struct bulk_cb_wrap));
419 bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
420 bcb->DataTransferLength = 0x200;
424 bcb->CDB[7] = (BYTE)addr;
425 bcb->CDB[6] = (BYTE)(addr / 0x0100);
426 bcb->CDB[5] = Media.Zone / 2;
428 result = ENE_SendScsiCmd(us, FDIR_READ, NULL, 0);
429 if (result != USB_STOR_XFER_GOOD)
430 return USB_STOR_TRANSPORT_ERROR;
432 return USB_STOR_TRANSPORT_GOOD;
436 /*----- Ssfdc_D_ReadRedtData() ----------------------------------------- */
437 int Ssfdc_D_ReadRedtData(struct us_data *us, BYTE *redundant)
439 struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf;
444 result = ENE_LoadBinCode(us, SM_RW_PATTERN);
445 if (result != USB_STOR_XFER_GOOD) {
446 dev_err(&us->pusb_dev->dev,
447 "Failed to load SmartMedia read/write code\n");
448 return USB_STOR_TRANSPORT_ERROR;
451 addr = (WORD)Media.Zone*Ssfdc.MaxBlocks + Media.PhyBlock;
452 addr = addr*(WORD)Ssfdc.MaxSectors + Media.Sector;
454 memset(bcb, 0, sizeof(struct bulk_cb_wrap));
455 bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
456 bcb->DataTransferLength = 0x10;
460 bcb->CDB[4] = (BYTE)addr;
461 bcb->CDB[3] = (BYTE)(addr / 0x0100);
462 bcb->CDB[2] = Media.Zone / 2;
466 buf = kmalloc(0x10, GFP_KERNEL);
467 result = ENE_SendScsiCmd(us, FDIR_READ, buf, 0);
468 memcpy(redundant, buf, 0x10);
470 if (result != USB_STOR_XFER_GOOD)
471 return USB_STOR_TRANSPORT_ERROR;
473 return USB_STOR_TRANSPORT_GOOD;
477 /* ----- Ssfdc_D_WriteRedtData() ---------------------------------------- */
478 int Ssfdc_D_WriteRedtData(struct us_data *us, BYTE *redundant)
480 struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf;
484 result = ENE_LoadBinCode(us, SM_RW_PATTERN);
485 if (result != USB_STOR_XFER_GOOD) {
486 dev_err(&us->pusb_dev->dev,
487 "Failed to load SmartMedia read/write code\n");
488 return USB_STOR_TRANSPORT_ERROR;
491 addr = (WORD)Media.Zone*Ssfdc.MaxBlocks + Media.PhyBlock;
492 addr = addr*(WORD)Ssfdc.MaxSectors + Media.Sector;
494 memset(bcb, 0, sizeof(struct bulk_cb_wrap));
495 bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
496 bcb->DataTransferLength = 0x10;
500 bcb->CDB[7] = (BYTE)addr;
501 bcb->CDB[6] = (BYTE)(addr / 0x0100);
502 bcb->CDB[5] = Media.Zone / 2;
503 bcb->CDB[8] = *(redundant + REDT_ADDR1H);
504 bcb->CDB[9] = *(redundant + REDT_ADDR1L);
506 result = ENE_SendScsiCmd(us, FDIR_READ, NULL, 0);
507 if (result != USB_STOR_XFER_GOOD)
508 return USB_STOR_TRANSPORT_ERROR;
510 return USB_STOR_TRANSPORT_GOOD;
513 /* ----- Ssfdc_D_CheckStatus() ------------------------------------------ */
514 int Ssfdc_D_CheckStatus(void)
521 /* SmartMedia ID Code Check & Mode Set Subroutine
522 * ----- Set_D_SsfdcModel() ---------------------------------------------
524 int Set_D_SsfdcModel(BYTE dcode)
526 switch (_Check_D_DevCode(dcode)) {
528 Ssfdc.Model = SSFDC1MB;
529 Ssfdc.Attribute = FLASH | AD3CYC | BS16 | PS256;
531 Ssfdc.MaxBlocks = 256;
532 Ssfdc.MaxLogBlocks = 250;
533 Ssfdc.MaxSectors = 8;
536 Ssfdc.Model = SSFDC2MB;
537 Ssfdc.Attribute = FLASH | AD3CYC | BS16 | PS256;
539 Ssfdc.MaxBlocks = 512;
540 Ssfdc.MaxLogBlocks = 500;
541 Ssfdc.MaxSectors = 8;
544 Ssfdc.Model = SSFDC4MB;
545 Ssfdc.Attribute = FLASH | AD3CYC | BS16 | PS512;
547 Ssfdc.MaxBlocks = 512;
548 Ssfdc.MaxLogBlocks = 500;
549 Ssfdc.MaxSectors = 16;
552 Ssfdc.Model = SSFDC8MB;
553 Ssfdc.Attribute = FLASH | AD3CYC | BS16 | PS512;
555 Ssfdc.MaxBlocks = 1024;
556 Ssfdc.MaxLogBlocks = 1000;
557 Ssfdc.MaxSectors = 16;
560 Ssfdc.Model = SSFDC16MB;
561 Ssfdc.Attribute = FLASH | AD3CYC | BS32 | PS512;
563 Ssfdc.MaxBlocks = 1024;
564 Ssfdc.MaxLogBlocks = 1000;
565 Ssfdc.MaxSectors = 32;
568 Ssfdc.Model = SSFDC32MB;
569 Ssfdc.Attribute = FLASH | AD3CYC | BS32 | PS512;
571 Ssfdc.MaxBlocks = 1024;
572 Ssfdc.MaxLogBlocks = 1000;
573 Ssfdc.MaxSectors = 32;
576 Ssfdc.Model = SSFDC64MB;
577 Ssfdc.Attribute = FLASH | AD4CYC | BS32 | PS512;
579 Ssfdc.MaxBlocks = 1024;
580 Ssfdc.MaxLogBlocks = 1000;
581 Ssfdc.MaxSectors = 32;
584 Ssfdc.Model = SSFDC128MB;
585 Ssfdc.Attribute = FLASH | AD4CYC | BS32 | PS512;
587 Ssfdc.MaxBlocks = 1024;
588 Ssfdc.MaxLogBlocks = 1000;
589 Ssfdc.MaxSectors = 32;
592 Ssfdc.Model = SSFDC256MB;
593 Ssfdc.Attribute = FLASH | AD4CYC | BS32 | PS512;
595 Ssfdc.MaxBlocks = 1024;
596 Ssfdc.MaxLogBlocks = 1000;
597 Ssfdc.MaxSectors = 32;
600 Ssfdc.Model = SSFDC512MB;
601 Ssfdc.Attribute = FLASH | AD4CYC | BS32 | PS512;
603 Ssfdc.MaxBlocks = 1024;
604 Ssfdc.MaxLogBlocks = 1000;
605 Ssfdc.MaxSectors = 32;
608 Ssfdc.Model = SSFDC1GB;
609 Ssfdc.Attribute = FLASH | AD4CYC | BS32 | PS512;
611 Ssfdc.MaxBlocks = 1024;
612 Ssfdc.MaxLogBlocks = 1000;
613 Ssfdc.MaxSectors = 32;
616 Ssfdc.Model = SSFDC2GB;
617 Ssfdc.Attribute = FLASH | AD4CYC | BS32 | PS512;
618 Ssfdc.MaxZones = 128;
619 Ssfdc.MaxBlocks = 1024;
620 Ssfdc.MaxLogBlocks = 1000;
621 Ssfdc.MaxSectors = 32;
624 Ssfdc.Model = NOSSFDC;
631 /* ----- _Check_D_DevCode() --------------------------------------------- */
632 BYTE _Check_D_DevCode(BYTE dcode)
637 case 0xEC: return SSFDC1MB; /* 8Mbit (1M) NAND */
639 case 0xEA: return SSFDC2MB; /* 16Mbit (2M) NAND */
642 case 0xE5: return SSFDC4MB; /* 32Mbit (4M) NAND */
643 case 0xE6: return SSFDC8MB; /* 64Mbit (8M) NAND */
644 case 0x73: return SSFDC16MB; /* 128Mbit (16M)NAND */
645 case 0x75: return SSFDC32MB; /* 256Mbit (32M)NAND */
646 case 0x76: return SSFDC64MB; /* 512Mbit (64M)NAND */
647 case 0x79: return SSFDC128MB; /* 1Gbit(128M)NAND */
648 case 0x71: return SSFDC256MB;
649 case 0xDC: return SSFDC512MB;
650 case 0xD3: return SSFDC1GB;
651 case 0xD5: return SSFDC2GB;
652 default: return NOSSFDC;
659 /* SmartMedia ECC Control Subroutine
660 * ----- Check_D_ReadError() ----------------------------------------------
662 int Check_D_ReadError(BYTE *redundant)
667 /* ----- Check_D_Correct() ---------------------------------------------- */
668 int Check_D_Correct(BYTE *buf, BYTE *redundant)
673 /* ----- Check_D_CISdata() ---------------------------------------------- */
674 int Check_D_CISdata(BYTE *buf, BYTE *redundant)
676 BYTE cis[] = {0x01, 0x03, 0xD9, 0x01, 0xFF, 0x18, 0x02,
679 int cis_len = sizeof(cis);
681 if (!IsSSFDCCompliance && !IsXDCompliance)
684 if (!memcmp(redundant + 0x0D, EccBuf, 3))
685 return memcmp(buf, cis, cis_len);
687 if (!_Correct_D_SwECC(buf, redundant + 0x0D, EccBuf))
688 return memcmp(buf, cis, cis_len);
691 if (!memcmp(redundant + 0x08, EccBuf + 0x03, 3))
692 return memcmp(buf, cis, cis_len);
694 if (!_Correct_D_SwECC(buf, redundant + 0x08, EccBuf + 0x03))
695 return memcmp(buf, cis, cis_len);
700 /* ----- Set_D_RightECC() ---------------------------------------------- */
701 void Set_D_RightECC(BYTE *redundant)
703 /* Driver ECC Check */