]>
git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blob - drivers/staging/rts5139/rts51x_fop.c
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_rts51x_sd_execute_no_data(chip
,
74 chip
->card2lun
[SD_CARD
],
75 cmd_idx
, standby
, acmd
,
77 if (retval
!= TRANSPORT_GOOD
)
78 TRACE_RET(chip
, STATUS_FAIL
);
83 buf
= kzalloc(cmnd
->buf_len
, GFP_KERNEL
);
85 TRACE_RET(chip
, STATUS_NOMEM
);
87 retval
= ext_rts51x_sd_execute_read_data(chip
,
88 chip
->card2lun
[SD_CARD
],
89 cmd_idx
, cmd12
, standby
, acmd
,
90 rsp_code
, arg
, len
, buf
,
92 if (retval
!= TRANSPORT_GOOD
) {
94 TRACE_RET(chip
, STATUS_FAIL
);
98 copy_to_user(cmnd
->buf
, (void *)buf
, cmnd
->buf_len
);
101 TRACE_RET(chip
, STATUS_NOMEM
);
109 buf
= kmalloc(cmnd
->buf_len
, GFP_KERNEL
);
111 TRACE_RET(chip
, STATUS_NOMEM
);
114 copy_from_user((void *)buf
, cmnd
->buf
,
118 TRACE_RET(chip
, STATUS_NOMEM
);
122 ext_rts51x_sd_execute_write_data(chip
,
123 chip
->card2lun
[SD_CARD
],
124 cmd_idx
, cmd12
, standby
, acmd
,
125 rsp_code
, arg
, len
, buf
,
127 if (retval
!= TRANSPORT_GOOD
) {
129 TRACE_RET(chip
, STATUS_FAIL
);
137 TRACE_RET(chip
, STATUS_FAIL
);
140 return STATUS_SUCCESS
;
143 static int rts51x_sd_get_rsp(struct rts51x_chip
*chip
, struct sd_rsp
*rsp
)
145 struct sd_info
*sd_card
= &(chip
->sd_card
);
146 int count
= 0, retval
;
148 if (sd_card
->pre_cmd_err
) {
149 sd_card
->pre_cmd_err
= 0;
150 TRACE_RET(chip
, STATUS_FAIL
);
153 if (sd_card
->last_rsp_type
== SD_RSP_TYPE_R0
)
154 TRACE_RET(chip
, STATUS_FAIL
);
155 else if (sd_card
->last_rsp_type
== SD_RSP_TYPE_R2
)
156 count
= (rsp
->rsp_len
< 17) ? rsp
->rsp_len
: 17;
158 count
= (rsp
->rsp_len
< 6) ? rsp
->rsp_len
: 6;
160 retval
= copy_to_user(rsp
->rsp
, (void *)sd_card
->rsp
, count
);
162 TRACE_RET(chip
, STATUS_NOMEM
);
164 RTS51X_DEBUGP("Response length: %d\n", count
);
165 RTS51X_DEBUGP("Response: 0x%x 0x%x 0x%x 0x%x\n",
166 sd_card
->rsp
[0], sd_card
->rsp
[1], sd_card
->rsp
[2],
169 return STATUS_SUCCESS
;
172 int rts51x_open(struct inode
*inode
, struct file
*filp
)
174 struct rts51x_chip
*chip
;
175 struct usb_interface
*interface
;
179 subminor
= iminor(inode
);
181 interface
= usb_find_interface(&rts51x_driver
, subminor
);
183 RTS51X_DEBUGP("%s - error, can't find device for minor %d\n",
189 chip
= (struct rts51x_chip
*)usb_get_intfdata(interface
);
191 RTS51X_DEBUGP("Can't find chip\n");
196 /* Increase our reference to the host */
197 scsi_host_get(rts51x_to_host(chip
));
199 /* lock the device pointers */
200 mutex_lock(&(chip
->usb
->dev_mutex
));
202 /* save our object in the file's private structure */
203 filp
->private_data
= chip
;
205 /* unlock the device pointers */
206 mutex_unlock(&chip
->usb
->dev_mutex
);
212 int rts51x_release(struct inode
*inode
, struct file
*filp
)
214 struct rts51x_chip
*chip
;
216 chip
= (struct rts51x_chip
*)filp
->private_data
;
220 /* Drop our reference to the host; the SCSI core will free it
221 * (and "chip" along with it) when the refcount becomes 0. */
222 scsi_host_put(rts51x_to_host(chip
));
227 ssize_t
rts51x_read(struct file
*filp
, char __user
*buf
, size_t count
,
233 ssize_t
rts51x_write(struct file
*filp
, const char __user
*buf
, size_t count
,
239 long rts51x_ioctl(struct file
*filp
, unsigned int cmd
, unsigned long arg
)
241 struct rts51x_chip
*chip
;
242 struct sd_direct_cmnd cmnd
;
246 chip
= (struct rts51x_chip
*)filp
->private_data
;
250 /* lock the device pointers */
251 mutex_lock(&(chip
->usb
->dev_mutex
));
254 case RTS5139_IOC_SD_DIRECT
:
256 copy_from_user((void *)&cmnd
, (void __user
*)arg
,
257 sizeof(struct sd_direct_cmnd
));
260 TRACE_GOTO(chip
, exit
);
262 retval
= rts51x_sd_direct_cmnd(chip
, &cmnd
);
263 if (retval
!= STATUS_SUCCESS
) {
265 TRACE_GOTO(chip
, exit
);
269 case RTS5139_IOC_SD_GET_RSP
:
271 copy_from_user(&rsp
, (void __user
*)arg
,
272 sizeof(struct sd_rsp
));
275 TRACE_GOTO(chip
, exit
);
277 retval
= rts51x_sd_get_rsp(chip
, &rsp
);
278 if (retval
!= STATUS_SUCCESS
) {
280 TRACE_GOTO(chip
, exit
);
289 /* unlock the device pointers */
290 mutex_unlock(&chip
->usb
->dev_mutex
);