Re: [PATCH] [USB] UAS: eliminate infinite loop; add debug print

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



--- On Mon, 11/8/10, Matthew Wilcox <willy@xxxxxxxxxxxxxxx> wrote:
> -0700, Luben Tuikov wrote:
> > Eliminate an infinite loop whereby the SCSI layer
> > would reissue a command (which would be failed by
> > the driver) ad infinitum. (Invariably due to the
> > driver's profuse use of the
> > SCSI_MLQUEUE_DEVICE_BUSY returned result in its
> > queuecommand() method.)
> > 
> > Also add a debug option and a few debug prints.
> 
> Why have you added your own debug scheme instead of using
> dev_dbg?

Because, this debug "scheme" produces copious and otherwise unnecessary volume of debug information in a working driver. And because you can turn it on/off just for this driver. It is intended to be used only for debugging this driver and the UAS device(s) to which the driver communicates. 99.9% of the time, this setting will be a 'N' out there.  And this is what the Kconfig help entry says: "If unsure, say 'N'."

> You've made a lot of other random whitespace changes too.
> I'll pick through this and see what I like in it.

Yes, it's my emacs. I didn't find a setting to right-justify a continuing argument list of a function definition, nor have I seen this in the kernel before (since 2000 A.D. at least). Have you tried a function declaration instead, in this style? Do you think it would look good in a header file with more than one declaration?

