1 /* Driver for Realtek RTS51xx USB card reader
3 * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved.
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2, or (at your option) any
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, see <http://www.gnu.org/licenses/>.
19 * wwang (wei_wang@realsil.com.cn)
20 * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China
22 * Edwin Rong (edwin_rong@realsil.com.cn)
23 * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China
26 #include <linux/blkdev.h>
27 #include <linux/kthread.h>
28 #include <linux/sched.h>
29 #include <linux/slab.h>
34 #include "rts51x_transport.h"
35 #include "rts51x_scsi.h"
36 #include "rts51x_card.h"
40 #ifdef SUPPORT_MAGIC_GATE
42 static int mg_check_int_error(struct rts51x_chip
*chip
)
46 rts51x_read_register(chip
, MS_TRANS_CFG
, &value
);
47 if (value
& (INT_ERR
| INT_CMDNK
))
48 TRACE_RET(chip
, STATUS_FAIL
);
50 return STATUS_SUCCESS
;
53 static int mg_send_ex_cmd(struct rts51x_chip
*chip
, u8 cmd
, u8 entry_num
)
67 for (i
= 0; i
< MS_MAX_RETRY_COUNT
; i
++) {
69 ms_write_bytes(chip
, PRO_EX_SET_CMD
, 7, WAIT_INT
, data
, 8);
70 if (retval
== STATUS_SUCCESS
)
73 if (i
== MS_MAX_RETRY_COUNT
)
74 TRACE_RET(chip
, STATUS_FAIL
);
75 retval
= mg_check_int_error(chip
);
76 if (retval
!= STATUS_SUCCESS
)
77 TRACE_RET(chip
, STATUS_FAIL
);
79 return STATUS_SUCCESS
;
82 int rts51x_mg_set_tpc_para_sub(struct rts51x_chip
*chip
, int type
, u8 mg_entry_num
)
87 RTS51X_DEBUGP("--%s--\n", __func__
);
90 retval
= ms_set_rw_reg_addr(chip
, 0, 0, Pro_TPCParm
, 1);
92 retval
= ms_set_rw_reg_addr(chip
, 0, 0, Pro_DataCount1
, 6);
93 if (retval
!= STATUS_SUCCESS
)
94 TRACE_RET(chip
, retval
);
102 buf
[5] = mg_entry_num
;
105 ms_write_bytes(chip
, PRO_WRITE_REG
, (type
== 0) ? 1 : 6,
106 NO_WAIT_INT
, buf
, 6);
107 if (retval
!= STATUS_SUCCESS
)
108 TRACE_RET(chip
, retval
);
110 return STATUS_SUCCESS
;
114 * Get MagciGate ID and set Leaf ID to medium.
116 * After receiving this SCSI command, adapter shall fulfill 2 tasks
118 * 1. send GET_ID TPC command to get MagicGate ID and hold it till
119 * Response&challenge CMD.
120 * 2. send SET_ID TPC command to medium with Leaf ID released by host
123 int rts51x_mg_set_leaf_id(struct scsi_cmnd
*srb
, struct rts51x_chip
*chip
)
127 unsigned int lun
= SCSI_LUN(srb
);
128 u8 buf1
[32], buf2
[12];
130 RTS51X_DEBUGP("--%s--\n", __func__
);
132 if (scsi_bufflen(srb
) < 12) {
133 rts51x_set_sense_type(chip
, lun
, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD
);
134 TRACE_RET(chip
, STATUS_FAIL
);
136 rts51x_ms_cleanup_work(chip
);
138 retval
= ms_switch_clock(chip
);
139 if (retval
!= STATUS_SUCCESS
)
140 TRACE_RET(chip
, retval
);
142 retval
= mg_send_ex_cmd(chip
, MG_SET_LID
, 0);
143 if (retval
!= STATUS_SUCCESS
) {
144 rts51x_set_sense_type(chip
, lun
, SENSE_TYPE_MG_KEY_FAIL_NOT_ESTAB
);
145 TRACE_RET(chip
, retval
);
149 rts51x_get_xfer_buf(buf2
, min(12, (int)scsi_bufflen(srb
)), srb
);
150 for (i
= 0; i
< 8; i
++)
151 buf1
[8 + i
] = buf2
[4 + i
];
153 ms_write_bytes(chip
, PRO_WRITE_SHORT_DATA
, 32, WAIT_INT
, buf1
, 32);
154 if (retval
!= STATUS_SUCCESS
) {
155 rts51x_set_sense_type(chip
, lun
, SENSE_TYPE_MG_KEY_FAIL_NOT_ESTAB
);
156 TRACE_RET(chip
, retval
);
158 retval
= mg_check_int_error(chip
);
159 if (retval
!= STATUS_SUCCESS
) {
160 rts51x_set_sense_type(chip
, lun
, SENSE_TYPE_MG_KEY_FAIL_NOT_ESTAB
);
161 TRACE_RET(chip
, retval
);
164 return STATUS_SUCCESS
;
168 * Send Local EKB to host.
170 * After receiving this SCSI command, adapter shall read the divided
171 * data(1536 bytes totally) from medium by using READ_LONG_DATA TPC
172 * for 3 times, and report data to host with data-length is 1052 bytes.
174 int rts51x_mg_get_local_EKB(struct scsi_cmnd
*srb
, struct rts51x_chip
*chip
)
176 int retval
= STATUS_FAIL
;
178 unsigned int lun
= SCSI_LUN(srb
);
181 RTS51X_DEBUGP("--%s--\n", __func__
);
183 rts51x_ms_cleanup_work(chip
);
185 retval
= ms_switch_clock(chip
);
186 if (retval
!= STATUS_SUCCESS
)
187 TRACE_RET(chip
, retval
);
189 buf
= kmalloc(1540, GFP_KERNEL
);
191 TRACE_RET(chip
, STATUS_NOMEM
);
198 retval
= mg_send_ex_cmd(chip
, MG_GET_LEKB
, 0);
199 if (retval
!= STATUS_SUCCESS
) {
200 rts51x_set_sense_type(chip
, lun
, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN
);
201 TRACE_GOTO(chip
, GetEKBFinish
);
204 retval
= ms_transfer_data(chip
, MS_TM_AUTO_READ
, PRO_READ_LONG_DATA
,
205 3, WAIT_INT
, 0, 0, buf
+ 4, 1536);
206 if (retval
!= STATUS_SUCCESS
) {
207 rts51x_set_sense_type(chip
, lun
, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN
);
208 rts51x_write_register(chip
, CARD_STOP
, MS_STOP
| MS_CLR_ERR
,
209 MS_STOP
| MS_CLR_ERR
);
210 TRACE_GOTO(chip
, GetEKBFinish
);
212 retval
= mg_check_int_error(chip
);
213 if (retval
!= STATUS_SUCCESS
) {
214 rts51x_set_sense_type(chip
, lun
, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN
);
215 TRACE_GOTO(chip
, GetEKBFinish
);
218 bufflen
= min(1052, (int)scsi_bufflen(srb
));
219 rts51x_set_xfer_buf(buf
, bufflen
, srb
);
227 * Send challenge(host) to medium.
229 * After receiving this SCSI command, adapter shall sequentially issues
230 * TPC commands to the medium for writing 8-bytes data as challenge
231 * by host within a short data packet.
233 int rts51x_mg_chg(struct scsi_cmnd
*srb
, struct rts51x_chip
*chip
)
235 struct ms_info
*ms_card
= &(chip
->ms_card
);
239 unsigned int lun
= SCSI_LUN(srb
);
242 RTS51X_DEBUGP("--%s--\n", __func__
);
244 rts51x_ms_cleanup_work(chip
);
246 retval
= ms_switch_clock(chip
);
247 if (retval
!= STATUS_SUCCESS
)
248 TRACE_RET(chip
, retval
);
250 retval
= mg_send_ex_cmd(chip
, MG_GET_ID
, 0);
251 if (retval
!= STATUS_SUCCESS
) {
252 rts51x_set_sense_type(chip
, lun
, SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM
);
253 TRACE_RET(chip
, retval
);
257 ms_read_bytes(chip
, PRO_READ_SHORT_DATA
, 32, WAIT_INT
, buf
, 32);
258 if (retval
!= STATUS_SUCCESS
) {
259 rts51x_set_sense_type(chip
, lun
, SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM
);
260 TRACE_RET(chip
, retval
);
262 retval
= mg_check_int_error(chip
);
263 if (retval
!= STATUS_SUCCESS
) {
264 rts51x_set_sense_type(chip
, lun
, SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM
);
265 TRACE_RET(chip
, retval
);
268 memcpy(ms_card
->magic_gate_id
, buf
, 16);
270 for (i
= 0; i
< 2500; i
++) {
271 RTS51X_READ_REG(chip
, MS_TRANS_CFG
, &tmp
);
273 (MS_INT_CED
| MS_INT_CMDNK
| MS_INT_BREQ
| MS_INT_ERR
))
280 rts51x_set_sense_type(chip
, lun
, SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM
);
281 TRACE_RET(chip
, STATUS_FAIL
);
284 retval
= mg_send_ex_cmd(chip
, MG_SET_RD
, 0);
285 if (retval
!= STATUS_SUCCESS
) {
286 rts51x_set_sense_type(chip
, lun
, SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM
);
287 TRACE_RET(chip
, retval
);
290 bufflen
= min(12, (int)scsi_bufflen(srb
));
291 rts51x_get_xfer_buf(buf
, bufflen
, srb
);
293 for (i
= 0; i
< 8; i
++)
295 for (i
= 0; i
< 24; i
++)
298 ms_write_bytes(chip
, PRO_WRITE_SHORT_DATA
, 32, WAIT_INT
, buf
, 32);
299 if (retval
!= STATUS_SUCCESS
) {
300 rts51x_set_sense_type(chip
, lun
, SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM
);
301 TRACE_RET(chip
, retval
);
303 retval
= mg_check_int_error(chip
);
304 if (retval
!= STATUS_SUCCESS
) {
305 rts51x_set_sense_type(chip
, lun
, SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM
);
306 TRACE_RET(chip
, retval
);
309 ms_card
->mg_auth
= 0;
311 return STATUS_SUCCESS
;
315 * Send Response and Challenge data to host.
317 * After receiving this SCSI command, adapter shall communicates with
318 * the medium, get parameters(HRd, Rms, MagicGateID) by using READ_SHORT_DATA
319 * TPC and send the data to host according to certain format required by
320 * MG-R specification.
321 * The paremeter MagicGateID is the one that adapter has obtained from
322 * the medium by TPC commands in Set Leaf ID command phase previously.
324 int rts51x_mg_get_rsp_chg(struct scsi_cmnd
*srb
, struct rts51x_chip
*chip
)
326 struct ms_info
*ms_card
= &(chip
->ms_card
);
329 unsigned int lun
= SCSI_LUN(srb
);
330 u8 buf1
[32], buf2
[36], tmp
;
332 RTS51X_DEBUGP("--%s--\n", __func__
);
334 rts51x_ms_cleanup_work(chip
);
336 retval
= ms_switch_clock(chip
);
337 if (retval
!= STATUS_SUCCESS
)
338 TRACE_RET(chip
, retval
);
340 retval
= mg_send_ex_cmd(chip
, MG_MAKE_RMS
, 0);
341 if (retval
!= STATUS_SUCCESS
) {
342 rts51x_set_sense_type(chip
, lun
, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN
);
343 TRACE_RET(chip
, retval
);
347 ms_read_bytes(chip
, PRO_READ_SHORT_DATA
, 32, WAIT_INT
, buf1
, 32);
348 if (retval
!= STATUS_SUCCESS
) {
349 rts51x_set_sense_type(chip
, lun
, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN
);
350 TRACE_RET(chip
, retval
);
352 retval
= mg_check_int_error(chip
);
353 if (retval
!= STATUS_SUCCESS
) {
354 rts51x_set_sense_type(chip
, lun
, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN
);
355 TRACE_RET(chip
, retval
);
363 memcpy(buf2
+ 4, ms_card
->magic_gate_id
, 16);
364 memcpy(buf2
+ 20, buf1
, 16);
366 bufflen
= min(36, (int)scsi_bufflen(srb
));
367 rts51x_set_xfer_buf(buf2
, bufflen
, srb
);
369 for (i
= 0; i
< 2500; i
++) {
370 RTS51X_READ_REG(chip
, MS_TRANS_CFG
, &tmp
);
371 if (tmp
& (MS_INT_CED
| MS_INT_CMDNK
|
372 MS_INT_BREQ
| MS_INT_ERR
))
379 rts51x_set_sense_type(chip
, lun
, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN
);
380 TRACE_RET(chip
, STATUS_FAIL
);
383 return STATUS_SUCCESS
;
387 * Send response(host) to medium.
389 * After receiving this SCSI command, adapter shall sequentially
390 * issues TPC commands to the medium for writing 8-bytes data as
391 * challenge by host within a short data packet.
393 int rts51x_mg_rsp(struct scsi_cmnd
*srb
, struct rts51x_chip
*chip
)
395 struct ms_info
*ms_card
= &(chip
->ms_card
);
399 unsigned int lun
= SCSI_LUN(srb
);
402 RTS51X_DEBUGP("--%s--\n", __func__
);
404 rts51x_ms_cleanup_work(chip
);
406 retval
= ms_switch_clock(chip
);
407 if (retval
!= STATUS_SUCCESS
)
408 TRACE_RET(chip
, retval
);
410 retval
= mg_send_ex_cmd(chip
, MG_MAKE_KSE
, 0);
411 if (retval
!= STATUS_SUCCESS
) {
412 rts51x_set_sense_type(chip
, lun
, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN
);
413 TRACE_RET(chip
, retval
);
416 bufflen
= min(12, (int)scsi_bufflen(srb
));
417 rts51x_get_xfer_buf(buf
, bufflen
, srb
);
419 for (i
= 0; i
< 8; i
++)
421 for (i
= 0; i
< 24; i
++)
424 ms_write_bytes(chip
, PRO_WRITE_SHORT_DATA
, 32, WAIT_INT
, buf
, 32);
425 if (retval
!= STATUS_SUCCESS
) {
426 rts51x_set_sense_type(chip
, lun
, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN
);
427 TRACE_RET(chip
, retval
);
429 retval
= mg_check_int_error(chip
);
430 if (retval
!= STATUS_SUCCESS
) {
431 rts51x_set_sense_type(chip
, lun
, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN
);
432 TRACE_RET(chip
, retval
);
435 ms_card
->mg_auth
= 1;
437 return STATUS_SUCCESS
;
440 /** * Send ICV data to host.
442 * After receiving this SCSI command, adapter shall read the divided
443 * data(1024 bytes totally) from medium by using READ_LONG_DATA TPC
444 * for 2 times, and report data to host with data-length is 1028 bytes.
446 * Since the extra 4 bytes data is just only a prefix to original data
447 * that read from medium, so that the 4-byte data pushed into Ring buffer
448 * precedes data transmission from medium to Ring buffer by DMA mechanism
449 * in order to get maximum performance and minimum code size simultaneously.
451 int rts51x_mg_get_ICV(struct scsi_cmnd
*srb
, struct rts51x_chip
*chip
)
453 struct ms_info
*ms_card
= &(chip
->ms_card
);
456 unsigned int lun
= SCSI_LUN(srb
);
459 RTS51X_DEBUGP("--%s--\n", __func__
);
461 rts51x_ms_cleanup_work(chip
);
463 retval
= ms_switch_clock(chip
);
464 if (retval
!= STATUS_SUCCESS
)
465 TRACE_RET(chip
, retval
);
467 buf
= kmalloc(1028, GFP_KERNEL
);
469 TRACE_RET(chip
, STATUS_NOMEM
);
476 retval
= mg_send_ex_cmd(chip
, MG_GET_IBD
, ms_card
->mg_entry_num
);
477 if (retval
!= STATUS_SUCCESS
) {
478 rts51x_set_sense_type(chip
, lun
, SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR
);
479 TRACE_GOTO(chip
, GetICVFinish
);
482 retval
= ms_transfer_data(chip
, MS_TM_AUTO_READ
, PRO_READ_LONG_DATA
,
483 2, WAIT_INT
, 0, 0, buf
+ 4, 1024);
484 if (retval
!= STATUS_SUCCESS
) {
485 rts51x_set_sense_type(chip
, lun
, SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR
);
486 rts51x_write_register(chip
, CARD_STOP
, MS_STOP
| MS_CLR_ERR
,
487 MS_STOP
| MS_CLR_ERR
);
488 TRACE_GOTO(chip
, GetICVFinish
);
490 retval
= mg_check_int_error(chip
);
491 if (retval
!= STATUS_SUCCESS
) {
492 rts51x_set_sense_type(chip
, lun
, SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR
);
493 TRACE_GOTO(chip
, GetICVFinish
);
496 bufflen
= min(1028, (int)scsi_bufflen(srb
));
497 rts51x_set_xfer_buf(buf
, bufflen
, srb
);
505 * Send ICV data to medium.
507 * After receiving this SCSI command, adapter shall receive 1028 bytes
508 * and write the later 1024 bytes to medium by WRITE_LONG_DATA TPC
511 * Since the first 4-bytes data is just only a prefix to original data
512 * that sent by host, and it should be skipped by shifting DMA pointer
513 * before writing 1024 bytes to medium.
515 int rts51x_mg_set_ICV(struct scsi_cmnd
*srb
, struct rts51x_chip
*chip
)
517 struct ms_info
*ms_card
= &(chip
->ms_card
);
520 #ifdef MG_SET_ICV_SLOW
523 unsigned int lun
= SCSI_LUN(srb
);
526 RTS51X_DEBUGP("--%s--\n", __func__
);
528 rts51x_ms_cleanup_work(chip
);
530 retval
= ms_switch_clock(chip
);
531 if (retval
!= STATUS_SUCCESS
)
532 TRACE_RET(chip
, retval
);
534 buf
= kmalloc(1028, GFP_KERNEL
);
536 TRACE_RET(chip
, STATUS_NOMEM
);
538 bufflen
= min(1028, (int)scsi_bufflen(srb
));
539 rts51x_get_xfer_buf(buf
, bufflen
, srb
);
541 retval
= mg_send_ex_cmd(chip
, MG_SET_IBD
, ms_card
->mg_entry_num
);
542 if (retval
!= STATUS_SUCCESS
) {
543 if (ms_card
->mg_auth
== 0) {
544 if ((buf
[5] & 0xC0) != 0)
545 rts51x_set_sense_type(chip
, lun
,
546 SENSE_TYPE_MG_KEY_FAIL_NOT_ESTAB
);
548 rts51x_set_sense_type(chip
, lun
,
549 SENSE_TYPE_MG_WRITE_ERR
);
551 rts51x_set_sense_type(chip
, lun
, SENSE_TYPE_MG_WRITE_ERR
);
553 TRACE_GOTO(chip
, SetICVFinish
);
556 #ifdef MG_SET_ICV_SLOW
557 for (i
= 0; i
< 2; i
++) {
560 rts51x_init_cmd(chip
);
562 rts51x_add_cmd(chip
, WRITE_REG_CMD
, MS_TPC
, 0xFF,
563 PRO_WRITE_LONG_DATA
);
564 rts51x_add_cmd(chip
, WRITE_REG_CMD
, MS_TRANS_CFG
, 0xFF,
567 rts51x_trans_dma_enable(DMA_TO_DEVICE
, chip
, 512, DMA_512
);
569 rts51x_add_cmd(chip
, WRITE_REG_CMD
, MS_TRANSFER
, 0xFF,
570 MS_TRANSFER_START
| MS_TM_NORMAL_WRITE
);
571 rts51x_add_cmd(chip
, CHECK_REG_CMD
, MS_TRANSFER
,
572 MS_TRANSFER_END
, MS_TRANSFER_END
);
574 retval
= rts51x_send_cmd(chip
, MODE_CDOR
, 100);
575 if (retval
!= STATUS_SUCCESS
) {
576 rts51x_set_sense_type(chip
, lun
, SENSE_TYPE_MG_WRITE_ERR
);
577 TRACE_GOTO(chip
, SetICVFinish
);
580 retval
= rts51x_transfer_data_rcc(chip
, SND_BULK_PIPE(chip
),
581 buf
+ 4 + i
* 512, 512, 0,
582 NULL
, 3000, STAGE_DO
);
583 if (retval
!= STATUS_SUCCESS
) {
584 rts51x_clear_ms_error(chip
);
585 if (ms_card
->mg_auth
== 0) {
586 if ((buf
[5] & 0xC0) != 0)
587 rts51x_set_sense_type(chip
, lun
,
588 SENSE_TYPE_MG_KEY_FAIL_NOT_ESTAB
);
590 rts51x_set_sense_type(chip
, lun
,
591 SENSE_TYPE_MG_WRITE_ERR
);
593 rts51x_set_sense_type(chip
, lun
,
594 SENSE_TYPE_MG_WRITE_ERR
);
596 retval
= STATUS_FAIL
;
597 TRACE_GOTO(chip
, SetICVFinish
);
600 retval
= rts51x_get_rsp(chip
, 1, 3000);
601 if (CHECK_MS_TRANS_FAIL(chip
, retval
)
602 || mg_check_int_error(chip
)) {
603 rts51x_clear_ms_error(chip
);
604 if (ms_card
->mg_auth
== 0) {
605 if ((buf
[5] & 0xC0) != 0)
606 rts51x_set_sense_type(chip
, lun
,
607 SENSE_TYPE_MG_KEY_FAIL_NOT_ESTAB
);
609 rts51x_set_sense_type(chip
, lun
,
610 SENSE_TYPE_MG_WRITE_ERR
);
612 rts51x_set_sense_type(chip
, lun
,
613 SENSE_TYPE_MG_WRITE_ERR
);
615 retval
= STATUS_FAIL
;
616 TRACE_GOTO(chip
, SetICVFinish
);
620 retval
= ms_transfer_data(chip
, MS_TM_AUTO_WRITE
, PRO_WRITE_LONG_DATA
,
621 2, WAIT_INT
, 0, 0, buf
+ 4, 1024);
622 if (retval
!= STATUS_SUCCESS
) {
623 rts51x_clear_ms_error(chip
);
624 if (ms_card
->mg_auth
== 0) {
625 if ((buf
[5] & 0xC0) != 0)
626 rts51x_set_sense_type(chip
, lun
,
627 SENSE_TYPE_MG_KEY_FAIL_NOT_ESTAB
);
629 rts51x_set_sense_type(chip
, lun
,
630 SENSE_TYPE_MG_WRITE_ERR
);
632 rts51x_set_sense_type(chip
, lun
, SENSE_TYPE_MG_WRITE_ERR
);
634 TRACE_GOTO(chip
, SetICVFinish
);
643 #endif /* SUPPORT_MAGIC_GATE */