Re: Support for Quatech ESU2-100 USB 2.0 8-port serial adaptor

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

 



On Thu, 2009-08-13 at 16:54 +0100, Alan Cox wrote:
> > +static int qt2_ioctl(struct tty_struct *tty, struct file *file,
> > +		     unsigned int cmd, unsigned long arg)
> 
> This looks pretty bogus.
> 
> TIOCMGET/TIOCMSET are not passed to the driver ioctl method but to your
> mget and mset operators so you can dump that lot in favour of the code
> you have later.
OK, the vendor driver not only had it in both places, but didn't do so
by calling the operators - it actually had the same code pasted in both
places. This patch removes the excess code and does some minor clean-up
of the remainder.

> > +	} else if (cmd == TIOCMIWAIT) {
> > +		dbg("%s() port %d, cmd == TIOCMIWAIT enter",
> > +			__func__, port->number);
> 
> This one if provided does need to be in the ioctl handler.
> 
> > +		prev_msr_value = port_extra->shadowMSR  & SERIAL_MSR_MASK;
> > +		while (1) {
> > +			add_wait_queue(&port_extra->wait, &wait);
> > +			set_current_state(TASK_INTERRUPTIBLE);
> > +			schedule();
> > +			dbg("%s(): port %d, cmd == TIOCMIWAIT here\n",
> > +				__func__, port->number);
> > +			remove_wait_queue(&port_extra->wait, &wait);
> > +			/* see if a signal woke us up */
> > +			if (signal_pending(current))
> > +				return -ERESTARTSYS;
> > +			msr_value = port_extra->shadowMSR & SERIAL_MSR_MASK;
> > +			if (msr_value == prev_msr_value)
> > +				return -EIO;  /* no change - error */
> 
> Why is this an error and not just a spurious wake up ?
Largely because it's what Greg K-H's example implementation of this function does ...
http://www.linuxjournal.com/article/6226
http://www.makelinux.net/ldd3/chp-18-sect-4.shtml
suggestions of what to return or whether to remove the test welcome, I
don't personally plan on using this ioctl, but as the vendor driver
includes it, I brought it along.

> What about disconnecting the adapter btw - shouldn't that break out of
> the loop with an error ?
I would think so, but I'm not sure how to achieve that. The crude
solution of inserting the line

port_extra->shadowMSR = !(port_extra->shadowMSR);

for each port into the release method, to ensure that the MSR always
changes on detach, comes to mind, but doesn't seem terribly elegant.
I've added a FIXME comment to this one.

Patch is on top of part 3 and the improvements to the write_room
implementation - I will re-send the patches in order once they are
nearer to ready.

Richard

Signed-off-by: Richard Ash <richard@xxxxxxxxxxxxxxxx>

---

Index: linux/drivers/staging/quatech_usb2/quatech_usb2.c
===================================================================
--- linux.orig/drivers/staging/quatech_usb2/quatech_usb2.c
+++ linux/drivers/staging/quatech_usb2/quatech_usb2.c
@@ -860,7 +860,10 @@ static int qt2_chars_in_buffer(struct tt
 	return chars;
 }
 
-
+/* called when userspace does an ioctl() on the device. Note that
+ * TIOCMGET and TIOCMSET are filtered off to their own methods before they get
+ * here, so we don't have to handle them.
+ */
 static int qt2_ioctl(struct tty_struct *tty, struct file *file,
 		     unsigned int cmd, unsigned long arg)
 {
@@ -887,22 +890,12 @@ static int qt2_ioctl(struct tty_struct *
 	dbg("%s(): port %d, UartNumber %d, tty =0x%p", __func__,
 	    port->number, UartNumber, tty);
 
-	if (cmd == TIOCMGET) {
-		return qt2_tiocmget(tty, file);
-		/* same as tiocmget function */
-	} else if (cmd == TIOCMSET) {
-		if (copy_from_user(&value, (unsigned int *)arg,
-			sizeof(unsigned int)))
-			return -EFAULT;
-		return qt2_tiocmset(tty, file, value, 0);
-		/* same as tiocmset function */
-	} else if (cmd == TIOCMBIS || cmd == TIOCMBIC) {
-		status = qt2_box_get_register(port->serial, UartNumber,
-				QT2_MODEM_CONTROL_REGISTER, &mcr_value);
-		if (status < 0)
+	if (cmd == TIOCMBIS || cmd == TIOCMBIC) {
+		if (qt2_box_get_register(port->serial, UartNumber,
+			QT2_MODEM_CONTROL_REGISTER, &mcr_value) < 0)
 			return -ESPIPE;
 		if (copy_from_user(&value, (unsigned int *)arg,
-			sizeof(unsigned int)))
+			sizeof(value)))
 			return -EFAULT;
 
 		switch (cmd) {
@@ -925,9 +918,8 @@ static int qt2_ioctl(struct tty_struct *
 		default:
 		break;
 		}	/* end of local switch on cmd */
-		status = qt2_box_set_register(port->serial,  UartNumber,
-				QT2_MODEM_CONTROL_REGISTER, mcr_value);
-		if (status < 0) {
+		if (qt2_box_set_register(port->serial,  UartNumber,
+		    QT2_MODEM_CONTROL_REGISTER, mcr_value) < 0) {
 			return -ESPIPE;
 		} else {
 			port_extra->shadowMCR = mcr_value;
@@ -965,6 +957,10 @@ static int qt2_ioctl(struct tty_struct *
 				return 0;
 			}
 		} /* end inifinite while */
+		/* FIXME: This while loop needs a way to break out if the device
+		 * is disconnected while a process is waiting for the MSR to
+		 * change, because once it's disconnected, it isn't going to
+		 * change state ... */
 	} else {
 		/* any other ioctls we don't know about come here */
 		dbg("%s(): No ioctl for that one. port = %d", __func__,


--
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