> 
> > Signed-off-by: Luben Tuikov <ltuikov@xxxxxxxxx>
> > ---
> >  drivers/usb/storage/Kconfig 
> |   10 ++++
> >  drivers/usb/storage/Makefile |    4
> ++
> >  drivers/usb/storage/uas.c    | 
> 102 +++++++++++++++++++++++++++--------------
> >  3 files changed, 81 insertions(+), 35
> deletions(-)
> > 
> > diff --git a/drivers/usb/storage/Kconfig
> b/drivers/usb/storage/Kconfig
> > index 49a489e..eb9f6af 100644
> > --- a/drivers/usb/storage/Kconfig
> > +++ b/drivers/usb/storage/Kconfig
> > @@ -185,6 +185,16 @@ config USB_UAS
>
> >        If you compile this
> driver as a module, it will be named uas.
>
> > +config USB_UAS_DEBUG
> > +       bool "Compile in
> debug mode"
> > +       default n
> > +       depends on USB_UAS
> > +       help
> > +     Compiles the uas driver
> in debug mode. In debug mode,
> > +     the driver prints debug
> messages to the console.
> > +
> > +     If unsure, say 'N'.
> > +
> >  config USB_LIBUSUAL
> >      bool "The shared table of
> common (or usual) storage devices"
> >      depends on USB
> > diff --git a/drivers/usb/storage/Makefile
> b/drivers/usb/storage/Makefile
> > index fcf14cd..16715ab 100644
> > --- a/drivers/usb/storage/Makefile
> > +++ b/drivers/usb/storage/Makefile
> > @@ -10,6 +10,10 @@ ccflags-y := -Idrivers/scsi
> >  obj-$(CONFIG_USB_UAS)   
>     += uas.o
> >  obj-$(CONFIG_USB_STORAGE)    +=
> usb-storage.o
>
> > +ifeq ($(CONFIG_USB_UAS_DEBUG),y)
> > +    EXTRA_CFLAGS += -DUAS_DEBUG
> > +endif
> > +
> >  usb-storage-y := scsiglue.o protocol.o
> transport.o usb.o
> >  usb-storage-y += initializers.o sierra_ms.o
> option_ms.o
>
> > diff --git a/drivers/usb/storage/uas.c
> b/drivers/usb/storage/uas.c
> > index 48dc2b8..ef6e707 100644
> > --- a/drivers/usb/storage/uas.c
> > +++ b/drivers/usb/storage/uas.c
> > @@ -21,6 +21,14 @@
> >  #include <scsi/scsi_host.h>
> >  #include <scsi/scsi_tcq.h>
>
> > +#define uas_printk(fmt, ...)   
> printk(KERN_NOTICE "uas: " fmt, ## __VA_ARGS__)
> > +
> > +#ifdef UAS_DEBUG
> > +#define UAS_DPRINTK uas_printk
> > +#else
> > +#define UAS_DPRINTK(fmt, ...)
> > +#endif
> > +
> >  /* Common header for all IUs */
> >  struct iu {
> >      __u8 iu_id;
> > @@ -128,6 +136,7 @@ static void uas_do_work(struct
> work_struct *work)
> >  {
> >      struct uas_cmd_info
> *cmdinfo;
> >      struct list_head list;
> > +    int res;
>
> >     
> spin_lock_irq(&uas_work_lock);
> >     
> list_replace_init(&uas_work_list, &list);
> > @@ -136,8 +145,10 @@ static void uas_do_work(struct
> work_struct *work)
> >      list_for_each_entry(cmdinfo,
> &list, list) {
> >          struct
> scsi_pointer *scp = (void *)cmdinfo;
> >          struct
> scsi_cmnd *cmnd = container_of(scp,
> > -       
>            
>         struct scsi_cmnd,
> SCp);
> > -       
> uas_submit_urbs(cmnd, cmnd->device->hostdata,
> GFP_KERNEL);
> > +       
>            
>           struct scsi_cmnd,
> SCp);
> > +        res =
> uas_submit_urbs(cmnd, cmnd->device->hostdata,
> GFP_KERNEL);
> > +       
> UAS_DPRINTK("%s: cmd:%p, res:%d, state:0x%x\n",
> __FUNCTION__,
> > +       
>         cmnd, res,
> cmdinfo->state);
> >      }
> >  }
>
> > @@ -198,13 +209,15 @@ static void uas_sense_old(struct
> urb *urb, struct scsi_cmnd *cmnd)
> >  }
>
> >  static void uas_xfer_data(struct urb *urb,
> struct scsi_cmnd *cmnd,
> > -       
>            
>         unsigned direction)
> > +       
>       unsigned direction)
> >  {
> >      struct uas_cmd_info *cmdinfo
> = (void *)&cmnd->SCp;
> >      int err;
>
> >      cmdinfo->state = direction
> | SUBMIT_STATUS_URB;
> >      err = uas_submit_urbs(cmnd,
> cmnd->device->hostdata, GFP_ATOMIC);
> > +    UAS_DPRINTK("%s: cmd:%p, err:%d,
> state:0x%x\n", __FUNCTION__,
> > +           
> cmnd, err, cmdinfo->state);
> >      if (err) {
> >         
> spin_lock(&uas_work_lock);
> >         
> list_add_tail(&cmdinfo->list, &uas_work_list);
> > @@ -222,7 +235,8 @@ static void uas_stat_cmplt(struct
> urb *urb)
> >      u16 tag;
>
> >      if (urb->status) {
> > -       
> dev_err(&urb->dev->dev, "URB BAD STATUS %d\n",
> urb->status);
> > +       
> dev_err(&urb->dev->dev, "%s: URB BAD STATUS
> %d\n",
> > +       
>     __FUNCTION__, urb->status);
> >         
> usb_free_urb(urb);
> >          return;
> >      }
> > @@ -259,6 +273,14 @@ static void uas_stat_cmplt(struct
> urb *urb)
> >  static void uas_data_cmplt(struct urb *urb)
> >  {
> >      struct scsi_data_buffer *sdb
> = urb->context;
> > +
> > +    if (urb->status) {
> > +       
> dev_err(&urb->dev->dev, "%s: URB BAD STATUS
> %d\n",
> > +       
>     __FUNCTION__, urb->status);
> > +       
> usb_free_urb(urb);
> > +        return;
> > +    }
> > +    
> >      sdb->resid =
> sdb->length - urb->actual_length;
> >      usb_free_urb(urb);
> >  }
> > @@ -339,7 +361,7 @@ static struct urb
> *uas_alloc_cmd_urb(struct uas_dev_info *devinfo, gfp_t gfp,
> >      memcpy(iu->cdb,
> cmnd->cmnd, cmnd->cmd_len);
>
> >      usb_fill_bulk_urb(urb, udev,
> devinfo->cmd_pipe, iu, sizeof(*iu) + len,
> > -       
>            
>         usb_free_urb, NULL);
> > +       
>       usb_free_urb, NULL);
> >      urb->transfer_flags |=
> URB_FREE_BUFFER;
> >   out:
> >      return urb;
> > @@ -355,23 +377,26 @@ static struct urb
> *uas_alloc_cmd_urb(struct uas_dev_info *devinfo, gfp_t gfp,
> >   */
>
> >  static int uas_submit_urbs(struct scsi_cmnd
> *cmnd,
> > -       
>            
> struct uas_dev_info *devinfo, gfp_t gfp)
> > +       
>        struct uas_dev_info
> *devinfo, gfp_t gfp)
> >  {
> >      struct uas_cmd_info *cmdinfo
> = (void *)&cmnd->SCp;
> > +    int res;
>
> >      if (cmdinfo->state &
> ALLOC_STATUS_URB) {
> >         
> cmdinfo->status_urb = uas_alloc_sense_urb(devinfo, gfp,
> cmnd,
> >         
>            
>          
> cmdinfo->stream);
> >          if
> (!cmdinfo->status_urb)
> > -       
>     return SCSI_MLQUEUE_DEVICE_BUSY;
> > +       
>     return -ENOMEM;
> >         
> cmdinfo->state &= ~ALLOC_STATUS_URB;
> >      }
>
> >      if (cmdinfo->state &
> SUBMIT_STATUS_URB) {
> > -        if
> (usb_submit_urb(cmdinfo->status_urb, gfp)) {
> > +        res =
> usb_submit_urb(cmdinfo->status_urb, gfp);
> > +        if (res) {
> >         
>     scmd_printk(KERN_INFO, cmnd,
> > -       
>            
> "sense urb submission failure\n");
> > -       
>     return SCSI_MLQUEUE_DEVICE_BUSY;
> > +       
>             "sense
> urb submission failure (%d)\n",
> > +       
>             res);
> > +       
>     return res;
> >          }
> >         
> cmdinfo->state &= ~SUBMIT_STATUS_URB;
> >      }
> > @@ -381,15 +406,17 @@ static int
> uas_submit_urbs(struct scsi_cmnd *cmnd,
> >         
>            
> devinfo->data_in_pipe, cmdinfo->stream,
> >         
>            
> scsi_in(cmnd), DMA_FROM_DEVICE);
> >          if
> (!cmdinfo->data_in_urb)
> > -       
>     return SCSI_MLQUEUE_DEVICE_BUSY;
> > +       
>     return -ENOMEM;
> >         
> cmdinfo->state &= ~ALLOC_DATA_IN_URB;
> >      }
>
> >      if (cmdinfo->state &
> SUBMIT_DATA_IN_URB) {
> > -        if
> (usb_submit_urb(cmdinfo->data_in_urb, gfp)) {
> > +        res =
> usb_submit_urb(cmdinfo->data_in_urb, gfp);
> > +        if (res) {
> >         
>     scmd_printk(KERN_INFO, cmnd,

> > -       
>            
> "data in urb submission failure\n");
> > -       
>     return SCSI_MLQUEUE_DEVICE_BUSY;
> > +       
>             "data in
> urb submission failure (%d)\n",
> > +       
>             res);
> > +       
>     return res;
> >          }
> >         
> cmdinfo->state &= ~SUBMIT_DATA_IN_URB;
> >      }
> > @@ -399,15 +426,17 @@ static int
> uas_submit_urbs(struct scsi_cmnd *cmnd,
> >         
>            
> devinfo->data_out_pipe, cmdinfo->stream,
> >         
>            
> scsi_out(cmnd), DMA_TO_DEVICE);
> >          if
> (!cmdinfo->data_out_urb)
> > -       
>     return SCSI_MLQUEUE_DEVICE_BUSY;
> > +       
>     return -ENOMEM;
> >         
> cmdinfo->state &= ~ALLOC_DATA_OUT_URB;
> >      }
>
> >      if (cmdinfo->state &
> SUBMIT_DATA_OUT_URB) {
> > -        if
> (usb_submit_urb(cmdinfo->data_out_urb, gfp)) {
> > +        res =
> usb_submit_urb(cmdinfo->data_out_urb, gfp);
> > +        if (res) {
> >         
>     scmd_printk(KERN_INFO, cmnd,
> > -       
>            
> "data out urb submission failure\n");
> > -       
>     return SCSI_MLQUEUE_DEVICE_BUSY;
> > +       
>             "data
> out urb submission failure (%d)\n",
> > +       
>             res);
> > +       
>     return res;
> >          }
> >         
> cmdinfo->state &= ~SUBMIT_DATA_OUT_URB;
> >      }
> > @@ -416,15 +445,16 @@ static int
> uas_submit_urbs(struct scsi_cmnd *cmnd,
> >         
> cmdinfo->cmd_urb = uas_alloc_cmd_urb(devinfo, gfp, cmnd,
> >         
>            
>         cmdinfo->stream);
> >          if
> (!cmdinfo->cmd_urb)
> > -       
>     return SCSI_MLQUEUE_DEVICE_BUSY;
> > +       
>     return -ENOMEM;
> >         
> cmdinfo->state &= ~ALLOC_CMD_URB;
> >      }
>
> >      if (cmdinfo->state &
> SUBMIT_CMD_URB) {
> > -        if
> (usb_submit_urb(cmdinfo->cmd_urb, gfp)) {
> > +        res =
> usb_submit_urb(cmdinfo->cmd_urb, gfp);
> > +        if (res) {
> >         
>     scmd_printk(KERN_INFO, cmnd,
> > -       
>            
> "cmd urb submission failure\n");
> > -       
>     return SCSI_MLQUEUE_DEVICE_BUSY;
> > +       
>             "cmd urb
> submission failure (%d)\n", res);
> > +       
>     return res;
> >          }
> >         
> cmdinfo->state &= ~SUBMIT_CMD_URB;
> >      }
> > @@ -433,12 +463,12 @@ static int
> uas_submit_urbs(struct scsi_cmnd *cmnd,
> >  }
>
> >  static int uas_queuecommand(struct scsi_cmnd
> *cmnd,
> > -       
>            
> void (*done)(struct scsi_cmnd *))
> > +       
>         void (*done)(struct
> scsi_cmnd *))
> >  {
> >      struct scsi_device *sdev =
> cmnd->device;
> >      struct uas_dev_info *devinfo
> = sdev->hostdata;
> >      struct uas_cmd_info *cmdinfo
> = (void *)&cmnd->SCp;
> > -    int err;
> > +    int res;
>
> >      BUILD_BUG_ON(sizeof(struct
> uas_cmd_info) > sizeof(struct scsi_pointer));
>
> > @@ -474,17 +504,19 @@ static int
> uas_queuecommand(struct scsi_cmnd *cmnd,
> >         
> cmdinfo->stream = 0;
> >      }
>
> > -    err = uas_submit_urbs(cmnd,
> devinfo, GFP_ATOMIC);
> > -    if (err) {
> > -        /* If we did
> nothing, give up now */
> > -        if
> (cmdinfo->state & SUBMIT_STATUS_URB) {
> > -       
>     usb_free_urb(cmdinfo->status_urb);
> > -       
>     return SCSI_MLQUEUE_DEVICE_BUSY;
> > -        }
> > -       
> spin_lock(&uas_work_lock);
> > -       
> list_add_tail(&cmdinfo->list, &uas_work_list);
> > -       
> spin_unlock(&uas_work_lock);
> > -       
> schedule_work(&uas_work);
> > +    res = uas_submit_urbs(cmnd,
> devinfo, GFP_ATOMIC);
> > +    UAS_DPRINTK("%s: cmd:%p (0x%02x),
> err:%d, state:0x%x\n", __FUNCTION__,
> > +           
> cmnd, cmnd->cmnd[0], res, cmdinfo->state);
> > +    if (res) {
> > +       
> usb_unlink_urb(cmdinfo->status_urb);
> > +       
> usb_unlink_urb(cmdinfo->data_in_urb);
> > +       
> usb_unlink_urb(cmdinfo->data_out_urb);
> > +       
> usb_unlink_urb(cmdinfo->cmd_urb);
> > +
> > +       
> sdev->current_cmnd = NULL;
> > +
> > +        cmnd->result
> = DID_NO_CONNECT << 16;
> > +        done(cmnd);
> >      }
>
> >      return 0;
> > -- 
> > 1.7.0.1
> 
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux