]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blob - drivers/staging/rts5139/rts51x_fop.c
imx-hdmi: Make checkpatch happy
[mirror_ubuntu-artful-kernel.git] / drivers / staging / rts5139 / rts51x_fop.c
1 /* Driver for Realtek RTS51xx USB card reader
2 *
3 * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved.
4 *
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
8 * later version.
9 *
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.
14 *
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/>.
17 *
18 * Author:
19 * wwang (wei_wang@realsil.com.cn)
20 * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China
21 * Maintainer:
22 * Edwin Rong (edwin_rong@realsil.com.cn)
23 * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China
24 */
25
26 #include "rts51x.h"
27
28 #ifdef SUPPORT_FILE_OP
29
30 #include <linux/types.h>
31 #include <linux/stat.h>
32 #include <linux/kref.h>
33 #include <linux/slab.h>
34
35 #include "rts51x_chip.h"
36 #include "rts51x_card.h"
37 #include "rts51x_fop.h"
38 #include "sd_cprm.h"
39
40 #define RTS5139_IOC_MAGIC 0x39
41
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)
44
45 static int rts51x_sd_direct_cmnd(struct rts51x_chip *chip,
46 struct sd_direct_cmnd *cmnd)
47 {
48 int retval;
49 u8 dir, cmd12, standby, acmd, cmd_idx, rsp_code;
50 u8 *buf;
51 u32 arg, len;
52
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];
60 len =
61 ((u32) (cmnd->cmnd[6]) << 16) | ((u32) (cmnd->cmnd[7]) << 8) |
62 cmnd->cmnd[8];
63 rsp_code = cmnd->cmnd[9];
64
65 if (dir) {
66 if (!cmnd->buf || (cmnd->buf_len < len))
67 TRACE_RET(chip, STATUS_FAIL);
68 }
69
70 switch (dir) {
71 case 0:
72 /* No data */
73 retval = ext_rts51x_sd_execute_no_data(chip,
74 chip->card2lun[SD_CARD],
75 cmd_idx, standby, acmd,
76 rsp_code, arg);
77 if (retval != TRANSPORT_GOOD)
78 TRACE_RET(chip, STATUS_FAIL);
79 break;
80
81 case 1:
82 /* Read from card */
83 buf = kzalloc(cmnd->buf_len, GFP_KERNEL);
84 if (!buf)
85 TRACE_RET(chip, STATUS_NOMEM);
86
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,
91 cmnd->buf_len, 0);
92 if (retval != TRANSPORT_GOOD) {
93 kfree(buf);
94 TRACE_RET(chip, STATUS_FAIL);
95 }
96
97 retval =
98 copy_to_user(cmnd->buf, (void *)buf, cmnd->buf_len);
99 if (retval) {
100 kfree(buf);
101 TRACE_RET(chip, STATUS_NOMEM);
102 }
103
104 kfree(buf);
105 break;
106
107 case 2:
108 /* Write to card */
109 buf = kmalloc(cmnd->buf_len, GFP_KERNEL);
110 if (!buf)
111 TRACE_RET(chip, STATUS_NOMEM);
112
113 retval =
114 copy_from_user((void *)buf, cmnd->buf,
115 cmnd->buf_len);
116 if (retval) {
117 kfree(buf);
118 TRACE_RET(chip, STATUS_NOMEM);
119 }
120
121 retval =
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,
126 cmnd->buf_len, 0);
127 if (retval != TRANSPORT_GOOD) {
128 kfree(buf);
129 TRACE_RET(chip, STATUS_FAIL);
130 }
131
132 kfree(buf);
133
134 break;
135
136 default:
137 TRACE_RET(chip, STATUS_FAIL);
138 }
139
140 return STATUS_SUCCESS;
141 }
142
143 static int rts51x_sd_get_rsp(struct rts51x_chip *chip, struct sd_rsp *rsp)
144 {
145 struct sd_info *sd_card = &(chip->sd_card);
146 int count = 0, retval;
147
148 if (sd_card->pre_cmd_err) {
149 sd_card->pre_cmd_err = 0;
150 TRACE_RET(chip, STATUS_FAIL);
151 }
152
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;
157 else
158 count = (rsp->rsp_len < 6) ? rsp->rsp_len : 6;
159
160 retval = copy_to_user(rsp->rsp, (void *)sd_card->rsp, count);
161 if (retval)
162 TRACE_RET(chip, STATUS_NOMEM);
163
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],
167 sd_card->rsp[3]);
168
169 return STATUS_SUCCESS;
170 }
171
172 int rts51x_open(struct inode *inode, struct file *filp)
173 {
174 struct rts51x_chip *chip;
175 struct usb_interface *interface;
176 int subminor;
177 int retval = 0;
178
179 subminor = iminor(inode);
180
181 interface = usb_find_interface(&rts51x_driver, subminor);
182 if (!interface) {
183 RTS51X_DEBUGP("%s - error, can't find device for minor %d\n",
184 __func__, subminor);
185 retval = -ENODEV;
186 goto exit;
187 }
188
189 chip = (struct rts51x_chip *)usb_get_intfdata(interface);
190 if (!chip) {
191 RTS51X_DEBUGP("Can't find chip\n");
192 retval = -ENODEV;
193 goto exit;
194 }
195
196 /* Increase our reference to the host */
197 scsi_host_get(rts51x_to_host(chip));
198
199 /* lock the device pointers */
200 mutex_lock(&(chip->usb->dev_mutex));
201
202 /* save our object in the file's private structure */
203 filp->private_data = chip;
204
205 /* unlock the device pointers */
206 mutex_unlock(&chip->usb->dev_mutex);
207
208 exit:
209 return retval;
210 }
211
212 int rts51x_release(struct inode *inode, struct file *filp)
213 {
214 struct rts51x_chip *chip;
215
216 chip = (struct rts51x_chip *)filp->private_data;
217 if (chip == NULL)
218 return -ENODEV;
219
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));
223
224 return 0;
225 }
226
227 ssize_t rts51x_read(struct file *filp, char __user *buf, size_t count,
228 loff_t *f_pos)
229 {
230 return 0;
231 }
232
233 ssize_t rts51x_write(struct file *filp, const char __user *buf, size_t count,
234 loff_t *f_pos)
235 {
236 return 0;
237 }
238
239 long rts51x_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
240 {
241 struct rts51x_chip *chip;
242 struct sd_direct_cmnd cmnd;
243 struct sd_rsp rsp;
244 int retval = 0;
245
246 chip = (struct rts51x_chip *)filp->private_data;
247 if (chip == NULL)
248 return -ENODEV;
249
250 /* lock the device pointers */
251 mutex_lock(&(chip->usb->dev_mutex));
252
253 switch (cmd) {
254 case RTS5139_IOC_SD_DIRECT:
255 retval =
256 copy_from_user((void *)&cmnd, (void __user *)arg,
257 sizeof(struct sd_direct_cmnd));
258 if (retval) {
259 retval = -ENOMEM;
260 TRACE_GOTO(chip, exit);
261 }
262 retval = rts51x_sd_direct_cmnd(chip, &cmnd);
263 if (retval != STATUS_SUCCESS) {
264 retval = -EIO;
265 TRACE_GOTO(chip, exit);
266 }
267 break;
268
269 case RTS5139_IOC_SD_GET_RSP:
270 retval =
271 copy_from_user(&rsp, (void __user *)arg,
272 sizeof(struct sd_rsp));
273 if (retval) {
274 retval = -ENOMEM;
275 TRACE_GOTO(chip, exit);
276 }
277 retval = rts51x_sd_get_rsp(chip, &rsp);
278 if (retval != STATUS_SUCCESS) {
279 retval = -EIO;
280 TRACE_GOTO(chip, exit);
281 }
282 break;
283
284 default:
285 break;
286 }
287
288 exit:
289 /* unlock the device pointers */
290 mutex_unlock(&chip->usb->dev_mutex);
291
292 return retval;
293 }
294
295 #endif