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