Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Staging: Merge ENE UB6250 MS card codes from keucr to drivers/usb/storage/ene_ub6250.c

Merge ENE UB6250 MS card codes from keucr to drivers/usb/storage/ene_ub6250.c.

Signed-off-by: Cho, Yu-Chen <acho@novell.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

authored by

Cho, Yu-Chen and committed by
Greg Kroah-Hartman
33842ced 01e57c57

+1632 -11
+2 -2
drivers/usb/storage/Kconfig
··· 187 187 depends on USB && SCSI 188 188 depends on USB_STORAGE 189 189 ---help--- 190 - Say Y here if you wish to control a ENE SD Card reader. 191 - To use SM/MS card, please build driver/staging/keucr/keucr.ko 190 + Say Y here if you wish to control a ENE SD/MS Card reader. 191 + To use SM card, please build driver/staging/keucr/keucr.ko 192 192 193 193 This option depends on 'SCSI' support being enabled, but you 194 194 probably also need 'SCSI device support: SCSI disk support'
+1630 -9
drivers/usb/storage/ene_ub6250.c
··· 100 100 #define FDIR_WRITE 0 101 101 #define FDIR_READ 1 102 102 103 + /* For MS Card */ 104 + 105 + /* Status Register 1 */ 106 + #define MS_REG_ST1_MB 0x80 /* media busy */ 107 + #define MS_REG_ST1_FB1 0x40 /* flush busy 1 */ 108 + #define MS_REG_ST1_DTER 0x20 /* error on data(corrected) */ 109 + #define MS_REG_ST1_UCDT 0x10 /* unable to correct data */ 110 + #define MS_REG_ST1_EXER 0x08 /* error on extra(corrected) */ 111 + #define MS_REG_ST1_UCEX 0x04 /* unable to correct extra */ 112 + #define MS_REG_ST1_FGER 0x02 /* error on overwrite flag(corrected) */ 113 + #define MS_REG_ST1_UCFG 0x01 /* unable to correct overwrite flag */ 114 + #define MS_REG_ST1_DEFAULT (MS_REG_ST1_MB | MS_REG_ST1_FB1 | MS_REG_ST1_DTER | MS_REG_ST1_UCDT | MS_REG_ST1_EXER | MS_REG_ST1_UCEX | MS_REG_ST1_FGER | MS_REG_ST1_UCFG) 115 + 116 + /* Overwrite Area */ 117 + #define MS_REG_OVR_BKST 0x80 /* block status */ 118 + #define MS_REG_OVR_BKST_OK MS_REG_OVR_BKST /* OK */ 119 + #define MS_REG_OVR_BKST_NG 0x00 /* NG */ 120 + #define MS_REG_OVR_PGST0 0x40 /* page status */ 121 + #define MS_REG_OVR_PGST1 0x20 122 + #define MS_REG_OVR_PGST_MASK (MS_REG_OVR_PGST0 | MS_REG_OVR_PGST1) 123 + #define MS_REG_OVR_PGST_OK (MS_REG_OVR_PGST0 | MS_REG_OVR_PGST1) /* OK */ 124 + #define MS_REG_OVR_PGST_NG MS_REG_OVR_PGST1 /* NG */ 125 + #define MS_REG_OVR_PGST_DATA_ERROR 0x00 /* data error */ 126 + #define MS_REG_OVR_UDST 0x10 /* update status */ 127 + #define MS_REG_OVR_UDST_UPDATING 0x00 /* updating */ 128 + #define MS_REG_OVR_UDST_NO_UPDATE MS_REG_OVR_UDST 129 + #define MS_REG_OVR_RESERVED 0x08 130 + #define MS_REG_OVR_DEFAULT (MS_REG_OVR_BKST_OK | MS_REG_OVR_PGST_OK | MS_REG_OVR_UDST_NO_UPDATE | MS_REG_OVR_RESERVED) 131 + 132 + /* Management Flag */ 133 + #define MS_REG_MNG_SCMS0 0x20 /* serial copy management system */ 134 + #define MS_REG_MNG_SCMS1 0x10 135 + #define MS_REG_MNG_SCMS_MASK (MS_REG_MNG_SCMS0 | MS_REG_MNG_SCMS1) 136 + #define MS_REG_MNG_SCMS_COPY_OK (MS_REG_MNG_SCMS0 | MS_REG_MNG_SCMS1) 137 + #define MS_REG_MNG_SCMS_ONE_COPY MS_REG_MNG_SCMS1 138 + #define MS_REG_MNG_SCMS_NO_COPY 0x00 139 + #define MS_REG_MNG_ATFLG 0x08 /* address transfer table flag */ 140 + #define MS_REG_MNG_ATFLG_OTHER MS_REG_MNG_ATFLG /* other */ 141 + #define MS_REG_MNG_ATFLG_ATTBL 0x00 /* address transfer table */ 142 + #define MS_REG_MNG_SYSFLG 0x04 /* system flag */ 143 + #define MS_REG_MNG_SYSFLG_USER MS_REG_MNG_SYSFLG /* user block */ 144 + #define MS_REG_MNG_SYSFLG_BOOT 0x00 /* system block */ 145 + #define MS_REG_MNG_RESERVED 0xc3 146 + #define MS_REG_MNG_DEFAULT (MS_REG_MNG_SCMS_COPY_OK | MS_REG_MNG_ATFLG_OTHER | MS_REG_MNG_SYSFLG_USER | MS_REG_MNG_RESERVED) 147 + 148 + 149 + #define MS_MAX_PAGES_PER_BLOCK 32 150 + #define MS_MAX_INITIAL_ERROR_BLOCKS 10 151 + #define MS_LIB_BITS_PER_BYTE 8 152 + 153 + #define MS_SYSINF_FORMAT_FAT 1 154 + #define MS_SYSINF_USAGE_GENERAL 0 155 + 156 + #define MS_SYSINF_MSCLASS_TYPE_1 1 157 + #define MS_SYSINF_PAGE_SIZE MS_BYTES_PER_PAGE /* fixed */ 158 + 159 + #define MS_SYSINF_CARDTYPE_RDONLY 1 160 + #define MS_SYSINF_CARDTYPE_RDWR 2 161 + #define MS_SYSINF_CARDTYPE_HYBRID 3 162 + #define MS_SYSINF_SECURITY 0x01 163 + #define MS_SYSINF_SECURITY_NO_SUPPORT MS_SYSINF_SECURITY 164 + #define MS_SYSINF_SECURITY_SUPPORT 0 165 + 166 + #define MS_SYSINF_RESERVED1 1 167 + #define MS_SYSINF_RESERVED2 1 168 + 169 + #define MS_SYSENT_TYPE_INVALID_BLOCK 0x01 170 + #define MS_SYSENT_TYPE_CIS_IDI 0x0a /* CIS/IDI */ 171 + 172 + #define SIZE_OF_KIRO 1024 173 + #define BYTE_MASK 0xff 174 + 175 + /* ms error code */ 176 + #define MS_STATUS_WRITE_PROTECT 0x0106 177 + #define MS_STATUS_SUCCESS 0x0000 178 + #define MS_ERROR_FLASH_READ 0x8003 179 + #define MS_ERROR_FLASH_ERASE 0x8005 180 + #define MS_LB_ERROR 0xfff0 181 + #define MS_LB_BOOT_BLOCK 0xfff1 182 + #define MS_LB_INITIAL_ERROR 0xfff2 183 + #define MS_STATUS_SUCCESS_WITH_ECC 0xfff3 184 + #define MS_LB_ACQUIRED_ERROR 0xfff4 185 + #define MS_LB_NOT_USED_ERASED 0xfff5 186 + #define MS_NOCARD_ERROR 0xfff8 187 + #define MS_NO_MEMORY_ERROR 0xfff9 188 + #define MS_STATUS_INT_ERROR 0xfffa 189 + #define MS_STATUS_ERROR 0xfffe 190 + #define MS_LB_NOT_USED 0xffff 191 + 192 + #define MS_REG_MNG_SYSFLG 0x04 /* system flag */ 193 + #define MS_REG_MNG_SYSFLG_USER MS_REG_MNG_SYSFLG /* user block */ 194 + 195 + #define MS_BOOT_BLOCK_ID 0x0001 196 + #define MS_BOOT_BLOCK_FORMAT_VERSION 0x0100 197 + #define MS_BOOT_BLOCK_DATA_ENTRIES 2 198 + 199 + #define MS_NUMBER_OF_SYSTEM_ENTRY 4 200 + #define MS_NUMBER_OF_BOOT_BLOCK 2 201 + #define MS_BYTES_PER_PAGE 512 202 + #define MS_LOGICAL_BLOCKS_PER_SEGMENT 496 203 + #define MS_LOGICAL_BLOCKS_IN_1ST_SEGMENT 494 204 + 205 + #define MS_PHYSICAL_BLOCKS_PER_SEGMENT 0x200 /* 512 */ 206 + #define MS_PHYSICAL_BLOCKS_PER_SEGMENT_MASK 0x1ff 207 + 208 + /* overwrite area */ 209 + #define MS_REG_OVR_BKST 0x80 /* block status */ 210 + #define MS_REG_OVR_BKST_OK MS_REG_OVR_BKST /* OK */ 211 + #define MS_REG_OVR_BKST_NG 0x00 /* NG */ 212 + 213 + /* Status Register 1 */ 214 + #define MS_REG_ST1_DTER 0x20 /* error on data(corrected) */ 215 + #define MS_REG_ST1_EXER 0x08 /* error on extra(corrected) */ 216 + #define MS_REG_ST1_FGER 0x02 /* error on overwrite flag(corrected) */ 217 + 218 + /* MemoryStick Register */ 219 + /* Status Register 0 */ 220 + #define MS_REG_ST0_WP 0x01 /* write protected */ 221 + #define MS_REG_ST0_WP_ON MS_REG_ST0_WP 222 + 223 + #define MS_LIB_CTRL_RDONLY 0 224 + #define MS_LIB_CTRL_WRPROTECT 1 225 + 226 + /*dphy->log table */ 227 + #define ms_libconv_to_logical(pdx, PhyBlock) (((PhyBlock) >= (pdx)->MS_Lib.NumberOfPhyBlock) ? MS_STATUS_ERROR : (pdx)->MS_Lib.Phy2LogMap[PhyBlock]) 228 + #define ms_libconv_to_physical(pdx, LogBlock) (((LogBlock) >= (pdx)->MS_Lib.NumberOfLogBlock) ? MS_STATUS_ERROR : (pdx)->MS_Lib.Log2PhyMap[LogBlock]) 229 + 230 + #define ms_lib_ctrl_set(pdx, Flag) ((pdx)->MS_Lib.flags |= (1 << (Flag))) 231 + #define ms_lib_ctrl_reset(pdx, Flag) ((pdx)->MS_Lib.flags &= ~(1 << (Flag))) 232 + #define ms_lib_ctrl_check(pdx, Flag) ((pdx)->MS_Lib.flags & (1 << (Flag))) 233 + 234 + #define ms_lib_iswritable(pdx) ((ms_lib_ctrl_check((pdx), MS_LIB_CTRL_RDONLY) == 0) && (ms_lib_ctrl_check(pdx, MS_LIB_CTRL_WRPROTECT) == 0)) 235 + #define ms_lib_clear_pagemap(pdx) memset((pdx)->MS_Lib.pagemap, 0, sizeof((pdx)->MS_Lib.pagemap)) 236 + #define memstick_logaddr(logadr1, logadr0) ((((u16)(logadr1)) << 8) | (logadr0)) 237 + 103 238 104 239 struct SD_STATUS { 105 240 u8 Insert:1; ··· 267 132 u8 IsMS:1; 268 133 }; 269 134 135 + struct ms_bootblock_cis { 136 + u8 bCistplDEVICE[6]; /* 0 */ 137 + u8 bCistplDEVICE0C[6]; /* 6 */ 138 + u8 bCistplJEDECC[4]; /* 12 */ 139 + u8 bCistplMANFID[6]; /* 16 */ 140 + u8 bCistplVER1[32]; /* 22 */ 141 + u8 bCistplFUNCID[4]; /* 54 */ 142 + u8 bCistplFUNCE0[4]; /* 58 */ 143 + u8 bCistplFUNCE1[5]; /* 62 */ 144 + u8 bCistplCONF[7]; /* 67 */ 145 + u8 bCistplCFTBLENT0[10];/* 74 */ 146 + u8 bCistplCFTBLENT1[8]; /* 84 */ 147 + u8 bCistplCFTBLENT2[12];/* 92 */ 148 + u8 bCistplCFTBLENT3[8]; /* 104 */ 149 + u8 bCistplCFTBLENT4[17];/* 112 */ 150 + u8 bCistplCFTBLENT5[8]; /* 129 */ 151 + u8 bCistplCFTBLENT6[17];/* 137 */ 152 + u8 bCistplCFTBLENT7[8]; /* 154 */ 153 + u8 bCistplNOLINK[3]; /* 162 */ 154 + } ; 155 + 156 + struct ms_bootblock_idi { 157 + #define MS_IDI_GENERAL_CONF 0x848A 158 + u16 wIDIgeneralConfiguration; /* 0 */ 159 + u16 wIDInumberOfCylinder; /* 1 */ 160 + u16 wIDIreserved0; /* 2 */ 161 + u16 wIDInumberOfHead; /* 3 */ 162 + u16 wIDIbytesPerTrack; /* 4 */ 163 + u16 wIDIbytesPerSector; /* 5 */ 164 + u16 wIDIsectorsPerTrack; /* 6 */ 165 + u16 wIDItotalSectors[2]; /* 7-8 high,low */ 166 + u16 wIDIreserved1[11]; /* 9-19 */ 167 + u16 wIDIbufferType; /* 20 */ 168 + u16 wIDIbufferSize; /* 21 */ 169 + u16 wIDIlongCmdECC; /* 22 */ 170 + u16 wIDIfirmVersion[4]; /* 23-26 */ 171 + u16 wIDImodelName[20]; /* 27-46 */ 172 + u16 wIDIreserved2; /* 47 */ 173 + u16 wIDIlongWordSupported; /* 48 */ 174 + u16 wIDIdmaSupported; /* 49 */ 175 + u16 wIDIreserved3; /* 50 */ 176 + u16 wIDIpioTiming; /* 51 */ 177 + u16 wIDIdmaTiming; /* 52 */ 178 + u16 wIDItransferParameter; /* 53 */ 179 + u16 wIDIformattedCylinder; /* 54 */ 180 + u16 wIDIformattedHead; /* 55 */ 181 + u16 wIDIformattedSectorsPerTrack;/* 56 */ 182 + u16 wIDIformattedTotalSectors[2];/* 57-58 */ 183 + u16 wIDImultiSector; /* 59 */ 184 + u16 wIDIlbaSectors[2]; /* 60-61 */ 185 + u16 wIDIsingleWordDMA; /* 62 */ 186 + u16 wIDImultiWordDMA; /* 63 */ 187 + u16 wIDIreserved4[192]; /* 64-255 */ 188 + }; 189 + 190 + struct ms_bootblock_sysent_rec { 191 + u32 dwStart; 192 + u32 dwSize; 193 + u8 bType; 194 + u8 bReserved[3]; 195 + }; 196 + 197 + struct ms_bootblock_sysent { 198 + struct ms_bootblock_sysent_rec entry[MS_NUMBER_OF_SYSTEM_ENTRY]; 199 + }; 200 + 201 + struct ms_bootblock_sysinf { 202 + u8 bMsClass; /* must be 1 */ 203 + u8 bCardType; /* see below */ 204 + u16 wBlockSize; /* n KB */ 205 + u16 wBlockNumber; /* number of physical block */ 206 + u16 wTotalBlockNumber; /* number of logical block */ 207 + u16 wPageSize; /* must be 0x200 */ 208 + u8 bExtraSize; /* 0x10 */ 209 + u8 bSecuritySupport; 210 + u8 bAssemblyDate[8]; 211 + u8 bFactoryArea[4]; 212 + u8 bAssemblyMakerCode; 213 + u8 bAssemblyMachineCode[3]; 214 + u16 wMemoryMakerCode; 215 + u16 wMemoryDeviceCode; 216 + u16 wMemorySize; 217 + u8 bReserved1; 218 + u8 bReserved2; 219 + u8 bVCC; 220 + u8 bVPP; 221 + u16 wControllerChipNumber; 222 + u16 wControllerFunction; /* New MS */ 223 + u8 bReserved3[9]; /* New MS */ 224 + u8 bParallelSupport; /* New MS */ 225 + u16 wFormatValue; /* New MS */ 226 + u8 bFormatType; 227 + u8 bUsage; 228 + u8 bDeviceType; 229 + u8 bReserved4[22]; 230 + u8 bFUValue3; 231 + u8 bFUValue4; 232 + u8 bReserved5[15]; 233 + }; 234 + 235 + struct ms_bootblock_header { 236 + u16 wBlockID; 237 + u16 wFormatVersion; 238 + u8 bReserved1[184]; 239 + u8 bNumberOfDataEntry; 240 + u8 bReserved2[179]; 241 + }; 242 + 243 + struct ms_bootblock_page0 { 244 + struct ms_bootblock_header header; 245 + struct ms_bootblock_sysent sysent; 246 + struct ms_bootblock_sysinf sysinf; 247 + }; 248 + 249 + struct ms_bootblock_cis_idi { 250 + union { 251 + struct ms_bootblock_cis cis; 252 + u8 dmy[256]; 253 + } cis; 254 + 255 + union { 256 + struct ms_bootblock_idi idi; 257 + u8 dmy[256]; 258 + } idi; 259 + 260 + }; 261 + 262 + /* ENE MS Lib struct */ 263 + struct ms_lib_type_extdat { 264 + u8 reserved; 265 + u8 intr; 266 + u8 status0; 267 + u8 status1; 268 + u8 ovrflg; 269 + u8 mngflg; 270 + u16 logadr; 271 + }; 272 + 273 + struct ms_lib_ctrl { 274 + u32 flags; 275 + u32 BytesPerSector; 276 + u32 NumberOfCylinder; 277 + u32 SectorsPerCylinder; 278 + u16 cardType; /* R/W, RO, Hybrid */ 279 + u16 blockSize; 280 + u16 PagesPerBlock; 281 + u16 NumberOfPhyBlock; 282 + u16 NumberOfLogBlock; 283 + u16 NumberOfSegment; 284 + u16 *Phy2LogMap; /* phy2log table */ 285 + u16 *Log2PhyMap; /* log2phy table */ 286 + u16 wrtblk; 287 + unsigned char *pagemap[(MS_MAX_PAGES_PER_BLOCK + (MS_LIB_BITS_PER_BYTE-1)) / MS_LIB_BITS_PER_BYTE]; 288 + unsigned char *blkpag; 289 + struct ms_lib_type_extdat *blkext; 290 + unsigned char copybuf[512]; 291 + }; 292 + 270 293 271 294 /* SD Block Length */ 272 295 /* 2^9 = 512 Bytes, The HW maximum read/write data length */ ··· 455 162 /*----- MS Control Data ---------------- */ 456 163 bool MS_SWWP; 457 164 u32 MSP_TotalBlock; 458 - /*MS_LibControl MS_Lib;*/ 165 + struct ms_lib_ctrl MS_Lib; 459 166 bool MS_IsRWPage; 460 167 u16 MS_Model; 461 168 ··· 473 180 }; 474 181 475 182 static int ene_sd_init(struct us_data *us); 183 + static int ene_ms_init(struct us_data *us); 476 184 static int ene_load_bincode(struct us_data *us, unsigned char flag); 477 185 478 186 static void ene_ub6250_info_destructor(void *extra) ··· 725 431 return result; 726 432 } 727 433 434 + /* 435 + * ENE MS Card 436 + */ 437 + 438 + static int ms_lib_set_logicalpair(struct us_data *us, u16 logblk, u16 phyblk) 439 + { 440 + struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra; 441 + 442 + if ((logblk >= info->MS_Lib.NumberOfLogBlock) || (phyblk >= info->MS_Lib.NumberOfPhyBlock)) 443 + return (u32)-1; 444 + 445 + info->MS_Lib.Phy2LogMap[phyblk] = logblk; 446 + info->MS_Lib.Log2PhyMap[logblk] = phyblk; 447 + 448 + return 0; 449 + } 450 + 451 + static int ms_lib_set_logicalblockmark(struct us_data *us, u16 phyblk, u16 mark) 452 + { 453 + struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra; 454 + 455 + if (phyblk >= info->MS_Lib.NumberOfPhyBlock) 456 + return (u32)-1; 457 + 458 + info->MS_Lib.Phy2LogMap[phyblk] = mark; 459 + 460 + return 0; 461 + } 462 + 463 + static int ms_lib_set_initialerrorblock(struct us_data *us, u16 phyblk) 464 + { 465 + return ms_lib_set_logicalblockmark(us, phyblk, MS_LB_INITIAL_ERROR); 466 + } 467 + 468 + static int ms_lib_set_bootblockmark(struct us_data *us, u16 phyblk) 469 + { 470 + return ms_lib_set_logicalblockmark(us, phyblk, MS_LB_BOOT_BLOCK); 471 + } 472 + 473 + static int ms_lib_free_logicalmap(struct us_data *us) 474 + { 475 + struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra; 476 + 477 + kfree(info->MS_Lib.Phy2LogMap); 478 + info->MS_Lib.Phy2LogMap = NULL; 479 + 480 + kfree(info->MS_Lib.Log2PhyMap); 481 + info->MS_Lib.Log2PhyMap = NULL; 482 + 483 + return 0; 484 + } 485 + 486 + int ms_lib_alloc_logicalmap(struct us_data *us) 487 + { 488 + u32 i; 489 + struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra; 490 + 491 + info->MS_Lib.Phy2LogMap = kmalloc(info->MS_Lib.NumberOfPhyBlock * sizeof(u16), GFP_KERNEL); 492 + info->MS_Lib.Log2PhyMap = kmalloc(info->MS_Lib.NumberOfLogBlock * sizeof(u16), GFP_KERNEL); 493 + 494 + if ((info->MS_Lib.Phy2LogMap == NULL) || (info->MS_Lib.Log2PhyMap == NULL)) { 495 + ms_lib_free_logicalmap(us); 496 + return (u32)-1; 497 + } 498 + 499 + for (i = 0; i < info->MS_Lib.NumberOfPhyBlock; i++) 500 + info->MS_Lib.Phy2LogMap[i] = MS_LB_NOT_USED; 501 + 502 + for (i = 0; i < info->MS_Lib.NumberOfLogBlock; i++) 503 + info->MS_Lib.Log2PhyMap[i] = MS_LB_NOT_USED; 504 + 505 + return 0; 506 + } 507 + 508 + static void ms_lib_clear_writebuf(struct us_data *us) 509 + { 510 + int i; 511 + struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra; 512 + 513 + info->MS_Lib.wrtblk = (u16)-1; 514 + ms_lib_clear_pagemap(info); 515 + 516 + if (info->MS_Lib.blkpag) 517 + memset(info->MS_Lib.blkpag, 0xff, info->MS_Lib.PagesPerBlock * info->MS_Lib.BytesPerSector); 518 + 519 + if (info->MS_Lib.blkext) { 520 + for (i = 0; i < info->MS_Lib.PagesPerBlock; i++) { 521 + info->MS_Lib.blkext[i].status1 = MS_REG_ST1_DEFAULT; 522 + info->MS_Lib.blkext[i].ovrflg = MS_REG_OVR_DEFAULT; 523 + info->MS_Lib.blkext[i].mngflg = MS_REG_MNG_DEFAULT; 524 + info->MS_Lib.blkext[i].logadr = MS_LB_NOT_USED; 525 + } 526 + } 527 + } 528 + 529 + static int ms_count_freeblock(struct us_data *us, u16 PhyBlock) 530 + { 531 + u32 Ende, Count; 532 + struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra; 533 + 534 + Ende = PhyBlock + MS_PHYSICAL_BLOCKS_PER_SEGMENT; 535 + for (Count = 0; PhyBlock < Ende; PhyBlock++) { 536 + switch (info->MS_Lib.Phy2LogMap[PhyBlock]) { 537 + case MS_LB_NOT_USED: 538 + case MS_LB_NOT_USED_ERASED: 539 + Count++; 540 + default: 541 + break; 542 + } 543 + } 544 + 545 + return Count; 546 + } 547 + 548 + static int ms_read_readpage(struct us_data *us, u32 PhyBlockAddr, 549 + u8 PageNum, u32 *PageBuf, struct ms_lib_type_extdat *ExtraDat) 550 + { 551 + struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf; 552 + int result; 553 + u8 ExtBuf[4]; 554 + u32 bn = PhyBlockAddr * 0x20 + PageNum; 555 + 556 + /* printk(KERN_INFO "MS --- MS_ReaderReadPage, 557 + PhyBlockAddr = %x, PageNum = %x\n", PhyBlockAddr, PageNum); */ 558 + 559 + result = ene_load_bincode(us, MS_RW_PATTERN); 560 + if (result != USB_STOR_XFER_GOOD) 561 + return USB_STOR_TRANSPORT_ERROR; 562 + 563 + /* Read Page Data */ 564 + memset(bcb, 0, sizeof(struct bulk_cb_wrap)); 565 + bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); 566 + bcb->DataTransferLength = 0x200; 567 + bcb->Flags = 0x80; 568 + bcb->CDB[0] = 0xF1; 569 + 570 + bcb->CDB[1] = 0x02; /* in init.c ENE_MSInit() is 0x01 */ 571 + 572 + bcb->CDB[5] = (unsigned char)(bn); 573 + bcb->CDB[4] = (unsigned char)(bn>>8); 574 + bcb->CDB[3] = (unsigned char)(bn>>16); 575 + bcb->CDB[2] = (unsigned char)(bn>>24); 576 + 577 + result = ene_send_scsi_cmd(us, FDIR_READ, PageBuf, 0); 578 + if (result != USB_STOR_XFER_GOOD) 579 + return USB_STOR_TRANSPORT_ERROR; 580 + 581 + 582 + /* Read Extra Data */ 583 + memset(bcb, 0, sizeof(struct bulk_cb_wrap)); 584 + bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); 585 + bcb->DataTransferLength = 0x4; 586 + bcb->Flags = 0x80; 587 + bcb->CDB[0] = 0xF1; 588 + bcb->CDB[1] = 0x03; 589 + 590 + bcb->CDB[5] = (unsigned char)(PageNum); 591 + bcb->CDB[4] = (unsigned char)(PhyBlockAddr); 592 + bcb->CDB[3] = (unsigned char)(PhyBlockAddr>>8); 593 + bcb->CDB[2] = (unsigned char)(PhyBlockAddr>>16); 594 + bcb->CDB[6] = 0x01; 595 + 596 + result = ene_send_scsi_cmd(us, FDIR_READ, &ExtBuf, 0); 597 + if (result != USB_STOR_XFER_GOOD) 598 + return USB_STOR_TRANSPORT_ERROR; 599 + 600 + ExtraDat->reserved = 0; 601 + ExtraDat->intr = 0x80; /* Not yet,fireware support */ 602 + ExtraDat->status0 = 0x10; /* Not yet,fireware support */ 603 + 604 + ExtraDat->status1 = 0x00; /* Not yet,fireware support */ 605 + ExtraDat->ovrflg = ExtBuf[0]; 606 + ExtraDat->mngflg = ExtBuf[1]; 607 + ExtraDat->logadr = memstick_logaddr(ExtBuf[2], ExtBuf[3]); 608 + 609 + return USB_STOR_TRANSPORT_GOOD; 610 + } 611 + 612 + static int ms_lib_process_bootblock(struct us_data *us, u16 PhyBlock, u8 *PageData) 613 + { 614 + struct ms_bootblock_sysent *SysEntry; 615 + struct ms_bootblock_sysinf *SysInfo; 616 + u32 i, result; 617 + u8 PageNumber; 618 + u8 *PageBuffer; 619 + struct ms_lib_type_extdat ExtraData; 620 + struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra; 621 + 622 + PageBuffer = kmalloc(MS_BYTES_PER_PAGE, GFP_KERNEL); 623 + if (PageBuffer == NULL) 624 + return (u32)-1; 625 + 626 + result = (u32)-1; 627 + 628 + SysInfo = &(((struct ms_bootblock_page0 *)PageData)->sysinf); 629 + 630 + if ((SysInfo->bMsClass != MS_SYSINF_MSCLASS_TYPE_1) || 631 + (be16_to_cpu(SysInfo->wPageSize) != MS_SYSINF_PAGE_SIZE) || 632 + ((SysInfo->bSecuritySupport & MS_SYSINF_SECURITY) == MS_SYSINF_SECURITY_SUPPORT) || 633 + (SysInfo->bReserved1 != MS_SYSINF_RESERVED1) || 634 + (SysInfo->bReserved2 != MS_SYSINF_RESERVED2) || 635 + (SysInfo->bFormatType != MS_SYSINF_FORMAT_FAT) || 636 + (SysInfo->bUsage != MS_SYSINF_USAGE_GENERAL)) 637 + goto exit; 638 + /* */ 639 + switch (info->MS_Lib.cardType = SysInfo->bCardType) { 640 + case MS_SYSINF_CARDTYPE_RDONLY: 641 + ms_lib_ctrl_set(info, MS_LIB_CTRL_RDONLY); 642 + break; 643 + case MS_SYSINF_CARDTYPE_RDWR: 644 + ms_lib_ctrl_reset(info, MS_LIB_CTRL_RDONLY); 645 + break; 646 + case MS_SYSINF_CARDTYPE_HYBRID: 647 + default: 648 + goto exit; 649 + } 650 + 651 + info->MS_Lib.blockSize = be16_to_cpu(SysInfo->wBlockSize); 652 + info->MS_Lib.NumberOfPhyBlock = be16_to_cpu(SysInfo->wBlockNumber); 653 + info->MS_Lib.NumberOfLogBlock = be16_to_cpu(SysInfo->wTotalBlockNumber)-2; 654 + info->MS_Lib.PagesPerBlock = info->MS_Lib.blockSize * SIZE_OF_KIRO / MS_BYTES_PER_PAGE; 655 + info->MS_Lib.NumberOfSegment = info->MS_Lib.NumberOfPhyBlock / MS_PHYSICAL_BLOCKS_PER_SEGMENT; 656 + info->MS_Model = be16_to_cpu(SysInfo->wMemorySize); 657 + 658 + /*Allocate to all number of logicalblock and physicalblock */ 659 + if (ms_lib_alloc_logicalmap(us)) 660 + goto exit; 661 + 662 + /* Mark the book block */ 663 + ms_lib_set_bootblockmark(us, PhyBlock); 664 + 665 + SysEntry = &(((struct ms_bootblock_page0 *)PageData)->sysent); 666 + 667 + for (i = 0; i < MS_NUMBER_OF_SYSTEM_ENTRY; i++) { 668 + u32 EntryOffset, EntrySize; 669 + 670 + EntryOffset = be32_to_cpu(SysEntry->entry[i].dwStart); 671 + 672 + if (EntryOffset == 0xffffff) 673 + continue; 674 + EntrySize = be32_to_cpu(SysEntry->entry[i].dwSize); 675 + 676 + if (EntrySize == 0) 677 + continue; 678 + 679 + if (EntryOffset + MS_BYTES_PER_PAGE + EntrySize > info->MS_Lib.blockSize * (u32)SIZE_OF_KIRO) 680 + continue; 681 + 682 + if (i == 0) { 683 + u8 PrevPageNumber = 0; 684 + u16 phyblk; 685 + 686 + if (SysEntry->entry[i].bType != MS_SYSENT_TYPE_INVALID_BLOCK) 687 + goto exit; 688 + 689 + while (EntrySize > 0) { 690 + 691 + PageNumber = (u8)(EntryOffset / MS_BYTES_PER_PAGE + 1); 692 + if (PageNumber != PrevPageNumber) { 693 + switch (ms_read_readpage(us, PhyBlock, PageNumber, (u32 *)PageBuffer, &ExtraData)) { 694 + case MS_STATUS_SUCCESS: 695 + break; 696 + case MS_STATUS_WRITE_PROTECT: 697 + case MS_ERROR_FLASH_READ: 698 + case MS_STATUS_ERROR: 699 + default: 700 + goto exit; 701 + } 702 + 703 + PrevPageNumber = PageNumber; 704 + } 705 + 706 + phyblk = be16_to_cpu(*(u16 *)(PageBuffer + (EntryOffset % MS_BYTES_PER_PAGE))); 707 + if (phyblk < 0x0fff) 708 + ms_lib_set_initialerrorblock(us, phyblk); 709 + 710 + EntryOffset += 2; 711 + EntrySize -= 2; 712 + } 713 + } else if (i == 1) { /* CIS/IDI */ 714 + struct ms_bootblock_idi *idi; 715 + 716 + if (SysEntry->entry[i].bType != MS_SYSENT_TYPE_CIS_IDI) 717 + goto exit; 718 + 719 + switch (ms_read_readpage(us, PhyBlock, (u8)(EntryOffset / MS_BYTES_PER_PAGE + 1), (u32 *)PageBuffer, &ExtraData)) { 720 + case MS_STATUS_SUCCESS: 721 + break; 722 + case MS_STATUS_WRITE_PROTECT: 723 + case MS_ERROR_FLASH_READ: 724 + case MS_STATUS_ERROR: 725 + default: 726 + goto exit; 727 + } 728 + 729 + idi = &((struct ms_bootblock_cis_idi *)(PageBuffer + (EntryOffset % MS_BYTES_PER_PAGE)))->idi.idi; 730 + if (le16_to_cpu(idi->wIDIgeneralConfiguration) != MS_IDI_GENERAL_CONF) 731 + goto exit; 732 + 733 + info->MS_Lib.BytesPerSector = le16_to_cpu(idi->wIDIbytesPerSector); 734 + if (info->MS_Lib.BytesPerSector != MS_BYTES_PER_PAGE) 735 + goto exit; 736 + } 737 + } /* End for .. */ 738 + 739 + result = 0; 740 + 741 + exit: 742 + if (result) 743 + ms_lib_free_logicalmap(us); 744 + 745 + kfree(PageBuffer); 746 + 747 + result = 0; 748 + return result; 749 + } 750 + 751 + static void ms_lib_free_writebuf(struct us_data *us) 752 + { 753 + struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra; 754 + info->MS_Lib.wrtblk = (u16)-1; /* set to -1 */ 755 + 756 + /* memset((fdoExt)->MS_Lib.pagemap, 0, sizeof((fdoExt)->MS_Lib.pagemap)) */ 757 + 758 + ms_lib_clear_pagemap(info); /* (pdx)->MS_Lib.pagemap memset 0 in ms.h */ 759 + 760 + if (info->MS_Lib.blkpag) { 761 + kfree((u8 *)(info->MS_Lib.blkpag)); /* Arnold test ... */ 762 + info->MS_Lib.blkpag = NULL; 763 + } 764 + 765 + if (info->MS_Lib.blkext) { 766 + kfree((u8 *)(info->MS_Lib.blkext)); /* Arnold test ... */ 767 + info->MS_Lib.blkext = NULL; 768 + } 769 + } 770 + 771 + 772 + static void ms_lib_free_allocatedarea(struct us_data *us) 773 + { 774 + struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra; 775 + 776 + ms_lib_free_writebuf(us); /* Free MS_Lib.pagemap */ 777 + ms_lib_free_logicalmap(us); /* kfree MS_Lib.Phy2LogMap and MS_Lib.Log2PhyMap */ 778 + 779 + /* set struct us point flag to 0 */ 780 + info->MS_Lib.flags = 0; 781 + info->MS_Lib.BytesPerSector = 0; 782 + info->MS_Lib.SectorsPerCylinder = 0; 783 + 784 + info->MS_Lib.cardType = 0; 785 + info->MS_Lib.blockSize = 0; 786 + info->MS_Lib.PagesPerBlock = 0; 787 + 788 + info->MS_Lib.NumberOfPhyBlock = 0; 789 + info->MS_Lib.NumberOfLogBlock = 0; 790 + } 791 + 792 + 793 + static int ms_lib_alloc_writebuf(struct us_data *us) 794 + { 795 + struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra; 796 + 797 + info->MS_Lib.wrtblk = (u16)-1; 798 + 799 + info->MS_Lib.blkpag = kmalloc(info->MS_Lib.PagesPerBlock * info->MS_Lib.BytesPerSector, GFP_KERNEL); 800 + info->MS_Lib.blkext = kmalloc(info->MS_Lib.PagesPerBlock * sizeof(struct ms_lib_type_extdat), GFP_KERNEL); 801 + 802 + if ((info->MS_Lib.blkpag == NULL) || (info->MS_Lib.blkext == NULL)) { 803 + ms_lib_free_writebuf(us); 804 + return (u32)-1; 805 + } 806 + 807 + ms_lib_clear_writebuf(us); 808 + 809 + return 0; 810 + } 811 + 812 + static int ms_lib_force_setlogical_pair(struct us_data *us, u16 logblk, u16 phyblk) 813 + { 814 + struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra; 815 + 816 + if (logblk == MS_LB_NOT_USED) 817 + return 0; 818 + 819 + if ((logblk >= info->MS_Lib.NumberOfLogBlock) || 820 + (phyblk >= info->MS_Lib.NumberOfPhyBlock)) 821 + return (u32)-1; 822 + 823 + info->MS_Lib.Phy2LogMap[phyblk] = logblk; 824 + info->MS_Lib.Log2PhyMap[logblk] = phyblk; 825 + 826 + return 0; 827 + } 828 + 829 + static int ms_read_copyblock(struct us_data *us, u16 oldphy, u16 newphy, 830 + u16 PhyBlockAddr, u8 PageNum, unsigned char *buf, u16 len) 831 + { 832 + struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf; 833 + int result; 834 + 835 + /* printk(KERN_INFO "MS_ReaderCopyBlock --- PhyBlockAddr = %x, 836 + PageNum = %x\n", PhyBlockAddr, PageNum); */ 837 + result = ene_load_bincode(us, MS_RW_PATTERN); 838 + if (result != USB_STOR_XFER_GOOD) 839 + return USB_STOR_TRANSPORT_ERROR; 840 + 841 + memset(bcb, 0, sizeof(struct bulk_cb_wrap)); 842 + bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); 843 + bcb->DataTransferLength = 0x200*len; 844 + bcb->Flags = 0x00; 845 + bcb->CDB[0] = 0xF0; 846 + bcb->CDB[1] = 0x08; 847 + bcb->CDB[4] = (unsigned char)(oldphy); 848 + bcb->CDB[3] = (unsigned char)(oldphy>>8); 849 + bcb->CDB[2] = 0; /* (BYTE)(oldphy>>16) */ 850 + bcb->CDB[7] = (unsigned char)(newphy); 851 + bcb->CDB[6] = (unsigned char)(newphy>>8); 852 + bcb->CDB[5] = 0; /* (BYTE)(newphy>>16) */ 853 + bcb->CDB[9] = (unsigned char)(PhyBlockAddr); 854 + bcb->CDB[8] = (unsigned char)(PhyBlockAddr>>8); 855 + bcb->CDB[10] = PageNum; 856 + 857 + result = ene_send_scsi_cmd(us, FDIR_WRITE, buf, 0); 858 + if (result != USB_STOR_XFER_GOOD) 859 + return USB_STOR_TRANSPORT_ERROR; 860 + 861 + return USB_STOR_TRANSPORT_GOOD; 862 + } 863 + 864 + static int ms_read_eraseblock(struct us_data *us, u32 PhyBlockAddr) 865 + { 866 + struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf; 867 + int result; 868 + u32 bn = PhyBlockAddr; 869 + 870 + /* printk(KERN_INFO "MS --- ms_read_eraseblock, 871 + PhyBlockAddr = %x\n", PhyBlockAddr); */ 872 + result = ene_load_bincode(us, MS_RW_PATTERN); 873 + if (result != USB_STOR_XFER_GOOD) 874 + return USB_STOR_TRANSPORT_ERROR; 875 + 876 + memset(bcb, 0, sizeof(struct bulk_cb_wrap)); 877 + bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); 878 + bcb->DataTransferLength = 0x200; 879 + bcb->Flags = 0x80; 880 + bcb->CDB[0] = 0xF2; 881 + bcb->CDB[1] = 0x06; 882 + bcb->CDB[4] = (unsigned char)(bn); 883 + bcb->CDB[3] = (unsigned char)(bn>>8); 884 + bcb->CDB[2] = (unsigned char)(bn>>16); 885 + 886 + result = ene_send_scsi_cmd(us, FDIR_READ, NULL, 0); 887 + if (result != USB_STOR_XFER_GOOD) 888 + return USB_STOR_TRANSPORT_ERROR; 889 + 890 + return USB_STOR_TRANSPORT_GOOD; 891 + } 892 + 893 + static int ms_lib_check_disableblock(struct us_data *us, u16 PhyBlock) 894 + { 895 + unsigned char *PageBuf = NULL; 896 + u16 result = MS_STATUS_SUCCESS; 897 + u16 blk, index = 0; 898 + struct ms_lib_type_extdat extdat; 899 + struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra; 900 + 901 + PageBuf = kmalloc(MS_BYTES_PER_PAGE, GFP_KERNEL); 902 + if (PageBuf == NULL) { 903 + result = MS_NO_MEMORY_ERROR; 904 + goto exit; 905 + } 906 + 907 + ms_read_readpage(us, PhyBlock, 1, (u32 *)PageBuf, &extdat); 908 + do { 909 + blk = be16_to_cpu(PageBuf[index]); 910 + if (blk == MS_LB_NOT_USED) 911 + break; 912 + if (blk == info->MS_Lib.Log2PhyMap[0]) { 913 + result = MS_ERROR_FLASH_READ; 914 + break; 915 + } 916 + index++; 917 + } while (1); 918 + 919 + exit: 920 + kfree(PageBuf); 921 + return result; 922 + } 923 + 924 + static int ms_lib_setacquired_errorblock(struct us_data *us, u16 phyblk) 925 + { 926 + u16 log; 927 + struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra; 928 + 929 + if (phyblk >= info->MS_Lib.NumberOfPhyBlock) 930 + return (u32)-1; 931 + 932 + log = info->MS_Lib.Phy2LogMap[phyblk]; 933 + 934 + if (log < info->MS_Lib.NumberOfLogBlock) 935 + info->MS_Lib.Log2PhyMap[log] = MS_LB_NOT_USED; 936 + 937 + if (info->MS_Lib.Phy2LogMap[phyblk] != MS_LB_INITIAL_ERROR) 938 + info->MS_Lib.Phy2LogMap[phyblk] = MS_LB_ACQUIRED_ERROR; 939 + 940 + return 0; 941 + } 942 + 943 + static int ms_lib_overwrite_extra(struct us_data *us, u32 PhyBlockAddr, 944 + u8 PageNum, u8 OverwriteFlag) 945 + { 946 + struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf; 947 + int result; 948 + 949 + /* printk("MS --- MS_LibOverwriteExtra, 950 + PhyBlockAddr = %x, PageNum = %x\n", PhyBlockAddr, PageNum); */ 951 + result = ene_load_bincode(us, MS_RW_PATTERN); 952 + if (result != USB_STOR_XFER_GOOD) 953 + return USB_STOR_TRANSPORT_ERROR; 954 + 955 + memset(bcb, 0, sizeof(struct bulk_cb_wrap)); 956 + bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); 957 + bcb->DataTransferLength = 0x4; 958 + bcb->Flags = 0x80; 959 + bcb->CDB[0] = 0xF2; 960 + bcb->CDB[1] = 0x05; 961 + bcb->CDB[5] = (unsigned char)(PageNum); 962 + bcb->CDB[4] = (unsigned char)(PhyBlockAddr); 963 + bcb->CDB[3] = (unsigned char)(PhyBlockAddr>>8); 964 + bcb->CDB[2] = (unsigned char)(PhyBlockAddr>>16); 965 + bcb->CDB[6] = OverwriteFlag; 966 + bcb->CDB[7] = 0xFF; 967 + bcb->CDB[8] = 0xFF; 968 + bcb->CDB[9] = 0xFF; 969 + 970 + result = ene_send_scsi_cmd(us, FDIR_READ, NULL, 0); 971 + if (result != USB_STOR_XFER_GOOD) 972 + return USB_STOR_TRANSPORT_ERROR; 973 + 974 + return USB_STOR_TRANSPORT_GOOD; 975 + } 976 + 977 + static int ms_lib_error_phyblock(struct us_data *us, u16 phyblk) 978 + { 979 + struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra; 980 + 981 + if (phyblk >= info->MS_Lib.NumberOfPhyBlock) 982 + return MS_STATUS_ERROR; 983 + 984 + ms_lib_setacquired_errorblock(us, phyblk); 985 + 986 + if (ms_lib_iswritable(info)) 987 + return ms_lib_overwrite_extra(us, phyblk, 0, (u8)(~MS_REG_OVR_BKST & BYTE_MASK)); 988 + 989 + return MS_STATUS_SUCCESS; 990 + } 991 + 992 + static int ms_lib_erase_phyblock(struct us_data *us, u16 phyblk) 993 + { 994 + u16 log; 995 + struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra; 996 + 997 + if (phyblk >= info->MS_Lib.NumberOfPhyBlock) 998 + return MS_STATUS_ERROR; 999 + 1000 + log = info->MS_Lib.Phy2LogMap[phyblk]; 1001 + 1002 + if (log < info->MS_Lib.NumberOfLogBlock) 1003 + info->MS_Lib.Log2PhyMap[log] = MS_LB_NOT_USED; 1004 + 1005 + info->MS_Lib.Phy2LogMap[phyblk] = MS_LB_NOT_USED; 1006 + 1007 + if (ms_lib_iswritable(info)) { 1008 + switch (ms_read_eraseblock(us, phyblk)) { 1009 + case MS_STATUS_SUCCESS: 1010 + info->MS_Lib.Phy2LogMap[phyblk] = MS_LB_NOT_USED_ERASED; 1011 + return MS_STATUS_SUCCESS; 1012 + case MS_ERROR_FLASH_ERASE: 1013 + case MS_STATUS_INT_ERROR: 1014 + ms_lib_error_phyblock(us, phyblk); 1015 + return MS_ERROR_FLASH_ERASE; 1016 + case MS_STATUS_ERROR: 1017 + default: 1018 + ms_lib_ctrl_set(info, MS_LIB_CTRL_RDONLY); /* MS_LibCtrlSet will used by ENE_MSInit ,need check, and why us to info*/ 1019 + ms_lib_setacquired_errorblock(us, phyblk); 1020 + return MS_STATUS_ERROR; 1021 + } 1022 + } 1023 + 1024 + ms_lib_setacquired_errorblock(us, phyblk); 1025 + 1026 + return MS_STATUS_SUCCESS; 1027 + } 1028 + 1029 + static int ms_lib_read_extra(struct us_data *us, u32 PhyBlock, 1030 + u8 PageNum, struct ms_lib_type_extdat *ExtraDat) 1031 + { 1032 + struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf; 1033 + int result; 1034 + u8 ExtBuf[4]; 1035 + 1036 + /* printk("MS_LibReadExtra --- PhyBlock = %x, PageNum = %x\n", PhyBlock, PageNum); */ 1037 + memset(bcb, 0, sizeof(struct bulk_cb_wrap)); 1038 + bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); 1039 + bcb->DataTransferLength = 0x4; 1040 + bcb->Flags = 0x80; 1041 + bcb->CDB[0] = 0xF1; 1042 + bcb->CDB[1] = 0x03; 1043 + bcb->CDB[5] = (unsigned char)(PageNum); 1044 + bcb->CDB[4] = (unsigned char)(PhyBlock); 1045 + bcb->CDB[3] = (unsigned char)(PhyBlock>>8); 1046 + bcb->CDB[2] = (unsigned char)(PhyBlock>>16); 1047 + bcb->CDB[6] = 0x01; 1048 + 1049 + result = ene_send_scsi_cmd(us, FDIR_READ, &ExtBuf, 0); 1050 + if (result != USB_STOR_XFER_GOOD) 1051 + return USB_STOR_TRANSPORT_ERROR; 1052 + 1053 + ExtraDat->reserved = 0; 1054 + ExtraDat->intr = 0x80; /* Not yet, waiting for fireware support */ 1055 + ExtraDat->status0 = 0x10; /* Not yet, waiting for fireware support */ 1056 + ExtraDat->status1 = 0x00; /* Not yet, waiting for fireware support */ 1057 + ExtraDat->ovrflg = ExtBuf[0]; 1058 + ExtraDat->mngflg = ExtBuf[1]; 1059 + ExtraDat->logadr = memstick_logaddr(ExtBuf[2], ExtBuf[3]); 1060 + 1061 + return USB_STOR_TRANSPORT_GOOD; 1062 + } 1063 + 1064 + static int ms_libsearch_block_from_physical(struct us_data *us, u16 phyblk) 1065 + { 1066 + u16 Newblk; 1067 + u16 blk; 1068 + struct ms_lib_type_extdat extdat; /* need check */ 1069 + struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra; 1070 + 1071 + 1072 + if (phyblk >= info->MS_Lib.NumberOfPhyBlock) 1073 + return MS_LB_ERROR; 1074 + 1075 + for (blk = phyblk + 1; blk != phyblk; blk++) { 1076 + if ((blk & MS_PHYSICAL_BLOCKS_PER_SEGMENT_MASK) == 0) 1077 + blk -= MS_PHYSICAL_BLOCKS_PER_SEGMENT; 1078 + 1079 + Newblk = info->MS_Lib.Phy2LogMap[blk]; 1080 + if (info->MS_Lib.Phy2LogMap[blk] == MS_LB_NOT_USED_ERASED) { 1081 + return blk; 1082 + } else if (info->MS_Lib.Phy2LogMap[blk] == MS_LB_NOT_USED) { 1083 + switch (ms_lib_read_extra(us, blk, 0, &extdat)) { 1084 + case MS_STATUS_SUCCESS: 1085 + case MS_STATUS_SUCCESS_WITH_ECC: 1086 + break; 1087 + case MS_NOCARD_ERROR: 1088 + return MS_NOCARD_ERROR; 1089 + case MS_STATUS_INT_ERROR: 1090 + return MS_LB_ERROR; 1091 + case MS_ERROR_FLASH_READ: 1092 + default: 1093 + ms_lib_setacquired_errorblock(us, blk); 1094 + continue; 1095 + } /* End switch */ 1096 + 1097 + if ((extdat.ovrflg & MS_REG_OVR_BKST) != MS_REG_OVR_BKST_OK) { 1098 + ms_lib_setacquired_errorblock(us, blk); 1099 + continue; 1100 + } 1101 + 1102 + switch (ms_lib_erase_phyblock(us, blk)) { 1103 + case MS_STATUS_SUCCESS: 1104 + return blk; 1105 + case MS_STATUS_ERROR: 1106 + return MS_LB_ERROR; 1107 + case MS_ERROR_FLASH_ERASE: 1108 + default: 1109 + ms_lib_error_phyblock(us, blk); 1110 + break; 1111 + } 1112 + } 1113 + } /* End for */ 1114 + 1115 + return MS_LB_ERROR; 1116 + } 1117 + static int ms_libsearch_block_from_logical(struct us_data *us, u16 logblk) 1118 + { 1119 + u16 phyblk; 1120 + struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra; 1121 + 1122 + phyblk = ms_libconv_to_physical(info, logblk); 1123 + if (phyblk >= MS_LB_ERROR) { 1124 + if (logblk >= info->MS_Lib.NumberOfLogBlock) 1125 + return MS_LB_ERROR; 1126 + 1127 + phyblk = (logblk + MS_NUMBER_OF_BOOT_BLOCK) / MS_LOGICAL_BLOCKS_PER_SEGMENT; 1128 + phyblk *= MS_PHYSICAL_BLOCKS_PER_SEGMENT; 1129 + phyblk += MS_PHYSICAL_BLOCKS_PER_SEGMENT - 1; 1130 + } 1131 + 1132 + return ms_libsearch_block_from_physical(us, phyblk); 1133 + } 1134 + 1135 + static int ms_scsi_test_unit_ready(struct us_data *us, struct scsi_cmnd *srb) 1136 + { 1137 + struct ene_ub6250_info *info = (struct ene_ub6250_info *)(us->extra); 1138 + 1139 + /* pr_info("MS_SCSI_Test_Unit_Ready\n"); */ 1140 + if (info->MS_Status.Insert && info->MS_Status.Ready) { 1141 + return USB_STOR_TRANSPORT_GOOD; 1142 + } else { 1143 + ene_ms_init(us); 1144 + return USB_STOR_TRANSPORT_GOOD; 1145 + } 1146 + 1147 + return USB_STOR_TRANSPORT_GOOD; 1148 + } 1149 + 1150 + static int ms_scsi_inquiry(struct us_data *us, struct scsi_cmnd *srb) 1151 + { 1152 + /* pr_info("MS_SCSI_Inquiry\n"); */ 1153 + unsigned char data_ptr[36] = { 1154 + 0x00, 0x80, 0x02, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x55, 1155 + 0x53, 0x42, 0x32, 0x2E, 0x30, 0x20, 0x20, 0x43, 0x61, 1156 + 0x72, 0x64, 0x52, 0x65, 0x61, 0x64, 0x65, 0x72, 0x20, 1157 + 0x20, 0x20, 0x20, 0x20, 0x20, 0x30, 0x31, 0x30, 0x30}; 1158 + 1159 + usb_stor_set_xfer_buf(data_ptr, 36, srb); 1160 + return USB_STOR_TRANSPORT_GOOD; 1161 + } 1162 + 1163 + static int ms_scsi_mode_sense(struct us_data *us, struct scsi_cmnd *srb) 1164 + { 1165 + struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra; 1166 + unsigned char mediaNoWP[12] = { 1167 + 0x0b, 0x00, 0x00, 0x08, 0x00, 0x00, 1168 + 0x71, 0xc0, 0x00, 0x00, 0x02, 0x00 }; 1169 + unsigned char mediaWP[12] = { 1170 + 0x0b, 0x00, 0x80, 0x08, 0x00, 0x00, 1171 + 0x71, 0xc0, 0x00, 0x00, 0x02, 0x00 }; 1172 + 1173 + if (info->MS_Status.WtP) 1174 + usb_stor_set_xfer_buf(mediaWP, 12, srb); 1175 + else 1176 + usb_stor_set_xfer_buf(mediaNoWP, 12, srb); 1177 + 1178 + return USB_STOR_TRANSPORT_GOOD; 1179 + } 1180 + 1181 + static int ms_scsi_read_capacity(struct us_data *us, struct scsi_cmnd *srb) 1182 + { 1183 + u32 bl_num; 1184 + u16 bl_len; 1185 + unsigned int offset = 0; 1186 + unsigned char buf[8]; 1187 + struct scatterlist *sg = NULL; 1188 + struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra; 1189 + 1190 + US_DEBUGP("ms_scsi_read_capacity\n"); 1191 + bl_len = 0x200; 1192 + if (info->MS_Status.IsMSPro) 1193 + bl_num = info->MSP_TotalBlock - 1; 1194 + else 1195 + bl_num = info->MS_Lib.NumberOfLogBlock * info->MS_Lib.blockSize * 2 - 1; 1196 + 1197 + info->bl_num = bl_num; 1198 + US_DEBUGP("bl_len = %x\n", bl_len); 1199 + US_DEBUGP("bl_num = %x\n", bl_num); 1200 + 1201 + /*srb->request_bufflen = 8; */ 1202 + buf[0] = (bl_num >> 24) & 0xff; 1203 + buf[1] = (bl_num >> 16) & 0xff; 1204 + buf[2] = (bl_num >> 8) & 0xff; 1205 + buf[3] = (bl_num >> 0) & 0xff; 1206 + buf[4] = (bl_len >> 24) & 0xff; 1207 + buf[5] = (bl_len >> 16) & 0xff; 1208 + buf[6] = (bl_len >> 8) & 0xff; 1209 + buf[7] = (bl_len >> 0) & 0xff; 1210 + 1211 + usb_stor_access_xfer_buf(buf, 8, srb, &sg, &offset, TO_XFER_BUF); 1212 + 1213 + return USB_STOR_TRANSPORT_GOOD; 1214 + } 1215 + 1216 + static void ms_lib_phy_to_log_range(u16 PhyBlock, u16 *LogStart, u16 *LogEnde) 1217 + { 1218 + PhyBlock /= MS_PHYSICAL_BLOCKS_PER_SEGMENT; 1219 + 1220 + if (PhyBlock) { 1221 + *LogStart = MS_LOGICAL_BLOCKS_IN_1ST_SEGMENT + (PhyBlock - 1) * MS_LOGICAL_BLOCKS_PER_SEGMENT;/*496*/ 1222 + *LogEnde = *LogStart + MS_LOGICAL_BLOCKS_PER_SEGMENT;/*496*/ 1223 + } else { 1224 + *LogStart = 0; 1225 + *LogEnde = MS_LOGICAL_BLOCKS_IN_1ST_SEGMENT;/*494*/ 1226 + } 1227 + } 1228 + 1229 + static int ms_lib_read_extrablock(struct us_data *us, u32 PhyBlock, 1230 + u8 PageNum, u8 blen, void *buf) 1231 + { 1232 + struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf; 1233 + int result; 1234 + 1235 + /* printk("MS_LibReadExtraBlock --- PhyBlock = %x, 1236 + PageNum = %x, blen = %x\n", PhyBlock, PageNum, blen); */ 1237 + 1238 + /* Read Extra Data */ 1239 + memset(bcb, 0, sizeof(struct bulk_cb_wrap)); 1240 + bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); 1241 + bcb->DataTransferLength = 0x4 * blen; 1242 + bcb->Flags = 0x80; 1243 + bcb->CDB[0] = 0xF1; 1244 + bcb->CDB[1] = 0x03; 1245 + bcb->CDB[5] = (unsigned char)(PageNum); 1246 + bcb->CDB[4] = (unsigned char)(PhyBlock); 1247 + bcb->CDB[3] = (unsigned char)(PhyBlock>>8); 1248 + bcb->CDB[2] = (unsigned char)(PhyBlock>>16); 1249 + bcb->CDB[6] = blen; 1250 + 1251 + result = ene_send_scsi_cmd(us, FDIR_READ, buf, 0); 1252 + if (result != USB_STOR_XFER_GOOD) 1253 + return USB_STOR_TRANSPORT_ERROR; 1254 + 1255 + return USB_STOR_TRANSPORT_GOOD; 1256 + } 1257 + 1258 + static int ms_lib_scan_logicalblocknumber(struct us_data *us, u16 btBlk1st) 1259 + { 1260 + u16 PhyBlock, newblk, i; 1261 + u16 LogStart, LogEnde; 1262 + struct ms_lib_type_extdat extdat; 1263 + u8 buf[0x200]; 1264 + u32 count = 0, index = 0; 1265 + struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra; 1266 + 1267 + for (PhyBlock = 0; PhyBlock < info->MS_Lib.NumberOfPhyBlock;) { 1268 + ms_lib_phy_to_log_range(PhyBlock, &LogStart, &LogEnde); 1269 + 1270 + for (i = 0; i < MS_PHYSICAL_BLOCKS_PER_SEGMENT; i++, PhyBlock++) { 1271 + switch (ms_libconv_to_logical(info, PhyBlock)) { 1272 + case MS_STATUS_ERROR: 1273 + continue; 1274 + default: 1275 + break; 1276 + } 1277 + 1278 + if (count == PhyBlock) { 1279 + ms_lib_read_extrablock(us, PhyBlock, 0, 0x80, &buf); 1280 + count += 0x80; 1281 + } 1282 + index = (PhyBlock % 0x80) * 4; 1283 + 1284 + extdat.ovrflg = buf[index]; 1285 + extdat.mngflg = buf[index+1]; 1286 + extdat.logadr = memstick_logaddr(buf[index+2], buf[index+3]); 1287 + 1288 + if ((extdat.ovrflg & MS_REG_OVR_BKST) != MS_REG_OVR_BKST_OK) { 1289 + ms_lib_setacquired_errorblock(us, PhyBlock); 1290 + continue; 1291 + } 1292 + 1293 + if ((extdat.mngflg & MS_REG_MNG_ATFLG) == MS_REG_MNG_ATFLG_ATTBL) { 1294 + ms_lib_erase_phyblock(us, PhyBlock); 1295 + continue; 1296 + } 1297 + 1298 + if (extdat.logadr != MS_LB_NOT_USED) { 1299 + if ((extdat.logadr < LogStart) || (LogEnde <= extdat.logadr)) { 1300 + ms_lib_erase_phyblock(us, PhyBlock); 1301 + continue; 1302 + } 1303 + 1304 + newblk = ms_libconv_to_physical(info, extdat.logadr); 1305 + 1306 + if (newblk != MS_LB_NOT_USED) { 1307 + if (extdat.logadr == 0) { 1308 + ms_lib_set_logicalpair(us, extdat.logadr, PhyBlock); 1309 + if (ms_lib_check_disableblock(us, btBlk1st)) { 1310 + ms_lib_set_logicalpair(us, extdat.logadr, newblk); 1311 + continue; 1312 + } 1313 + } 1314 + 1315 + ms_lib_read_extra(us, newblk, 0, &extdat); 1316 + if ((extdat.ovrflg & MS_REG_OVR_UDST) == MS_REG_OVR_UDST_UPDATING) { 1317 + ms_lib_erase_phyblock(us, PhyBlock); 1318 + continue; 1319 + } else { 1320 + ms_lib_erase_phyblock(us, newblk); 1321 + } 1322 + } 1323 + 1324 + ms_lib_set_logicalpair(us, extdat.logadr, PhyBlock); 1325 + } 1326 + } 1327 + } /* End for ... */ 1328 + 1329 + return MS_STATUS_SUCCESS; 1330 + } 1331 + 1332 + 1333 + static int ms_scsi_read(struct us_data *us, struct scsi_cmnd *srb) 1334 + { 1335 + int result; 1336 + unsigned char *cdb = srb->cmnd; 1337 + struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf; 1338 + struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra; 1339 + 1340 + u32 bn = ((cdb[2] << 24) & 0xff000000) | ((cdb[3] << 16) & 0x00ff0000) | 1341 + ((cdb[4] << 8) & 0x0000ff00) | ((cdb[5] << 0) & 0x000000ff); 1342 + u16 blen = ((cdb[7] << 8) & 0xff00) | ((cdb[8] << 0) & 0x00ff); 1343 + u32 blenByte = blen * 0x200; 1344 + 1345 + if (bn > info->bl_num) 1346 + return USB_STOR_TRANSPORT_ERROR; 1347 + 1348 + if (info->MS_Status.IsMSPro) { 1349 + result = ene_load_bincode(us, MSP_RW_PATTERN); 1350 + if (result != USB_STOR_XFER_GOOD) { 1351 + US_DEBUGP("Load MPS RW pattern Fail !!\n"); 1352 + return USB_STOR_TRANSPORT_ERROR; 1353 + } 1354 + 1355 + /* set up the command wrapper */ 1356 + memset(bcb, 0, sizeof(struct bulk_cb_wrap)); 1357 + bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); 1358 + bcb->DataTransferLength = blenByte; 1359 + bcb->Flags = 0x80; 1360 + bcb->CDB[0] = 0xF1; 1361 + bcb->CDB[1] = 0x02; 1362 + bcb->CDB[5] = (unsigned char)(bn); 1363 + bcb->CDB[4] = (unsigned char)(bn>>8); 1364 + bcb->CDB[3] = (unsigned char)(bn>>16); 1365 + bcb->CDB[2] = (unsigned char)(bn>>24); 1366 + 1367 + result = ene_send_scsi_cmd(us, FDIR_READ, scsi_sglist(srb), 1); 1368 + } else { 1369 + void *buf; 1370 + int offset = 0; 1371 + u16 phyblk, logblk; 1372 + u8 PageNum; 1373 + u16 len; 1374 + u32 blkno; 1375 + 1376 + buf = kmalloc(blenByte, GFP_KERNEL); 1377 + if (buf == NULL) 1378 + return USB_STOR_TRANSPORT_ERROR; 1379 + 1380 + result = ene_load_bincode(us, MS_RW_PATTERN); 1381 + if (result != USB_STOR_XFER_GOOD) { 1382 + pr_info("Load MS RW pattern Fail !!\n"); 1383 + result = USB_STOR_TRANSPORT_ERROR; 1384 + goto exit; 1385 + } 1386 + 1387 + logblk = (u16)(bn / info->MS_Lib.PagesPerBlock); 1388 + PageNum = (u8)(bn % info->MS_Lib.PagesPerBlock); 1389 + 1390 + while (1) { 1391 + if (blen > (info->MS_Lib.PagesPerBlock-PageNum)) 1392 + len = info->MS_Lib.PagesPerBlock-PageNum; 1393 + else 1394 + len = blen; 1395 + 1396 + phyblk = ms_libconv_to_physical(info, logblk); 1397 + blkno = phyblk * 0x20 + PageNum; 1398 + 1399 + /* set up the command wrapper */ 1400 + memset(bcb, 0, sizeof(struct bulk_cb_wrap)); 1401 + bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); 1402 + bcb->DataTransferLength = 0x200 * len; 1403 + bcb->Flags = 0x80; 1404 + bcb->CDB[0] = 0xF1; 1405 + bcb->CDB[1] = 0x02; 1406 + bcb->CDB[5] = (unsigned char)(blkno); 1407 + bcb->CDB[4] = (unsigned char)(blkno>>8); 1408 + bcb->CDB[3] = (unsigned char)(blkno>>16); 1409 + bcb->CDB[2] = (unsigned char)(blkno>>24); 1410 + 1411 + result = ene_send_scsi_cmd(us, FDIR_READ, buf+offset, 0); 1412 + if (result != USB_STOR_XFER_GOOD) { 1413 + pr_info("MS_SCSI_Read --- result = %x\n", result); 1414 + result = USB_STOR_TRANSPORT_ERROR; 1415 + goto exit; 1416 + } 1417 + 1418 + blen -= len; 1419 + if (blen <= 0) 1420 + break; 1421 + logblk++; 1422 + PageNum = 0; 1423 + offset += MS_BYTES_PER_PAGE*len; 1424 + } 1425 + usb_stor_set_xfer_buf(buf, blenByte, srb); 1426 + exit: 1427 + kfree(buf); 1428 + } 1429 + return result; 1430 + } 1431 + 1432 + static int ms_scsi_write(struct us_data *us, struct scsi_cmnd *srb) 1433 + { 1434 + int result; 1435 + struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf; 1436 + unsigned char *cdb = srb->cmnd; 1437 + struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra; 1438 + 1439 + u32 bn = ((cdb[2] << 24) & 0xff000000) | 1440 + ((cdb[3] << 16) & 0x00ff0000) | 1441 + ((cdb[4] << 8) & 0x0000ff00) | 1442 + ((cdb[5] << 0) & 0x000000ff); 1443 + u16 blen = ((cdb[7] << 8) & 0xff00) | ((cdb[8] << 0) & 0x00ff); 1444 + u32 blenByte = blen * 0x200; 1445 + 1446 + if (bn > info->bl_num) 1447 + return USB_STOR_TRANSPORT_ERROR; 1448 + 1449 + if (info->MS_Status.IsMSPro) { 1450 + result = ene_load_bincode(us, MSP_RW_PATTERN); 1451 + if (result != USB_STOR_XFER_GOOD) { 1452 + pr_info("Load MSP RW pattern Fail !!\n"); 1453 + return USB_STOR_TRANSPORT_ERROR; 1454 + } 1455 + 1456 + /* set up the command wrapper */ 1457 + memset(bcb, 0, sizeof(struct bulk_cb_wrap)); 1458 + bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); 1459 + bcb->DataTransferLength = blenByte; 1460 + bcb->Flags = 0x00; 1461 + bcb->CDB[0] = 0xF0; 1462 + bcb->CDB[1] = 0x04; 1463 + bcb->CDB[5] = (unsigned char)(bn); 1464 + bcb->CDB[4] = (unsigned char)(bn>>8); 1465 + bcb->CDB[3] = (unsigned char)(bn>>16); 1466 + bcb->CDB[2] = (unsigned char)(bn>>24); 1467 + 1468 + result = ene_send_scsi_cmd(us, FDIR_WRITE, scsi_sglist(srb), 1); 1469 + } else { 1470 + void *buf; 1471 + int offset; 1472 + u16 PhyBlockAddr; 1473 + u8 PageNum; 1474 + u32 result; 1475 + u16 len, oldphy, newphy; 1476 + 1477 + buf = kmalloc(blenByte, GFP_KERNEL); 1478 + if (buf == NULL) 1479 + return USB_STOR_TRANSPORT_ERROR; 1480 + usb_stor_set_xfer_buf(buf, blenByte, srb); 1481 + 1482 + result = ene_load_bincode(us, MS_RW_PATTERN); 1483 + if (result != USB_STOR_XFER_GOOD) { 1484 + pr_info("Load MS RW pattern Fail !!\n"); 1485 + result = USB_STOR_TRANSPORT_ERROR; 1486 + goto exit; 1487 + } 1488 + 1489 + PhyBlockAddr = (u16)(bn / info->MS_Lib.PagesPerBlock); 1490 + PageNum = (u8)(bn % info->MS_Lib.PagesPerBlock); 1491 + 1492 + while (1) { 1493 + if (blen > (info->MS_Lib.PagesPerBlock-PageNum)) 1494 + len = info->MS_Lib.PagesPerBlock-PageNum; 1495 + else 1496 + len = blen; 1497 + 1498 + oldphy = ms_libconv_to_physical(info, PhyBlockAddr); /* need check us <-> info */ 1499 + newphy = ms_libsearch_block_from_logical(us, PhyBlockAddr); 1500 + 1501 + result = ms_read_copyblock(us, oldphy, newphy, PhyBlockAddr, PageNum, buf+offset, len); 1502 + 1503 + if (result != USB_STOR_XFER_GOOD) { 1504 + pr_info("MS_SCSI_Write --- result = %x\n", result); 1505 + result = USB_STOR_TRANSPORT_ERROR; 1506 + goto exit; 1507 + } 1508 + 1509 + info->MS_Lib.Phy2LogMap[oldphy] = MS_LB_NOT_USED_ERASED; 1510 + ms_lib_force_setlogical_pair(us, PhyBlockAddr, newphy); 1511 + 1512 + blen -= len; 1513 + if (blen <= 0) 1514 + break; 1515 + PhyBlockAddr++; 1516 + PageNum = 0; 1517 + offset += MS_BYTES_PER_PAGE*len; 1518 + } 1519 + exit: 1520 + kfree(buf); 1521 + } 1522 + return result; 1523 + } 1524 + 1525 + /* 1526 + * ENE MS Card 1527 + */ 1528 + 728 1529 static int ene_get_card_type(struct us_data *us, u16 index, void *buf) 729 1530 { 730 1531 struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf; ··· 1894 505 US_DEBUGP("SD_RDWR_PATTERN\n"); 1895 506 fw_name = "ene-ub6250/sd_rdwr.bin"; 1896 507 break; 508 + /* For MS */ 509 + case MS_INIT_PATTERN: 510 + US_DEBUGP("MS_INIT_PATTERN\n"); 511 + fw_name = "ene-ub6250/ms_init.bin"; 512 + break; 513 + case MSP_RW_PATTERN: 514 + US_DEBUGP("MSP_RW_PATTERN\n"); 515 + fw_name = "ene-ub6250/msp_rdwr.bin"; 516 + break; 517 + case MS_RW_PATTERN: 518 + US_DEBUGP("MS_RW_PATTERN\n"); 519 + fw_name = "ene-ub6250/ms_rdwr.bin"; 520 + break; 1897 521 default: 1898 522 US_DEBUGP("----------- Unknown PATTERN ----------\n"); 1899 523 goto nofw; ··· 1940 538 } 1941 539 1942 540 return result; 541 + } 542 + 543 + static int ms_card_init(struct us_data *us) 544 + { 545 + u32 result; 546 + u16 TmpBlock; 547 + unsigned char *PageBuffer0 = NULL, *PageBuffer1 = NULL; 548 + struct ms_lib_type_extdat extdat; 549 + u16 btBlk1st, btBlk2nd; 550 + u32 btBlk1stErred; 551 + struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra; 552 + 553 + printk(KERN_INFO "MS_CardInit start\n"); 554 + 555 + ms_lib_free_allocatedarea(us); /* Clean buffer and set struct us_data flag to 0 */ 556 + 557 + /* get two PageBuffer */ 558 + PageBuffer0 = kmalloc(MS_BYTES_PER_PAGE, GFP_KERNEL); 559 + PageBuffer1 = kmalloc(MS_BYTES_PER_PAGE, GFP_KERNEL); 560 + if ((PageBuffer0 == NULL) || (PageBuffer1 == NULL)) { 561 + result = MS_NO_MEMORY_ERROR; 562 + goto exit; 563 + } 564 + 565 + btBlk1st = btBlk2nd = MS_LB_NOT_USED; 566 + btBlk1stErred = 0; 567 + 568 + for (TmpBlock = 0; TmpBlock < MS_MAX_INITIAL_ERROR_BLOCKS+2; TmpBlock++) { 569 + 570 + switch (ms_read_readpage(us, TmpBlock, 0, (u32 *)PageBuffer0, &extdat)) { 571 + case MS_STATUS_SUCCESS: 572 + break; 573 + case MS_STATUS_INT_ERROR: 574 + break; 575 + case MS_STATUS_ERROR: 576 + default: 577 + continue; 578 + } 579 + 580 + if ((extdat.ovrflg & MS_REG_OVR_BKST) == MS_REG_OVR_BKST_NG) 581 + continue; 582 + 583 + if (((extdat.mngflg & MS_REG_MNG_SYSFLG) == MS_REG_MNG_SYSFLG_USER) || 584 + (be16_to_cpu(((struct ms_bootblock_page0 *)PageBuffer0)->header.wBlockID) != MS_BOOT_BLOCK_ID) || 585 + (be16_to_cpu(((struct ms_bootblock_page0 *)PageBuffer0)->header.wFormatVersion) != MS_BOOT_BLOCK_FORMAT_VERSION) || 586 + (((struct ms_bootblock_page0 *)PageBuffer0)->header.bNumberOfDataEntry != MS_BOOT_BLOCK_DATA_ENTRIES)) 587 + continue; 588 + 589 + if (btBlk1st != MS_LB_NOT_USED) { 590 + btBlk2nd = TmpBlock; 591 + break; 592 + } 593 + 594 + btBlk1st = TmpBlock; 595 + memcpy(PageBuffer1, PageBuffer0, MS_BYTES_PER_PAGE); 596 + if (extdat.status1 & (MS_REG_ST1_DTER | MS_REG_ST1_EXER | MS_REG_ST1_FGER)) 597 + btBlk1stErred = 1; 598 + } 599 + 600 + if (btBlk1st == MS_LB_NOT_USED) { 601 + result = MS_STATUS_ERROR; 602 + goto exit; 603 + } 604 + 605 + /* write protect */ 606 + if ((extdat.status0 & MS_REG_ST0_WP) == MS_REG_ST0_WP_ON) 607 + ms_lib_ctrl_set(info, MS_LIB_CTRL_WRPROTECT); 608 + 609 + result = MS_STATUS_ERROR; 610 + /* 1st Boot Block */ 611 + if (btBlk1stErred == 0) 612 + result = ms_lib_process_bootblock(us, btBlk1st, PageBuffer1); 613 + /* 1st */ 614 + /* 2nd Boot Block */ 615 + if (result && (btBlk2nd != MS_LB_NOT_USED)) 616 + result = ms_lib_process_bootblock(us, btBlk2nd, PageBuffer0); 617 + 618 + if (result) { 619 + result = MS_STATUS_ERROR; 620 + goto exit; 621 + } 622 + 623 + for (TmpBlock = 0; TmpBlock < btBlk1st; TmpBlock++) 624 + info->MS_Lib.Phy2LogMap[TmpBlock] = MS_LB_INITIAL_ERROR; 625 + 626 + info->MS_Lib.Phy2LogMap[btBlk1st] = MS_LB_BOOT_BLOCK; 627 + 628 + if (btBlk2nd != MS_LB_NOT_USED) { 629 + for (TmpBlock = btBlk1st + 1; TmpBlock < btBlk2nd; TmpBlock++) 630 + info->MS_Lib.Phy2LogMap[TmpBlock] = MS_LB_INITIAL_ERROR; 631 + 632 + info->MS_Lib.Phy2LogMap[btBlk2nd] = MS_LB_BOOT_BLOCK; 633 + } 634 + 635 + result = ms_lib_scan_logicalblocknumber(us, btBlk1st); 636 + if (result) 637 + goto exit; 638 + 639 + for (TmpBlock = MS_PHYSICAL_BLOCKS_PER_SEGMENT; 640 + TmpBlock < info->MS_Lib.NumberOfPhyBlock; 641 + TmpBlock += MS_PHYSICAL_BLOCKS_PER_SEGMENT) { 642 + if (ms_count_freeblock(us, TmpBlock) == 0) { 643 + ms_lib_ctrl_set(info, MS_LIB_CTRL_WRPROTECT); 644 + break; 645 + } 646 + } 647 + 648 + /* write */ 649 + if (ms_lib_alloc_writebuf(us)) { 650 + result = MS_NO_MEMORY_ERROR; 651 + goto exit; 652 + } 653 + 654 + result = MS_STATUS_SUCCESS; 655 + 656 + exit: 657 + kfree(PageBuffer1); 658 + kfree(PageBuffer0); 659 + 660 + printk(KERN_INFO "MS_CardInit end\n"); 661 + return result; 662 + } 663 + 664 + static int ene_ms_init(struct us_data *us) 665 + { 666 + struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf; 667 + int result; 668 + u8 buf[0x200]; 669 + u16 MSP_BlockSize, MSP_UserAreaBlocks; 670 + struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra; 671 + 672 + printk(KERN_INFO "transport --- ENE_MSInit\n"); 673 + 674 + /* the same part to test ENE */ 675 + 676 + result = ene_load_bincode(us, MS_INIT_PATTERN); 677 + if (result != USB_STOR_XFER_GOOD) { 678 + printk(KERN_ERR "Load MS Init Code Fail !!\n"); 679 + return USB_STOR_TRANSPORT_ERROR; 680 + } 681 + 682 + memset(bcb, 0, sizeof(struct bulk_cb_wrap)); 683 + bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); 684 + bcb->DataTransferLength = 0x200; 685 + bcb->Flags = 0x80; 686 + bcb->CDB[0] = 0xF1; 687 + bcb->CDB[1] = 0x01; 688 + 689 + result = ene_send_scsi_cmd(us, FDIR_READ, &buf, 0); 690 + if (result != USB_STOR_XFER_GOOD) { 691 + printk(KERN_ERR "Execution MS Init Code Fail !!\n"); 692 + return USB_STOR_TRANSPORT_ERROR; 693 + } 694 + /* the same part to test ENE */ 695 + info->MS_Status = *(struct MS_STATUS *)&buf[0]; 696 + 697 + if (info->MS_Status.Insert && info->MS_Status.Ready) { 698 + printk(KERN_INFO "Insert = %x\n", info->MS_Status.Insert); 699 + printk(KERN_INFO "Ready = %x\n", info->MS_Status.Ready); 700 + printk(KERN_INFO "IsMSPro = %x\n", info->MS_Status.IsMSPro); 701 + printk(KERN_INFO "IsMSPHG = %x\n", info->MS_Status.IsMSPHG); 702 + printk(KERN_INFO "WtP= %x\n", info->MS_Status.WtP); 703 + if (info->MS_Status.IsMSPro) { 704 + MSP_BlockSize = (buf[6] << 8) | buf[7]; 705 + MSP_UserAreaBlocks = (buf[10] << 8) | buf[11]; 706 + info->MSP_TotalBlock = MSP_BlockSize * MSP_UserAreaBlocks; 707 + } else { 708 + ms_card_init(us); /* Card is MS (to ms.c)*/ 709 + } 710 + US_DEBUGP("MS Init Code OK !!\n"); 711 + } else { 712 + US_DEBUGP("MS Card Not Ready --- %x\n", buf[0]); 713 + return USB_STOR_TRANSPORT_ERROR; 714 + } 715 + 716 + return USB_STOR_TRANSPORT_GOOD; 1943 717 } 1944 718 1945 719 static int ene_sd_init(struct us_data *us) ··· 2197 619 return USB_STOR_TRANSPORT_ERROR; 2198 620 } 2199 621 } 2200 - 622 + if (misc_reg03 & 0x02) { 623 + if (!info->MS_Status.Ready) { 624 + result = ene_ms_init(us); 625 + if (result != USB_STOR_XFER_GOOD) 626 + return USB_STOR_TRANSPORT_ERROR; 627 + } 628 + } 2201 629 return result; 2202 630 } 2203 631 ··· 2246 662 return result; 2247 663 } 2248 664 665 + /* 666 + * ms_scsi_irp() 667 + */ 668 + int ms_scsi_irp(struct us_data *us, struct scsi_cmnd *srb) 669 + { 670 + int result; 671 + struct ene_ub6250_info *info = (struct ene_ub6250_info *)us->extra; 672 + info->SrbStatus = SS_SUCCESS; 673 + switch (srb->cmnd[0]) { 674 + case TEST_UNIT_READY: 675 + result = ms_scsi_test_unit_ready(us, srb); 676 + break; /* 0x00 */ 677 + case INQUIRY: 678 + result = ms_scsi_inquiry(us, srb); 679 + break; /* 0x12 */ 680 + case MODE_SENSE: 681 + result = ms_scsi_mode_sense(us, srb); 682 + break; /* 0x1A */ 683 + case READ_CAPACITY: 684 + result = ms_scsi_read_capacity(us, srb); 685 + break; /* 0x25 */ 686 + case READ_10: 687 + result = ms_scsi_read(us, srb); 688 + break; /* 0x28 */ 689 + case WRITE_10: 690 + result = ms_scsi_write(us, srb); 691 + break; /* 0x2A */ 692 + default: 693 + info->SrbStatus = SS_ILLEGAL_REQUEST; 694 + result = USB_STOR_TRANSPORT_FAILED; 695 + break; 696 + } 697 + return result; 698 + } 699 + 2249 700 static int ene_transport(struct scsi_cmnd *srb, struct us_data *us) 2250 701 { 2251 702 int result = 0; ··· 2288 669 2289 670 /*US_DEBUG(usb_stor_show_command(srb)); */ 2290 671 scsi_set_resid(srb, 0); 2291 - if (unlikely(!info->SD_Status.Ready)) 672 + if (unlikely(!(info->SD_Status.Ready || info->MS_Status.Ready))) { 2292 673 result = ene_init(us); 2293 - else 2294 - result = sd_scsi_irp(us, srb); 674 + } else { 675 + if (info->SD_Status.Ready) 676 + result = sd_scsi_irp(us, srb); 2295 677 678 + if (info->MS_Status.Ready) 679 + result = ms_scsi_irp(us, srb); 680 + } 2296 681 return 0; 2297 682 } 2298 683 ··· 2337 714 } 2338 715 2339 716 if (!(misc_reg03 & 0x01)) { 2340 - result = -ENODEV; 2341 - printk(KERN_NOTICE "ums_eneub6250: The driver only supports SD card. " 2342 - "To use SM/MS card, please build driver/staging/keucr\n"); 2343 - usb_stor_disconnect(intf); 717 + pr_info("ums_eneub6250: The driver only supports SD/MS card. " 718 + "To use SM card, please build driver/staging/keucr\n"); 2344 719 } 2345 720 2346 721 return result;