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"
39 #ifdef SUPPORT_MAGIC_GATE
41 int mg_check_int_error(struct rts51x_chip
*chip
)
45 rts51x_read_register(chip
, MS_TRANS_CFG
, &value
);
46 if (value
& (INT_ERR
| INT_CMDNK
))
47 TRACE_RET(chip
, STATUS_FAIL
);
49 return STATUS_SUCCESS
;
52 static int mg_send_ex_cmd(struct rts51x_chip
*chip
, u8 cmd
, u8 entry_num
)
66 for (i
= 0; i
< MS_MAX_RETRY_COUNT
; i
++) {
68 ms_write_bytes(chip
, PRO_EX_SET_CMD
, 7, WAIT_INT
, data
, 8);
69 if (retval
== STATUS_SUCCESS
)
72 if (i
== MS_MAX_RETRY_COUNT
)
73 TRACE_RET(chip
, STATUS_FAIL
);
74 retval
= mg_check_int_error(chip
);
75 if (retval
!= STATUS_SUCCESS
)
76 TRACE_RET(chip
, STATUS_FAIL
);
78 return STATUS_SUCCESS
;
81 int mg_set_tpc_para_sub(struct rts51x_chip
*chip
, int type
, u8 mg_entry_num
)
86 RTS51X_DEBUGP("--%s--\n", __func__
);
89 retval
= ms_set_rw_reg_addr(chip
, 0, 0, Pro_TPCParm
, 1);
91 retval
= ms_set_rw_reg_addr(chip
, 0, 0, Pro_DataCount1
, 6);
92 if (retval
!= STATUS_SUCCESS
)
93 TRACE_RET(chip
, retval
);
101 buf
[5] = mg_entry_num
;
104 ms_write_bytes(chip
, PRO_WRITE_REG
, (type
== 0) ? 1 : 6,
105 NO_WAIT_INT
, buf
, 6);
106 if (retval
!= STATUS_SUCCESS
)
107 TRACE_RET(chip
, retval
);
109 return STATUS_SUCCESS
;
113 * Get MagciGate ID and set Leaf ID to medium.
115 * After receiving this SCSI command, adapter shall fulfill 2 tasks
117 * 1. send GET_ID TPC command to get MagicGate ID and hold it till
118 * Response&challenge CMD.
119 * 2. send SET_ID TPC command to medium with Leaf ID released by host
122 int mg_set_leaf_id(struct scsi_cmnd
*srb
, struct rts51x_chip
*chip
)
126 unsigned int lun
= SCSI_LUN(srb
);
127 u8 buf1
[32], buf2
[12];
129 RTS51X_DEBUGP("--%s--\n", __func__
);
131 if (scsi_bufflen(srb
) < 12) {
132 set_sense_type(chip
, lun
, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD
);
133 TRACE_RET(chip
, STATUS_FAIL
);
135 ms_cleanup_work(chip
);
137 retval
= ms_switch_clock(chip
);
138 if (retval
!= STATUS_SUCCESS
)
139 TRACE_RET(chip
, retval
);
141 retval
= mg_send_ex_cmd(chip
, MG_SET_LID
, 0);
142 if (retval
!= STATUS_SUCCESS
) {
143 set_sense_type(chip
, lun
, SENSE_TYPE_MG_KEY_FAIL_NOT_ESTAB
);
144 TRACE_RET(chip
, retval
);
148 rts51x_get_xfer_buf(buf2
, min(12, (int)scsi_bufflen(srb
)), srb
);
149 for (i
= 0; i
< 8; i
++)
150 buf1
[8 + i
] = buf2
[4 + i
];
152 ms_write_bytes(chip
, PRO_WRITE_SHORT_DATA
, 32, WAIT_INT
, buf1
, 32);
153 if (retval
!= STATUS_SUCCESS
) {
154 set_sense_type(chip
, lun
, SENSE_TYPE_MG_KEY_FAIL_NOT_ESTAB
);
155 TRACE_RET(chip
, retval
);
157 retval
= mg_check_int_error(chip
);
158 if (retval
!= STATUS_SUCCESS
) {
159 set_sense_type(chip
, lun
, SENSE_TYPE_MG_KEY_FAIL_NOT_ESTAB
);
160 TRACE_RET(chip
, retval
);
163 return STATUS_SUCCESS
;
167 * Send Local EKB to host.
169 * After receiving this SCSI command, adapter shall read the divided
170 * data(1536 bytes totally) from medium by using READ_LONG_DATA TPC
171 * for 3 times, and report data to host with data-length is 1052 bytes.
173 int mg_get_local_EKB(struct scsi_cmnd
*srb
, struct rts51x_chip
*chip
)
175 int retval
= STATUS_FAIL
;
177 unsigned int lun
= SCSI_LUN(srb
);
180 RTS51X_DEBUGP("--%s--\n", __func__
);
182 ms_cleanup_work(chip
);
184 retval
= ms_switch_clock(chip
);
185 if (retval
!= STATUS_SUCCESS
)
186 TRACE_RET(chip
, retval
);
188 buf
= kmalloc(1540, GFP_KERNEL
);
190 TRACE_RET(chip
, STATUS_NOMEM
);
197 retval
= mg_send_ex_cmd(chip
, MG_GET_LEKB
, 0);
198 if (retval
!= STATUS_SUCCESS
) {
199 set_sense_type(chip
, lun
, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN
);
200 TRACE_GOTO(chip
, GetEKBFinish
);
203 retval
= ms_transfer_data(chip
, MS_TM_AUTO_READ
, PRO_READ_LONG_DATA
,
204 3, WAIT_INT
, 0, 0, buf
+ 4, 1536);
205 if (retval
!= STATUS_SUCCESS
) {
206 set_sense_type(chip
, lun
, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN
);
207 rts51x_write_register(chip
, CARD_STOP
, MS_STOP
| MS_CLR_ERR
,
208 MS_STOP
| MS_CLR_ERR
);
209 TRACE_GOTO(chip
, GetEKBFinish
);
211 retval
= mg_check_int_error(chip
);
212 if (retval
!= STATUS_SUCCESS
) {
213 set_sense_type(chip
, lun
, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN
);
214 TRACE_GOTO(chip
, GetEKBFinish
);
217 bufflen
= min(1052, (int)scsi_bufflen(srb
));
218 rts51x_set_xfer_buf(buf
, bufflen
, srb
);
226 * Send challenge(host) to medium.
228 * After receiving this SCSI command, adapter shall sequentially issues
229 * TPC commands to the medium for writing 8-bytes data as challenge
230 * by host within a short data packet.
232 int mg_chg(struct scsi_cmnd
*srb
, struct rts51x_chip
*chip
)
234 struct ms_info
*ms_card
= &(chip
->ms_card
);
238 unsigned int lun
= SCSI_LUN(srb
);
241 RTS51X_DEBUGP("--%s--\n", __func__
);
243 ms_cleanup_work(chip
);
245 retval
= ms_switch_clock(chip
);
246 if (retval
!= STATUS_SUCCESS
)
247 TRACE_RET(chip
, retval
);
249 retval
= mg_send_ex_cmd(chip
, MG_GET_ID
, 0);
250 if (retval
!= STATUS_SUCCESS
) {
251 set_sense_type(chip
, lun
, SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM
);
252 TRACE_RET(chip
, retval
);
256 ms_read_bytes(chip
, PRO_READ_SHORT_DATA
, 32, WAIT_INT
, buf
, 32);
257 if (retval
!= STATUS_SUCCESS
) {
258 set_sense_type(chip
, lun
, SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM
);
259 TRACE_RET(chip
, retval
);
261 retval
= mg_check_int_error(chip
);
262 if (retval
!= STATUS_SUCCESS
) {
263 set_sense_type(chip
, lun
, SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM
);
264 TRACE_RET(chip
, retval
);
267 memcpy(ms_card
->magic_gate_id
, buf
, 16);
269 for (i
= 0; i
< 2500; i
++) {
270 RTS51X_READ_REG(chip
, MS_TRANS_CFG
, &tmp
);
272 (MS_INT_CED
| MS_INT_CMDNK
| MS_INT_BREQ
| MS_INT_ERR
))
279 set_sense_type(chip
, lun
, SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM
);
280 TRACE_RET(chip
, STATUS_FAIL
);
283 retval
= mg_send_ex_cmd(chip
, MG_SET_RD
, 0);
284 if (retval
!= STATUS_SUCCESS
) {
285 set_sense_type(chip
, lun
, SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM
);
286 TRACE_RET(chip
, retval
);
289 bufflen
= min(12, (int)scsi_bufflen(srb
));
290 rts51x_get_xfer_buf(buf
, bufflen
, srb
);
292 for (i
= 0; i
< 8; i
++)
294 for (i
= 0; i
< 24; i
++)
297 ms_write_bytes(chip
, PRO_WRITE_SHORT_DATA
, 32, WAIT_INT
, buf
, 32);
298 if (retval
!= STATUS_SUCCESS
) {
299 set_sense_type(chip
, lun
, SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM
);
300 TRACE_RET(chip
, retval
);
302 retval
= mg_check_int_error(chip
);
303 if (retval
!= STATUS_SUCCESS
) {
304 set_sense_type(chip
, lun
, SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM
);
305 TRACE_RET(chip
, retval
);
308 ms_card
->mg_auth
= 0;
310 return STATUS_SUCCESS
;
314 * Send Response and Challenge data to host.
316 * After receiving this SCSI command, adapter shall communicates with
317 * the medium, get parameters(HRd, Rms, MagicGateID) by using READ_SHORT_DATA
318 * TPC and send the data to host according to certain format required by
319 * MG-R specification.
320 * The paremeter MagicGateID is the one that adapter has obtained from
321 * the medium by TPC commands in Set Leaf ID command phase previously.
323 int mg_get_rsp_chg(struct scsi_cmnd
*srb
, struct rts51x_chip
*chip
)
325 struct ms_info
*ms_card
= &(chip
->ms_card
);
328 unsigned int lun
= SCSI_LUN(srb
);
329 u8 buf1
[32], buf2
[36], tmp
;
331 RTS51X_DEBUGP("--%s--\n", __func__
);
333 ms_cleanup_work(chip
);
335 retval
= ms_switch_clock(chip
);
336 if (retval
!= STATUS_SUCCESS
)
337 TRACE_RET(chip
, retval
);
339 retval
= mg_send_ex_cmd(chip
, MG_MAKE_RMS
, 0);
340 if (retval
!= STATUS_SUCCESS
) {
341 set_sense_type(chip
, lun
, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN
);
342 TRACE_RET(chip
, retval
);
346 ms_read_bytes(chip
, PRO_READ_SHORT_DATA
, 32, WAIT_INT
, buf1
, 32);
347 if (retval
!= STATUS_SUCCESS
) {
348 set_sense_type(chip
, lun
, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN
);
349 TRACE_RET(chip
, retval
);
351 retval
= mg_check_int_error(chip
);
352 if (retval
!= STATUS_SUCCESS
) {
353 set_sense_type(chip
, lun
, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN
);
354 TRACE_RET(chip
, retval
);
362 memcpy(buf2
+ 4, ms_card
->magic_gate_id
, 16);
363 memcpy(buf2
+ 20, buf1
, 16);
365 bufflen
= min(36, (int)scsi_bufflen(srb
));
366 rts51x_set_xfer_buf(buf2
, bufflen
, srb
);
368 for (i
= 0; i
< 2500; i
++) {
369 RTS51X_READ_REG(chip
, MS_TRANS_CFG
, &tmp
);
370 if (tmp
& (MS_INT_CED
| MS_INT_CMDNK
|
371 MS_INT_BREQ
| MS_INT_ERR
))
378 set_sense_type(chip
, lun
, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN
);
379 TRACE_RET(chip
, STATUS_FAIL
);
382 return STATUS_SUCCESS
;
386 * Send response(host) to medium.
388 * After receiving this SCSI command, adapter shall sequentially
389 * issues TPC commands to the medium for writing 8-bytes data as
390 * challenge by host within a short data packet.
392 int mg_rsp(struct scsi_cmnd
*srb
, struct rts51x_chip
*chip
)
394 struct ms_info
*ms_card
= &(chip
->ms_card
);
398 unsigned int lun
= SCSI_LUN(srb
);
401 RTS51X_DEBUGP("--%s--\n", __func__
);
403 ms_cleanup_work(chip
);
405 retval
= ms_switch_clock(chip
);
406 if (retval
!= STATUS_SUCCESS
)
407 TRACE_RET(chip
, retval
);
409 retval
= mg_send_ex_cmd(chip
, MG_MAKE_KSE
, 0);
410 if (retval
!= STATUS_SUCCESS
) {
411 set_sense_type(chip
, lun
, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN
);
412 TRACE_RET(chip
, retval
);
415 bufflen
= min(12, (int)scsi_bufflen(srb
));
416 rts51x_get_xfer_buf(buf
, bufflen
, srb
);
418 for (i
= 0; i
< 8; i
++)
420 for (i
= 0; i
< 24; i
++)
423 ms_write_bytes(chip
, PRO_WRITE_SHORT_DATA
, 32, WAIT_INT
, buf
, 32);
424 if (retval
!= STATUS_SUCCESS
) {
425 set_sense_type(chip
, lun
, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN
);
426 TRACE_RET(chip
, retval
);
428 retval
= mg_check_int_error(chip
);
429 if (retval
!= STATUS_SUCCESS
) {
430 set_sense_type(chip
, lun
, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN
);
431 TRACE_RET(chip
, retval
);
434 ms_card
->mg_auth
= 1;
436 return STATUS_SUCCESS
;
439 /** * Send ICV data to host.
441 * After receiving this SCSI command, adapter shall read the divided
442 * data(1024 bytes totally) from medium by using READ_LONG_DATA TPC
443 * for 2 times, and report data to host with data-length is 1028 bytes.
445 * Since the extra 4 bytes data is just only a prefix to original data
446 * that read from medium, so that the 4-byte data pushed into Ring buffer
447 * precedes data tramsinssion from medium to Ring buffer by DMA mechanisim
448 * in order to get maximum performance and minimum code size simultaneously.
450 int mg_get_ICV(struct scsi_cmnd
*srb
, struct rts51x_chip
*chip
)
452 struct ms_info
*ms_card
= &(chip
->ms_card
);
455 unsigned int lun
= SCSI_LUN(srb
);
458 RTS51X_DEBUGP("--%s--\n", __func__
);
460 ms_cleanup_work(chip
);
462 retval
= ms_switch_clock(chip
);
463 if (retval
!= STATUS_SUCCESS
)
464 TRACE_RET(chip
, retval
);
466 buf
= kmalloc(1028, GFP_KERNEL
);
468 TRACE_RET(chip
, STATUS_NOMEM
);
475 retval
= mg_send_ex_cmd(chip
, MG_GET_IBD
, ms_card
->mg_entry_num
);
476 if (retval
!= STATUS_SUCCESS
) {
477 set_sense_type(chip
, lun
, SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR
);
478 TRACE_GOTO(chip
, GetICVFinish
);
481 retval
= ms_transfer_data(chip
, MS_TM_AUTO_READ
, PRO_READ_LONG_DATA
,
482 2, WAIT_INT
, 0, 0, buf
+ 4, 1024);
483 if (retval
!= STATUS_SUCCESS
) {
484 set_sense_type(chip
, lun
, SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR
);
485 rts51x_write_register(chip
, CARD_STOP
, MS_STOP
| MS_CLR_ERR
,
486 MS_STOP
| MS_CLR_ERR
);
487 TRACE_GOTO(chip
, GetICVFinish
);
489 retval
= mg_check_int_error(chip
);
490 if (retval
!= STATUS_SUCCESS
) {
491 set_sense_type(chip
, lun
, SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR
);
492 TRACE_GOTO(chip
, GetICVFinish
);
495 bufflen
= min(1028, (int)scsi_bufflen(srb
));
496 rts51x_set_xfer_buf(buf
, bufflen
, srb
);
504 * Send ICV data to medium.
506 * After receiving this SCSI command, adapter shall receive 1028 bytes
507 * and write the later 1024 bytes to medium by WRITE_LONG_DATA TPC
510 * Since the first 4-bytes data is just only a prefix to original data
511 * that sent by host, and it should be skipped by shifting DMA pointer
512 * before writing 1024 bytes to medium.
514 int mg_set_ICV(struct scsi_cmnd
*srb
, struct rts51x_chip
*chip
)
516 struct ms_info
*ms_card
= &(chip
->ms_card
);
519 #ifdef MG_SET_ICV_SLOW
522 unsigned int lun
= SCSI_LUN(srb
);
525 RTS51X_DEBUGP("--%s--\n", __func__
);
527 ms_cleanup_work(chip
);
529 retval
= ms_switch_clock(chip
);
530 if (retval
!= STATUS_SUCCESS
)
531 TRACE_RET(chip
, retval
);
533 buf
= kmalloc(1028, GFP_KERNEL
);
535 TRACE_RET(chip
, STATUS_NOMEM
);
537 bufflen
= min(1028, (int)scsi_bufflen(srb
));
538 rts51x_get_xfer_buf(buf
, bufflen
, srb
);
540 retval
= mg_send_ex_cmd(chip
, MG_SET_IBD
, ms_card
->mg_entry_num
);
541 if (retval
!= STATUS_SUCCESS
) {
542 if (ms_card
->mg_auth
== 0) {
543 if ((buf
[5] & 0xC0) != 0)
544 set_sense_type(chip
, lun
,
545 SENSE_TYPE_MG_KEY_FAIL_NOT_ESTAB
);
547 set_sense_type(chip
, lun
,
548 SENSE_TYPE_MG_WRITE_ERR
);
550 set_sense_type(chip
, lun
, SENSE_TYPE_MG_WRITE_ERR
);
552 TRACE_GOTO(chip
, SetICVFinish
);
555 #ifdef MG_SET_ICV_SLOW
556 for (i
= 0; i
< 2; i
++) {
559 rts51x_init_cmd(chip
);
561 rts51x_add_cmd(chip
, WRITE_REG_CMD
, MS_TPC
, 0xFF,
562 PRO_WRITE_LONG_DATA
);
563 rts51x_add_cmd(chip
, WRITE_REG_CMD
, MS_TRANS_CFG
, 0xFF,
566 trans_dma_enable(DMA_TO_DEVICE
, chip
, 512, DMA_512
);
568 rts51x_add_cmd(chip
, WRITE_REG_CMD
, MS_TRANSFER
, 0xFF,
569 MS_TRANSFER_START
| MS_TM_NORMAL_WRITE
);
570 rts51x_add_cmd(chip
, CHECK_REG_CMD
, MS_TRANSFER
,
571 MS_TRANSFER_END
, MS_TRANSFER_END
);
573 retval
= rts51x_send_cmd(chip
, MODE_CDOR
, 100);
574 if (retval
!= STATUS_SUCCESS
) {
575 set_sense_type(chip
, lun
, SENSE_TYPE_MG_WRITE_ERR
);
576 TRACE_GOTO(chip
, SetICVFinish
);
579 retval
= rts51x_transfer_data_rcc(chip
, SND_BULK_PIPE(chip
),
580 buf
+ 4 + i
* 512, 512, 0,
581 NULL
, 3000, STAGE_DO
);
582 if (retval
!= STATUS_SUCCESS
) {
583 rts51x_clear_ms_error(chip
);
584 if (ms_card
->mg_auth
== 0) {
585 if ((buf
[5] & 0xC0) != 0)
586 set_sense_type(chip
, lun
,
587 SENSE_TYPE_MG_KEY_FAIL_NOT_ESTAB
);
589 set_sense_type(chip
, lun
,
590 SENSE_TYPE_MG_WRITE_ERR
);
592 set_sense_type(chip
, lun
,
593 SENSE_TYPE_MG_WRITE_ERR
);
595 retval
= STATUS_FAIL
;
596 TRACE_GOTO(chip
, SetICVFinish
);
599 retval
= rts51x_get_rsp(chip
, 1, 3000);
600 if (CHECK_MS_TRANS_FAIL(chip
, retval
)
601 || mg_check_int_error(chip
)) {
602 rts51x_clear_ms_error(chip
);
603 if (ms_card
->mg_auth
== 0) {
604 if ((buf
[5] & 0xC0) != 0)
605 set_sense_type(chip
, lun
,
606 SENSE_TYPE_MG_KEY_FAIL_NOT_ESTAB
);
608 set_sense_type(chip
, lun
,
609 SENSE_TYPE_MG_WRITE_ERR
);
611 set_sense_type(chip
, lun
,
612 SENSE_TYPE_MG_WRITE_ERR
);
614 retval
= STATUS_FAIL
;
615 TRACE_GOTO(chip
, SetICVFinish
);
619 retval
= ms_transfer_data(chip
, MS_TM_AUTO_WRITE
, PRO_WRITE_LONG_DATA
,
620 2, WAIT_INT
, 0, 0, buf
+ 4, 1024);
621 if (retval
!= STATUS_SUCCESS
) {
622 rts51x_clear_ms_error(chip
);
623 if (ms_card
->mg_auth
== 0) {
624 if ((buf
[5] & 0xC0) != 0)
625 set_sense_type(chip
, lun
,
626 SENSE_TYPE_MG_KEY_FAIL_NOT_ESTAB
);
628 set_sense_type(chip
, lun
,
629 SENSE_TYPE_MG_WRITE_ERR
);
631 set_sense_type(chip
, lun
, SENSE_TYPE_MG_WRITE_ERR
);
633 TRACE_GOTO(chip
, SetICVFinish
);
642 #endif /* SUPPORT_MAGIC_GATE */