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