On Fri, 22 Jun 2007 10:52:18 +0200, Oliver Neukum <[EMAIL PROTECTED]> wrote:

> > +   if (urb->status < 0)
> > +           usblp->rstatus = urb->status;
> > +   else
> > +           usblp->rstatus = urb->actual_length;
> >     usblp->rcomplete = 1;
> > -unplug:
> > -   wake_up_interruptible(&usblp->wait);
> > +   wake_up(&usblp->rwait);
> 
> Why no longer _interruptible ?

Because I want to wake anything that gets into this wait list.
Currently, every waiter is interruptible, but I don't want to keep
track. It's the same thing as using spin_lock_irqsave().

> > +   spin_lock(&usblp->lock);
> > +   if (urb->status < 0)
> > +           usblp->wstatus = urb->status;
> > +   else
> > +           usblp->wstatus = urb->actual_length;
> 
> This raises the question why an error would mean that no payload
> has been transfered.

In the context of usblp it's pretty much the same thing. If the
stream is corrupt, you might as well abort the whole job: it's going
to be illegible. There's no reason to return the actual_length to
the application.

> > +   /* XXX Use usb_setup_bulk_urb when available. Talk to Marcel. */
> > +   kfree(urb->transfer_buffer);
> > +   urb->transfer_buffer = NULL;    /* Not refcounted, so to be safe... */
> > +   usb_free_urb(urb);
> 
> If you want to be safe, do it without a race.

What race?

> >  static void usblp_unlink_urbs(struct usblp *usblp)
> >  {
> > -   usb_kill_urb(usblp->writeurb);
> > -   if (usblp->bidir)
> > -           usb_kill_urb(usblp->readurb);
> > +   usb_kill_anchored_urbs(&usblp->urbs);
> >  }
> 
> What good does encapsulation here?

Believe it or not, this thought has crossed my mind.
I just wanted to preserve the area in case something else
would be needed. Observe that the usb-skeleton waits for the URBs
to complete. We do NOT do it on purpose, but this is unusual.

> >  static unsigned int usblp_poll(struct file *file, struct poll_table_struct 
> > *wait)
> >  {
> > +   int ret;
> > +   unsigned long flags;
> 
> We are called with interrupts on.

We discussed it a few times before. I guess my use of spin_lock in
callbacks wasn't enough to appease you, eh?

> > +   spin_lock_irqsave(&usblp->lock, flags);
> > +   ret = ((!usblp->bidir || !usblp->rcomplete) ? 0 : POLLIN  | POLLRDNORM)
> >                            | (!usblp->wcomplete ? 0 : POLLOUT | POLLWRNORM);
> > +   spin_unlock_irqrestore(&usblp->lock, flags);
> > +   return ret;
> >  }
> 
> Shouldn't disconnect cause an error to be reported?

Good question. Old driver didn't do it. Since URBs fail on disconnect,
it caused a momentary spin of the application and a EIO from next write.

If you have good contacts with CUPS people or other application writers,
it may help to ask them if they want anything. It's easy to add.

N.B., it may be useless, depending who schedules earlier. If the writer
wakes up before the khubd does, everything would happen just as it
always did (e.g. a quick loop-around and a EIO).

> > +   if (mutex_lock_interruptible(&usblp->wmut)) {
> > +           rv = -EINTR;
> 
> Why not -ERESTARTSYS ?

Hmm. Yes, the syscall is restartable at this point. I guess I inherited
it from the old driver, where the loop was unified, so it didn't try
to distinguish the cases when something was written or nothing was written,
and returned -EINTR always. On the other hand, what's the harm?

-- Pete

-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
linux-usb-devel@lists.sourceforge.net
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to