On Thu, Oct 05, 2006 at 09:04:11AM +0200, Oliver Neukum wrote: > Hi, > > this implements suspend support for usblp. According to the CUPS people > ENODEV will make CUPS retry the job. Thus it is returned in the runtime > case. My printer survives suspend/resume cycles with it. > > Regards > Oliver
It looks very good, thanks Oliver! I hope it works as well, too. :) > Signed-off-by: Oliver Neukum <[EMAIL PROTECTED]> Signed-off-by: Vojtech Pavlik <[EMAIL PROTECTED]> Greg, can you add this to your tree? Vojtech > --- current/drivers/usb/class/usblp.c 2006-09-20 05:42:06.000000000 +0200 > +++ linux-2.6.18/drivers/usb/class/usblp.c 2006-10-05 08:50:57.000000000 > +0200 > @@ -154,6 +154,7 @@ > unsigned char used; /* True if open */ > unsigned char present; /* True if not > disconnected */ > unsigned char bidir; /* interface is > bidirectional */ > + unsigned char sleeping; /* interface is > suspended */ > unsigned char *device_id_string; /* IEEE 1284 DEVICE ID > string (ptr) */ > /* first 2 bytes are > (big-endian) length */ > }; > @@ -183,6 +184,7 @@ > dbg("quirks=%d", usblp->quirks); > dbg("used=%d", usblp->used); > dbg("bidir=%d", usblp->bidir); > + dbg("sleeping=%d", usblp->sleeping); > dbg("device_id_string=\"%s\"", > usblp->device_id_string ? > usblp->device_id_string + 2 : > @@ -338,6 +340,20 @@ > return newerr; > } > > +static int handle_bidir (struct usblp *usblp) > +{ > + if (usblp->bidir && usblp->used && !usblp->sleeping) { > + usblp->readcount = 0; > + usblp->readurb->dev = usblp->dev; > + if (usb_submit_urb(usblp->readurb, GFP_KERNEL) < 0) { > + usblp->used = 0; > + return -EIO; > + } > + } > + > + return 0; > +} > + > /* > * File op functions. > */ > @@ -390,14 +406,9 @@ > usblp->writeurb->status = 0; > usblp->readurb->status = 0; > > - if (usblp->bidir) { > - usblp->readcount = 0; > - usblp->readurb->dev = usblp->dev; > - if (usb_submit_urb(usblp->readurb, GFP_KERNEL) < 0) { > - retval = -EIO; > - usblp->used = 0; > - file->private_data = NULL; > - } > + if (handle_bidir(usblp) < 0) { > + file->private_data = NULL; > + retval = -EIO; > } > out: > mutex_unlock (&usblp_mutex); > @@ -460,6 +471,11 @@ > goto done; > } > > + if (usblp->sleeping) { > + retval = -ENODEV; > + goto done; > + } > + > dbg("usblp_ioctl: cmd=0x%x (%c nr=%d len=%d dir=%d)", cmd, > _IOC_TYPE(cmd), > _IOC_NR(cmd), _IOC_SIZE(cmd), _IOC_DIR(cmd) ); > > @@ -658,6 +674,11 @@ > return -ENODEV; > } > > + if (usblp->sleeping) { > + up (&usblp->sem); > + return writecount ? writecount : -ENODEV; > + } > + > if (usblp->writeurb->status != 0) { > if (usblp->quirks & USBLP_QUIRK_BIDIR) { > if (!usblp->wcomplete) > @@ -749,6 +770,11 @@ > goto done; > } > > + if (usblp->sleeping) { > + count = -ENODEV; > + goto done; > + } > + > if (usblp->readurb->status) { > err("usblp%d: error %d reading from printer", > usblp->minor, usblp->readurb->status); > @@ -1170,6 +1196,41 @@ > mutex_unlock (&usblp_mutex); > } > > +static int usblp_suspend (struct usb_interface *intf, pm_message_t message) > +{ > + struct usblp *usblp = usb_get_intfdata (intf); > + > + /* this races against normal access and open */ > + mutex_lock (&usblp_mutex); > + down (&usblp->sem); > + /* we take no more IO */ > + usblp->sleeping = 1; > + /* we wait for anything printing */ > + wait_event (usblp->wait, usblp->wcomplete || !usblp->present); > + usblp_unlink_urbs(usblp); > + up (&usblp->sem); > + mutex_unlock (&usblp_mutex); > + > + return 0; > +} > + > +static int usblp_resume (struct usb_interface *intf) > +{ > + struct usblp *usblp = usb_get_intfdata (intf); > + int r; > + > + mutex_lock (&usblp_mutex); > + down (&usblp->sem); > + > + usblp->sleeping = 0; > + r = handle_bidir (usblp); > + > + up (&usblp->sem); > + mutex_unlock (&usblp_mutex); > + > + return r; > +} > + > static struct usb_device_id usblp_ids [] = { > { USB_DEVICE_INFO(7, 1, 1) }, > { USB_DEVICE_INFO(7, 1, 2) }, > @@ -1186,6 +1247,8 @@ > .name = "usblp", > .probe = usblp_probe, > .disconnect = usblp_disconnect, > + .suspend = usblp_suspend, > + .resume = usblp_resume, > .id_table = usblp_ids, > }; > -- Vojtech Pavlik Director SuSE Labs ------------------------------------------------------------------------- Take Surveys. Earn Cash. Influence the Future of IT Join SourceForge.net's Techsay panel and you'll get the chance to share your opinions on IT & business topics through brief surveys -- and earn cash http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV _______________________________________________ linux-usb-devel@lists.sourceforge.net To unsubscribe, use the last form field at: https://lists.sourceforge.net/lists/listinfo/linux-usb-devel