3 * This program is free software; you can redistribute it and/or modify it
4 * under the terms of the GNU General Public License as published by the
5 * Free Software Foundation; either version 2, or (at your option) any
8 * This program is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * General Public License for more details.
13 * You should have received a copy of the GNU General Public License along
14 * with this program; if not, write to the Free Software Foundation, Inc.,
15 * 675 Mass Ave, Cambridge, MA 02139, USA.
17 #include <linux/jiffies.h>
18 #include <linux/errno.h>
19 #include <linux/module.h>
20 #include <linux/slab.h>
22 #include <scsi/scsi.h>
23 #include <scsi/scsi_cmnd.h>
25 #include <linux/firmware.h>
28 #include "transport.h"
32 MODULE_DESCRIPTION("Driver for ENE UB6250 reader");
33 MODULE_LICENSE("GPL");
37 * The table of devices
39 #define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \
40 vendorName, productName, useProtocol, useTransport, \
41 initFunction, flags) \
42 { USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \
43 .driver_info = (flags)|(USB_US_TYPE_STOR<<24) }
45 struct usb_device_id ene_ub6250_usb_ids[] = {
46 # include "unusual_ene_ub6250.h"
47 { } /* Terminating entry */
49 MODULE_DEVICE_TABLE(usb, ene_ub6250_usb_ids);
56 #define UNUSUAL_DEV(idVendor, idProduct, bcdDeviceMin, bcdDeviceMax, \
57 vendor_name, product_name, use_protocol, use_transport, \
58 init_function, Flags) \
60 .vendorName = vendor_name, \
61 .productName = product_name, \
62 .useProtocol = use_protocol, \
63 .useTransport = use_transport, \
64 .initFunction = init_function, \
67 static struct us_unusual_dev ene_ub6250_unusual_dev_list[] = {
68 # include "unusual_ene_ub6250.h"
69 { } /* Terminating entry */
76 /* ENE bin code len */
77 #define ENE_BIN_CODE_LEN 0x800
79 #define REG_CARD_STATUS 0xFF83
80 #define REG_HW_TRAP1 0xFF89
83 #define SS_SUCCESS 0x00 /* No Sense */
84 #define SS_NOT_READY 0x02
85 #define SS_MEDIUM_ERR 0x03
86 #define SS_HW_ERR 0x04
87 #define SS_ILLEGAL_REQUEST 0x05
88 #define SS_UNIT_ATTENTION 0x06
90 /* ENE Load FW Pattern */
91 #define SD_INIT1_PATTERN 1
92 #define SD_INIT2_PATTERN 2
93 #define SD_RW_PATTERN 3
94 #define MS_INIT_PATTERN 4
95 #define MSP_RW_PATTERN 5
96 #define MS_RW_PATTERN 6
97 #define SM_INIT_PATTERN 7
98 #define SM_RW_PATTERN 8
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)
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)
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)
149 #define MS_MAX_PAGES_PER_BLOCK 32
150 #define MS_MAX_INITIAL_ERROR_BLOCKS 10
151 #define MS_LIB_BITS_PER_BYTE 8
153 #define MS_SYSINF_FORMAT_FAT 1
154 #define MS_SYSINF_USAGE_GENERAL 0
156 #define MS_SYSINF_MSCLASS_TYPE_1 1
157 #define MS_SYSINF_PAGE_SIZE MS_BYTES_PER_PAGE /* fixed */
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
166 #define MS_SYSINF_RESERVED1 1
167 #define MS_SYSINF_RESERVED2 1
169 #define MS_SYSENT_TYPE_INVALID_BLOCK 0x01
170 #define MS_SYSENT_TYPE_CIS_IDI 0x0a /* CIS/IDI */
172 #define SIZE_OF_KIRO 1024
173 #define BYTE_MASK 0xff
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
192 #define MS_REG_MNG_SYSFLG 0x04 /* system flag */
193 #define MS_REG_MNG_SYSFLG_USER MS_REG_MNG_SYSFLG /* user block */
195 #define MS_BOOT_BLOCK_ID 0x0001
196 #define MS_BOOT_BLOCK_FORMAT_VERSION 0x0100
197 #define MS_BOOT_BLOCK_DATA_ENTRIES 2
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
205 #define MS_PHYSICAL_BLOCKS_PER_SEGMENT 0x200 /* 512 */
206 #define MS_PHYSICAL_BLOCKS_PER_SEGMENT_MASK 0x1ff
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 */
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) */
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
223 #define MS_LIB_CTRL_RDONLY 0
224 #define MS_LIB_CTRL_WRPROTECT 1
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])
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)))
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))
270 struct ms_bootblock_cis {
271 u8 bCistplDEVICE[6]; /* 0 */
272 u8 bCistplDEVICE0C[6]; /* 6 */
273 u8 bCistplJEDECC[4]; /* 12 */
274 u8 bCistplMANFID[6]; /* 16 */
275 u8 bCistplVER1[32]; /* 22 */
276 u8 bCistplFUNCID[4]; /* 54 */
277 u8 bCistplFUNCE0[4]; /* 58 */
278 u8 bCistplFUNCE1[5]; /* 62 */
279 u8 bCistplCONF[7]; /* 67 */
280 u8 bCistplCFTBLENT0[10];/* 74 */
281 u8 bCistplCFTBLENT1[8]; /* 84 */
282 u8 bCistplCFTBLENT2[12];/* 92 */
283 u8 bCistplCFTBLENT3[8]; /* 104 */
284 u8 bCistplCFTBLENT4[17];/* 112 */
285 u8 bCistplCFTBLENT5[8]; /* 129 */
286 u8 bCistplCFTBLENT6[17];/* 137 */
287 u8 bCistplCFTBLENT7[8]; /* 154 */
288 u8 bCistplNOLINK[3]; /* 162 */
291 struct ms_bootblock_idi {
292 #define MS_IDI_GENERAL_CONF 0x848A
293 u16 wIDIgeneralConfiguration; /* 0 */
294 u16 wIDInumberOfCylinder; /* 1 */
295 u16 wIDIreserved0; /* 2 */
296 u16 wIDInumberOfHead; /* 3 */
297 u16 wIDIbytesPerTrack; /* 4 */
298 u16 wIDIbytesPerSector; /* 5 */
299 u16 wIDIsectorsPerTrack; /* 6 */
300 u16 wIDItotalSectors[2]; /* 7-8 high,low */
301 u16 wIDIreserved1[11]; /* 9-19 */
302 u16 wIDIbufferType; /* 20 */
303 u16 wIDIbufferSize; /* 21 */
304 u16 wIDIlongCmdECC; /* 22 */
305 u16 wIDIfirmVersion[4]; /* 23-26 */
306 u16 wIDImodelName[20]; /* 27-46 */
307 u16 wIDIreserved2; /* 47 */
308 u16 wIDIlongWordSupported; /* 48 */
309 u16 wIDIdmaSupported; /* 49 */
310 u16 wIDIreserved3; /* 50 */
311 u16 wIDIpioTiming; /* 51 */
312 u16 wIDIdmaTiming; /* 52 */
313 u16 wIDItransferParameter; /* 53 */
314 u16 wIDIformattedCylinder; /* 54 */
315 u16 wIDIformattedHead; /* 55 */
316 u16 wIDIformattedSectorsPerTrack;/* 56 */
317 u16 wIDIformattedTotalSectors[2];/* 57-58 */
318 u16 wIDImultiSector; /* 59 */
319 u16 wIDIlbaSectors[2]; /* 60-61 */
320 u16 wIDIsingleWordDMA; /* 62 */
321 u16 wIDImultiWordDMA; /* 63 */
322 u16 wIDIreserved4[192]; /* 64-255 */
325 struct ms_bootblock_sysent_rec {
332 struct ms_bootblock_sysent {
333 struct ms_bootblock_sysent_rec entry[MS_NUMBER_OF_SYSTEM_ENTRY];
336 struct ms_bootblock_sysinf {
337 u8 bMsClass; /* must be 1 */
338 u8 bCardType; /* see below */
339 u16 wBlockSize; /* n KB */
340 u16 wBlockNumber; /* number of physical block */
341 u16 wTotalBlockNumber; /* number of logical block */
342 u16 wPageSize; /* must be 0x200 */
343 u8 bExtraSize; /* 0x10 */
347 u8 bAssemblyMakerCode;
348 u8 bAssemblyMachineCode[3];
349 u16 wMemoryMakerCode;
350 u16 wMemoryDeviceCode;
356 u16 wControllerChipNumber;
357 u16 wControllerFunction; /* New MS */
358 u8 bReserved3[9]; /* New MS */
359 u8 bParallelSupport; /* New MS */
360 u16 wFormatValue; /* New MS */
370 struct ms_bootblock_header {
374 u8 bNumberOfDataEntry;
378 struct ms_bootblock_page0 {
379 struct ms_bootblock_header header;
380 struct ms_bootblock_sysent sysent;
381 struct ms_bootblock_sysinf sysinf;
384 struct ms_bootblock_cis_idi {
386 struct ms_bootblock_cis cis;
391 struct ms_bootblock_idi idi;
397 /* ENE MS Lib struct */
398 struct ms_lib_type_extdat {
411 u32 NumberOfCylinder;
412 u32 SectorsPerCylinder;
413 u16 cardType; /* R/W, RO, Hybrid */
416 u16 NumberOfPhyBlock;
417 u16 NumberOfLogBlock;
419 u16 *Phy2LogMap; /* phy2log table */
420 u16 *Log2PhyMap; /* log2phy table */
422 unsigned char *pagemap[(MS_MAX_PAGES_PER_BLOCK + (MS_LIB_BITS_PER_BYTE-1)) / MS_LIB_BITS_PER_BYTE];
423 unsigned char *blkpag;
424 struct ms_lib_type_extdat *blkext;
425 unsigned char copybuf[512];
429 /* SD Block Length */
430 /* 2^9 = 512 Bytes, The HW maximum read/write data length */
431 #define SD_BLOCK_LEN 9
433 struct ene_ub6250_info {
435 /* I/O bounce buffer */
439 struct SD_STATUS SD_Status;
440 struct MS_STATUS MS_Status;
441 struct SM_STATUS SM_Status;
443 /* ----- SD Control Data ---------------- */
444 /*SD_REGISTER SD_Regs; */
450 /* SD/MMC New spec. */
453 u8 SD20_HIGH_CAPACITY;
457 u8 MMC_HIGH_CAPACITY;
459 /*----- MS Control Data ---------------- */
462 struct ms_lib_ctrl MS_Lib;
466 /*----- SM Control Data ---------------- */
470 unsigned char *testbuf;
475 /*------Power Managerment ---------------*/
479 static int ene_sd_init(struct us_data *us);
480 static int ene_ms_init(struct us_data *us);
481 static int ene_load_bincode(struct us_data *us, unsigned char flag);
483 static void ene_ub6250_info_destructor(void *extra)
485 struct ene_ub6250_info *info = (struct ene_ub6250_info *) extra;
492 static int ene_send_scsi_cmd(struct us_data *us, u8 fDir, void *buf, int use_sg)
494 struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf;
495 struct bulk_cs_wrap *bcs = (struct bulk_cs_wrap *) us->iobuf;
498 unsigned int residue;
499 unsigned int cswlen = 0, partial = 0;
500 unsigned int transfer_length = bcb->DataTransferLength;
502 /* US_DEBUGP("transport --- ene_send_scsi_cmd\n"); */
503 /* send cmd to out endpoint */
504 result = usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe,
505 bcb, US_BULK_CB_WRAP_LEN, NULL);
506 if (result != USB_STOR_XFER_GOOD) {
507 US_DEBUGP("send cmd to out endpoint fail ---\n");
508 return USB_STOR_TRANSPORT_ERROR;
512 unsigned int pipe = fDir;
514 if (fDir == FDIR_READ)
515 pipe = us->recv_bulk_pipe;
517 pipe = us->send_bulk_pipe;
521 result = usb_stor_bulk_srb(us, pipe, us->srb);
523 result = usb_stor_bulk_transfer_sg(us, pipe, buf,
524 transfer_length, 0, &partial);
526 if (result != USB_STOR_XFER_GOOD) {
527 US_DEBUGP("data transfer fail ---\n");
528 return USB_STOR_TRANSPORT_ERROR;
532 /* Get CSW for device status */
533 result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe, bcs,
534 US_BULK_CS_WRAP_LEN, &cswlen);
536 if (result == USB_STOR_XFER_SHORT && cswlen == 0) {
537 US_DEBUGP("Received 0-length CSW; retrying...\n");
538 result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe,
539 bcs, US_BULK_CS_WRAP_LEN, &cswlen);
542 if (result == USB_STOR_XFER_STALLED) {
543 /* get the status again */
544 US_DEBUGP("Attempting to get CSW (2nd try)...\n");
545 result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe,
546 bcs, US_BULK_CS_WRAP_LEN, NULL);
549 if (result != USB_STOR_XFER_GOOD)
550 return USB_STOR_TRANSPORT_ERROR;
552 /* check bulk status */
553 residue = le32_to_cpu(bcs->Residue);
555 /* try to compute the actual residue, based on how much data
556 * was really transferred and what the device tells us */
557 if (residue && !(us->fflags & US_FL_IGNORE_RESIDUE)) {
558 residue = min(residue, transfer_length);
560 scsi_set_resid(us->srb, max(scsi_get_resid(us->srb),
564 if (bcs->Status != US_BULK_STAT_OK)
565 return USB_STOR_TRANSPORT_ERROR;
567 return USB_STOR_TRANSPORT_GOOD;
570 static int sd_scsi_test_unit_ready(struct us_data *us, struct scsi_cmnd *srb)
572 struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra;
574 if (info->SD_Status.Insert && info->SD_Status.Ready)
575 return USB_STOR_TRANSPORT_GOOD;
578 return USB_STOR_TRANSPORT_GOOD;
581 return USB_STOR_TRANSPORT_GOOD;
584 static int sd_scsi_inquiry(struct us_data *us, struct scsi_cmnd *srb)
586 unsigned char data_ptr[36] = {
587 0x00, 0x80, 0x02, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x55,
588 0x53, 0x42, 0x32, 0x2E, 0x30, 0x20, 0x20, 0x43, 0x61,
589 0x72, 0x64, 0x52, 0x65, 0x61, 0x64, 0x65, 0x72, 0x20,
590 0x20, 0x20, 0x20, 0x20, 0x20, 0x30, 0x31, 0x30, 0x30 };
592 usb_stor_set_xfer_buf(data_ptr, 36, srb);
593 return USB_STOR_TRANSPORT_GOOD;
596 static int sd_scsi_mode_sense(struct us_data *us, struct scsi_cmnd *srb)
598 struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra;
599 unsigned char mediaNoWP[12] = {
600 0x0b, 0x00, 0x00, 0x08, 0x00, 0x00,
601 0x71, 0xc0, 0x00, 0x00, 0x02, 0x00 };
602 unsigned char mediaWP[12] = {
603 0x0b, 0x00, 0x80, 0x08, 0x00, 0x00,
604 0x71, 0xc0, 0x00, 0x00, 0x02, 0x00 };
606 if (info->SD_Status.WtP)
607 usb_stor_set_xfer_buf(mediaWP, 12, srb);
609 usb_stor_set_xfer_buf(mediaNoWP, 12, srb);
612 return USB_STOR_TRANSPORT_GOOD;
615 static int sd_scsi_read_capacity(struct us_data *us, struct scsi_cmnd *srb)
619 unsigned int offset = 0;
620 unsigned char buf[8];
621 struct scatterlist *sg = NULL;
622 struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra;
624 US_DEBUGP("sd_scsi_read_capacity\n");
625 if (info->SD_Status.HiCapacity) {
627 if (info->SD_Status.IsMMC)
628 bl_num = info->HC_C_SIZE-1;
630 bl_num = (info->HC_C_SIZE + 1) * 1024 - 1;
632 bl_len = 1<<(info->SD_READ_BL_LEN);
633 bl_num = info->SD_Block_Mult * (info->SD_C_SIZE + 1)
634 * (1 << (info->SD_C_SIZE_MULT + 2)) - 1;
636 info->bl_num = bl_num;
637 US_DEBUGP("bl_len = %x\n", bl_len);
638 US_DEBUGP("bl_num = %x\n", bl_num);
640 /*srb->request_bufflen = 8; */
641 buf[0] = (bl_num >> 24) & 0xff;
642 buf[1] = (bl_num >> 16) & 0xff;
643 buf[2] = (bl_num >> 8) & 0xff;
644 buf[3] = (bl_num >> 0) & 0xff;
645 buf[4] = (bl_len >> 24) & 0xff;
646 buf[5] = (bl_len >> 16) & 0xff;
647 buf[6] = (bl_len >> 8) & 0xff;
648 buf[7] = (bl_len >> 0) & 0xff;
650 usb_stor_access_xfer_buf(buf, 8, srb, &sg, &offset, TO_XFER_BUF);
652 return USB_STOR_TRANSPORT_GOOD;
655 static int sd_scsi_read(struct us_data *us, struct scsi_cmnd *srb)
658 unsigned char *cdb = srb->cmnd;
659 struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf;
660 struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra;
662 u32 bn = ((cdb[2] << 24) & 0xff000000) | ((cdb[3] << 16) & 0x00ff0000) |
663 ((cdb[4] << 8) & 0x0000ff00) | ((cdb[5] << 0) & 0x000000ff);
664 u16 blen = ((cdb[7] << 8) & 0xff00) | ((cdb[8] << 0) & 0x00ff);
665 u32 bnByte = bn * 0x200;
666 u32 blenByte = blen * 0x200;
668 if (bn > info->bl_num)
669 return USB_STOR_TRANSPORT_ERROR;
671 result = ene_load_bincode(us, SD_RW_PATTERN);
672 if (result != USB_STOR_XFER_GOOD) {
673 US_DEBUGP("Load SD RW pattern Fail !!\n");
674 return USB_STOR_TRANSPORT_ERROR;
677 if (info->SD_Status.HiCapacity)
680 /* set up the command wrapper */
681 memset(bcb, 0, sizeof(struct bulk_cb_wrap));
682 bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
683 bcb->DataTransferLength = blenByte;
686 bcb->CDB[5] = (unsigned char)(bnByte);
687 bcb->CDB[4] = (unsigned char)(bnByte>>8);
688 bcb->CDB[3] = (unsigned char)(bnByte>>16);
689 bcb->CDB[2] = (unsigned char)(bnByte>>24);
691 result = ene_send_scsi_cmd(us, FDIR_READ, scsi_sglist(srb), 1);
695 static int sd_scsi_write(struct us_data *us, struct scsi_cmnd *srb)
698 unsigned char *cdb = srb->cmnd;
699 struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf;
700 struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra;
702 u32 bn = ((cdb[2] << 24) & 0xff000000) | ((cdb[3] << 16) & 0x00ff0000) |
703 ((cdb[4] << 8) & 0x0000ff00) | ((cdb[5] << 0) & 0x000000ff);
704 u16 blen = ((cdb[7] << 8) & 0xff00) | ((cdb[8] << 0) & 0x00ff);
705 u32 bnByte = bn * 0x200;
706 u32 blenByte = blen * 0x200;
708 if (bn > info->bl_num)
709 return USB_STOR_TRANSPORT_ERROR;
711 result = ene_load_bincode(us, SD_RW_PATTERN);
712 if (result != USB_STOR_XFER_GOOD) {
713 US_DEBUGP("Load SD RW pattern Fail !!\n");
714 return USB_STOR_TRANSPORT_ERROR;
717 if (info->SD_Status.HiCapacity)
720 /* set up the command wrapper */
721 memset(bcb, 0, sizeof(struct bulk_cb_wrap));
722 bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
723 bcb->DataTransferLength = blenByte;
726 bcb->CDB[5] = (unsigned char)(bnByte);
727 bcb->CDB[4] = (unsigned char)(bnByte>>8);
728 bcb->CDB[3] = (unsigned char)(bnByte>>16);
729 bcb->CDB[2] = (unsigned char)(bnByte>>24);
731 result = ene_send_scsi_cmd(us, FDIR_WRITE, scsi_sglist(srb), 1);
739 static int ms_lib_set_logicalpair(struct us_data *us, u16 logblk, u16 phyblk)
741 struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra;
743 if ((logblk >= info->MS_Lib.NumberOfLogBlock) || (phyblk >= info->MS_Lib.NumberOfPhyBlock))
746 info->MS_Lib.Phy2LogMap[phyblk] = logblk;
747 info->MS_Lib.Log2PhyMap[logblk] = phyblk;
752 static int ms_lib_set_logicalblockmark(struct us_data *us, u16 phyblk, u16 mark)
754 struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra;
756 if (phyblk >= info->MS_Lib.NumberOfPhyBlock)
759 info->MS_Lib.Phy2LogMap[phyblk] = mark;
764 static int ms_lib_set_initialerrorblock(struct us_data *us, u16 phyblk)
766 return ms_lib_set_logicalblockmark(us, phyblk, MS_LB_INITIAL_ERROR);
769 static int ms_lib_set_bootblockmark(struct us_data *us, u16 phyblk)
771 return ms_lib_set_logicalblockmark(us, phyblk, MS_LB_BOOT_BLOCK);
774 static int ms_lib_free_logicalmap(struct us_data *us)
776 struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra;
778 kfree(info->MS_Lib.Phy2LogMap);
779 info->MS_Lib.Phy2LogMap = NULL;
781 kfree(info->MS_Lib.Log2PhyMap);
782 info->MS_Lib.Log2PhyMap = NULL;
787 int ms_lib_alloc_logicalmap(struct us_data *us)
790 struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra;
792 info->MS_Lib.Phy2LogMap = kmalloc(info->MS_Lib.NumberOfPhyBlock * sizeof(u16), GFP_KERNEL);
793 info->MS_Lib.Log2PhyMap = kmalloc(info->MS_Lib.NumberOfLogBlock * sizeof(u16), GFP_KERNEL);
795 if ((info->MS_Lib.Phy2LogMap == NULL) || (info->MS_Lib.Log2PhyMap == NULL)) {
796 ms_lib_free_logicalmap(us);
800 for (i = 0; i < info->MS_Lib.NumberOfPhyBlock; i++)
801 info->MS_Lib.Phy2LogMap[i] = MS_LB_NOT_USED;
803 for (i = 0; i < info->MS_Lib.NumberOfLogBlock; i++)
804 info->MS_Lib.Log2PhyMap[i] = MS_LB_NOT_USED;
809 static void ms_lib_clear_writebuf(struct us_data *us)
812 struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra;
814 info->MS_Lib.wrtblk = (u16)-1;
815 ms_lib_clear_pagemap(info);
817 if (info->MS_Lib.blkpag)
818 memset(info->MS_Lib.blkpag, 0xff, info->MS_Lib.PagesPerBlock * info->MS_Lib.BytesPerSector);
820 if (info->MS_Lib.blkext) {
821 for (i = 0; i < info->MS_Lib.PagesPerBlock; i++) {
822 info->MS_Lib.blkext[i].status1 = MS_REG_ST1_DEFAULT;
823 info->MS_Lib.blkext[i].ovrflg = MS_REG_OVR_DEFAULT;
824 info->MS_Lib.blkext[i].mngflg = MS_REG_MNG_DEFAULT;
825 info->MS_Lib.blkext[i].logadr = MS_LB_NOT_USED;
830 static int ms_count_freeblock(struct us_data *us, u16 PhyBlock)
833 struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra;
835 Ende = PhyBlock + MS_PHYSICAL_BLOCKS_PER_SEGMENT;
836 for (Count = 0; PhyBlock < Ende; PhyBlock++) {
837 switch (info->MS_Lib.Phy2LogMap[PhyBlock]) {
839 case MS_LB_NOT_USED_ERASED:
849 static int ms_read_readpage(struct us_data *us, u32 PhyBlockAddr,
850 u8 PageNum, u32 *PageBuf, struct ms_lib_type_extdat *ExtraDat)
852 struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf;
853 struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra;
854 u8 *bbuf = info->bbuf;
856 u32 bn = PhyBlockAddr * 0x20 + PageNum;
858 /* printk(KERN_INFO "MS --- MS_ReaderReadPage,
859 PhyBlockAddr = %x, PageNum = %x\n", PhyBlockAddr, PageNum); */
861 result = ene_load_bincode(us, MS_RW_PATTERN);
862 if (result != USB_STOR_XFER_GOOD)
863 return USB_STOR_TRANSPORT_ERROR;
866 memset(bcb, 0, sizeof(struct bulk_cb_wrap));
867 bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
868 bcb->DataTransferLength = 0x200;
872 bcb->CDB[1] = 0x02; /* in init.c ENE_MSInit() is 0x01 */
874 bcb->CDB[5] = (unsigned char)(bn);
875 bcb->CDB[4] = (unsigned char)(bn>>8);
876 bcb->CDB[3] = (unsigned char)(bn>>16);
877 bcb->CDB[2] = (unsigned char)(bn>>24);
879 result = ene_send_scsi_cmd(us, FDIR_READ, PageBuf, 0);
880 if (result != USB_STOR_XFER_GOOD)
881 return USB_STOR_TRANSPORT_ERROR;
884 /* Read Extra Data */
885 memset(bcb, 0, sizeof(struct bulk_cb_wrap));
886 bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
887 bcb->DataTransferLength = 0x4;
892 bcb->CDB[5] = (unsigned char)(PageNum);
893 bcb->CDB[4] = (unsigned char)(PhyBlockAddr);
894 bcb->CDB[3] = (unsigned char)(PhyBlockAddr>>8);
895 bcb->CDB[2] = (unsigned char)(PhyBlockAddr>>16);
898 result = ene_send_scsi_cmd(us, FDIR_READ, bbuf, 0);
899 if (result != USB_STOR_XFER_GOOD)
900 return USB_STOR_TRANSPORT_ERROR;
902 ExtraDat->reserved = 0;
903 ExtraDat->intr = 0x80; /* Not yet,fireware support */
904 ExtraDat->status0 = 0x10; /* Not yet,fireware support */
906 ExtraDat->status1 = 0x00; /* Not yet,fireware support */
907 ExtraDat->ovrflg = bbuf[0];
908 ExtraDat->mngflg = bbuf[1];
909 ExtraDat->logadr = memstick_logaddr(bbuf[2], bbuf[3]);
911 return USB_STOR_TRANSPORT_GOOD;
914 static int ms_lib_process_bootblock(struct us_data *us, u16 PhyBlock, u8 *PageData)
916 struct ms_bootblock_sysent *SysEntry;
917 struct ms_bootblock_sysinf *SysInfo;
921 struct ms_lib_type_extdat ExtraData;
922 struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra;
924 PageBuffer = kmalloc(MS_BYTES_PER_PAGE, GFP_KERNEL);
925 if (PageBuffer == NULL)
930 SysInfo = &(((struct ms_bootblock_page0 *)PageData)->sysinf);
932 if ((SysInfo->bMsClass != MS_SYSINF_MSCLASS_TYPE_1) ||
933 (be16_to_cpu(SysInfo->wPageSize) != MS_SYSINF_PAGE_SIZE) ||
934 ((SysInfo->bSecuritySupport & MS_SYSINF_SECURITY) == MS_SYSINF_SECURITY_SUPPORT) ||
935 (SysInfo->bReserved1 != MS_SYSINF_RESERVED1) ||
936 (SysInfo->bReserved2 != MS_SYSINF_RESERVED2) ||
937 (SysInfo->bFormatType != MS_SYSINF_FORMAT_FAT) ||
938 (SysInfo->bUsage != MS_SYSINF_USAGE_GENERAL))
941 switch (info->MS_Lib.cardType = SysInfo->bCardType) {
942 case MS_SYSINF_CARDTYPE_RDONLY:
943 ms_lib_ctrl_set(info, MS_LIB_CTRL_RDONLY);
945 case MS_SYSINF_CARDTYPE_RDWR:
946 ms_lib_ctrl_reset(info, MS_LIB_CTRL_RDONLY);
948 case MS_SYSINF_CARDTYPE_HYBRID:
953 info->MS_Lib.blockSize = be16_to_cpu(SysInfo->wBlockSize);
954 info->MS_Lib.NumberOfPhyBlock = be16_to_cpu(SysInfo->wBlockNumber);
955 info->MS_Lib.NumberOfLogBlock = be16_to_cpu(SysInfo->wTotalBlockNumber)-2;
956 info->MS_Lib.PagesPerBlock = info->MS_Lib.blockSize * SIZE_OF_KIRO / MS_BYTES_PER_PAGE;
957 info->MS_Lib.NumberOfSegment = info->MS_Lib.NumberOfPhyBlock / MS_PHYSICAL_BLOCKS_PER_SEGMENT;
958 info->MS_Model = be16_to_cpu(SysInfo->wMemorySize);
960 /*Allocate to all number of logicalblock and physicalblock */
961 if (ms_lib_alloc_logicalmap(us))
964 /* Mark the book block */
965 ms_lib_set_bootblockmark(us, PhyBlock);
967 SysEntry = &(((struct ms_bootblock_page0 *)PageData)->sysent);
969 for (i = 0; i < MS_NUMBER_OF_SYSTEM_ENTRY; i++) {
970 u32 EntryOffset, EntrySize;
972 EntryOffset = be32_to_cpu(SysEntry->entry[i].dwStart);
974 if (EntryOffset == 0xffffff)
976 EntrySize = be32_to_cpu(SysEntry->entry[i].dwSize);
981 if (EntryOffset + MS_BYTES_PER_PAGE + EntrySize > info->MS_Lib.blockSize * (u32)SIZE_OF_KIRO)
985 u8 PrevPageNumber = 0;
988 if (SysEntry->entry[i].bType != MS_SYSENT_TYPE_INVALID_BLOCK)
991 while (EntrySize > 0) {
993 PageNumber = (u8)(EntryOffset / MS_BYTES_PER_PAGE + 1);
994 if (PageNumber != PrevPageNumber) {
995 switch (ms_read_readpage(us, PhyBlock, PageNumber, (u32 *)PageBuffer, &ExtraData)) {
996 case MS_STATUS_SUCCESS:
998 case MS_STATUS_WRITE_PROTECT:
999 case MS_ERROR_FLASH_READ:
1000 case MS_STATUS_ERROR:
1005 PrevPageNumber = PageNumber;
1008 phyblk = be16_to_cpu(*(u16 *)(PageBuffer + (EntryOffset % MS_BYTES_PER_PAGE)));
1009 if (phyblk < 0x0fff)
1010 ms_lib_set_initialerrorblock(us, phyblk);
1015 } else if (i == 1) { /* CIS/IDI */
1016 struct ms_bootblock_idi *idi;
1018 if (SysEntry->entry[i].bType != MS_SYSENT_TYPE_CIS_IDI)
1021 switch (ms_read_readpage(us, PhyBlock, (u8)(EntryOffset / MS_BYTES_PER_PAGE + 1), (u32 *)PageBuffer, &ExtraData)) {
1022 case MS_STATUS_SUCCESS:
1024 case MS_STATUS_WRITE_PROTECT:
1025 case MS_ERROR_FLASH_READ:
1026 case MS_STATUS_ERROR:
1031 idi = &((struct ms_bootblock_cis_idi *)(PageBuffer + (EntryOffset % MS_BYTES_PER_PAGE)))->idi.idi;
1032 if (le16_to_cpu(idi->wIDIgeneralConfiguration) != MS_IDI_GENERAL_CONF)
1035 info->MS_Lib.BytesPerSector = le16_to_cpu(idi->wIDIbytesPerSector);
1036 if (info->MS_Lib.BytesPerSector != MS_BYTES_PER_PAGE)
1045 ms_lib_free_logicalmap(us);
1053 static void ms_lib_free_writebuf(struct us_data *us)
1055 struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra;
1056 info->MS_Lib.wrtblk = (u16)-1; /* set to -1 */
1058 /* memset((fdoExt)->MS_Lib.pagemap, 0, sizeof((fdoExt)->MS_Lib.pagemap)) */
1060 ms_lib_clear_pagemap(info); /* (pdx)->MS_Lib.pagemap memset 0 in ms.h */
1062 if (info->MS_Lib.blkpag) {
1063 kfree((u8 *)(info->MS_Lib.blkpag)); /* Arnold test ... */
1064 info->MS_Lib.blkpag = NULL;
1067 if (info->MS_Lib.blkext) {
1068 kfree((u8 *)(info->MS_Lib.blkext)); /* Arnold test ... */
1069 info->MS_Lib.blkext = NULL;
1074 static void ms_lib_free_allocatedarea(struct us_data *us)
1076 struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra;
1078 ms_lib_free_writebuf(us); /* Free MS_Lib.pagemap */
1079 ms_lib_free_logicalmap(us); /* kfree MS_Lib.Phy2LogMap and MS_Lib.Log2PhyMap */
1081 /* set struct us point flag to 0 */
1082 info->MS_Lib.flags = 0;
1083 info->MS_Lib.BytesPerSector = 0;
1084 info->MS_Lib.SectorsPerCylinder = 0;
1086 info->MS_Lib.cardType = 0;
1087 info->MS_Lib.blockSize = 0;
1088 info->MS_Lib.PagesPerBlock = 0;
1090 info->MS_Lib.NumberOfPhyBlock = 0;
1091 info->MS_Lib.NumberOfLogBlock = 0;
1095 static int ms_lib_alloc_writebuf(struct us_data *us)
1097 struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra;
1099 info->MS_Lib.wrtblk = (u16)-1;
1101 info->MS_Lib.blkpag = kmalloc(info->MS_Lib.PagesPerBlock * info->MS_Lib.BytesPerSector, GFP_KERNEL);
1102 info->MS_Lib.blkext = kmalloc(info->MS_Lib.PagesPerBlock * sizeof(struct ms_lib_type_extdat), GFP_KERNEL);
1104 if ((info->MS_Lib.blkpag == NULL) || (info->MS_Lib.blkext == NULL)) {
1105 ms_lib_free_writebuf(us);
1109 ms_lib_clear_writebuf(us);
1114 static int ms_lib_force_setlogical_pair(struct us_data *us, u16 logblk, u16 phyblk)
1116 struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra;
1118 if (logblk == MS_LB_NOT_USED)
1121 if ((logblk >= info->MS_Lib.NumberOfLogBlock) ||
1122 (phyblk >= info->MS_Lib.NumberOfPhyBlock))
1125 info->MS_Lib.Phy2LogMap[phyblk] = logblk;
1126 info->MS_Lib.Log2PhyMap[logblk] = phyblk;
1131 static int ms_read_copyblock(struct us_data *us, u16 oldphy, u16 newphy,
1132 u16 PhyBlockAddr, u8 PageNum, unsigned char *buf, u16 len)
1134 struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf;
1137 /* printk(KERN_INFO "MS_ReaderCopyBlock --- PhyBlockAddr = %x,
1138 PageNum = %x\n", PhyBlockAddr, PageNum); */
1139 result = ene_load_bincode(us, MS_RW_PATTERN);
1140 if (result != USB_STOR_XFER_GOOD)
1141 return USB_STOR_TRANSPORT_ERROR;
1143 memset(bcb, 0, sizeof(struct bulk_cb_wrap));
1144 bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
1145 bcb->DataTransferLength = 0x200*len;
1149 bcb->CDB[4] = (unsigned char)(oldphy);
1150 bcb->CDB[3] = (unsigned char)(oldphy>>8);
1151 bcb->CDB[2] = 0; /* (BYTE)(oldphy>>16) */
1152 bcb->CDB[7] = (unsigned char)(newphy);
1153 bcb->CDB[6] = (unsigned char)(newphy>>8);
1154 bcb->CDB[5] = 0; /* (BYTE)(newphy>>16) */
1155 bcb->CDB[9] = (unsigned char)(PhyBlockAddr);
1156 bcb->CDB[8] = (unsigned char)(PhyBlockAddr>>8);
1157 bcb->CDB[10] = PageNum;
1159 result = ene_send_scsi_cmd(us, FDIR_WRITE, buf, 0);
1160 if (result != USB_STOR_XFER_GOOD)
1161 return USB_STOR_TRANSPORT_ERROR;
1163 return USB_STOR_TRANSPORT_GOOD;
1166 static int ms_read_eraseblock(struct us_data *us, u32 PhyBlockAddr)
1168 struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf;
1170 u32 bn = PhyBlockAddr;
1172 /* printk(KERN_INFO "MS --- ms_read_eraseblock,
1173 PhyBlockAddr = %x\n", PhyBlockAddr); */
1174 result = ene_load_bincode(us, MS_RW_PATTERN);
1175 if (result != USB_STOR_XFER_GOOD)
1176 return USB_STOR_TRANSPORT_ERROR;
1178 memset(bcb, 0, sizeof(struct bulk_cb_wrap));
1179 bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
1180 bcb->DataTransferLength = 0x200;
1184 bcb->CDB[4] = (unsigned char)(bn);
1185 bcb->CDB[3] = (unsigned char)(bn>>8);
1186 bcb->CDB[2] = (unsigned char)(bn>>16);
1188 result = ene_send_scsi_cmd(us, FDIR_READ, NULL, 0);
1189 if (result != USB_STOR_XFER_GOOD)
1190 return USB_STOR_TRANSPORT_ERROR;
1192 return USB_STOR_TRANSPORT_GOOD;
1195 static int ms_lib_check_disableblock(struct us_data *us, u16 PhyBlock)
1197 unsigned char *PageBuf = NULL;
1198 u16 result = MS_STATUS_SUCCESS;
1200 struct ms_lib_type_extdat extdat;
1201 struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra;
1203 PageBuf = kmalloc(MS_BYTES_PER_PAGE, GFP_KERNEL);
1204 if (PageBuf == NULL) {
1205 result = MS_NO_MEMORY_ERROR;
1209 ms_read_readpage(us, PhyBlock, 1, (u32 *)PageBuf, &extdat);
1211 blk = be16_to_cpu(PageBuf[index]);
1212 if (blk == MS_LB_NOT_USED)
1214 if (blk == info->MS_Lib.Log2PhyMap[0]) {
1215 result = MS_ERROR_FLASH_READ;
1226 static int ms_lib_setacquired_errorblock(struct us_data *us, u16 phyblk)
1229 struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra;
1231 if (phyblk >= info->MS_Lib.NumberOfPhyBlock)
1234 log = info->MS_Lib.Phy2LogMap[phyblk];
1236 if (log < info->MS_Lib.NumberOfLogBlock)
1237 info->MS_Lib.Log2PhyMap[log] = MS_LB_NOT_USED;
1239 if (info->MS_Lib.Phy2LogMap[phyblk] != MS_LB_INITIAL_ERROR)
1240 info->MS_Lib.Phy2LogMap[phyblk] = MS_LB_ACQUIRED_ERROR;
1245 static int ms_lib_overwrite_extra(struct us_data *us, u32 PhyBlockAddr,
1246 u8 PageNum, u8 OverwriteFlag)
1248 struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf;
1251 /* printk("MS --- MS_LibOverwriteExtra,
1252 PhyBlockAddr = %x, PageNum = %x\n", PhyBlockAddr, PageNum); */
1253 result = ene_load_bincode(us, MS_RW_PATTERN);
1254 if (result != USB_STOR_XFER_GOOD)
1255 return USB_STOR_TRANSPORT_ERROR;
1257 memset(bcb, 0, sizeof(struct bulk_cb_wrap));
1258 bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
1259 bcb->DataTransferLength = 0x4;
1263 bcb->CDB[5] = (unsigned char)(PageNum);
1264 bcb->CDB[4] = (unsigned char)(PhyBlockAddr);
1265 bcb->CDB[3] = (unsigned char)(PhyBlockAddr>>8);
1266 bcb->CDB[2] = (unsigned char)(PhyBlockAddr>>16);
1267 bcb->CDB[6] = OverwriteFlag;
1272 result = ene_send_scsi_cmd(us, FDIR_READ, NULL, 0);
1273 if (result != USB_STOR_XFER_GOOD)
1274 return USB_STOR_TRANSPORT_ERROR;
1276 return USB_STOR_TRANSPORT_GOOD;
1279 static int ms_lib_error_phyblock(struct us_data *us, u16 phyblk)
1281 struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra;
1283 if (phyblk >= info->MS_Lib.NumberOfPhyBlock)
1284 return MS_STATUS_ERROR;
1286 ms_lib_setacquired_errorblock(us, phyblk);
1288 if (ms_lib_iswritable(info))
1289 return ms_lib_overwrite_extra(us, phyblk, 0, (u8)(~MS_REG_OVR_BKST & BYTE_MASK));
1291 return MS_STATUS_SUCCESS;
1294 static int ms_lib_erase_phyblock(struct us_data *us, u16 phyblk)
1297 struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra;
1299 if (phyblk >= info->MS_Lib.NumberOfPhyBlock)
1300 return MS_STATUS_ERROR;
1302 log = info->MS_Lib.Phy2LogMap[phyblk];
1304 if (log < info->MS_Lib.NumberOfLogBlock)
1305 info->MS_Lib.Log2PhyMap[log] = MS_LB_NOT_USED;
1307 info->MS_Lib.Phy2LogMap[phyblk] = MS_LB_NOT_USED;
1309 if (ms_lib_iswritable(info)) {
1310 switch (ms_read_eraseblock(us, phyblk)) {
1311 case MS_STATUS_SUCCESS:
1312 info->MS_Lib.Phy2LogMap[phyblk] = MS_LB_NOT_USED_ERASED;
1313 return MS_STATUS_SUCCESS;
1314 case MS_ERROR_FLASH_ERASE:
1315 case MS_STATUS_INT_ERROR:
1316 ms_lib_error_phyblock(us, phyblk);
1317 return MS_ERROR_FLASH_ERASE;
1318 case MS_STATUS_ERROR:
1320 ms_lib_ctrl_set(info, MS_LIB_CTRL_RDONLY); /* MS_LibCtrlSet will used by ENE_MSInit ,need check, and why us to info*/
1321 ms_lib_setacquired_errorblock(us, phyblk);
1322 return MS_STATUS_ERROR;
1326 ms_lib_setacquired_errorblock(us, phyblk);
1328 return MS_STATUS_SUCCESS;
1331 static int ms_lib_read_extra(struct us_data *us, u32 PhyBlock,
1332 u8 PageNum, struct ms_lib_type_extdat *ExtraDat)
1334 struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf;
1335 struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra;
1336 u8 *bbuf = info->bbuf;
1339 /* printk("MS_LibReadExtra --- PhyBlock = %x, PageNum = %x\n", PhyBlock, PageNum); */
1340 memset(bcb, 0, sizeof(struct bulk_cb_wrap));
1341 bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
1342 bcb->DataTransferLength = 0x4;
1346 bcb->CDB[5] = (unsigned char)(PageNum);
1347 bcb->CDB[4] = (unsigned char)(PhyBlock);
1348 bcb->CDB[3] = (unsigned char)(PhyBlock>>8);
1349 bcb->CDB[2] = (unsigned char)(PhyBlock>>16);
1352 result = ene_send_scsi_cmd(us, FDIR_READ, bbuf, 0);
1353 if (result != USB_STOR_XFER_GOOD)
1354 return USB_STOR_TRANSPORT_ERROR;
1356 ExtraDat->reserved = 0;
1357 ExtraDat->intr = 0x80; /* Not yet, waiting for fireware support */
1358 ExtraDat->status0 = 0x10; /* Not yet, waiting for fireware support */
1359 ExtraDat->status1 = 0x00; /* Not yet, waiting for fireware support */
1360 ExtraDat->ovrflg = bbuf[0];
1361 ExtraDat->mngflg = bbuf[1];
1362 ExtraDat->logadr = memstick_logaddr(bbuf[2], bbuf[3]);
1364 return USB_STOR_TRANSPORT_GOOD;
1367 static int ms_libsearch_block_from_physical(struct us_data *us, u16 phyblk)
1371 struct ms_lib_type_extdat extdat; /* need check */
1372 struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra;
1375 if (phyblk >= info->MS_Lib.NumberOfPhyBlock)
1378 for (blk = phyblk + 1; blk != phyblk; blk++) {
1379 if ((blk & MS_PHYSICAL_BLOCKS_PER_SEGMENT_MASK) == 0)
1380 blk -= MS_PHYSICAL_BLOCKS_PER_SEGMENT;
1382 Newblk = info->MS_Lib.Phy2LogMap[blk];
1383 if (info->MS_Lib.Phy2LogMap[blk] == MS_LB_NOT_USED_ERASED) {
1385 } else if (info->MS_Lib.Phy2LogMap[blk] == MS_LB_NOT_USED) {
1386 switch (ms_lib_read_extra(us, blk, 0, &extdat)) {
1387 case MS_STATUS_SUCCESS:
1388 case MS_STATUS_SUCCESS_WITH_ECC:
1390 case MS_NOCARD_ERROR:
1391 return MS_NOCARD_ERROR;
1392 case MS_STATUS_INT_ERROR:
1394 case MS_ERROR_FLASH_READ:
1396 ms_lib_setacquired_errorblock(us, blk);
1400 if ((extdat.ovrflg & MS_REG_OVR_BKST) != MS_REG_OVR_BKST_OK) {
1401 ms_lib_setacquired_errorblock(us, blk);
1405 switch (ms_lib_erase_phyblock(us, blk)) {
1406 case MS_STATUS_SUCCESS:
1408 case MS_STATUS_ERROR:
1410 case MS_ERROR_FLASH_ERASE:
1412 ms_lib_error_phyblock(us, blk);
1420 static int ms_libsearch_block_from_logical(struct us_data *us, u16 logblk)
1423 struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra;
1425 phyblk = ms_libconv_to_physical(info, logblk);
1426 if (phyblk >= MS_LB_ERROR) {
1427 if (logblk >= info->MS_Lib.NumberOfLogBlock)
1430 phyblk = (logblk + MS_NUMBER_OF_BOOT_BLOCK) / MS_LOGICAL_BLOCKS_PER_SEGMENT;
1431 phyblk *= MS_PHYSICAL_BLOCKS_PER_SEGMENT;
1432 phyblk += MS_PHYSICAL_BLOCKS_PER_SEGMENT - 1;
1435 return ms_libsearch_block_from_physical(us, phyblk);
1438 static int ms_scsi_test_unit_ready(struct us_data *us, struct scsi_cmnd *srb)
1440 struct ene_ub6250_info *info = (struct ene_ub6250_info *)(us->extra);
1442 /* pr_info("MS_SCSI_Test_Unit_Ready\n"); */
1443 if (info->MS_Status.Insert && info->MS_Status.Ready) {
1444 return USB_STOR_TRANSPORT_GOOD;
1447 return USB_STOR_TRANSPORT_GOOD;
1450 return USB_STOR_TRANSPORT_GOOD;
1453 static int ms_scsi_inquiry(struct us_data *us, struct scsi_cmnd *srb)
1455 /* pr_info("MS_SCSI_Inquiry\n"); */
1456 unsigned char data_ptr[36] = {
1457 0x00, 0x80, 0x02, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x55,
1458 0x53, 0x42, 0x32, 0x2E, 0x30, 0x20, 0x20, 0x43, 0x61,
1459 0x72, 0x64, 0x52, 0x65, 0x61, 0x64, 0x65, 0x72, 0x20,
1460 0x20, 0x20, 0x20, 0x20, 0x20, 0x30, 0x31, 0x30, 0x30};
1462 usb_stor_set_xfer_buf(data_ptr, 36, srb);
1463 return USB_STOR_TRANSPORT_GOOD;
1466 static int ms_scsi_mode_sense(struct us_data *us, struct scsi_cmnd *srb)
1468 struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra;
1469 unsigned char mediaNoWP[12] = {
1470 0x0b, 0x00, 0x00, 0x08, 0x00, 0x00,
1471 0x71, 0xc0, 0x00, 0x00, 0x02, 0x00 };
1472 unsigned char mediaWP[12] = {
1473 0x0b, 0x00, 0x80, 0x08, 0x00, 0x00,
1474 0x71, 0xc0, 0x00, 0x00, 0x02, 0x00 };
1476 if (info->MS_Status.WtP)
1477 usb_stor_set_xfer_buf(mediaWP, 12, srb);
1479 usb_stor_set_xfer_buf(mediaNoWP, 12, srb);
1481 return USB_STOR_TRANSPORT_GOOD;
1484 static int ms_scsi_read_capacity(struct us_data *us, struct scsi_cmnd *srb)
1488 unsigned int offset = 0;
1489 unsigned char buf[8];
1490 struct scatterlist *sg = NULL;
1491 struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra;
1493 US_DEBUGP("ms_scsi_read_capacity\n");
1495 if (info->MS_Status.IsMSPro)
1496 bl_num = info->MSP_TotalBlock - 1;
1498 bl_num = info->MS_Lib.NumberOfLogBlock * info->MS_Lib.blockSize * 2 - 1;
1500 info->bl_num = bl_num;
1501 US_DEBUGP("bl_len = %x\n", bl_len);
1502 US_DEBUGP("bl_num = %x\n", bl_num);
1504 /*srb->request_bufflen = 8; */
1505 buf[0] = (bl_num >> 24) & 0xff;
1506 buf[1] = (bl_num >> 16) & 0xff;
1507 buf[2] = (bl_num >> 8) & 0xff;
1508 buf[3] = (bl_num >> 0) & 0xff;
1509 buf[4] = (bl_len >> 24) & 0xff;
1510 buf[5] = (bl_len >> 16) & 0xff;
1511 buf[6] = (bl_len >> 8) & 0xff;
1512 buf[7] = (bl_len >> 0) & 0xff;
1514 usb_stor_access_xfer_buf(buf, 8, srb, &sg, &offset, TO_XFER_BUF);
1516 return USB_STOR_TRANSPORT_GOOD;
1519 static void ms_lib_phy_to_log_range(u16 PhyBlock, u16 *LogStart, u16 *LogEnde)
1521 PhyBlock /= MS_PHYSICAL_BLOCKS_PER_SEGMENT;
1524 *LogStart = MS_LOGICAL_BLOCKS_IN_1ST_SEGMENT + (PhyBlock - 1) * MS_LOGICAL_BLOCKS_PER_SEGMENT;/*496*/
1525 *LogEnde = *LogStart + MS_LOGICAL_BLOCKS_PER_SEGMENT;/*496*/
1528 *LogEnde = MS_LOGICAL_BLOCKS_IN_1ST_SEGMENT;/*494*/
1532 static int ms_lib_read_extrablock(struct us_data *us, u32 PhyBlock,
1533 u8 PageNum, u8 blen, void *buf)
1535 struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf;
1538 /* printk("MS_LibReadExtraBlock --- PhyBlock = %x,
1539 PageNum = %x, blen = %x\n", PhyBlock, PageNum, blen); */
1541 /* Read Extra Data */
1542 memset(bcb, 0, sizeof(struct bulk_cb_wrap));
1543 bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
1544 bcb->DataTransferLength = 0x4 * blen;
1548 bcb->CDB[5] = (unsigned char)(PageNum);
1549 bcb->CDB[4] = (unsigned char)(PhyBlock);
1550 bcb->CDB[3] = (unsigned char)(PhyBlock>>8);
1551 bcb->CDB[2] = (unsigned char)(PhyBlock>>16);
1554 result = ene_send_scsi_cmd(us, FDIR_READ, buf, 0);
1555 if (result != USB_STOR_XFER_GOOD)
1556 return USB_STOR_TRANSPORT_ERROR;
1558 return USB_STOR_TRANSPORT_GOOD;
1561 static int ms_lib_scan_logicalblocknumber(struct us_data *us, u16 btBlk1st)
1563 u16 PhyBlock, newblk, i;
1564 u16 LogStart, LogEnde;
1565 struct ms_lib_type_extdat extdat;
1566 u32 count = 0, index = 0;
1567 struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra;
1568 u8 *bbuf = info->bbuf;
1570 for (PhyBlock = 0; PhyBlock < info->MS_Lib.NumberOfPhyBlock;) {
1571 ms_lib_phy_to_log_range(PhyBlock, &LogStart, &LogEnde);
1573 for (i = 0; i < MS_PHYSICAL_BLOCKS_PER_SEGMENT; i++, PhyBlock++) {
1574 switch (ms_libconv_to_logical(info, PhyBlock)) {
1575 case MS_STATUS_ERROR:
1581 if (count == PhyBlock) {
1582 ms_lib_read_extrablock(us, PhyBlock, 0, 0x80,
1586 index = (PhyBlock % 0x80) * 4;
1588 extdat.ovrflg = bbuf[index];
1589 extdat.mngflg = bbuf[index+1];
1590 extdat.logadr = memstick_logaddr(bbuf[index+2],
1593 if ((extdat.ovrflg & MS_REG_OVR_BKST) != MS_REG_OVR_BKST_OK) {
1594 ms_lib_setacquired_errorblock(us, PhyBlock);
1598 if ((extdat.mngflg & MS_REG_MNG_ATFLG) == MS_REG_MNG_ATFLG_ATTBL) {
1599 ms_lib_erase_phyblock(us, PhyBlock);
1603 if (extdat.logadr != MS_LB_NOT_USED) {
1604 if ((extdat.logadr < LogStart) || (LogEnde <= extdat.logadr)) {
1605 ms_lib_erase_phyblock(us, PhyBlock);
1609 newblk = ms_libconv_to_physical(info, extdat.logadr);
1611 if (newblk != MS_LB_NOT_USED) {
1612 if (extdat.logadr == 0) {
1613 ms_lib_set_logicalpair(us, extdat.logadr, PhyBlock);
1614 if (ms_lib_check_disableblock(us, btBlk1st)) {
1615 ms_lib_set_logicalpair(us, extdat.logadr, newblk);
1620 ms_lib_read_extra(us, newblk, 0, &extdat);
1621 if ((extdat.ovrflg & MS_REG_OVR_UDST) == MS_REG_OVR_UDST_UPDATING) {
1622 ms_lib_erase_phyblock(us, PhyBlock);
1625 ms_lib_erase_phyblock(us, newblk);
1629 ms_lib_set_logicalpair(us, extdat.logadr, PhyBlock);
1634 return MS_STATUS_SUCCESS;
1638 static int ms_scsi_read(struct us_data *us, struct scsi_cmnd *srb)
1641 unsigned char *cdb = srb->cmnd;
1642 struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf;
1643 struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra;
1645 u32 bn = ((cdb[2] << 24) & 0xff000000) | ((cdb[3] << 16) & 0x00ff0000) |
1646 ((cdb[4] << 8) & 0x0000ff00) | ((cdb[5] << 0) & 0x000000ff);
1647 u16 blen = ((cdb[7] << 8) & 0xff00) | ((cdb[8] << 0) & 0x00ff);
1648 u32 blenByte = blen * 0x200;
1650 if (bn > info->bl_num)
1651 return USB_STOR_TRANSPORT_ERROR;
1653 if (info->MS_Status.IsMSPro) {
1654 result = ene_load_bincode(us, MSP_RW_PATTERN);
1655 if (result != USB_STOR_XFER_GOOD) {
1656 US_DEBUGP("Load MPS RW pattern Fail !!\n");
1657 return USB_STOR_TRANSPORT_ERROR;
1660 /* set up the command wrapper */
1661 memset(bcb, 0, sizeof(struct bulk_cb_wrap));
1662 bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
1663 bcb->DataTransferLength = blenByte;
1667 bcb->CDB[5] = (unsigned char)(bn);
1668 bcb->CDB[4] = (unsigned char)(bn>>8);
1669 bcb->CDB[3] = (unsigned char)(bn>>16);
1670 bcb->CDB[2] = (unsigned char)(bn>>24);
1672 result = ene_send_scsi_cmd(us, FDIR_READ, scsi_sglist(srb), 1);
1681 buf = kmalloc(blenByte, GFP_KERNEL);
1683 return USB_STOR_TRANSPORT_ERROR;
1685 result = ene_load_bincode(us, MS_RW_PATTERN);
1686 if (result != USB_STOR_XFER_GOOD) {
1687 pr_info("Load MS RW pattern Fail !!\n");
1688 result = USB_STOR_TRANSPORT_ERROR;
1692 logblk = (u16)(bn / info->MS_Lib.PagesPerBlock);
1693 PageNum = (u8)(bn % info->MS_Lib.PagesPerBlock);
1696 if (blen > (info->MS_Lib.PagesPerBlock-PageNum))
1697 len = info->MS_Lib.PagesPerBlock-PageNum;
1701 phyblk = ms_libconv_to_physical(info, logblk);
1702 blkno = phyblk * 0x20 + PageNum;
1704 /* set up the command wrapper */
1705 memset(bcb, 0, sizeof(struct bulk_cb_wrap));
1706 bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
1707 bcb->DataTransferLength = 0x200 * len;
1711 bcb->CDB[5] = (unsigned char)(blkno);
1712 bcb->CDB[4] = (unsigned char)(blkno>>8);
1713 bcb->CDB[3] = (unsigned char)(blkno>>16);
1714 bcb->CDB[2] = (unsigned char)(blkno>>24);
1716 result = ene_send_scsi_cmd(us, FDIR_READ, buf+offset, 0);
1717 if (result != USB_STOR_XFER_GOOD) {
1718 pr_info("MS_SCSI_Read --- result = %x\n", result);
1719 result = USB_STOR_TRANSPORT_ERROR;
1728 offset += MS_BYTES_PER_PAGE*len;
1730 usb_stor_set_xfer_buf(buf, blenByte, srb);
1737 static int ms_scsi_write(struct us_data *us, struct scsi_cmnd *srb)
1740 struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf;
1741 unsigned char *cdb = srb->cmnd;
1742 struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra;
1744 u32 bn = ((cdb[2] << 24) & 0xff000000) |
1745 ((cdb[3] << 16) & 0x00ff0000) |
1746 ((cdb[4] << 8) & 0x0000ff00) |
1747 ((cdb[5] << 0) & 0x000000ff);
1748 u16 blen = ((cdb[7] << 8) & 0xff00) | ((cdb[8] << 0) & 0x00ff);
1749 u32 blenByte = blen * 0x200;
1751 if (bn > info->bl_num)
1752 return USB_STOR_TRANSPORT_ERROR;
1754 if (info->MS_Status.IsMSPro) {
1755 result = ene_load_bincode(us, MSP_RW_PATTERN);
1756 if (result != USB_STOR_XFER_GOOD) {
1757 pr_info("Load MSP RW pattern Fail !!\n");
1758 return USB_STOR_TRANSPORT_ERROR;
1761 /* set up the command wrapper */
1762 memset(bcb, 0, sizeof(struct bulk_cb_wrap));
1763 bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
1764 bcb->DataTransferLength = blenByte;
1768 bcb->CDB[5] = (unsigned char)(bn);
1769 bcb->CDB[4] = (unsigned char)(bn>>8);
1770 bcb->CDB[3] = (unsigned char)(bn>>16);
1771 bcb->CDB[2] = (unsigned char)(bn>>24);
1773 result = ene_send_scsi_cmd(us, FDIR_WRITE, scsi_sglist(srb), 1);
1779 u16 len, oldphy, newphy;
1781 buf = kmalloc(blenByte, GFP_KERNEL);
1783 return USB_STOR_TRANSPORT_ERROR;
1784 usb_stor_set_xfer_buf(buf, blenByte, srb);
1786 result = ene_load_bincode(us, MS_RW_PATTERN);
1787 if (result != USB_STOR_XFER_GOOD) {
1788 pr_info("Load MS RW pattern Fail !!\n");
1789 result = USB_STOR_TRANSPORT_ERROR;
1793 PhyBlockAddr = (u16)(bn / info->MS_Lib.PagesPerBlock);
1794 PageNum = (u8)(bn % info->MS_Lib.PagesPerBlock);
1797 if (blen > (info->MS_Lib.PagesPerBlock-PageNum))
1798 len = info->MS_Lib.PagesPerBlock-PageNum;
1802 oldphy = ms_libconv_to_physical(info, PhyBlockAddr); /* need check us <-> info */
1803 newphy = ms_libsearch_block_from_logical(us, PhyBlockAddr);
1805 result = ms_read_copyblock(us, oldphy, newphy, PhyBlockAddr, PageNum, buf+offset, len);
1807 if (result != USB_STOR_XFER_GOOD) {
1808 pr_info("MS_SCSI_Write --- result = %x\n", result);
1809 result = USB_STOR_TRANSPORT_ERROR;
1813 info->MS_Lib.Phy2LogMap[oldphy] = MS_LB_NOT_USED_ERASED;
1814 ms_lib_force_setlogical_pair(us, PhyBlockAddr, newphy);
1821 offset += MS_BYTES_PER_PAGE*len;
1833 static int ene_get_card_type(struct us_data *us, u16 index, void *buf)
1835 struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf;
1838 memset(bcb, 0, sizeof(struct bulk_cb_wrap));
1839 bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
1840 bcb->DataTransferLength = 0x01;
1843 bcb->CDB[2] = (unsigned char)(index>>8);
1844 bcb->CDB[3] = (unsigned char)index;
1846 result = ene_send_scsi_cmd(us, FDIR_READ, buf, 0);
1850 static int ene_get_card_status(struct us_data *us, u8 *buf)
1854 struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra;
1856 /*US_DEBUGP("transport --- ENE_ReadSDReg\n");*/
1857 reg4b = *(u32 *)&buf[0x18];
1858 info->SD_READ_BL_LEN = (u8)((reg4b >> 8) & 0x0f);
1860 tmpreg = (u16) reg4b;
1861 reg4b = *(u32 *)(&buf[0x14]);
1862 if (info->SD_Status.HiCapacity && !info->SD_Status.IsMMC)
1863 info->HC_C_SIZE = (reg4b >> 8) & 0x3fffff;
1865 info->SD_C_SIZE = ((tmpreg & 0x03) << 10) | (u16)(reg4b >> 22);
1866 info->SD_C_SIZE_MULT = (u8)(reg4b >> 7) & 0x07;
1867 if (info->SD_Status.HiCapacity && info->SD_Status.IsMMC)
1868 info->HC_C_SIZE = *(u32 *)(&buf[0x100]);
1870 if (info->SD_READ_BL_LEN > SD_BLOCK_LEN) {
1871 info->SD_Block_Mult = 1 << (info->SD_READ_BL_LEN-SD_BLOCK_LEN);
1872 info->SD_READ_BL_LEN = SD_BLOCK_LEN;
1874 info->SD_Block_Mult = 1;
1877 return USB_STOR_TRANSPORT_GOOD;
1880 static int ene_load_bincode(struct us_data *us, unsigned char flag)
1883 char *fw_name = NULL;
1884 unsigned char *buf = NULL;
1885 const struct firmware *sd_fw = NULL;
1886 int result = USB_STOR_TRANSPORT_ERROR;
1887 struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf;
1888 struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra;
1890 if (info->BIN_FLAG == flag)
1891 return USB_STOR_TRANSPORT_GOOD;
1895 case SD_INIT1_PATTERN:
1896 US_DEBUGP("SD_INIT1_PATTERN\n");
1897 fw_name = "ene-ub6250/sd_init1.bin";
1899 case SD_INIT2_PATTERN:
1900 US_DEBUGP("SD_INIT2_PATTERN\n");
1901 fw_name = "ene-ub6250/sd_init2.bin";
1904 US_DEBUGP("SD_RDWR_PATTERN\n");
1905 fw_name = "ene-ub6250/sd_rdwr.bin";
1908 case MS_INIT_PATTERN:
1909 US_DEBUGP("MS_INIT_PATTERN\n");
1910 fw_name = "ene-ub6250/ms_init.bin";
1912 case MSP_RW_PATTERN:
1913 US_DEBUGP("MSP_RW_PATTERN\n");
1914 fw_name = "ene-ub6250/msp_rdwr.bin";
1917 US_DEBUGP("MS_RW_PATTERN\n");
1918 fw_name = "ene-ub6250/ms_rdwr.bin";
1921 US_DEBUGP("----------- Unknown PATTERN ----------\n");
1925 err = request_firmware(&sd_fw, fw_name, &us->pusb_dev->dev);
1927 US_DEBUGP("load firmware %s failed\n", fw_name);
1930 buf = kmalloc(sd_fw->size, GFP_KERNEL);
1932 US_DEBUGP("Malloc memory for fireware failed!\n");
1935 memcpy(buf, sd_fw->data, sd_fw->size);
1936 memset(bcb, 0, sizeof(struct bulk_cb_wrap));
1937 bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
1938 bcb->DataTransferLength = sd_fw->size;
1942 result = ene_send_scsi_cmd(us, FDIR_WRITE, buf, 0);
1943 info->BIN_FLAG = flag;
1947 if (sd_fw != NULL) {
1948 release_firmware(sd_fw);
1955 static int ms_card_init(struct us_data *us)
1959 unsigned char *PageBuffer0 = NULL, *PageBuffer1 = NULL;
1960 struct ms_lib_type_extdat extdat;
1961 u16 btBlk1st, btBlk2nd;
1963 struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra;
1965 printk(KERN_INFO "MS_CardInit start\n");
1967 ms_lib_free_allocatedarea(us); /* Clean buffer and set struct us_data flag to 0 */
1969 /* get two PageBuffer */
1970 PageBuffer0 = kmalloc(MS_BYTES_PER_PAGE, GFP_KERNEL);
1971 PageBuffer1 = kmalloc(MS_BYTES_PER_PAGE, GFP_KERNEL);
1972 if ((PageBuffer0 == NULL) || (PageBuffer1 == NULL)) {
1973 result = MS_NO_MEMORY_ERROR;
1977 btBlk1st = btBlk2nd = MS_LB_NOT_USED;
1980 for (TmpBlock = 0; TmpBlock < MS_MAX_INITIAL_ERROR_BLOCKS+2; TmpBlock++) {
1982 switch (ms_read_readpage(us, TmpBlock, 0, (u32 *)PageBuffer0, &extdat)) {
1983 case MS_STATUS_SUCCESS:
1985 case MS_STATUS_INT_ERROR:
1987 case MS_STATUS_ERROR:
1992 if ((extdat.ovrflg & MS_REG_OVR_BKST) == MS_REG_OVR_BKST_NG)
1995 if (((extdat.mngflg & MS_REG_MNG_SYSFLG) == MS_REG_MNG_SYSFLG_USER) ||
1996 (be16_to_cpu(((struct ms_bootblock_page0 *)PageBuffer0)->header.wBlockID) != MS_BOOT_BLOCK_ID) ||
1997 (be16_to_cpu(((struct ms_bootblock_page0 *)PageBuffer0)->header.wFormatVersion) != MS_BOOT_BLOCK_FORMAT_VERSION) ||
1998 (((struct ms_bootblock_page0 *)PageBuffer0)->header.bNumberOfDataEntry != MS_BOOT_BLOCK_DATA_ENTRIES))
2001 if (btBlk1st != MS_LB_NOT_USED) {
2002 btBlk2nd = TmpBlock;
2006 btBlk1st = TmpBlock;
2007 memcpy(PageBuffer1, PageBuffer0, MS_BYTES_PER_PAGE);
2008 if (extdat.status1 & (MS_REG_ST1_DTER | MS_REG_ST1_EXER | MS_REG_ST1_FGER))
2012 if (btBlk1st == MS_LB_NOT_USED) {
2013 result = MS_STATUS_ERROR;
2018 if ((extdat.status0 & MS_REG_ST0_WP) == MS_REG_ST0_WP_ON)
2019 ms_lib_ctrl_set(info, MS_LIB_CTRL_WRPROTECT);
2021 result = MS_STATUS_ERROR;
2022 /* 1st Boot Block */
2023 if (btBlk1stErred == 0)
2024 result = ms_lib_process_bootblock(us, btBlk1st, PageBuffer1);
2026 /* 2nd Boot Block */
2027 if (result && (btBlk2nd != MS_LB_NOT_USED))
2028 result = ms_lib_process_bootblock(us, btBlk2nd, PageBuffer0);
2031 result = MS_STATUS_ERROR;
2035 for (TmpBlock = 0; TmpBlock < btBlk1st; TmpBlock++)
2036 info->MS_Lib.Phy2LogMap[TmpBlock] = MS_LB_INITIAL_ERROR;
2038 info->MS_Lib.Phy2LogMap[btBlk1st] = MS_LB_BOOT_BLOCK;
2040 if (btBlk2nd != MS_LB_NOT_USED) {
2041 for (TmpBlock = btBlk1st + 1; TmpBlock < btBlk2nd; TmpBlock++)
2042 info->MS_Lib.Phy2LogMap[TmpBlock] = MS_LB_INITIAL_ERROR;
2044 info->MS_Lib.Phy2LogMap[btBlk2nd] = MS_LB_BOOT_BLOCK;
2047 result = ms_lib_scan_logicalblocknumber(us, btBlk1st);
2051 for (TmpBlock = MS_PHYSICAL_BLOCKS_PER_SEGMENT;
2052 TmpBlock < info->MS_Lib.NumberOfPhyBlock;
2053 TmpBlock += MS_PHYSICAL_BLOCKS_PER_SEGMENT) {
2054 if (ms_count_freeblock(us, TmpBlock) == 0) {
2055 ms_lib_ctrl_set(info, MS_LIB_CTRL_WRPROTECT);
2061 if (ms_lib_alloc_writebuf(us)) {
2062 result = MS_NO_MEMORY_ERROR;
2066 result = MS_STATUS_SUCCESS;
2072 printk(KERN_INFO "MS_CardInit end\n");
2076 static int ene_ms_init(struct us_data *us)
2078 struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf;
2080 u16 MSP_BlockSize, MSP_UserAreaBlocks;
2081 struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra;
2082 u8 *bbuf = info->bbuf;
2084 printk(KERN_INFO "transport --- ENE_MSInit\n");
2086 /* the same part to test ENE */
2088 result = ene_load_bincode(us, MS_INIT_PATTERN);
2089 if (result != USB_STOR_XFER_GOOD) {
2090 printk(KERN_ERR "Load MS Init Code Fail !!\n");
2091 return USB_STOR_TRANSPORT_ERROR;
2094 memset(bcb, 0, sizeof(struct bulk_cb_wrap));
2095 bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
2096 bcb->DataTransferLength = 0x200;
2101 result = ene_send_scsi_cmd(us, FDIR_READ, bbuf, 0);
2102 if (result != USB_STOR_XFER_GOOD) {
2103 printk(KERN_ERR "Execution MS Init Code Fail !!\n");
2104 return USB_STOR_TRANSPORT_ERROR;
2106 /* the same part to test ENE */
2107 info->MS_Status = *(struct MS_STATUS *) bbuf;
2109 if (info->MS_Status.Insert && info->MS_Status.Ready) {
2110 printk(KERN_INFO "Insert = %x\n", info->MS_Status.Insert);
2111 printk(KERN_INFO "Ready = %x\n", info->MS_Status.Ready);
2112 printk(KERN_INFO "IsMSPro = %x\n", info->MS_Status.IsMSPro);
2113 printk(KERN_INFO "IsMSPHG = %x\n", info->MS_Status.IsMSPHG);
2114 printk(KERN_INFO "WtP= %x\n", info->MS_Status.WtP);
2115 if (info->MS_Status.IsMSPro) {
2116 MSP_BlockSize = (bbuf[6] << 8) | bbuf[7];
2117 MSP_UserAreaBlocks = (bbuf[10] << 8) | bbuf[11];
2118 info->MSP_TotalBlock = MSP_BlockSize * MSP_UserAreaBlocks;
2120 ms_card_init(us); /* Card is MS (to ms.c)*/
2122 US_DEBUGP("MS Init Code OK !!\n");
2124 US_DEBUGP("MS Card Not Ready --- %x\n", bbuf[0]);
2125 return USB_STOR_TRANSPORT_ERROR;
2128 return USB_STOR_TRANSPORT_GOOD;
2131 static int ene_sd_init(struct us_data *us)
2134 struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf;
2135 struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra;
2136 u8 *bbuf = info->bbuf;
2138 US_DEBUGP("transport --- ENE_SDInit\n");
2139 /* SD Init Part-1 */
2140 result = ene_load_bincode(us, SD_INIT1_PATTERN);
2141 if (result != USB_STOR_XFER_GOOD) {
2142 US_DEBUGP("Load SD Init Code Part-1 Fail !!\n");
2143 return USB_STOR_TRANSPORT_ERROR;
2146 memset(bcb, 0, sizeof(struct bulk_cb_wrap));
2147 bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
2151 result = ene_send_scsi_cmd(us, FDIR_READ, NULL, 0);
2152 if (result != USB_STOR_XFER_GOOD) {
2153 US_DEBUGP("Execution SD Init Code Fail !!\n");
2154 return USB_STOR_TRANSPORT_ERROR;
2157 /* SD Init Part-2 */
2158 result = ene_load_bincode(us, SD_INIT2_PATTERN);
2159 if (result != USB_STOR_XFER_GOOD) {
2160 US_DEBUGP("Load SD Init Code Part-2 Fail !!\n");
2161 return USB_STOR_TRANSPORT_ERROR;
2164 memset(bcb, 0, sizeof(struct bulk_cb_wrap));
2165 bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
2166 bcb->DataTransferLength = 0x200;
2170 result = ene_send_scsi_cmd(us, FDIR_READ, bbuf, 0);
2171 if (result != USB_STOR_XFER_GOOD) {
2172 US_DEBUGP("Execution SD Init Code Fail !!\n");
2173 return USB_STOR_TRANSPORT_ERROR;
2176 info->SD_Status = *(struct SD_STATUS *) bbuf;
2177 if (info->SD_Status.Insert && info->SD_Status.Ready) {
2178 ene_get_card_status(us, bbuf);
2179 US_DEBUGP("Insert = %x\n", info->SD_Status.Insert);
2180 US_DEBUGP("Ready = %x\n", info->SD_Status.Ready);
2181 US_DEBUGP("IsMMC = %x\n", info->SD_Status.IsMMC);
2182 US_DEBUGP("HiCapacity = %x\n", info->SD_Status.HiCapacity);
2183 US_DEBUGP("HiSpeed = %x\n", info->SD_Status.HiSpeed);
2184 US_DEBUGP("WtP = %x\n", info->SD_Status.WtP);
2186 US_DEBUGP("SD Card Not Ready --- %x\n", bbuf[0]);
2187 return USB_STOR_TRANSPORT_ERROR;
2189 return USB_STOR_TRANSPORT_GOOD;
2193 static int ene_init(struct us_data *us)
2197 struct ene_ub6250_info *info = (struct ene_ub6250_info *)(us->extra);
2198 u8 *bbuf = info->bbuf;
2200 result = ene_get_card_type(us, REG_CARD_STATUS, bbuf);
2201 if (result != USB_STOR_XFER_GOOD)
2202 return USB_STOR_TRANSPORT_ERROR;
2204 misc_reg03 = bbuf[0];
2205 if (misc_reg03 & 0x01) {
2206 if (!info->SD_Status.Ready) {
2207 result = ene_sd_init(us);
2208 if (result != USB_STOR_XFER_GOOD)
2209 return USB_STOR_TRANSPORT_ERROR;
2212 if (misc_reg03 & 0x02) {
2213 if (!info->MS_Status.Ready) {
2214 result = ene_ms_init(us);
2215 if (result != USB_STOR_XFER_GOOD)
2216 return USB_STOR_TRANSPORT_ERROR;
2222 /*----- sd_scsi_irp() ---------*/
2223 static int sd_scsi_irp(struct us_data *us, struct scsi_cmnd *srb)
2226 struct ene_ub6250_info *info = (struct ene_ub6250_info *)us->extra;
2228 info->SrbStatus = SS_SUCCESS;
2229 switch (srb->cmnd[0]) {
2230 case TEST_UNIT_READY:
2231 result = sd_scsi_test_unit_ready(us, srb);
2234 result = sd_scsi_inquiry(us, srb);
2237 result = sd_scsi_mode_sense(us, srb);
2241 result = SD_SCSI_Start_Stop(us, srb);
2245 result = sd_scsi_read_capacity(us, srb);
2248 result = sd_scsi_read(us, srb);
2251 result = sd_scsi_write(us, srb);
2254 info->SrbStatus = SS_ILLEGAL_REQUEST;
2255 result = USB_STOR_TRANSPORT_FAILED;
2264 int ms_scsi_irp(struct us_data *us, struct scsi_cmnd *srb)
2267 struct ene_ub6250_info *info = (struct ene_ub6250_info *)us->extra;
2268 info->SrbStatus = SS_SUCCESS;
2269 switch (srb->cmnd[0]) {
2270 case TEST_UNIT_READY:
2271 result = ms_scsi_test_unit_ready(us, srb);
2274 result = ms_scsi_inquiry(us, srb);
2277 result = ms_scsi_mode_sense(us, srb);
2280 result = ms_scsi_read_capacity(us, srb);
2283 result = ms_scsi_read(us, srb);
2286 result = ms_scsi_write(us, srb);
2289 info->SrbStatus = SS_ILLEGAL_REQUEST;
2290 result = USB_STOR_TRANSPORT_FAILED;
2296 static int ene_transport(struct scsi_cmnd *srb, struct us_data *us)
2299 struct ene_ub6250_info *info = (struct ene_ub6250_info *)(us->extra);
2301 /*US_DEBUG(usb_stor_show_command(srb)); */
2302 scsi_set_resid(srb, 0);
2303 if (unlikely(!(info->SD_Status.Ready || info->MS_Status.Ready))) {
2304 result = ene_init(us);
2306 if (info->SD_Status.Ready)
2307 result = sd_scsi_irp(us, srb);
2309 if (info->MS_Status.Ready)
2310 result = ms_scsi_irp(us, srb);
2316 static int ene_ub6250_probe(struct usb_interface *intf,
2317 const struct usb_device_id *id)
2322 struct ene_ub6250_info *info;
2324 result = usb_stor_probe1(&us, intf, id,
2325 (id - ene_ub6250_usb_ids) + ene_ub6250_unusual_dev_list);
2329 /* FIXME: where should the code alloc extra buf ? */
2330 us->extra = kzalloc(sizeof(struct ene_ub6250_info), GFP_KERNEL);
2333 us->extra_destructor = ene_ub6250_info_destructor;
2335 info = (struct ene_ub6250_info *)(us->extra);
2336 info->bbuf = kmalloc(512, GFP_KERNEL);
2342 us->transport_name = "ene_ub6250";
2343 us->transport = ene_transport;
2346 result = usb_stor_probe2(us);
2350 /* probe card type */
2351 result = ene_get_card_type(us, REG_CARD_STATUS, info->bbuf);
2352 if (result != USB_STOR_XFER_GOOD) {
2353 usb_stor_disconnect(intf);
2354 return USB_STOR_TRANSPORT_ERROR;
2357 misc_reg03 = info->bbuf[0];
2358 if (!(misc_reg03 & 0x01)) {
2359 pr_info("ums_eneub6250: The driver only supports SD/MS card. "
2360 "To use SM card, please build driver/staging/keucr\n");
2369 static int ene_ub6250_resume(struct usb_interface *iface)
2372 struct us_data *us = usb_get_intfdata(iface);
2373 struct ene_ub6250_info *info = (struct ene_ub6250_info *)(us->extra);
2375 mutex_lock(&us->dev_mutex);
2377 US_DEBUGP("%s\n", __func__);
2378 if (us->suspend_resume_hook)
2379 (us->suspend_resume_hook)(us, US_RESUME);
2381 mutex_unlock(&us->dev_mutex);
2383 info->Power_IsResum = true;
2384 /*info->SD_Status.Ready = 0; */
2385 info->SD_Status = *(struct SD_STATUS *)&tmp;
2386 info->MS_Status = *(struct MS_STATUS *)&tmp;
2387 info->SM_Status = *(struct SM_STATUS *)&tmp;
2392 static int ene_ub6250_reset_resume(struct usb_interface *iface)
2395 struct us_data *us = usb_get_intfdata(iface);
2396 struct ene_ub6250_info *info = (struct ene_ub6250_info *)(us->extra);
2397 US_DEBUGP("%s\n", __func__);
2398 /* Report the reset to the SCSI core */
2399 usb_stor_reset_resume(iface);
2401 /* FIXME: Notify the subdrivers that they need to reinitialize
2403 info->Power_IsResum = true;
2404 /*info->SD_Status.Ready = 0; */
2405 info->SD_Status = *(struct SD_STATUS *)&tmp;
2406 info->MS_Status = *(struct MS_STATUS *)&tmp;
2407 info->SM_Status = *(struct SM_STATUS *)&tmp;
2414 #define ene_ub6250_resume NULL
2415 #define ene_ub6250_reset_resume NULL
2419 static struct usb_driver ene_ub6250_driver = {
2420 .name = "ums_eneub6250",
2421 .probe = ene_ub6250_probe,
2422 .disconnect = usb_stor_disconnect,
2423 .suspend = usb_stor_suspend,
2424 .resume = ene_ub6250_resume,
2425 .reset_resume = ene_ub6250_reset_resume,
2426 .pre_reset = usb_stor_pre_reset,
2427 .post_reset = usb_stor_post_reset,
2428 .id_table = ene_ub6250_usb_ids,
2432 static int __init ene_ub6250_init(void)
2434 return usb_register(&ene_ub6250_driver);
2437 static void __exit ene_ub6250_exit(void)
2439 usb_deregister(&ene_ub6250_driver);
2442 module_init(ene_ub6250_init);
2443 module_exit(ene_ub6250_exit);