Staging: add USB ENE card reader driver
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / staging / keucr / usb.c
CommitLineData
126bb03b
AC
1#include <linux/sched.h>
2#include <linux/errno.h>
3#include <linux/freezer.h>
4#include <linux/module.h>
5#include <linux/init.h>
6#include <linux/slab.h>
7#include <linux/kthread.h>
8#include <linux/mutex.h>
9#include <linux/utsname.h>
10
11#include <scsi/scsi.h>
12#include <scsi/scsi_cmnd.h>
13#include <scsi/scsi_device.h>
14
15#include "usb.h"
16#include "scsiglue.h"
17#include "transport.h"
18
19/* Some informational data */
20MODULE_AUTHOR("Domao");
21MODULE_DESCRIPTION("ENE USB Mass Storage driver for Linux");
22MODULE_LICENSE("GPL");
23
24static struct usb_device_id eucr_usb_ids [] = {
25 { USB_DEVICE(0x058f, 0x6366) },
26 { USB_DEVICE(0x0cf2, 0x6230) },
27 { USB_DEVICE(0x0cf2, 0x6250) },
28 { } /* Terminating entry */
29};
30MODULE_DEVICE_TABLE (usb, eucr_usb_ids);
31
32
33
34int eucr_suspend(struct usb_interface *iface, pm_message_t message)
35{
36 struct us_data *us = usb_get_intfdata(iface);
37 printk("--- eucr_suspend ---\n");
38 /* Wait until no command is running */
39 mutex_lock(&us->dev_mutex);
40
41 //US_DEBUGP("%s\n", __func__);
42 if (us->suspend_resume_hook)
43 (us->suspend_resume_hook)(us, US_SUSPEND);
44
45 /* When runtime PM is working, we'll set a flag to indicate
46 * whether we should autoresume when a SCSI request arrives. */
47 // us->Power_IsResum = true;
48 //us->SD_Status.Ready = 0;
49
50 mutex_unlock(&us->dev_mutex);
51 return 0;
52}
53//EXPORT_SYMBOL_GPL(eucr_suspend);
54
55int eucr_resume(struct usb_interface *iface)
56{
57 BYTE tmp = 0;
58
59 struct us_data *us = usb_get_intfdata(iface);
60 printk("--- eucr_resume---\n");
61 mutex_lock(&us->dev_mutex);
62
63 //US_DEBUGP("%s\n", __func__);
64 if (us->suspend_resume_hook)
65 (us->suspend_resume_hook)(us, US_RESUME);
66
67
68 mutex_unlock(&us->dev_mutex);
69
70
71 us->Power_IsResum = true;
72 //
73 //us->SD_Status.Ready = 0; //??
74 us->SD_Status = *(PSD_STATUS)&tmp;
75 us->MS_Status = *(PMS_STATUS)&tmp;
76 us->SM_Status = *(PSM_STATUS)&tmp;
77
78 return 0;
79}
80//EXPORT_SYMBOL_GPL(eucr_resume);
81int eucr_reset_resume(struct usb_interface *iface)
82{
83 BYTE tmp = 0;
84 struct us_data *us = usb_get_intfdata(iface);
85
86 printk("--- eucr_reset_resume---\n");
87 //US_DEBUGP("%s\n", __func__);
88
89 /* Report the reset to the SCSI core */
90 usb_stor_report_bus_reset(us);
91
92 /* FIXME: Notify the subdrivers that they need to reinitialize
93 * the device */
94 //ENE_InitMedia(us);
95 us->Power_IsResum = true;
96 //
97 //us->SD_Status.Ready = 0; //??
98 us->SD_Status = *(PSD_STATUS)&tmp;
99 us->MS_Status = *(PMS_STATUS)&tmp;
100 us->SM_Status = *(PSM_STATUS)&tmp;
101 return 0;
102}
103//EXPORT_SYMBOL_GPL(usb_stor_reset_resume);
104
105//----- eucr_pre_reset() ---------------------
106static int eucr_pre_reset(struct usb_interface *iface)
107{
108 struct us_data *us = usb_get_intfdata(iface);
109
110 printk("usb --- eucr_pre_reset\n");
111
112 /* Make sure no command runs during the reset */
113 mutex_lock(&us->dev_mutex);
114 return 0;
115}
116
117//----- eucr_post_reset() ---------------------
118static int eucr_post_reset(struct usb_interface *iface)
119{
120 struct us_data *us = usb_get_intfdata(iface);
121
122 printk("usb --- eucr_post_reset\n");
123
124 /* Report the reset to the SCSI core */
125 usb_stor_report_bus_reset(us);
126
127 mutex_unlock(&us->dev_mutex);
128 return 0;
129}
130
131//----- fill_inquiry_response() ---------------------
132void fill_inquiry_response(struct us_data *us, unsigned char *data, unsigned int data_len)
133{
134 printk("usb --- fill_inquiry_response\n");
135 if (data_len<36) // You lose.
136 return;
137
138 if (data[0]&0x20)
139 {
140 memset(data+8,0,28);
141 }
142 else
143 {
144 u16 bcdDevice = le16_to_cpu(us->pusb_dev->descriptor.bcdDevice);
145 memcpy(data+8, us->unusual_dev->vendorName,
146 strlen(us->unusual_dev->vendorName) > 8 ? 8 :
147 strlen(us->unusual_dev->vendorName));
148 memcpy(data+16, us->unusual_dev->productName,
149 strlen(us->unusual_dev->productName) > 16 ? 16 :
150 strlen(us->unusual_dev->productName));
151 data[32] = 0x30 + ((bcdDevice>>12) & 0x0F);
152 data[33] = 0x30 + ((bcdDevice>>8) & 0x0F);
153 data[34] = 0x30 + ((bcdDevice>>4) & 0x0F);
154 data[35] = 0x30 + ((bcdDevice) & 0x0F);
155 }
156 usb_stor_set_xfer_buf(us, data, data_len, us->srb, TO_XFER_BUF);
157}
158
159//----- usb_stor_control_thread() ---------------------
160static int usb_stor_control_thread(void * __us)
161{
162 struct us_data *us = (struct us_data *)__us;
163 struct Scsi_Host *host = us_to_host(us);
164
165 printk("usb --- usb_stor_control_thread\n");
166 for(;;)
167 {
168 if (wait_for_completion_interruptible(&us->cmnd_ready))
169 break;
170
171 /* lock the device pointers */
172 mutex_lock(&(us->dev_mutex));
173
174 /* if the device has disconnected, we are free to exit */
175/* if (test_bit(US_FLIDX_DISCONNECTING, &us->flags))
176 {
177 mutex_unlock(&us->dev_mutex);
178 break;
179 }*/
180
181 /* lock access to the state */
182 scsi_lock(host);
183
184 /* When we are called with no command pending, we're done */
185 if (us->srb == NULL)
186 {
187 scsi_unlock(host);
188 mutex_unlock(&us->dev_mutex);
189 //US_DEBUGP("-- exiting\n");
190 break;
191 }
192
193 /* has the command timed out *already* ? */
194 if (test_bit(US_FLIDX_TIMED_OUT, &us->dflags))
195 {
196 us->srb->result = DID_ABORT << 16;
197 goto SkipForAbort;
198 }
199
200 scsi_unlock(host);
201
202 if (us->srb->sc_data_direction == DMA_BIDIRECTIONAL)
203 {
204 us->srb->result = DID_ERROR << 16;
205 }
206 else if (us->srb->device->id && !(us->fflags & US_FL_SCM_MULT_TARG))
207 {
208 us->srb->result = DID_BAD_TARGET << 16;
209 }
210 else if (us->srb->device->lun > us->max_lun)
211 {
212 us->srb->result = DID_BAD_TARGET << 16;
213 }
214 else if ((us->srb->cmnd[0] == INQUIRY) && (us->fflags & US_FL_FIX_INQUIRY))
215 {
216 unsigned char data_ptr[36] = {0x00, 0x80, 0x02, 0x02, 0x1F, 0x00, 0x00, 0x00};
217
218 fill_inquiry_response(us, data_ptr, 36);
219 us->srb->result = SAM_STAT_GOOD;
220 }
221 else
222 {
223 us->proto_handler(us->srb, us);
224 }
225
226 /* lock access to the state */
227 scsi_lock(host);
228
229 /* indicate that the command is done */
230 if (us->srb->result != DID_ABORT << 16)
231 {
232 us->srb->scsi_done(us->srb);
233 }
234 else
235 {
236SkipForAbort:
237 printk("scsi command aborted\n");
238 }
239
240 if (test_bit(US_FLIDX_TIMED_OUT, &us->dflags))
241 {
242 complete(&(us->notify));
243
244 /* Allow USB transfers to resume */
245 clear_bit(US_FLIDX_ABORTING, &us->dflags);
246 clear_bit(US_FLIDX_TIMED_OUT, &us->dflags);
247 }
248
249 /* finished working on this command */
250 us->srb = NULL;
251 scsi_unlock(host);
252
253 /* unlock the device pointers */
254 mutex_unlock(&us->dev_mutex);
255 } /* for (;;) */
256
257 /* Wait until we are told to stop */
258 for (;;)
259 {
260 set_current_state(TASK_INTERRUPTIBLE);
261 if (kthread_should_stop())
262 break;
263 schedule();
264 }
265 __set_current_state(TASK_RUNNING);
266 return 0;
267}
268
269//----- associate_dev() ---------------------
270static int associate_dev(struct us_data *us, struct usb_interface *intf)
271{
272 printk("usb --- associate_dev\n");
273
274 /* Fill in the device-related fields */
275 us->pusb_dev = interface_to_usbdev(intf);
276 us->pusb_intf = intf;
277 us->ifnum = intf->cur_altsetting->desc.bInterfaceNumber;
278
279 /* Store our private data in the interface */
280 usb_set_intfdata(intf, us);
281
282 /* Allocate the device-related DMA-mapped buffers */
283 us->cr = usb_alloc_coherent(us->pusb_dev, sizeof(*us->cr), GFP_KERNEL, &us->cr_dma);
284 if (!us->cr)
285 {
286 printk("usb_ctrlrequest allocation failed\n");
287 return -ENOMEM;
288 }
289
290 us->iobuf = usb_alloc_coherent(us->pusb_dev, US_IOBUF_SIZE, GFP_KERNEL, &us->iobuf_dma);
291 if (!us->iobuf)
292 {
293 printk("I/O buffer allocation failed\n");
294 return -ENOMEM;
295 }
296
297 us->sensebuf = kmalloc(US_SENSE_SIZE, GFP_KERNEL);
298 if (!us->sensebuf)
299 {
300 printk("Sense buffer allocation failed\n");
301 return -ENOMEM;
302 }
303 return 0;
304}
305
306//----- get_device_info() ---------------------
307static int get_device_info(struct us_data *us, const struct usb_device_id *id)
308{
309 struct usb_device *dev = us->pusb_dev;
310 struct usb_interface_descriptor *idesc = &us->pusb_intf->cur_altsetting->desc;
311
312 printk("usb --- get_device_info\n");
313
314 us->subclass = idesc->bInterfaceSubClass;
315 us->protocol = idesc->bInterfaceProtocol;
316 us->fflags = USB_US_ORIG_FLAGS(id->driver_info);
317 us->Power_IsResum = false;
318
319 if (us->fflags & US_FL_IGNORE_DEVICE)
320 {
321 printk("device ignored\n");
322 return -ENODEV;
323 }
324
325 if (dev->speed != USB_SPEED_HIGH)
326 us->fflags &= ~US_FL_GO_SLOW;
327
328 return 0;
329}
330
331//----- get_transport() ---------------------
332static int get_transport(struct us_data *us)
333{
334 printk("usb --- get_transport\n");
335 switch (us->protocol) {
336 case US_PR_BULK:
337 us->transport_name = "Bulk";
338 us->transport = usb_stor_Bulk_transport;
339 us->transport_reset = usb_stor_Bulk_reset;
340 break;
341
342 default:
343 return -EIO;
344 }
345 //printk("Transport: %s\n", us->transport_name);
346
347 /* fix for single-lun devices */
348 if (us->fflags & US_FL_SINGLE_LUN)
349 us->max_lun = 0;
350 return 0;
351}
352
353//----- get_protocol() ---------------------
354static int get_protocol(struct us_data *us)
355{
356 printk("usb --- get_protocol\n");
357 printk("us->pusb_dev->descriptor.idVendor = %x\n", us->pusb_dev->descriptor.idVendor);
358 printk("us->pusb_dev->descriptor.idProduct = %x\n", us->pusb_dev->descriptor.idProduct);
359 switch (us->subclass) {
360 case US_SC_SCSI:
361 us->protocol_name = "Transparent SCSI";
362 if( (us->pusb_dev->descriptor.idVendor == 0x0CF2) && (us->pusb_dev->descriptor.idProduct == 0x6250) )
363 us->proto_handler = ENE_stor_invoke_transport;
364 else
365 us->proto_handler = usb_stor_invoke_transport;
366 break;
367
368 default:
369 return -EIO;
370 }
371 //printk("Protocol: %s\n", us->protocol_name);
372 return 0;
373}
374
375//----- get_pipes() ---------------------
376static int get_pipes(struct us_data *us)
377{
378 struct usb_host_interface *altsetting = us->pusb_intf->cur_altsetting;
379 int i;
380 struct usb_endpoint_descriptor *ep;
381 struct usb_endpoint_descriptor *ep_in = NULL;
382 struct usb_endpoint_descriptor *ep_out = NULL;
383 struct usb_endpoint_descriptor *ep_int = NULL;
384
385 printk("usb --- get_pipes\n");
386
387 for (i = 0; i < altsetting->desc.bNumEndpoints; i++)
388 {
389 ep = &altsetting->endpoint[i].desc;
390
391 if (usb_endpoint_xfer_bulk(ep))
392 {
393 if (usb_endpoint_dir_in(ep))
394 {
395 if (!ep_in)
396 ep_in = ep;
397 }
398 else
399 {
400 if (!ep_out)
401 ep_out = ep;
402 }
403 }
404 else if (usb_endpoint_is_int_in(ep))
405 {
406 if (!ep_int)
407 ep_int = ep;
408 }
409 }
410
411 if (!ep_in || !ep_out || (us->protocol == US_PR_CBI && !ep_int))
412 {
413 printk("Endpoint sanity check failed! Rejecting dev.\n");
414 return -EIO;
415 }
416
417 /* Calculate and store the pipe values */
418 us->send_ctrl_pipe = usb_sndctrlpipe(us->pusb_dev, 0);
419 us->recv_ctrl_pipe = usb_rcvctrlpipe(us->pusb_dev, 0);
420 us->send_bulk_pipe = usb_sndbulkpipe(us->pusb_dev, ep_out->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
421 us->recv_bulk_pipe = usb_rcvbulkpipe(us->pusb_dev, ep_in->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
422 if (ep_int)
423 {
424 us->recv_intr_pipe = usb_rcvintpipe(us->pusb_dev, ep_int->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
425 us->ep_bInterval = ep_int->bInterval;
426 }
427 return 0;
428}
429
430//----- usb_stor_acquire_resources() ---------------------
431static int usb_stor_acquire_resources(struct us_data *us)
432{
433 struct task_struct *th;
434
435 printk("usb --- usb_stor_acquire_resources\n");
436 us->current_urb = usb_alloc_urb(0, GFP_KERNEL);
437 if (!us->current_urb)
438 {
439 printk("URB allocation failed\n");
440 return -ENOMEM;
441 }
442
443 /* Start up our control thread */
444 th = kthread_run(usb_stor_control_thread, us, "eucr-storage");
445 if (IS_ERR(th))
446 {
447 printk("Unable to start control thread\n");
448 return PTR_ERR(th);
449 }
450 us->ctl_thread = th;
451
452 return 0;
453}
454
455//----- usb_stor_release_resources() ---------------------
456static void usb_stor_release_resources(struct us_data *us)
457{
458 printk("usb --- usb_stor_release_resources\n");
459
460 SM_FreeMem();
461
462 complete(&us->cmnd_ready);
463 if (us->ctl_thread)
464 kthread_stop(us->ctl_thread);
465
466 /* Call the destructor routine, if it exists */
467 if (us->extra_destructor)
468 {
469 printk("-- calling extra_destructor()\n");
470 us->extra_destructor(us->extra);
471 }
472
473 /* Free the extra data and the URB */
474 kfree(us->extra);
475 usb_free_urb(us->current_urb);
476}
477
478//----- dissociate_dev() ---------------------
479static void dissociate_dev(struct us_data *us)
480{
481 printk("usb --- dissociate_dev\n");
482
483 kfree(us->sensebuf);
484
485 /* Free the device-related DMA-mapped buffers */
486 if (us->cr)
487 usb_free_coherent(us->pusb_dev, sizeof(*us->cr), us->cr, us->cr_dma);
488 if (us->iobuf)
489 usb_free_coherent(us->pusb_dev, US_IOBUF_SIZE, us->iobuf, us->iobuf_dma);
490
491 /* Remove our private data from the interface */
492 usb_set_intfdata(us->pusb_intf, NULL);
493}
494
495//----- quiesce_and_remove_host() ---------------------
496static void quiesce_and_remove_host(struct us_data *us)
497{
498 struct Scsi_Host *host = us_to_host(us);
499
500 printk("usb --- quiesce_and_remove_host\n");
501
502 /* If the device is really gone, cut short reset delays */
503 if (us->pusb_dev->state == USB_STATE_NOTATTACHED)
504 set_bit(US_FLIDX_DISCONNECTING, &us->dflags);
505
506 /* Prevent SCSI-scanning (if it hasn't started yet)
507 * and wait for the SCSI-scanning thread to stop.
508 */
509 set_bit(US_FLIDX_DONT_SCAN, &us->dflags);
510 wake_up(&us->delay_wait);
511 wait_for_completion(&us->scanning_done);
512
513 /* Removing the host will perform an orderly shutdown: caches
514 * synchronized, disks spun down, etc.
515 */
516 scsi_remove_host(host);
517
518 /* Prevent any new commands from being accepted and cut short
519 * reset delays.
520 */
521 scsi_lock(host);
522 set_bit(US_FLIDX_DISCONNECTING, &us->dflags);
523 scsi_unlock(host);
524 wake_up(&us->delay_wait);
525}
526
527//----- release_everything() ---------------------
528static void release_everything(struct us_data *us)
529{
530 printk("usb --- release_everything\n");
531
532 usb_stor_release_resources(us);
533 dissociate_dev(us);
534 scsi_host_put(us_to_host(us));
535}
536
537//----- usb_stor_scan_thread() ---------------------
538static int usb_stor_scan_thread(void * __us)
539{
540 struct us_data *us = (struct us_data *)__us;
541
542 printk("usb --- usb_stor_scan_thread\n");
543 printk("EUCR : device found at %d\n", us->pusb_dev->devnum);
544
545// Have we to add this code ?
546// set_freezable();
547// /* Wait for the timeout to expire or for a disconnect */
548// if (delay_use > 0)
549// {
550// wait_event_freezable_timeout(us->delay_wait,
551// test_bit(US_FLIDX_DONT_SCAN, &us->dflags),
552// delay_use * HZ);
553// }
554
555 /* If the device is still connected, perform the scanning */
556 if (!test_bit(US_FLIDX_DONT_SCAN, &us->dflags))
557 {
558 /* For bulk-only devices, determine the max LUN value */
559 if (us->protocol == US_PR_BULK && !(us->fflags & US_FL_SINGLE_LUN))
560 {
561 mutex_lock(&us->dev_mutex);
562 us->max_lun = usb_stor_Bulk_max_lun(us);
563 mutex_unlock(&us->dev_mutex);
564 }
565 scsi_scan_host(us_to_host(us));
566 printk("EUCR : device scan complete\n");
567 }
568 complete_and_exit(&us->scanning_done, 0);
569}
570
571//----- eucr_probe() ---------------------
572static int eucr_probe(struct usb_interface *intf, const struct usb_device_id *id)
573{
574 struct Scsi_Host *host;
575 struct us_data *us;
576 int result;
577 struct task_struct *th;
578
579 printk("usb --- eucr_probe\n");
580
581 host = scsi_host_alloc(&usb_stor_host_template, sizeof(*us));
582 if (!host)
583 {
584 printk("Unable to allocate the scsi host\n");
585 return -ENOMEM;
586 }
587
588 /* Allow 16-byte CDBs and thus > 2TB */
589 host->max_cmd_len = 16;
590 us = host_to_us(host);
591 memset(us, 0, sizeof(struct us_data));
592 mutex_init(&(us->dev_mutex));
593 init_completion(&us->cmnd_ready);
594 init_completion(&(us->notify));
595 init_waitqueue_head(&us->delay_wait);
596 init_completion(&us->scanning_done);
597
598 /* Associate the us_data structure with the USB device */
599 result = associate_dev(us, intf);
600 if (result)
601 goto BadDevice;
602
603 /* Get Device info */
604 result = get_device_info(us, id);
605 if (result)
606 goto BadDevice;
607
608 /* Get the transport, protocol, and pipe settings */
609 result = get_transport(us);
610 if (result)
611 goto BadDevice;
612 result = get_protocol(us);
613 if (result)
614 goto BadDevice;
615 result = get_pipes(us);
616 if (result)
617 goto BadDevice;
618
619 /* Acquire all the other resources and add the host */
620 result = usb_stor_acquire_resources(us);
621 if (result)
622 goto BadDevice;
623
624 result = scsi_add_host(host, &intf->dev);
625 if (result)
626 {
627 printk("Unable to add the scsi host\n");
628 goto BadDevice;
629 }
630
631 /* Start up the thread for delayed SCSI-device scanning */
632 th = kthread_create(usb_stor_scan_thread, us, "eucr-stor-scan");
633 if (IS_ERR(th))
634 {
635 printk("Unable to start the device-scanning thread\n");
636 complete(&us->scanning_done);
637 quiesce_and_remove_host(us);
638 result = PTR_ERR(th);
639 goto BadDevice;
640 }
641 wake_up_process(th);
642 return 0;
643
644 /* We come here if there are any problems */
645BadDevice:
646 printk("usb --- eucr_probe failed\n");
647 release_everything(us);
648 return result;
649}
650
651//----- eucr_disconnect() ---------------------
652static void eucr_disconnect(struct usb_interface *intf)
653{
654 struct us_data *us = usb_get_intfdata(intf);
655
656 printk("usb --- eucr_disconnect\n");
657 quiesce_and_remove_host(us);
658 release_everything(us);
659}
660
661/***********************************************************************
662 * Initialization and registration
663 ***********************************************************************/
664
665//----- usb_storage_driver() ---------------------
666static struct usb_driver usb_storage_driver = {
667 .name = "eucr",
668 .probe = eucr_probe,
669 .suspend = eucr_suspend,
670 .resume = eucr_resume,
671 .reset_resume = eucr_reset_resume,
672 .disconnect = eucr_disconnect,
673 .pre_reset = eucr_pre_reset,
674 .post_reset = eucr_post_reset,
675 .id_table = eucr_usb_ids,
676 .soft_unbind = 1,
677};
678
679//----- usb_stor_init() ---------------------
680static int __init usb_stor_init(void)
681{
682 int retval;
683 printk("usb --- usb_stor_init start\n");
684
685 retval = usb_register(&usb_storage_driver);
686 if (retval == 0)
687 printk("ENE USB Mass Storage support registered.\n");
688
689 return retval;
690}
691
692//----- usb_stor_exit() ---------------------
693static void __exit usb_stor_exit(void)
694{
695 printk("usb --- usb_stor_exit\n");
696
697 usb_deregister(&usb_storage_driver) ;
698}
699
700module_init(usb_stor_init);
701module_exit(usb_stor_exit);