]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
Merge 4.12-rc2 into usb-next
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 22 May 2017 07:00:23 +0000 (09:00 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 22 May 2017 07:00:23 +0000 (09:00 +0200)
We want the USB fixes in here as well to handle testing and merge
issues.

Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1  2 
drivers/usb/core/hcd.c
drivers/usb/misc/iowarrior.c
drivers/usb/storage/ene_ub6250.c

diff --combined drivers/usb/core/hcd.c
index 26d710eec7dacec4a5296e153f1e20670aeb7b50,5dea98358c05c46b09f913fee8b7c48d9f2c4f85..e72cbc75161919622e517c2d74d9deb04ef43367
@@@ -26,7 -26,6 +26,7 @@@
  #include <linux/module.h>
  #include <linux/version.h>
  #include <linux/kernel.h>
 +#include <linux/sched/task_stack.h>
  #include <linux/slab.h>
  #include <linux/completion.h>
  #include <linux/utsname.h>
@@@ -1524,14 -1523,6 +1524,14 @@@ int usb_hcd_map_urb_for_dma(struct usb_
                if (hcd->self.uses_pio_for_control)
                        return ret;
                if (IS_ENABLED(CONFIG_HAS_DMA) && hcd->self.uses_dma) {
 +                      if (is_vmalloc_addr(urb->setup_packet)) {
 +                              WARN_ONCE(1, "setup packet is not dma capable\n");
 +                              return -EAGAIN;
 +                      } else if (object_is_on_stack(urb->setup_packet)) {
 +                              WARN_ONCE(1, "setup packet is on stack\n");
 +                              return -EAGAIN;
 +                      }
 +
                        urb->setup_dma = dma_map_single(
                                        hcd->self.sysdev,
                                        urb->setup_packet,
                        } else if (is_vmalloc_addr(urb->transfer_buffer)) {
                                WARN_ONCE(1, "transfer buffer not dma capable\n");
                                ret = -EAGAIN;
 +                      } else if (object_is_on_stack(urb->transfer_buffer)) {
 +                              WARN_ONCE(1, "transfer buffer is on stack\n");
 +                              ret = -EAGAIN;
                        } else {
                                urb->transfer_dma = dma_map_single(
                                                hcd->self.sysdev,
@@@ -1735,7 -1723,7 +1735,7 @@@ int usb_hcd_unlink_urb (struct urb *urb
                if (retval == 0)
                        retval = -EINPROGRESS;
                else if (retval != -EIDRM && retval != -EBUSY)
-                       dev_dbg(&udev->dev, "hcd_unlink_urb %p fail %d\n",
+                       dev_dbg(&udev->dev, "hcd_unlink_urb %pK fail %d\n",
                                        urb, retval);
                usb_put_dev(udev);
        }
@@@ -1902,7 -1890,7 +1902,7 @@@ rescan
                /* kick hcd */
                unlink1(hcd, urb, -ESHUTDOWN);
                dev_dbg (hcd->self.controller,
-                       "shutdown urb %p ep%d%s%s\n",
+                       "shutdown urb %pK ep%d%s%s\n",
                        urb, usb_endpoint_num(&ep->desc),
                        is_in ? "in" : "out",
                        ({      char *s;
@@@ -2532,6 -2520,7 +2532,7 @@@ struct usb_hcd *__usb_create_hcd(const 
                hcd->bandwidth_mutex = kmalloc(sizeof(*hcd->bandwidth_mutex),
                                GFP_KERNEL);
                if (!hcd->bandwidth_mutex) {
+                       kfree(hcd->address0_mutex);
                        kfree(hcd);
                        dev_dbg(dev, "hcd bandwidth mutex alloc failed\n");
                        return NULL;
index 816afadc470729922c70dd63a2654b220b77e375,83b05a287b0c58f2b0b29f91fcddd0f307510b88..7ca4c7e0ea0ded0a651707546dc3eb04e71cc7bb
@@@ -368,9 -368,14 +368,9 @@@ static ssize_t iowarrior_write(struct f
        case USB_DEVICE_ID_CODEMERCS_IOWPV2:
        case USB_DEVICE_ID_CODEMERCS_IOW40:
                /* IOW24 and IOW40 use a synchronous call */
 -              buf = kmalloc(count, GFP_KERNEL);
 -              if (!buf) {
 -                      retval = -ENOMEM;
 -                      goto exit;
 -              }
 -              if (copy_from_user(buf, user_buffer, count)) {
 -                      retval = -EFAULT;
 -                      kfree(buf);
 +              buf = memdup_user(user_buffer, count);
 +              if (IS_ERR(buf)) {
 +                      retval = PTR_ERR(buf);
                        goto exit;
                }
                retval = usb_set_report(dev->interface, 2, 0, buf, count);
@@@ -549,7 -554,7 +549,7 @@@ static long iowarrior_ioctl(struct fil
                        info.revision = le16_to_cpu(dev->udev->descriptor.bcdDevice);
  
                        /* 0==UNKNOWN, 1==LOW(usb1.1) ,2=FULL(usb1.1), 3=HIGH(usb2.0) */
-                       info.speed = le16_to_cpu(dev->udev->speed);
+                       info.speed = dev->udev->speed;
                        info.if_num = dev->interface->cur_altsetting->desc.bInterfaceNumber;
                        info.report_size = dev->report_size;
  
index 22b850a1ce06c545dc085479b90a08bac76a0ad3,44af719194b239f760c77919bf7cf5bad19ed9d7..28100374f7bdec1e9f0f8eea1fb4923b32a97e62
@@@ -95,12 -95,12 +95,12 @@@ static struct us_unusual_dev ene_ub6250
  #define REG_HW_TRAP1        0xFF89
  
  /* SRB Status */
 -#define SS_SUCCESS                  0x00      /* No Sense */
 -#define SS_NOT_READY                0x02
 -#define SS_MEDIUM_ERR               0x03
 -#define SS_HW_ERR                   0x04
 -#define SS_ILLEGAL_REQUEST          0x05
 -#define SS_UNIT_ATTENTION           0x06
 +#define SS_SUCCESS            0x000000        /* No Sense */
 +#define SS_NOT_READY          0x023A00        /* Medium not present */
 +#define SS_MEDIUM_ERR         0x031100        /* Unrecovered read error */
 +#define SS_HW_ERR             0x040800        /* Communication failure */
 +#define SS_ILLEGAL_REQUEST    0x052000        /* Invalid command */
 +#define SS_UNIT_ATTENTION     0x062900        /* Reset occurred */
  
  /* ENE Load FW Pattern */
  #define SD_INIT1_PATTERN   1
@@@ -446,6 -446,10 +446,10 @@@ struct ms_lib_ctrl 
  #define SD_BLOCK_LEN  9
  
  struct ene_ub6250_info {
+       /* I/O bounce buffer */
+       u8              *bbuf;
        /* for 6250 code */
        struct SD_STATUS        SD_Status;
        struct MS_STATUS        MS_Status;
@@@ -493,8 -497,11 +497,11 @@@ static int ene_load_bincode(struct us_d
  
  static void ene_ub6250_info_destructor(void *extra)
  {
+       struct ene_ub6250_info *info = (struct ene_ub6250_info *) extra;
        if (!extra)
                return;
+       kfree(info->bbuf);
  }
  
  static int ene_send_scsi_cmd(struct us_data *us, u8 fDir, void *buf, int use_sg)
        return USB_STOR_TRANSPORT_GOOD;
  }
  
 -static int sd_scsi_test_unit_ready(struct us_data *us, struct scsi_cmnd *srb)
 +static int do_scsi_request_sense(struct us_data *us, struct scsi_cmnd *srb)
  {
        struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra;
 +      unsigned char buf[18];
  
 -      if (info->SD_Status.Insert && info->SD_Status.Ready)
 -              return USB_STOR_TRANSPORT_GOOD;
 -      else {
 -              ene_sd_init(us);
 -              return USB_STOR_TRANSPORT_GOOD;
 -      }
 +      memset(buf, 0, 18);
 +      buf[0] = 0x70;                          /* Current error */
 +      buf[2] = info->SrbStatus >> 16;         /* Sense key */
 +      buf[7] = 10;                            /* Additional length */
 +      buf[12] = info->SrbStatus >> 8;         /* ASC */
 +      buf[13] = info->SrbStatus;              /* ASCQ */
  
 +      usb_stor_set_xfer_buf(buf, sizeof(buf), srb);
        return USB_STOR_TRANSPORT_GOOD;
  }
  
 -static int sd_scsi_inquiry(struct us_data *us, struct scsi_cmnd *srb)
 +static int do_scsi_inquiry(struct us_data *us, struct scsi_cmnd *srb)
  {
        unsigned char data_ptr[36] = {
 -              0x00, 0x80, 0x02, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x55,
 +              0x00, 0x00, 0x02, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x55,
                0x53, 0x42, 0x32, 0x2E, 0x30, 0x20, 0x20, 0x43, 0x61,
                0x72, 0x64, 0x52, 0x65, 0x61, 0x64, 0x65, 0x72, 0x20,
                0x20, 0x20, 0x20, 0x20, 0x20, 0x30, 0x31, 0x30, 0x30 };
        return USB_STOR_TRANSPORT_GOOD;
  }
  
 +static int sd_scsi_test_unit_ready(struct us_data *us, struct scsi_cmnd *srb)
 +{
 +      struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra;
 +
 +      if (info->SD_Status.Insert && info->SD_Status.Ready)
 +              return USB_STOR_TRANSPORT_GOOD;
 +      else {
 +              ene_sd_init(us);
 +              return USB_STOR_TRANSPORT_GOOD;
 +      }
 +
 +      return USB_STOR_TRANSPORT_GOOD;
 +}
 +
  static int sd_scsi_mode_sense(struct us_data *us, struct scsi_cmnd *srb)
  {
        struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra;
@@@ -876,8 -867,9 +883,9 @@@ static int ms_read_readpage(struct us_d
                u8 PageNum, u32 *PageBuf, struct ms_lib_type_extdat *ExtraDat)
  {
        struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf;
+       struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra;
+       u8 *bbuf = info->bbuf;
        int result;
-       u8 ExtBuf[4];
        u32 bn = PhyBlockAddr * 0x20 + PageNum;
  
        result = ene_load_bincode(us, MS_RW_PATTERN);
        bcb->CDB[2]     = (unsigned char)(PhyBlockAddr>>16);
        bcb->CDB[6]     = 0x01;
  
-       result = ene_send_scsi_cmd(us, FDIR_READ, &ExtBuf, 0);
+       result = ene_send_scsi_cmd(us, FDIR_READ, bbuf, 0);
        if (result != USB_STOR_XFER_GOOD)
                return USB_STOR_TRANSPORT_ERROR;
  
        ExtraDat->status0  = 0x10;  /* Not yet,fireware support */
  
        ExtraDat->status1  = 0x00;  /* Not yet,fireware support */
-       ExtraDat->ovrflg   = ExtBuf[0];
-       ExtraDat->mngflg   = ExtBuf[1];
-       ExtraDat->logadr   = memstick_logaddr(ExtBuf[2], ExtBuf[3]);
+       ExtraDat->ovrflg   = bbuf[0];
+       ExtraDat->mngflg   = bbuf[1];
+       ExtraDat->logadr   = memstick_logaddr(bbuf[2], bbuf[3]);
  
        return USB_STOR_TRANSPORT_GOOD;
  }
@@@ -1348,8 -1340,9 +1356,9 @@@ static int ms_lib_read_extra(struct us_
                                u8 PageNum, struct ms_lib_type_extdat *ExtraDat)
  {
        struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf;
+       struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra;
+       u8 *bbuf = info->bbuf;
        int result;
-       u8 ExtBuf[4];
  
        memset(bcb, 0, sizeof(struct bulk_cb_wrap));
        bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
        bcb->CDB[2]     = (unsigned char)(PhyBlock>>16);
        bcb->CDB[6]     = 0x01;
  
-       result = ene_send_scsi_cmd(us, FDIR_READ, &ExtBuf, 0);
+       result = ene_send_scsi_cmd(us, FDIR_READ, bbuf, 0);
        if (result != USB_STOR_XFER_GOOD)
                return USB_STOR_TRANSPORT_ERROR;
  
        ExtraDat->intr     = 0x80;  /* Not yet, waiting for fireware support */
        ExtraDat->status0  = 0x10;  /* Not yet, waiting for fireware support */
        ExtraDat->status1  = 0x00;  /* Not yet, waiting for fireware support */
-       ExtraDat->ovrflg   = ExtBuf[0];
-       ExtraDat->mngflg   = ExtBuf[1];
-       ExtraDat->logadr   = memstick_logaddr(ExtBuf[2], ExtBuf[3]);
+       ExtraDat->ovrflg   = bbuf[0];
+       ExtraDat->mngflg   = bbuf[1];
+       ExtraDat->logadr   = memstick_logaddr(bbuf[2], bbuf[3]);
  
        return USB_STOR_TRANSPORT_GOOD;
  }
@@@ -1462,6 -1455,19 +1471,6 @@@ static int ms_scsi_test_unit_ready(stru
        return USB_STOR_TRANSPORT_GOOD;
  }
  
 -static int ms_scsi_inquiry(struct us_data *us, struct scsi_cmnd *srb)
 -{
 -      /* pr_info("MS_SCSI_Inquiry\n"); */
 -      unsigned char data_ptr[36] = {
 -              0x00, 0x80, 0x02, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x55,
 -              0x53, 0x42, 0x32, 0x2E, 0x30, 0x20, 0x20, 0x43, 0x61,
 -              0x72, 0x64, 0x52, 0x65, 0x61, 0x64, 0x65, 0x72, 0x20,
 -              0x20, 0x20, 0x20, 0x20, 0x20, 0x30, 0x31, 0x30, 0x30};
 -
 -      usb_stor_set_xfer_buf(data_ptr, 36, srb);
 -      return USB_STOR_TRANSPORT_GOOD;
 -}
 -
  static int ms_scsi_mode_sense(struct us_data *us, struct scsi_cmnd *srb)
  {
        struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra;
@@@ -1559,9 -1565,9 +1568,9 @@@ static int ms_lib_scan_logicalblocknumb
        u16 PhyBlock, newblk, i;
        u16 LogStart, LogEnde;
        struct ms_lib_type_extdat extdat;
-       u8 buf[0x200];
        u32 count = 0, index = 0;
        struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra;
+       u8 *bbuf = info->bbuf;
  
        for (PhyBlock = 0; PhyBlock < info->MS_Lib.NumberOfPhyBlock;) {
                ms_lib_phy_to_log_range(PhyBlock, &LogStart, &LogEnde);
                        }
  
                        if (count == PhyBlock) {
-                               ms_lib_read_extrablock(us, PhyBlock, 0, 0x80, &buf);
+                               ms_lib_read_extrablock(us, PhyBlock, 0, 0x80,
+                                               bbuf);
                                count += 0x80;
                        }
                        index = (PhyBlock % 0x80) * 4;
  
-                       extdat.ovrflg = buf[index];
-                       extdat.mngflg = buf[index+1];
-                       extdat.logadr = memstick_logaddr(buf[index+2], buf[index+3]);
+                       extdat.ovrflg = bbuf[index];
+                       extdat.mngflg = bbuf[index+1];
+                       extdat.logadr = memstick_logaddr(bbuf[index+2],
+                                       bbuf[index+3]);
  
                        if ((extdat.ovrflg & MS_REG_OVR_BKST) != MS_REG_OVR_BKST_OK) {
                                ms_lib_setacquired_errorblock(us, PhyBlock);
@@@ -1932,8 -1940,6 +1943,8 @@@ static int ene_load_bincode(struct us_d
        bcb->CDB[0] = 0xEF;
  
        result = ene_send_scsi_cmd(us, FDIR_WRITE, buf, 0);
 +      if (us->srb != NULL)
 +              scsi_set_resid(us->srb, 0);
        info->BIN_FLAG = flag;
        kfree(buf);
  
@@@ -2067,9 -2073,9 +2078,9 @@@ static int ene_ms_init(struct us_data *
  {
        struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf;
        int result;
-       u8 buf[0x200];
        u16 MSP_BlockSize, MSP_UserAreaBlocks;
        struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra;
+       u8 *bbuf = info->bbuf;
  
        printk(KERN_INFO "transport --- ENE_MSInit\n");
  
        bcb->CDB[0]     = 0xF1;
        bcb->CDB[1]     = 0x01;
  
-       result = ene_send_scsi_cmd(us, FDIR_READ, &buf, 0);
+       result = ene_send_scsi_cmd(us, FDIR_READ, bbuf, 0);
        if (result != USB_STOR_XFER_GOOD) {
                printk(KERN_ERR "Execution MS Init Code Fail !!\n");
                return USB_STOR_TRANSPORT_ERROR;
        }
        /* the same part to test ENE */
-       info->MS_Status = *(struct MS_STATUS *)&buf[0];
+       info->MS_Status = *(struct MS_STATUS *) bbuf;
  
        if (info->MS_Status.Insert && info->MS_Status.Ready) {
                printk(KERN_INFO "Insert     = %x\n", info->MS_Status.Insert);
                printk(KERN_INFO "IsMSPHG    = %x\n", info->MS_Status.IsMSPHG);
                printk(KERN_INFO "WtP= %x\n", info->MS_Status.WtP);
                if (info->MS_Status.IsMSPro) {
-                       MSP_BlockSize      = (buf[6] << 8) | buf[7];
-                       MSP_UserAreaBlocks = (buf[10] << 8) | buf[11];
+                       MSP_BlockSize      = (bbuf[6] << 8) | bbuf[7];
+                       MSP_UserAreaBlocks = (bbuf[10] << 8) | bbuf[11];
                        info->MSP_TotalBlock = MSP_BlockSize * MSP_UserAreaBlocks;
                } else {
                        ms_card_init(us); /* Card is MS (to ms.c)*/
                }
                usb_stor_dbg(us, "MS Init Code OK !!\n");
        } else {
-               usb_stor_dbg(us, "MS Card Not Ready --- %x\n", buf[0]);
+               usb_stor_dbg(us, "MS Card Not Ready --- %x\n", bbuf[0]);
                return USB_STOR_TRANSPORT_ERROR;
        }
  
  static int ene_sd_init(struct us_data *us)
  {
        int result;
-       u8  buf[0x200];
        struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf;
        struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra;
+       u8 *bbuf = info->bbuf;
  
        usb_stor_dbg(us, "transport --- ENE_SDInit\n");
        /* SD Init Part-1 */
        bcb->Flags              = US_BULK_FLAG_IN;
        bcb->CDB[0]             = 0xF1;
  
-       result = ene_send_scsi_cmd(us, FDIR_READ, &buf, 0);
+       result = ene_send_scsi_cmd(us, FDIR_READ, bbuf, 0);
        if (result != USB_STOR_XFER_GOOD) {
                usb_stor_dbg(us, "Execution SD Init Code Fail !!\n");
                return USB_STOR_TRANSPORT_ERROR;
        }
  
-       info->SD_Status =  *(struct SD_STATUS *)&buf[0];
+       info->SD_Status =  *(struct SD_STATUS *) bbuf;
        if (info->SD_Status.Insert && info->SD_Status.Ready) {
                struct SD_STATUS *s = &info->SD_Status;
  
-               ene_get_card_status(us, (unsigned char *)&buf);
+               ene_get_card_status(us, bbuf);
                usb_stor_dbg(us, "Insert     = %x\n", s->Insert);
                usb_stor_dbg(us, "Ready      = %x\n", s->Ready);
                usb_stor_dbg(us, "IsMMC      = %x\n", s->IsMMC);
                usb_stor_dbg(us, "HiSpeed    = %x\n", s->HiSpeed);
                usb_stor_dbg(us, "WtP        = %x\n", s->WtP);
        } else {
-               usb_stor_dbg(us, "SD Card Not Ready --- %x\n", buf[0]);
+               usb_stor_dbg(us, "SD Card Not Ready --- %x\n", bbuf[0]);
                return USB_STOR_TRANSPORT_ERROR;
        }
        return USB_STOR_TRANSPORT_GOOD;
  static int ene_init(struct us_data *us)
  {
        int result;
-       u8  misc_reg03 = 0;
+       u8  misc_reg03;
        struct ene_ub6250_info *info = (struct ene_ub6250_info *)(us->extra);
+       u8 *bbuf = info->bbuf;
  
-       result = ene_get_card_type(us, REG_CARD_STATUS, &misc_reg03);
+       result = ene_get_card_type(us, REG_CARD_STATUS, bbuf);
        if (result != USB_STOR_XFER_GOOD)
                return USB_STOR_TRANSPORT_ERROR;
  
+       misc_reg03 = bbuf[0];
        if (misc_reg03 & 0x01) {
                if (!info->SD_Status.Ready) {
                        result = ene_sd_init(us);
@@@ -2215,15 -2223,13 +2228,15 @@@ static int sd_scsi_irp(struct us_data *
        int    result;
        struct ene_ub6250_info *info = (struct ene_ub6250_info *)us->extra;
  
 -      info->SrbStatus = SS_SUCCESS;
        switch (srb->cmnd[0]) {
        case TEST_UNIT_READY:
                result = sd_scsi_test_unit_ready(us, srb);
                break; /* 0x00 */
 +      case REQUEST_SENSE:
 +              result = do_scsi_request_sense(us, srb);
 +              break; /* 0x03 */
        case INQUIRY:
 -              result = sd_scsi_inquiry(us, srb);
 +              result = do_scsi_inquiry(us, srb);
                break; /* 0x12 */
        case MODE_SENSE:
                result = sd_scsi_mode_sense(us, srb);
                result = USB_STOR_TRANSPORT_FAILED;
                break;
        }
 +      if (result == USB_STOR_TRANSPORT_GOOD)
 +              info->SrbStatus = SS_SUCCESS;
        return result;
  }
  
@@@ -2259,16 -2263,13 +2272,16 @@@ static int ms_scsi_irp(struct us_data *
  {
        int result;
        struct ene_ub6250_info *info = (struct ene_ub6250_info *)us->extra;
 -      info->SrbStatus = SS_SUCCESS;
 +
        switch (srb->cmnd[0]) {
        case TEST_UNIT_READY:
                result = ms_scsi_test_unit_ready(us, srb);
                break; /* 0x00 */
 +      case REQUEST_SENSE:
 +              result = do_scsi_request_sense(us, srb);
 +              break; /* 0x03 */
        case INQUIRY:
 -              result = ms_scsi_inquiry(us, srb);
 +              result = do_scsi_inquiry(us, srb);
                break; /* 0x12 */
        case MODE_SENSE:
                result = ms_scsi_mode_sense(us, srb);
                result = USB_STOR_TRANSPORT_FAILED;
                break;
        }
 +      if (result == USB_STOR_TRANSPORT_GOOD)
 +              info->SrbStatus = SS_SUCCESS;
        return result;
  }
  
  static int ene_transport(struct scsi_cmnd *srb, struct us_data *us)
  {
 -      int result = 0;
 +      int result = USB_STOR_XFER_GOOD;
        struct ene_ub6250_info *info = (struct ene_ub6250_info *)(us->extra);
  
        /*US_DEBUG(usb_stor_show_command(us, srb)); */
        scsi_set_resid(srb, 0);
 -      if (unlikely(!(info->SD_Status.Ready || info->MS_Status.Ready))) {
 +      if (unlikely(!(info->SD_Status.Ready || info->MS_Status.Ready)))
                result = ene_init(us);
 -      } else {
 +      if (result == USB_STOR_XFER_GOOD) {
 +              result = USB_STOR_TRANSPORT_ERROR;
                if (info->SD_Status.Ready)
                        result = sd_scsi_irp(us, srb);
  
                if (info->MS_Status.Ready)
                        result = ms_scsi_irp(us, srb);
        }
 -      return 0;
 +      return result;
  }
  
  static struct scsi_host_template ene_ub6250_host_template;
@@@ -2318,8 -2316,9 +2331,9 @@@ static int ene_ub6250_probe(struct usb_
                         const struct usb_device_id *id)
  {
        int result;
-       u8  misc_reg03 = 0;
+       u8  misc_reg03;
        struct us_data *us;
+       struct ene_ub6250_info *info;
  
        result = usb_stor_probe1(&us, intf, id,
                   (id - ene_ub6250_usb_ids) + ene_ub6250_unusual_dev_list,
                return result;
  
        /* FIXME: where should the code alloc extra buf ? */
-       if (!us->extra) {
-               us->extra = kzalloc(sizeof(struct ene_ub6250_info), GFP_KERNEL);
-               if (!us->extra)
-                       return -ENOMEM;
-               us->extra_destructor = ene_ub6250_info_destructor;
+       us->extra = kzalloc(sizeof(struct ene_ub6250_info), GFP_KERNEL);
+       if (!us->extra)
+               return -ENOMEM;
+       us->extra_destructor = ene_ub6250_info_destructor;
+       info = (struct ene_ub6250_info *)(us->extra);
+       info->bbuf = kmalloc(512, GFP_KERNEL);
+       if (!info->bbuf) {
+               kfree(us->extra);
+               return -ENOMEM;
        }
  
        us->transport_name = "ene_ub6250";
                return result;
  
        /* probe card type */
-       result = ene_get_card_type(us, REG_CARD_STATUS, &misc_reg03);
+       result = ene_get_card_type(us, REG_CARD_STATUS, info->bbuf);
        if (result != USB_STOR_XFER_GOOD) {
                usb_stor_disconnect(intf);
                return USB_STOR_TRANSPORT_ERROR;
        }
  
+       misc_reg03 = info->bbuf[0];
        if (!(misc_reg03 & 0x01)) {
                pr_info("ums_eneub6250: This driver only supports SD/MS cards. "
                        "It does not support SM cards.\n");