]> Pileus Git - ~andy/linux/blob - drivers/staging/keucr/init.c
Merge tag 'regmap-v3.11-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie...
[~andy/linux] / drivers / staging / keucr / init.c
1 #include <linux/sched.h>
2 #include <linux/errno.h>
3 #include <linux/slab.h>
4
5 #include <scsi/scsi.h>
6 #include <scsi/scsi_eh.h>
7 #include <scsi/scsi_device.h>
8
9 #include "usb.h"
10 #include "scsiglue.h"
11 #include "transport.h"
12 #include "init.h"
13
14 /*
15  * ENE_InitMedia():
16  */
17 int ENE_InitMedia(struct us_data *us)
18 {
19         int     result;
20         BYTE    MiscReg03 = 0;
21
22         dev_info(&us->pusb_dev->dev, "--- Init Media ---\n");
23         result = ene_read_byte(us, REG_CARD_STATUS, &MiscReg03);
24         if (result != USB_STOR_XFER_GOOD) {
25                 dev_err(&us->pusb_dev->dev, "Failed to read register\n");
26                 return USB_STOR_TRANSPORT_ERROR;
27         }
28         dev_info(&us->pusb_dev->dev, "MiscReg03 = %x\n", MiscReg03);
29
30         if (MiscReg03 & 0x02) {
31                 if (!us->SM_Status.Ready && !us->MS_Status.Ready) {
32                         result = ENE_SMInit(us);
33                         if (result != USB_STOR_XFER_GOOD)
34                                 return USB_STOR_TRANSPORT_ERROR;
35                 }
36
37         }
38         return result;
39 }
40
41 /*
42  * ene_read_byte() :
43  */
44 int ene_read_byte(struct us_data *us, WORD index, void *buf)
45 {
46         struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf;
47         int result;
48
49         memset(bcb, 0, sizeof(struct bulk_cb_wrap));
50         bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
51         bcb->DataTransferLength = 0x01;
52         bcb->Flags                      = 0x80;
53         bcb->CDB[0]                     = 0xED;
54         bcb->CDB[2]                     = (BYTE)(index>>8);
55         bcb->CDB[3]                     = (BYTE)index;
56
57         result = ENE_SendScsiCmd(us, FDIR_READ, buf, 0);
58         return result;
59 }
60
61 /*
62  *ENE_SMInit()
63  */
64 int ENE_SMInit(struct us_data *us)
65 {
66         struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf;
67         int     result;
68         BYTE    buf[0x200];
69
70         dev_dbg(&us->pusb_dev->dev, "transport --- ENE_SMInit\n");
71
72         result = ENE_LoadBinCode(us, SM_INIT_PATTERN);
73         if (result != USB_STOR_XFER_GOOD) {
74                 dev_info(&us->pusb_dev->dev,
75                          "Failed to load SmartMedia init code\n: result= %x\n",
76                          result);
77                 return USB_STOR_TRANSPORT_ERROR;
78         }
79
80         memset(bcb, 0, sizeof(struct bulk_cb_wrap));
81         bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
82         bcb->DataTransferLength = 0x200;
83         bcb->Flags                      = 0x80;
84         bcb->CDB[0]                     = 0xF1;
85         bcb->CDB[1]                     = 0x01;
86
87         result = ENE_SendScsiCmd(us, FDIR_READ, &buf, 0);
88         if (result != USB_STOR_XFER_GOOD) {
89                 dev_err(&us->pusb_dev->dev,
90                         "Failed to load SmartMedia init code: result = %x\n",
91                         result);
92                 return USB_STOR_TRANSPORT_ERROR;
93         }
94
95         us->SM_Status = *(struct keucr_sm_status *)&buf[0];
96
97         us->SM_DeviceID = buf[1];
98         us->SM_CardID   = buf[2];
99
100         if (us->SM_Status.Insert && us->SM_Status.Ready) {
101                 dev_info(&us->pusb_dev->dev, "Insert     = %x\n",
102                                              us->SM_Status.Insert);
103                 dev_info(&us->pusb_dev->dev, "Ready      = %x\n",
104                                              us->SM_Status.Ready);
105                 dev_info(&us->pusb_dev->dev, "WtP        = %x\n",
106                                              us->SM_Status.WtP);
107                 dev_info(&us->pusb_dev->dev, "DeviceID   = %x\n",
108                                              us->SM_DeviceID);
109                 dev_info(&us->pusb_dev->dev, "CardID     = %x\n",
110                                              us->SM_CardID);
111                 MediaChange = 1;
112                 Check_D_MediaFmt(us);
113         } else {
114                 dev_err(&us->pusb_dev->dev,
115                         "SmartMedia Card Not Ready --- %x\n", buf[0]);
116                 return USB_STOR_TRANSPORT_ERROR;
117         }
118
119         return USB_STOR_TRANSPORT_GOOD;
120 }
121
122 /*
123  * ENE_LoadBinCode()
124  */
125 int ENE_LoadBinCode(struct us_data *us, BYTE flag)
126 {
127         struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf;
128         int result;
129         /* void *buf; */
130         PBYTE buf;
131
132         /* dev_info(&us->pusb_dev->dev, "transport --- ENE_LoadBinCode\n"); */
133         if (us->BIN_FLAG == flag)
134                 return USB_STOR_TRANSPORT_GOOD;
135
136         buf = kmalloc(0x800, GFP_KERNEL);
137         if (buf == NULL)
138                 return USB_STOR_TRANSPORT_ERROR;
139         switch (flag) {
140         /* For SS */
141         case SM_INIT_PATTERN:
142                 dev_dbg(&us->pusb_dev->dev, "SM_INIT_PATTERN\n");
143                 memcpy(buf, SM_Init, 0x800);
144                 break;
145         case SM_RW_PATTERN:
146                 dev_dbg(&us->pusb_dev->dev, "SM_RW_PATTERN\n");
147                 memcpy(buf, SM_Rdwr, 0x800);
148                 break;
149         }
150
151         memset(bcb, 0, sizeof(struct bulk_cb_wrap));
152         bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
153         bcb->DataTransferLength = 0x800;
154         bcb->Flags = 0x00;
155         bcb->CDB[0] = 0xEF;
156
157         result = ENE_SendScsiCmd(us, FDIR_WRITE, buf, 0);
158
159         kfree(buf);
160         us->BIN_FLAG = flag;
161         return result;
162 }
163
164 /*
165  * ENE_SendScsiCmd():
166  */
167 int ENE_SendScsiCmd(struct us_data *us, BYTE fDir, void *buf, int use_sg)
168 {
169         struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf;
170         struct bulk_cs_wrap *bcs = (struct bulk_cs_wrap *) us->iobuf;
171
172         int result;
173         unsigned int transfer_length = bcb->DataTransferLength,
174                      cswlen = 0, partial = 0;
175         unsigned int residue;
176
177         /* dev_dbg(&us->pusb_dev->dev, "transport --- ENE_SendScsiCmd\n"); */
178         /* send cmd to out endpoint */
179         result = usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe,
180                                             bcb, US_BULK_CB_WRAP_LEN, NULL);
181         if (result != USB_STOR_XFER_GOOD) {
182                 dev_err(&us->pusb_dev->dev,
183                                 "send cmd to out endpoint fail ---\n");
184                 return USB_STOR_TRANSPORT_ERROR;
185         }
186
187         if (buf) {
188                 unsigned int pipe = fDir;
189
190                 if (fDir == FDIR_READ)
191                         pipe = us->recv_bulk_pipe;
192                 else
193                         pipe = us->send_bulk_pipe;
194
195                 /* Bulk */
196                 if (use_sg)
197                         result = usb_stor_bulk_srb(us, pipe, us->srb);
198                 else
199                         result = usb_stor_bulk_transfer_sg(us, pipe, buf,
200                                                 transfer_length, 0, &partial);
201                 if (result != USB_STOR_XFER_GOOD) {
202                         dev_err(&us->pusb_dev->dev, "data transfer fail ---\n");
203                         return USB_STOR_TRANSPORT_ERROR;
204                 }
205         }
206
207         /* Get CSW for device status */
208         result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe, bcs,
209                                                 US_BULK_CS_WRAP_LEN, &cswlen);
210
211         if (result == USB_STOR_XFER_SHORT && cswlen == 0) {
212                 dev_warn(&us->pusb_dev->dev,
213                                 "Received 0-length CSW; retrying...\n");
214                 result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe,
215                                         bcs, US_BULK_CS_WRAP_LEN, &cswlen);
216         }
217
218         if (result == USB_STOR_XFER_STALLED) {
219                 /* get the status again */
220                 dev_warn(&us->pusb_dev->dev,
221                                 "Attempting to get CSW (2nd try)...\n");
222                 result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe,
223                                                 bcs, US_BULK_CS_WRAP_LEN, NULL);
224         }
225
226         if (result != USB_STOR_XFER_GOOD)
227                 return USB_STOR_TRANSPORT_ERROR;
228
229         /* check bulk status */
230         residue = le32_to_cpu(bcs->Residue);
231
232         /*
233          * try to compute the actual residue, based on how much data
234          * was really transferred and what the device tells us
235          */
236         if (residue && !(us->fflags & US_FL_IGNORE_RESIDUE)) {
237                 residue = min(residue, transfer_length);
238                 if (us->srb)
239                         scsi_set_resid(us->srb, max(scsi_get_resid(us->srb),
240                                         (int) residue));
241         }
242
243         if (bcs->Status != US_BULK_STAT_OK)
244                 return USB_STOR_TRANSPORT_ERROR;
245
246         return USB_STOR_TRANSPORT_GOOD;
247 }
248
249 /*
250  * ENE_Read_Data()
251  */
252 int ENE_Read_Data(struct us_data *us, void *buf, unsigned int length)
253 {
254         struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf;
255         struct bulk_cs_wrap *bcs = (struct bulk_cs_wrap *) us->iobuf;
256         int result;
257
258         /* dev_dbg(&us->pusb_dev->dev, "transport --- ENE_Read_Data\n"); */
259         /* set up the command wrapper */
260         memset(bcb, 0, sizeof(struct bulk_cb_wrap));
261         bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
262         bcb->DataTransferLength = length;
263         bcb->Flags = 0x80;
264         bcb->CDB[0] = 0xED;
265         bcb->CDB[2] = 0xFF;
266         bcb->CDB[3] = 0x81;
267
268         /* send cmd to out endpoint */
269         result = usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe, bcb,
270                                                 US_BULK_CB_WRAP_LEN, NULL);
271         if (result != USB_STOR_XFER_GOOD)
272                 return USB_STOR_TRANSPORT_ERROR;
273
274         /* R/W data */
275         result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe,
276                                                 buf, length, NULL);
277         if (result != USB_STOR_XFER_GOOD)
278                 return USB_STOR_TRANSPORT_ERROR;
279
280         /* Get CSW for device status */
281         result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe, bcs,
282                                                 US_BULK_CS_WRAP_LEN, NULL);
283         if (result != USB_STOR_XFER_GOOD)
284                 return USB_STOR_TRANSPORT_ERROR;
285         if (bcs->Status != US_BULK_STAT_OK)
286                 return USB_STOR_TRANSPORT_ERROR;
287
288         return USB_STOR_TRANSPORT_GOOD;
289 }
290
291 /*
292  * ENE_Write_Data():
293  */
294 int ENE_Write_Data(struct us_data *us, void *buf, unsigned int length)
295 {
296         struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf;
297         struct bulk_cs_wrap *bcs = (struct bulk_cs_wrap *) us->iobuf;
298         int result;
299
300         /* printk("transport --- ENE_Write_Data\n"); */
301         /* set up the command wrapper */
302         memset(bcb, 0, sizeof(struct bulk_cb_wrap));
303         bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
304         bcb->DataTransferLength = length;
305         bcb->Flags = 0x00;
306         bcb->CDB[0] = 0xEE;
307         bcb->CDB[2] = 0xFF;
308         bcb->CDB[3] = 0x81;
309
310         /* send cmd to out endpoint */
311         result = usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe, bcb,
312                                                 US_BULK_CB_WRAP_LEN, NULL);
313         if (result != USB_STOR_XFER_GOOD)
314                 return USB_STOR_TRANSPORT_ERROR;
315
316         /* R/W data */
317         result = usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe,
318                                                 buf, length, NULL);
319         if (result != USB_STOR_XFER_GOOD)
320                 return USB_STOR_TRANSPORT_ERROR;
321
322         /* Get CSW for device status */
323         result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe, bcs,
324                                                 US_BULK_CS_WRAP_LEN, NULL);
325         if (result != USB_STOR_XFER_GOOD)
326                 return USB_STOR_TRANSPORT_ERROR;
327         if (bcs->Status != US_BULK_STAT_OK)
328                 return USB_STOR_TRANSPORT_ERROR;
329
330         return USB_STOR_TRANSPORT_GOOD;
331 }
332