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"
41 #define RTS5139_IOC_MAGIC 0x39
43 #define RTS5139_IOC_SD_DIRECT _IOWR(RTS5139_IOC_MAGIC, 0xA0, int)
44 #define RTS5139_IOC_SD_GET_RSP _IOWR(RTS5139_IOC_MAGIC, 0xA1, int)
46 static int rts51x_sd_direct_cmnd(struct rts51x_chip
*chip
,
47 struct sd_direct_cmnd
*cmnd
)
50 u8 dir
, cmd12
, standby
, acmd
, cmd_idx
, rsp_code
;
54 dir
= (cmnd
->cmnd
[0] >> 3) & 0x03;
55 cmd12
= (cmnd
->cmnd
[0] >> 2) & 0x01;
56 standby
= (cmnd
->cmnd
[0] >> 1) & 0x01;
57 acmd
= cmnd
->cmnd
[0] & 0x01;
58 cmd_idx
= cmnd
->cmnd
[1];
59 arg
= ((u32
) (cmnd
->cmnd
[2]) << 24) | ((u32
) (cmnd
->cmnd
[3]) << 16) |
60 ((u32
) (cmnd
->cmnd
[4]) << 8) | cmnd
->cmnd
[5];
62 ((u32
) (cmnd
->cmnd
[6]) << 16) | ((u32
) (cmnd
->cmnd
[7]) << 8) |
64 rsp_code
= cmnd
->cmnd
[9];
67 if (!cmnd
->buf
|| (cmnd
->buf_len
< len
))
68 TRACE_RET(chip
, STATUS_FAIL
);
74 retval
= ext_sd_execute_no_data(chip
, chip
->card2lun
[SD_CARD
],
75 cmd_idx
, standby
, acmd
,
77 if (retval
!= TRANSPORT_GOOD
)
78 TRACE_RET(chip
, STATUS_FAIL
);
83 buf
= kmalloc(cmnd
->buf_len
, GFP_KERNEL
);
85 TRACE_RET(chip
, STATUS_NOMEM
);
87 retval
= ext_sd_execute_read_data(chip
, chip
->card2lun
[SD_CARD
],
88 cmd_idx
, cmd12
, standby
, acmd
,
89 rsp_code
, arg
, len
, buf
,
91 if (retval
!= TRANSPORT_GOOD
) {
93 TRACE_RET(chip
, STATUS_FAIL
);
97 copy_to_user((void *)cmnd
->buf
, (void *)buf
, cmnd
->buf_len
);
100 TRACE_RET(chip
, STATUS_NOMEM
);
108 buf
= kmalloc(cmnd
->buf_len
, GFP_KERNEL
);
110 TRACE_RET(chip
, STATUS_NOMEM
);
113 copy_from_user((void *)buf
, (void *)cmnd
->buf
,
117 TRACE_RET(chip
, STATUS_NOMEM
);
121 ext_sd_execute_write_data(chip
, chip
->card2lun
[SD_CARD
],
122 cmd_idx
, cmd12
, standby
, acmd
,
123 rsp_code
, arg
, len
, buf
,
125 if (retval
!= TRANSPORT_GOOD
) {
127 TRACE_RET(chip
, STATUS_FAIL
);
135 TRACE_RET(chip
, STATUS_FAIL
);
138 return STATUS_SUCCESS
;
141 static int rts51x_sd_get_rsp(struct rts51x_chip
*chip
, struct sd_rsp
*rsp
)
143 struct sd_info
*sd_card
= &(chip
->sd_card
);
144 int count
= 0, retval
;
146 if (sd_card
->pre_cmd_err
) {
147 sd_card
->pre_cmd_err
= 0;
148 TRACE_RET(chip
, STATUS_FAIL
);
151 if (sd_card
->last_rsp_type
== SD_RSP_TYPE_R0
)
152 TRACE_RET(chip
, STATUS_FAIL
);
153 else if (sd_card
->last_rsp_type
== SD_RSP_TYPE_R2
)
154 count
= (rsp
->rsp_len
< 17) ? rsp
->rsp_len
: 17;
156 count
= (rsp
->rsp_len
< 6) ? rsp
->rsp_len
: 6;
158 retval
= copy_to_user((void *)rsp
->rsp
, (void *)sd_card
->rsp
, count
);
160 TRACE_RET(chip
, STATUS_NOMEM
);
162 RTS51X_DEBUGP("Response length: %d\n", count
);
163 RTS51X_DEBUGP("Response: 0x%x 0x%x 0x%x 0x%x\n",
164 sd_card
->rsp
[0], sd_card
->rsp
[1], sd_card
->rsp
[2],
167 return STATUS_SUCCESS
;
170 int rts51x_open(struct inode
*inode
, struct file
*filp
)
172 struct rts51x_chip
*chip
;
173 struct usb_interface
*interface
;
177 subminor
= iminor(inode
);
179 interface
= usb_find_interface(&rts51x_driver
, subminor
);
181 RTS51X_DEBUGP("%s - error, can't find device for minor %d\n",
187 chip
= (struct rts51x_chip
*)usb_get_intfdata(interface
);
189 RTS51X_DEBUGP("Can't find chip\n");
194 /* Increase our reference to the host */
195 scsi_host_get(rts51x_to_host(chip
));
197 /* lock the device pointers */
198 mutex_lock(&(chip
->usb
->dev_mutex
));
200 /* save our object in the file's private structure */
201 filp
->private_data
= chip
;
203 /* unlock the device pointers */
204 mutex_unlock(&chip
->usb
->dev_mutex
);
210 int rts51x_release(struct inode
*inode
, struct file
*filp
)
212 struct rts51x_chip
*chip
;
214 chip
= (struct rts51x_chip
*)filp
->private_data
;
218 /* Drop our reference to the host; the SCSI core will free it
219 * (and "chip" along with it) when the refcount becomes 0. */
220 scsi_host_put(rts51x_to_host(chip
));
225 ssize_t
rts51x_read(struct file
*filp
, char __user
*buf
, size_t count
,
231 ssize_t
rts51x_write(struct file
*filp
, const char __user
*buf
, size_t count
,
237 #if 0 /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 36) */
238 int rts51x_ioctl(struct inode
*inode
, struct file
*filp
, unsigned int cmd
,
241 long rts51x_ioctl(struct file
*filp
, unsigned int cmd
, unsigned long arg
)
244 struct rts51x_chip
*chip
;
245 struct sd_direct_cmnd cmnd
;
249 chip
= (struct rts51x_chip
*)filp
->private_data
;
253 /* lock the device pointers */
254 mutex_lock(&(chip
->usb
->dev_mutex
));
257 case RTS5139_IOC_SD_DIRECT
:
259 copy_from_user((void *)&cmnd
, (void *)arg
,
260 sizeof(struct sd_direct_cmnd
));
263 TRACE_GOTO(chip
, exit
);
265 retval
= rts51x_sd_direct_cmnd(chip
, &cmnd
);
266 if (retval
!= STATUS_SUCCESS
) {
268 TRACE_GOTO(chip
, exit
);
272 case RTS5139_IOC_SD_GET_RSP
:
274 copy_from_user((void *)&rsp
, (void *)arg
,
275 sizeof(struct sd_rsp
));
278 TRACE_GOTO(chip
, exit
);
280 retval
= rts51x_sd_get_rsp(chip
, &rsp
);
281 if (retval
!= STATUS_SUCCESS
) {
283 TRACE_GOTO(chip
, exit
);
292 /* unlock the device pointers */
293 mutex_unlock(&chip
->usb
->dev_mutex
);