patch-2.4.26 linux-2.4.26/drivers/usb/printer.c
Next file: linux-2.4.26/drivers/usb/serial/ftdi_sio.c
Previous file: linux-2.4.26/drivers/usb/pegasus.h
Back to the patch index
Back to the overall index
- Lines: 66
- Date:
2004-04-14 06:05:33.000000000 -0700
- Orig file:
linux-2.4.25/drivers/usb/printer.c
- Orig date:
2004-02-18 05:36:31.000000000 -0800
diff -urN linux-2.4.25/drivers/usb/printer.c linux-2.4.26/drivers/usb/printer.c
@@ -604,14 +604,16 @@
{
DECLARE_WAITQUEUE(wait, current);
struct usblp *usblp = file->private_data;
- int timeout, err = 0;
+ int timeout, err = 0, transfer_length = 0;
size_t writecount = 0;
while (writecount < count) {
if (!usblp->wcomplete) {
barrier();
- if (file->f_flags & O_NONBLOCK)
- return -EAGAIN;
+ if (file->f_flags & O_NONBLOCK) {
+ writecount += transfer_length;
+ return writecount ? writecount : -EAGAIN;
+ }
timeout = USBLP_WRITE_TIMEOUT;
add_wait_queue(&usblp->wait, &wait);
@@ -655,27 +657,36 @@
continue;
}
- writecount += usblp->writeurb->transfer_buffer_length;
- usblp->writeurb->transfer_buffer_length = 0;
-
+ /* We must increment writecount here, and not at the
+ * end of the loop. Otherwise, the final loop iteration may
+ * be skipped, leading to incomplete printer output.
+ */
+ writecount += transfer_length;
if (writecount == count) {
up (&usblp->sem);
break;
}
- usblp->writeurb->transfer_buffer_length = (count - writecount) < USBLP_BUF_SIZE ?
- (count - writecount) : USBLP_BUF_SIZE;
+ transfer_length = count - writecount;
+ if(transfer_length > USBLP_BUF_SIZE)
+ transfer_length = USBLP_BUF_SIZE;
+
+ usblp->writeurb->transfer_buffer_length = transfer_length;
- if (copy_from_user(usblp->writeurb->transfer_buffer, buffer + writecount,
- usblp->writeurb->transfer_buffer_length)) {
+ if (copy_from_user(usblp->writeurb->transfer_buffer,
+ buffer + writecount, transfer_length)) {
up(&usblp->sem);
return writecount ? writecount : -EFAULT;
}
usblp->writeurb->dev = usblp->dev;
usblp->wcomplete = 0;
- if (usb_submit_urb(usblp->writeurb)) {
- count = -EIO;
+ err = usb_submit_urb(usblp->writeurb);
+ if (err) {
+ if (err != -ENOMEM)
+ count = -EIO;
+ else
+ count = writecount ? writecount : -ENOMEM;
up (&usblp->sem);
break;
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)