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
28 #ifdef SUPPORT_FILE_OP
30 #include <linux/types.h>
31 #include <linux/stat.h>
32 #include <linux/kref.h>
33 #include <linux/slab.h>
35 #include "rts51x_chip.h"
36 #include "rts51x_card.h"
37 #include "rts51x_fop.h"
40 #define RTS5139_IOC_MAGIC 0x39
42 #define RTS5139_IOC_SD_DIRECT _IOWR(RTS5139_IOC_MAGIC, 0xA0, int)
43 #define RTS5139_IOC_SD_GET_RSP _IOWR(RTS5139_IOC_MAGIC, 0xA1, int)
45 static int rts51x_sd_direct_cmnd(struct rts51x_chip
*chip
,
46 struct sd_direct_cmnd
*cmnd
)
49 u8 dir
, cmd12
, standby
, acmd
, cmd_idx
, rsp_code
;
53 dir
= (cmnd
->cmnd
[0] >> 3) & 0x03;
54 cmd12
= (cmnd
->cmnd
[0] >> 2) & 0x01;
55 standby
= (cmnd
->cmnd
[0] >> 1) & 0x01;
56 acmd
= cmnd
->cmnd
[0] & 0x01;
57 cmd_idx
= cmnd
->cmnd
[1];
58 arg
= ((u32
) (cmnd
->cmnd
[2]) << 24) | ((u32
) (cmnd
->cmnd
[3]) << 16) |
59 ((u32
) (cmnd
->cmnd
[4]) << 8) | cmnd
->cmnd
[5];
61 ((u32
) (cmnd
->cmnd
[6]) << 16) | ((u32
) (cmnd
->cmnd
[7]) << 8) |
63 rsp_code
= cmnd
->cmnd
[9];
66 if (!cmnd
->buf
|| (cmnd
->buf_len
< len
))
67 TRACE_RET(chip
, STATUS_FAIL
);
73 retval
= ext_sd_execute_no_data(chip
, chip
->card2lun
[SD_CARD
],
74 cmd_idx
, standby
, acmd
,
76 if (retval
!= TRANSPORT_GOOD
)
77 TRACE_RET(chip
, STATUS_FAIL
);
82 buf
= kzalloc(cmnd
->buf_len
, GFP_KERNEL
);
84 TRACE_RET(chip
, STATUS_NOMEM
);
86 retval
= ext_sd_execute_read_data(chip
, chip
->card2lun
[SD_CARD
],
87 cmd_idx
, cmd12
, standby
, acmd
,
88 rsp_code
, arg
, len
, buf
,
90 if (retval
!= TRANSPORT_GOOD
) {
92 TRACE_RET(chip
, STATUS_FAIL
);
96 copy_to_user((void *)cmnd
->buf
, (void *)buf
, cmnd
->buf_len
);
99 TRACE_RET(chip
, STATUS_NOMEM
);
107 buf
= kmalloc(cmnd
->buf_len
, GFP_KERNEL
);
109 TRACE_RET(chip
, STATUS_NOMEM
);
112 copy_from_user((void *)buf
, (void *)cmnd
->buf
,
116 TRACE_RET(chip
, STATUS_NOMEM
);
120 ext_sd_execute_write_data(chip
, chip
->card2lun
[SD_CARD
],
121 cmd_idx
, cmd12
, standby
, acmd
,
122 rsp_code
, arg
, len
, buf
,
124 if (retval
!= TRANSPORT_GOOD
) {
126 TRACE_RET(chip
, STATUS_FAIL
);
134 TRACE_RET(chip
, STATUS_FAIL
);
137 return STATUS_SUCCESS
;
140 static int rts51x_sd_get_rsp(struct rts51x_chip
*chip
, struct sd_rsp
*rsp
)
142 struct sd_info
*sd_card
= &(chip
->sd_card
);
143 int count
= 0, retval
;
145 if (sd_card
->pre_cmd_err
) {
146 sd_card
->pre_cmd_err
= 0;
147 TRACE_RET(chip
, STATUS_FAIL
);
150 if (sd_card
->last_rsp_type
== SD_RSP_TYPE_R0
)
151 TRACE_RET(chip
, STATUS_FAIL
);
152 else if (sd_card
->last_rsp_type
== SD_RSP_TYPE_R2
)
153 count
= (rsp
->rsp_len
< 17) ? rsp
->rsp_len
: 17;
155 count
= (rsp
->rsp_len
< 6) ? rsp
->rsp_len
: 6;
157 retval
= copy_to_user((void *)rsp
->rsp
, (void *)sd_card
->rsp
, count
);
159 TRACE_RET(chip
, STATUS_NOMEM
);
161 RTS51X_DEBUGP("Response length: %d\n", count
);
162 RTS51X_DEBUGP("Response: 0x%x 0x%x 0x%x 0x%x\n",
163 sd_card
->rsp
[0], sd_card
->rsp
[1], sd_card
->rsp
[2],
166 return STATUS_SUCCESS
;
169 int rts51x_open(struct inode
*inode
, struct file
*filp
)
171 struct rts51x_chip
*chip
;
172 struct usb_interface
*interface
;
176 subminor
= iminor(inode
);
178 interface
= usb_find_interface(&rts51x_driver
, subminor
);
180 RTS51X_DEBUGP("%s - error, can't find device for minor %d\n",
186 chip
= (struct rts51x_chip
*)usb_get_intfdata(interface
);
188 RTS51X_DEBUGP("Can't find chip\n");
193 /* Increase our reference to the host */
194 scsi_host_get(rts51x_to_host(chip
));
196 /* lock the device pointers */
197 mutex_lock(&(chip
->usb
->dev_mutex
));
199 /* save our object in the file's private structure */
200 filp
->private_data
= chip
;
202 /* unlock the device pointers */
203 mutex_unlock(&chip
->usb
->dev_mutex
);
209 int rts51x_release(struct inode
*inode
, struct file
*filp
)
211 struct rts51x_chip
*chip
;
213 chip
= (struct rts51x_chip
*)filp
->private_data
;
217 /* Drop our reference to the host; the SCSI core will free it
218 * (and "chip" along with it) when the refcount becomes 0. */
219 scsi_host_put(rts51x_to_host(chip
));
224 ssize_t
rts51x_read(struct file
*filp
, char __user
*buf
, size_t count
,
230 ssize_t
rts51x_write(struct file
*filp
, const char __user
*buf
, size_t count
,
236 long rts51x_ioctl(struct file
*filp
, unsigned int cmd
, unsigned long arg
)
238 struct rts51x_chip
*chip
;
239 struct sd_direct_cmnd cmnd
;
243 chip
= (struct rts51x_chip
*)filp
->private_data
;
247 /* lock the device pointers */
248 mutex_lock(&(chip
->usb
->dev_mutex
));
251 case RTS5139_IOC_SD_DIRECT
:
253 copy_from_user((void *)&cmnd
, (void *)arg
,
254 sizeof(struct sd_direct_cmnd
));
257 TRACE_GOTO(chip
, exit
);
259 retval
= rts51x_sd_direct_cmnd(chip
, &cmnd
);
260 if (retval
!= STATUS_SUCCESS
) {
262 TRACE_GOTO(chip
, exit
);
266 case RTS5139_IOC_SD_GET_RSP
:
268 copy_from_user((void *)&rsp
, (void *)arg
,
269 sizeof(struct sd_rsp
));
272 TRACE_GOTO(chip
, exit
);
274 retval
= rts51x_sd_get_rsp(chip
, &rsp
);
275 if (retval
!= STATUS_SUCCESS
) {
277 TRACE_GOTO(chip
, exit
);
286 /* unlock the device pointers */
287 mutex_unlock(&chip
->usb
->dev_mutex
);